]> The Tcpdump Group git mirrors - libpcap/commitdiff
Turn off non-blocking mode on the socket we got from accept().
authorGuy Harris <[email protected]>
Sun, 1 Apr 2018 02:28:15 +0000 (19:28 -0700)
committerGuy Harris <[email protected]>
Sun, 1 Apr 2018 02:28:15 +0000 (19:28 -0700)
Doing WSAEventSelect() on a socket turns on non-blocking mode on that
socket.  accept(), on a non-blocking socket, returns a non-blocking
socket and, if the listen socket is non-blocking because
WSAEventSelect() was done on it, returns a non-blocking socket *with
WSAEventSelect() in effect*, so you have to remove the events and then
turn off non-blocking mode.

Thanks, Microsoft.

rpcapd/rpcapd.c

index eb11aafb8e7c13b74fae3ba4c1111c4b6358d779..6f6ea136ebb43d2a515aed4e4de9a10d665e1871 100755 (executable)
@@ -892,6 +892,7 @@ accept_connection(SOCKET listen_sock)
 
 #ifdef _WIN32
        HANDLE threadId;                        // handle for the subthread
+       u_long off = 0;
 #else
        pid_t pid;
 #endif
@@ -942,8 +943,31 @@ accept_connection(SOCKET listen_sock)
                return;
        }
 
-
 #ifdef _WIN32
+       //
+       // Put the socket back into blocking mode; doing WSAEventSelect()
+       // on the listen socket makes that socket non-blocking, and it
+       // appears that sockets returned from an accept() on that socket
+       // are also non-blocking.
+       //
+       // First, we have to un-WSAEventSelect() this socket, and then
+       // we can turn non-blocking mode off.
+       //
+       if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
+       {
+               sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
+               rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+               sock_close(sockctrl, NULL, 0);
+               return;
+       }
+       if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
+       {
+               sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
+               rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+               sock_close(sockctrl, NULL, 0);
+               return;
+       }
+
        // in case of passive mode, this variable is deallocated by the daemon_serviceloop()
        pars = (struct daemon_slpars *) malloc (sizeof(struct daemon_slpars));
        if (pars == NULL)