[ovs-dev] [PATCH] stream-tcp: Call setsockopt TCP_NODELAY after TCP is connected for Windows.

Gurucharan Shetty shettyg at nicira.com
Thu Oct 2 15:16:56 UTC 2014


On Windows platform, TCP_NODELAY can only be set when TCP is established.
The current code does not create any problems while running unit tests
(because connections get established immediately) but is observed while
connecting to a different machine.

commit 8b76839(Move setsockopt TCP_NODELAY to when TCP is connected.)
made changes to call setsockopt with TCP_NODELAY after TCP is connected
only in lib/stream-ssl.c. We need the same change for stream-tcp too.

Signed-off-by: Gurucharan Shetty <gshetty at nicira.com>
---
 lib/socket-util.c       |   15 +++++++++++++++
 lib/socket-util.h       |    1 +
 lib/stream-fd-windows.c |    9 ++++++++-
 lib/stream-ssl.c        |   14 --------------
 lib/stream-tcp.c        |   21 ++++++++++++++-------
 5 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/lib/socket-util.c b/lib/socket-util.c
index c0438d9..c9b6b80 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <net/if.h>
 #include <netdb.h>
+#include <netinet/tcp.h>
 #include <poll.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -88,6 +89,20 @@ xset_nonblocking(int fd)
 }
 
 int
+setsockopt_tcp_nodelay(int fd)
+{
+    int on = 1;
+    int retval;
+
+    retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
+    if (retval) {
+        retval = sock_errno();
+        VLOG_ERR("setsockopt(TCP_NODELAY): %s", sock_strerror(retval));
+    }
+    return retval;
+}
+
+int
 set_dscp(int fd, uint8_t dscp)
 {
     int val;
diff --git a/lib/socket-util.h b/lib/socket-util.h
index 3db9a89..68b412b 100644
--- a/lib/socket-util.h
+++ b/lib/socket-util.h
@@ -29,6 +29,7 @@
 
 int set_nonblocking(int fd);
 void xset_nonblocking(int fd);
+int setsockopt_tcp_nodelay(int fd);
 int set_dscp(int fd, uint8_t dscp);
 
 int lookup_ip(const char *host_name, struct in_addr *address);
diff --git a/lib/stream-fd-windows.c b/lib/stream-fd-windows.c
index e366c71..f7550ff 100644
--- a/lib/stream-fd-windows.c
+++ b/lib/stream-fd-windows.c
@@ -83,7 +83,14 @@ static int
 fd_connect(struct stream *stream)
 {
     struct stream_fd *s = stream_fd_cast(stream);
-    return check_connection_completion(s->fd);
+    int retval = check_connection_completion(s->fd);
+    if (retval == 0) {
+        retval = setsockopt_tcp_nodelay(s->fd);
+        if (retval) {
+            return retval;
+        }
+    }
+    return retval;
 }
 
 static ssize_t
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index dd40010..4913066 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -219,20 +219,6 @@ want_to_poll_events(int want)
 }
 
 static int
-setsockopt_tcp_nodelay(int fd)
-{
-    int on = 1;
-    int retval;
-
-    retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
-    if (retval) {
-        retval = sock_errno();
-        VLOG_ERR("setsockopt(TCP_NODELAY): %s", sock_strerror(retval));
-    }
-    return retval;
-}
-
-static int
 new_ssl_stream(const char *name, int fd, enum session_type type,
                enum ssl_state state, struct stream **streamp)
 {
diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c
index ea6ef69..b8c4680 100644
--- a/lib/stream-tcp.c
+++ b/lib/stream-tcp.c
@@ -20,7 +20,6 @@
 #include <inttypes.h>
 #include <sys/types.h>
 #include <netinet/in.h>
-#include <netinet/tcp.h>
 #include <netdb.h>
 #include <stdlib.h>
 #include <string.h>
@@ -44,7 +43,6 @@ new_tcp_stream(const char *name, int fd, int connect_status,
 {
     struct sockaddr_storage local;
     socklen_t local_len = sizeof local;
-    int on = 1;
     int retval;
 
     /* Get the local IP and port information */
@@ -53,14 +51,23 @@ new_tcp_stream(const char *name, int fd, int connect_status,
         memset(&local, 0, sizeof local);
     }
 
-    retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
+#ifdef _WIN32
+    /* On Windows platform, disabling of Nagle algorithm can only be
+     * done when TCP session is connected. */
+    if (connect_status == 0) {
+        retval = setsockopt_tcp_nodelay(fd);
+        if (retval) {
+            closesocket(fd);
+            return retval;
+        }
+    }
+#else
+    retval = setsockopt_tcp_nodelay(fd);
     if (retval) {
-        int error = sock_errno();
-        VLOG_ERR("%s: setsockopt(TCP_NODELAY): %s",
-                 name, sock_strerror(error));
         closesocket(fd);
-        return error;
+        return retval;
     }
+#endif
 
     return new_fd_stream(name, fd, connect_status, streamp);
 }
-- 
1.7.9.5




More information about the dev mailing list