Skip to content

Commit

Permalink
Use (non-POSIX) timeout variant for thread joining at the end of the …
Browse files Browse the repository at this point in the history
…dhcp-discover routine to prevent hanging threads from being able to cause the tool to stall forever

Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
DL6ER committed Feb 11, 2025
1 parent c8df4b6 commit a7cee05
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions src/tools/dhcp-discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ struct dhcp_packet_data
};

// sends a DHCPDISCOVER message to the specified in an attempt to find DHCP servers
static bool send_dhcp_discover(const int sock, const uint32_t xid, const char *iface, unsigned char *mac)
static bool send_dhcp_discover(const int sock, const uint32_t xid, const char *iface, const unsigned char *mac)
{
struct dhcp_packet_data discover_packet = { 0 };

Expand Down Expand Up @@ -560,7 +560,7 @@ static bool receive_dhcp_packet(void *buffer, int buffer_size, const char *iface
}

// waits for a DHCPOFFER message from one or more DHCP servers
static unsigned int get_dhcp_offer(const int sock, const uint32_t xid, const char *iface, unsigned char *mac)
static unsigned int get_dhcp_offer(const int sock, const uint32_t xid, const char *iface, const unsigned char *mac)
{
struct dhcp_packet_data offer_packet;
struct sockaddr_in source;
Expand Down Expand Up @@ -825,6 +825,22 @@ int run_dhcp_discover(void)
tmp = tmp->ifa_next;
}

// Warn if there are additional interfaces we have not checked here
// because of the limit given my MAXTHREADS
if(tmp != NULL)
printf_locked("Warning: Not all interfaces will be scanned, internal limit of %d reached\n", MAXTHREADS);

// Destroy the thread attributes object, since we're done with it
pthread_attr_destroy(&attr);

// Set timeout for pthread_timedjoin_np() relative to CLOCK_REALTIME
struct timespec timeout = { 0 };
if(clock_gettime(CLOCK_REALTIME, &timeout) < 0)
perror("Error setting joining timeout");

// Add SCAN_TIMEOUT + 2 (safety margin) seconds to the current time
timeout.tv_sec += SCAN_TIMEOUT + 2;

// Wait for all threads to join back with us
for(tid--; tid > -1; tid--)
{
Expand All @@ -835,9 +851,14 @@ int run_dhcp_discover(void)
if(scanthread[tid] != 0)
{
void *args = NULL;
pthread_join(scanthread[tid], &args);
const int ret = pthread_timedjoin_np(scanthread[tid], &args, &timeout);
struct thread_info *tdata = (struct thread_info *)args;
if(tdata != NULL)
if (ret != 0)
{
const char *reason = ret == ETIMEDOUT ? "timeout" : strerror(ret);
printf("Error joining IPv4 scanning thread %d: %s\n", tid, reason);
}
else if(tdata != NULL)
{
iface = tdata->iface;
v4 = tdata->responses > 0 ? tdata->responses : 0;
Expand All @@ -848,9 +869,14 @@ int run_dhcp_discover(void)
if(scanthread[MAXTHREADS + tid] != 0)
{
void *args = NULL;
pthread_join(scanthread[MAXTHREADS + tid], &args);
const int ret = pthread_timedjoin_np(scanthread[MAXTHREADS + tid], &args, &timeout);
struct thread_info *tdata = (struct thread_info *)args;
if(tdata != NULL)
if (ret != 0)
{
const char *reason = ret == ETIMEDOUT ? "timeout" : strerror(ret);
printf("Error joining IPv6 scanning thread %d: %s\n", tid, reason);
}
else if(tdata != NULL)
{
iface = tdata->iface;
v6 = tdata->responses > 0 ? tdata->responses : 0;
Expand Down

0 comments on commit a7cee05

Please sign in to comment.