- Partial rewrite of dispatch()

- Header cleanup
 - Fix several bugs related to null pointer access and out-of-bounds array access
 - Found by Amine Khaldi
 - This should fix the issue with dhcp crashing and hogging tons of cpu time

svn path=/trunk/; revision=43095
This commit is contained in:
Cameron Gutman 2009-09-20 15:00:08 +00:00
parent ba7067eafa
commit 4834de3328
6 changed files with 45 additions and 66 deletions

View file

@ -169,10 +169,9 @@ BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
Adapter->DhclientState.state = S_STATIC;
Netmask = RegReadString( AdapterKey, NULL, "Subnetmask" );
if( !Netmask ) Netmask = "255.255.255.0";
Status = AddIPAddress( inet_addr( IPAddress ),
inet_addr( Netmask ),
inet_addr( Netmask ? Netmask : "255.255.255.0" ),
Adapter->IfMib.dwIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
@ -257,7 +256,7 @@ BOOLEAN AdapterDiscover() {
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
Table->table[i].dwIndex));
if (AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen))
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
{
/* This is an existing adapter */
if (InterfaceConnected(Table->table[i])) {

View file

@ -1576,8 +1576,10 @@ write_client_lease(struct interface_info *ip, struct client_lease *lease,
if (!leaseFile) { /* XXX */
leaseFile = fopen(path_dhclient_db, "w");
if (!leaseFile)
if (!leaseFile) {
error("can't create %s", path_dhclient_db);
return;
}
}
fprintf(leaseFile, "lease {\n");
@ -1600,17 +1602,20 @@ write_client_lease(struct interface_info *ip, struct client_lease *lease,
lease->options[i].len, 1, 1));
t = gmtime(&lease->renewal);
fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
if (t)
fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
t = gmtime(&lease->rebind);
fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
if (t)
fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
t = gmtime(&lease->expiry);
fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
if (t)
fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
fprintf(leaseFile, "}\n");
fflush(leaseFile);
}
@ -1765,7 +1770,7 @@ supersede:
config->defaults[i].data,
ip->client->
config->defaults[i].len);
dp[len] = '\0';
dp[len-1] = '\0';
}
} else {
dp = ip->client->

View file

@ -63,12 +63,17 @@ void (*bootp_packet_handler)(struct interface_info *,
void
dispatch(void)
{
int count, i, to_msec, nfds, err;
int count, to_msec, err;
struct protocol *l;
fd_set fds;
time_t howlong, cur_time;
struct timeval timeval;
if (!AdapterDiscover()) {
AdapterStop();
return;
}
ApiLock();
do {
@ -76,17 +81,6 @@ dispatch(void)
* Call any expired timeouts, and then if there's still
* a timeout registered, time out the select call then.
*/
another:
if (!AdapterDiscover()) {
AdapterStop();
break;
}
for (l = protocols, nfds = 0; l; l = l->next)
nfds++;
FD_ZERO(&fds);
time(&cur_time);
if (timeouts) {
@ -98,7 +92,7 @@ dispatch(void)
(*(t->func))(t->what);
t->next = free_timeouts;
free_timeouts = t;
goto another;
continue;
}
/*
@ -112,50 +106,31 @@ dispatch(void)
howlong = INT_MAX / 1000;
to_msec = howlong * 1000;
} else
to_msec = -1;
to_msec = 5000;
/* Set up the descriptors to be polled. */
for (i = 0, l = protocols; l; l = l->next) {
struct interface_info *ip = l->local;
FD_ZERO(&fds);
if (ip && (l->handler != got_one || !ip->dead)) {
FD_SET(l->fd, &fds);
i++;
}
}
for (l = protocols; l; l = l->next)
FD_SET(l->fd, &fds);
if (i == 0) {
/* Wait for 5 seconds before looking for more interfaces */
Sleep(5000);
continue;
} else {
/* Wait for a packet or a timeout... XXX */
timeval.tv_sec = to_msec / 1000;
timeval.tv_usec = (to_msec % 1000) * 1000;
}
/* Wait for a packet or a timeout... XXX */
timeval.tv_sec = to_msec / 1000;
timeval.tv_usec = to_msec % 1000;
ApiUnlock();
count = select(nfds, &fds, NULL, NULL, &timeval);
DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
/* Review poll output */
for (i = 0, l = protocols; l; l = l->next) {
struct interface_info *ip = l->local;
if (ip && (l->handler != got_one || !ip->dead)) {
DH_DbgPrint
(MID_TRACE,
("set(%d) -> %s\n",
l->fd, FD_ISSET(l->fd, &fds) ? "true" : "false"));
i++;
}
if (protocols)
count = select(0, &fds, NULL, NULL, &timeval);
else {
Sleep(to_msec);
count = 0;
}
ApiLock();
DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
/* Not likely to be transitory... */
if (count == SOCKET_ERROR) {
err = WSAGetLastError();
@ -163,7 +138,6 @@ dispatch(void)
break;
}
i = 0;
for (l = protocols; l; l = l->next) {
struct interface_info *ip;
ip = l->local;
@ -173,7 +147,6 @@ dispatch(void)
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
(*(l->handler))(l);
}
i++;
}
}
} while (1);
@ -269,8 +242,10 @@ add_timeout(time_t when, void (*where)(void *), void *what)
q->what = what;
} else {
q = malloc(sizeof(struct timeout));
if (!q)
if (!q) {
error("Can't allocate timeout structure!");
return;
}
q->func = where;
q->what = what;
}

View file

@ -101,7 +101,6 @@ struct udphdr {
#include <fcntl.h>
#include <limits.h>
//#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -10,7 +10,6 @@
#include <dhcpcsdk.h>
#include <stdio.h>
#include <io.h>
#include <setjmp.h>
#include "stdint.h"
#include "predec.h"
#include <dhcp/rosdhcp_public.h>

View file

@ -175,9 +175,11 @@ parse_option_buffer(struct packet *packet,
* for clients, but what the heck...
*/
t = calloc(1, len + packet->options[code].len + 1);
if (!t)
if (!t) {
error("Can't expand storage for option %s.",
dhcp_options[code].name);
return;
}
memcpy(t, packet->options[code].data,
packet->options[code].len);
memcpy(t + packet->options[code].len,