#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
#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
}
//
- // 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 */
{
rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
strerror(errno));
- goto error;
+ sock_close(sockctrl, NULL, 0);
+ return;
}
if (pid == 0)
{
// 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);
}
/*!
//
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);
//
// 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;
}