This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Bug at getsockopt when TCP_NODELAY is used as parameter

While compiling varnish 3.0.5, I have detected a possible bug at getsockopt when TCP_NODELAY is used as parameter. The issue is caused because at cygwin it returns a BOOL, instead returning INT value like at Linux.

At varnish 3.0.5, the following code at "sock_test(int fd)" uses getsockopt:

    l = sizeof tcp_nodelay;
    i = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay, &l);
    if (i) {
    assert(l == sizeof tcp_nodelay);
    if (!tcp_nodelay)
        need_tcpnodelay = 1;

The problem is that at cygwin, this ASSERT fails:
    -     assert(l == sizeof tcp_nodelay);

Because before function call, the initial tcp_nodelay variable size is INT, but after funtion call, it returns a pointer to a BOOL variable, so assert (sizeof INT == sizeof BOOL) fails.

After some investigations I have seen that at windows, its getsockopt function, returns BOOL for TCP_NODELAY: -

But at Unix, the correct behaviour is to return INT:

I suppose that the cygwin getsockopt internally calls to Windows getsockopt, and no type conversion of variables is done. I think the solution would be to wrap getsockopt response and change it from bool size variable to a int size variable.

As a temporary workaround for varnish 3.0.5 I have changed the variable types to bool, but I think It would be better to directly fix it at cygwin layer, to avoid modifications to original Linux code:

--- origsrc/varnish-3.0.5/bin/varnishd/cache_acceptor.c 2013-12-02 08:48:15.000000000 +0100 +++ src/varnish-3.0.5/bin/varnishd/cache_acceptor.c 2014-04-17 21:31:12.555512600 +0200
@@ -36,6 +36,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
+#if defined(__CYGWIN__)
+#include <stdbool.h>

 #include <sys/uio.h>
 #include <sys/types.h>
@@ -105,7 +108,12 @@ sock_test(int fd)
     struct linger lin;
     struct timeval tv;
     socklen_t l;
-    int i, tcp_nodelay;
+    int i;
+    #if defined(__CYGWIN__)
+    bool tcp_nodelay;
+    #else
+    int tcp_nodelay;
+    #endif

     l = sizeof lin;
     i = getsockopt(fd, SOL_SOCKET, SO_LINGER, &lin, &l);
@@ -172,7 +180,11 @@ VCA_Prep(struct sess *sp)
     char addr[VTCP_ADDRBUFSIZE];
     char port[VTCP_PORTBUFSIZE];
+    #if defined(__CYGWIN__)
+    bool tcp_nodelay = true;
+    #else
     int tcp_nodelay = 1;
+    #endif

     VTCP_name(sp->sockaddr, sp->sockaddrlen,
         addr, sizeof addr, port, sizeof port);

Thank you

This email is free from viruses and malware because avast! Antivirus protection is active.

Problem reports:
Unsubscribe info:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]