]> The Tcpdump Group git mirrors - libpcap/commitdiff
Pass a copy of the host/port list to daemon_serviceloop() on Windows.
authorGuy Harris <[email protected]>
Tue, 8 Jan 2019 07:25:40 +0000 (23:25 -0800)
committerGuy Harris <[email protected]>
Tue, 8 Jan 2019 07:25:40 +0000 (23:25 -0800)
Rename the sock_copy structure to params_copy, and add a pointer to the
host list to it.  Make the copy, stuff a pointer to it into the
allocated structure, and do the appropriate freeing on errors; in the
initial routine of the service thread, pass on the host list pointer
from the structure.

rpcapd/rpcapd.c

index 26b6e8ab5d06ba8be3ab94fd1b5873786644d5d6..cb855d7f8005cc639dd5e7b14e37a8d71e566879 100644 (file)
@@ -1102,12 +1102,15 @@ accept_connections(void)
 
 #ifdef _WIN32
 //
-// A structure to hold the parameter to the windows thread
-// (on unix there is no need for this explicit copy since the
-// fork "inherits" the parent stack)
+// A structure to hold the parameters to the daemon service loop
+// thread on Windows.
 //
-struct sock_copy {
+// (On UN*X, there is no need for this explicit copy since the
+// fork "inherits" the parent stack.)
+//
+struct params_copy {
        SOCKET sockctrl;
+       char *hostlist;
 };
 #endif
 
@@ -1126,7 +1129,7 @@ accept_connection(SOCKET listen_sock)
 #ifdef _WIN32
        HANDLE threadId;                        // handle for the subthread
        u_long off = 0;
-       struct sock_copy *sock_copy = NULL;
+       struct params_copy *parms_copy = NULL;
 #else
        pid_t pid;
 #endif
@@ -1197,28 +1200,45 @@ accept_connection(SOCKET listen_sock)
        }
 
        //
-       // Allocate a location to hold the value of sockctrl.
+       // Make a copy of the host list to pass to the new thread, so that
+       // if we update it in the main thread, it won't catch us in the
+       // middle of updating it.
+       //
+       // daemon_serviceloop() will free it once it's done with it.
+       //
+       char *hostlist_copy = strdup(hostlist);
+       if (hostlist_copy == NULL)
+       {
+               rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
+               sock_close(sockctrl, NULL, 0);
+               return;
+       }
+
+       //
+       // Allocate a location to hold the values of sockctrl.
        // It will be freed in the newly-created thread once it's
        // finished with it.
-       // I guess we *could* just cast sockctrl to a void *, but that's
-       // a bit ugly.
        //
-       sock_copy = malloc(sizeof(*sock_copy));
-       if (sock_copy == NULL)
+       params_copy = malloc(sizeof(*params_copy));
+       if (params_copy == NULL)
        {
-               pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
-                   errno, "malloc() failed");
-               rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
-               goto error;
+               rpcapd_log(LOGPRIO_ERROR, "Out of memory allocating the parameter copy structure");
+               free(hostlist_copy);
+               sock_close(sockctrl, NULL, 0);
+               return;
        }
-       sock_copy->sockctrl = sockctrl;
+       params_copy->sockctrl = sockctrl;
+       params_copy->hostlist = hostlist_copy;
 
        threadId = (HANDLE)_beginthreadex(NULL, 0,
-           main_passive_serviceloop_thread, (void *) sock_copy, 0, NULL);
+           main_passive_serviceloop_thread, (void *) params_copy, 0, NULL);
        if (threadId == 0)
        {
                rpcapd_log(LOG_ERROR, "Error creating the child thread");
-               goto error;
+               free(params_copy);
+               free(hostlist_copy);
+               sock_close(sockctrl, NULL, 0);
+               return;
        }
        CloseHandle(threadId);
 #else /* _WIN32 */
@@ -1227,7 +1247,8 @@ accept_connection(SOCKET listen_sock)
        {
                rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
                    strerror(errno));
-               goto error;
+               sock_close(sockctrl, NULL, 0);
+               return;
        }
        if (pid == 0)
        {
@@ -1276,13 +1297,6 @@ accept_connection(SOCKET listen_sock)
        // Close the socket for this session (must be open only in the child)
        closesocket(sockctrl);
 #endif /* _WIN32 */
-       return;
-
-error:
-#ifdef _WIN32
-       if (sock_copy) free(sock_copy);
-#endif
-       sock_close(sockctrl, NULL, 0);
 }
 
 /*!
@@ -1382,7 +1396,7 @@ main_active(void *ptr)
 //
 unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
 {
-       struct sock_copy sock = *(struct sock_copy *)ptr;
+       struct params_copy params = *(struct params_copy *)ptr;
        free(ptr);
 
        //
@@ -1390,10 +1404,10 @@ unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
        // This is passive mode, so we don't care whether we were
        // told by the client to close.
        //
-       (void)daemon_serviceloop(sock.sockctrl, sock.sockctrl, 0,
-           nullAuthAllowed, uses_ssl);
+       (void)daemon_serviceloop(params.sockctrl, params.sockctrl, 0,
+           params.hostlist, nullAuthAllowed, uses_ssl);
 
-       sock_close(sock.sockctrl, NULL, 0);
+       sock_close(params.sockctrl, NULL, 0);
 
        return 0;
 }