From: Roy Marples Date: Wed, 20 Feb 2008 17:04:56 +0000 (+0000) Subject: Use tailq from queue.h instead of rolling our down linked lists. X-Git-Tag: v3.2.3~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7fc53ef79484dd1ee618be3f39b8efba95e2d24e;p=thirdparty%2Fdhcpcd.git Use tailq from queue.h instead of rolling our down linked lists. --- diff --git a/configure.c b/configure.c index e2373558..131f771a 100644 --- a/configure.c +++ b/configure.c @@ -212,7 +212,7 @@ static int make_resolv (const char *ifname, const dhcp_t *dhcp) fprintf (f, "search %s\n", dhcp->dnsdomain); } - for (address = dhcp->dnsservers; address; address = address->next) + STAILQ_FOREACH (address, dhcp->dnsservers, entries) fprintf (f, "nameserver %s\n", inet_ntoa (address->address)); #ifdef ENABLE_RESOLVCONF @@ -237,22 +237,26 @@ static void restore_resolv (const char *ifname) #endif } -static bool in_addresses (const address_t *addresses, struct in_addr addr) +static bool in_addresses (const struct address_head *addresses, + struct in_addr address) { - const address_t *address; + const address_t *addr; - for (address = addresses; address; address = address->next) - if (address->address.s_addr == addr.s_addr) + STAILQ_FOREACH (addr, addresses, entries) + if (addr->address.s_addr == address.s_addr) return (true); return (false); } -static bool in_routes (const route_t *routes, route_t *route) +static bool in_routes (const struct route_head *routes, route_t *route) { const route_t *r; + + if (! routes) + return (false); - for (r = routes; r; r=r->next) + STAILQ_FOREACH (r, routes, entries) if (r->destination.s_addr == route->destination.s_addr && r->netmask.s_addr == route->netmask.s_addr && r->gateway.s_addr == route->gateway.s_addr) @@ -272,7 +276,7 @@ static int _make_ntp (const char *file, const char *ifname, const dhcp_t *dhcp) char *token; bool ntp = false; - for (address = dhcp->ntpservers; address; address = address->next) + STAILQ_FOREACH (address, dhcp->ntpservers, entries) tomatch++; /* Check that we really need to update the servers. @@ -329,7 +333,7 @@ next: } #endif - for (address = dhcp->ntpservers; address; address = address->next) { + STAILQ_FOREACH (address, dhcp->ntpservers, entries) { a = inet_ntoa (address->address); if (ntp) fprintf (f, "restrict %s nomodify notrap noquery\n", a); @@ -424,7 +428,7 @@ static int make_nis (const char *ifname, const dhcp_t *dhcp) else snprintf (prefix, PREFIXSIZE, "%s", "ypserver"); - for (address = dhcp->nisservers; address; address = address->next) + STAILQ_FOREACH (address, dhcp->nisservers, entries) fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address)); free (prefix); @@ -526,7 +530,7 @@ int configure (const options_t *options, interface_t *iface, const dhcp_t *dhcp, bool up) { route_t *route = NULL; - route_t *new_routes = NULL; + struct route_head *new_routes = NULL; route_t *new_route = NULL; char *newhostname = NULL; char *curhostname = NULL; @@ -549,13 +553,12 @@ int configure (const options_t *options, interface_t *iface, /* Remove old routes. * Always do this as the interface may have >1 address not added by us * so the routes we added may still exist. */ - for (route = iface->previous_routes; route; route = route->next) + NSTAILQ_FOREACH (route, iface->previous_routes, entries) if ((route->destination.s_addr || options->dogateway) && (! up || ! in_routes (dhcp->routes, route))) del_route (iface->name, route->destination, route->netmask, route->gateway, options->metric); - /* If we aren't up, then reset the interface as much as we can */ if (! up) { if (iface->previous_routes) { @@ -647,7 +650,7 @@ int configure (const options_t *options, interface_t *iface, #endif /* Remember added routes */ - for (route = dhcp->routes; route; route = route->next) { + NSTAILQ_FOREACH (route, dhcp->routes, entries) { #ifdef ENABLE_IPV4LL /* Check if we have already got a link locale route dished * out by the DHCP server */ @@ -672,13 +675,11 @@ int configure (const options_t *options, interface_t *iface, if (remember >= 0) { if (! new_routes) { new_routes = xmalloc (sizeof (*new_routes)); - new_route = new_routes; - } else { - new_route->next = xmalloc (sizeof (*new_route)); - new_route = new_route->next; + STAILQ_INIT (new_routes); } + new_route = xmalloc (sizeof (route_t)); memcpy (new_route, route, sizeof (*new_route)); - new_route -> next = NULL; + STAILQ_INSERT_TAIL (new_routes, new_route, entries); } #ifdef THERE_IS_NO_FORK /* If we have daemonised yet we need to record which routes @@ -725,15 +726,13 @@ int configure (const options_t *options, interface_t *iface, if (remember >= 0) { if (! new_routes) { new_routes = xmalloc (sizeof (*new_routes)); - new_route = new_routes; - } else { - new_route->next = xmalloc (sizeof (*new_route)); - new_route = new_route->next; + STAILQ_INIT (new_routes); } + new_route = xmalloc (sizeof (*new_route)); new_route->destination.s_addr = dest.s_addr; new_route->netmask.s_addr = mask.s_addr; new_route->gateway.s_addr = gate.s_addr; - new_route->next = NULL; + STAILQ_INSERT_TAIL (new_routes, new_route, entries); } } #endif diff --git a/dhcp.c b/dhcp.c index 8620c5be..7f467f1c 100644 --- a/dhcp.c +++ b/dhcp.c @@ -51,6 +51,16 @@ #include "logger.h" #include "socket.h" +#ifndef STAILQ_CONCAT +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) +#endif + typedef struct message { int value; const char *name; @@ -395,30 +405,32 @@ static unsigned int decode_search (const unsigned char *p, int len, char *out) /* Add our classless static routes to the routes variable * and return the last route set */ -static route_t *decode_CSR(const unsigned char *p, int len) +static struct route_head *decode_CSR (const unsigned char *p, int len) { const unsigned char *q = p; unsigned int cidr; unsigned int ocets; - route_t *first; + struct route_head *routes = NULL; route_t *route; /* Minimum is 5 -first is CIDR and a router length of 4 */ if (len < 5) return NULL; - first = xzalloc (sizeof (*first)); - route = first; - while (q - p < len) { - memset (route, 0, sizeof (*route)); + if (! routes) { + routes = xmalloc (sizeof (*routes)); + STAILQ_INIT (routes); + } + + route = xzalloc (sizeof (*route)); cidr = *q++; if (cidr > 32) { logger (LOG_ERR, "invalid CIDR of %d in classless static route", cidr); - free_route (first); + free_route (routes); return (NULL); } ocets = (cidr + 7) / 8; @@ -440,14 +452,10 @@ static route_t *decode_CSR(const unsigned char *p, int len) memcpy (&route->gateway.s_addr, q, 4); q += 4; - /* We have another route */ - if (q - p < len) { - route->next = xzalloc (sizeof (*route)); - route = route->next; - } + STAILQ_INSERT_TAIL (routes, route, entries); } - return first; + return (routes); } void free_dhcp (dhcp_t *dhcp) @@ -471,27 +479,27 @@ void free_dhcp (dhcp_t *dhcp) } } -static bool dhcp_add_address (address_t **address, - const unsigned char *data, int length) +static bool dhcp_add_address (struct address_head **addresses, + const unsigned char *data, + int length) { int i; - address_t *p = *address; + address_t *address; for (i = 0; i < length; i += 4) { - if (*address == NULL) { - p = *address = xzalloc (sizeof (*p)); - } else { - p->next = xzalloc (sizeof (*p)); - p = p->next; - } - /* Sanity check */ if (i + 4 > length) { logger (LOG_ERR, "invalid address length"); return (false); } - memcpy (&p->address.s_addr, data + i, 4); + if (*addresses == NULL) { + *addresses = xmalloc (sizeof (**addresses)); + STAILQ_INIT (*addresses); + } + address = xzalloc (sizeof (*address)); + memcpy (&address->address.s_addr, data + i, 4); + STAILQ_INSERT_TAIL (*addresses, address, entries); } return (true); @@ -572,40 +580,42 @@ static uint32_t route_netmask (uint32_t ip_in) return (htonl (~t)); } -static route_t *decode_routes (const unsigned char *data, int length) +static struct route_head *decode_routes (const unsigned char *data, int length) { int i; - route_t *head = NULL; - route_t *routes = NULL; + struct route_head *head = NULL; + route_t *route; for (i = 0; i < length; i += 8) { - if (routes) { - routes->next = xzalloc (sizeof (*routes)); - routes = routes->next; - } else - head = routes = xzalloc (sizeof (*head)); - memcpy (&routes->destination.s_addr, data + i, 4); - memcpy (&routes->gateway.s_addr, data + i + 4, 4); - routes->netmask.s_addr = - route_netmask (routes->destination.s_addr); + if (! head) { + head = xmalloc (sizeof (*head)); + STAILQ_INIT (head); + } + route = xzalloc (sizeof (*route)); + memcpy (&route->destination.s_addr, data + i, 4); + memcpy (&route->gateway.s_addr, data + i + 4, 4); + route->netmask.s_addr = + route_netmask (route->destination.s_addr); + STAILQ_INSERT_TAIL (head, route, entries); } return (head); } -static route_t *decode_routers (const unsigned char *data, int length) +static struct route_head *decode_routers (const unsigned char *data, int length) { int i; - route_t *head = NULL; - route_t *routes = NULL; + struct route_head *head = NULL; + route_t *route = NULL; for (i = 0; i < length; i += 4) { - if (routes) { - routes->next = xzalloc (sizeof (*routes)); - routes = routes->next; - } else - head = routes = xzalloc (sizeof (*head)); - memcpy (&routes->gateway.s_addr, data + i, 4); + if (! head) { + head = xmalloc (sizeof (*head)); + STAILQ_INIT (head); + } + route = xzalloc (sizeof (*route)); + memcpy (&route->gateway.s_addr, data + i, 4); + STAILQ_INSERT_TAIL (head, route, entries); } return (head); @@ -620,10 +630,10 @@ int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message) unsigned int len = 0; int retval = -1; struct timeval tv; - route_t *routers = NULL; - route_t *routes = NULL; - route_t *csr = NULL; - route_t *mscsr = NULL; + struct route_head *routers = NULL; + struct route_head *routes = NULL; + struct route_head *csr = NULL; + struct route_head *mscsr = NULL; bool in_overload = false; bool parse_sname = false; bool parse_file = false; @@ -914,14 +924,11 @@ eexit: free_route (routes); } else { /* Ensure that we apply static routes before routers */ - if (routes) - { - dhcp->routes = routes; - while (routes->next) - routes = routes->next; - routes->next = routers; - } else - dhcp->routes = routers; + if (! routes) + routes = routers; + else if (routers) + STAILQ_CONCAT (routes, routers); + dhcp->routes = routes; } return (retval); diff --git a/dhcp.h b/dhcp.h index 1d9e781d..cc66d137 100644 --- a/dhcp.h +++ b/dhcp.h @@ -144,18 +144,18 @@ typedef struct dhcp_t uint32_t renewaltime; uint32_t rebindtime; - route_t *routes; + struct route_head *routes; char *hostname; fqdn_t *fqdn; - address_t *dnsservers; + struct address_head *dnsservers; char *dnsdomain; char *dnssearch; - address_t *ntpservers; + struct address_head *ntpservers; - address_t *nisservers; + struct address_head *nisservers; char *nisdomain; char *sipservers; diff --git a/info.c b/info.c index 9c788b33..8369b43f 100644 --- a/info.c +++ b/info.c @@ -78,13 +78,13 @@ static char *cleanmetas (const char *cstr) } -static void print_addresses (FILE *f, const address_t *addresses) +static void print_addresses (FILE *f, const struct address_head *addresses) { const address_t *addr; - for (addr = addresses; addr; addr = addr->next) { + STAILQ_FOREACH (addr, addresses, entries) { fprintf (f, "%s", inet_ntoa (addr->address)); - if (addr->next) + if (STAILQ_NEXT (addr, entries)) fprintf (f, " "); } } @@ -136,7 +136,7 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, if (dhcp->routes) { bool doneone = false; fprintf (f, "ROUTES='"); - for (route = dhcp->routes; route; route = route->next) { + STAILQ_FOREACH (route, dhcp->routes, entries) { if (route->destination.s_addr != 0) { if (doneone) fprintf (f, " "); @@ -150,7 +150,7 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, doneone = false; fprintf (f, "GATEWAYS='"); - for (route = dhcp->routes; route; route = route->next) { + STAILQ_FOREACH (route, dhcp->routes, entries) { if (route->destination.s_addr == 0) { if (doneone) fprintf (f, " "); @@ -222,9 +222,9 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, address_t *addr; fprintf (f, "DNS='"); - for (addr = dhcp->dnsservers; addr; addr = addr->next) { + STAILQ_FOREACH (addr, dhcp->dnsservers, entries) { fprintf (f, "%s", inet_ntoa (addr->address)); - if (addr->next) + if (STAILQ_NEXT (addr, entries)) fprintf (f, ","); } fprintf (f, "'\n"); @@ -233,7 +233,7 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp, if (dhcp->routes) { bool doneone = false; fprintf (f, "GATEWAY='"); - for (route = dhcp->routes; route; route = route->next) { + STAILQ_FOREACH (route, dhcp->routes, entries) { if (route->destination.s_addr == 0) { if (doneone) fprintf (f, ","); @@ -283,31 +283,30 @@ static bool parse_ushort (unsigned short *s, return (true); } -static bool parse_addresses (address_t **address, char *value, const char *var) +static struct address_head *parse_addresses (char *value, const char *var) { char *token; char *p = value; - bool retval = true; + struct address_head *head = NULL; while ((token = strsep (&p, " "))) { address_t *a = xzalloc (sizeof (*a)); if (inet_aton (token, &a->address) == 0) { logger (LOG_ERR, "%s: invalid address `%s'", var, token); + free_address (head); free (a); - retval = false; - } else { - if (*address) { - address_t *aa = *address; - while (aa->next) - aa = aa->next; - aa->next = a; - } else - *address = a; + return (NULL); } + + if (! head) { + head = xmalloc (sizeof (*head)); + STAILQ_INIT (head); + } + STAILQ_INSERT_TAIL (head, a, entries); } - return (retval); + return (head); } bool read_info (const interface_t *iface, dhcp_t *dhcp) @@ -413,26 +412,22 @@ bool read_info (const interface_t *iface, dhcp_t *dhcp) } /* OK, now add our route */ - if (dhcp->routes) { - route_t *r = dhcp->routes; - while (r->next) - r = r->next; - r->next = route; - } else - dhcp->routes = route; + if (! dhcp->routes) { + dhcp->routes = xmalloc (sizeof (*dhcp->routes)); + STAILQ_INIT (dhcp->routes); + } + STAILQ_INSERT_TAIL (dhcp->routes, route, entries); } } else if (strcmp (var, "GATEWAYS") == 0) { p = value; while ((value = strsep (&p, " "))) { route_t *route = xzalloc (sizeof (*route)); if (parse_address (&route->gateway, value, "GATEWAYS")) { - if (dhcp->routes) { - route_t *r = dhcp->routes; - while (r->next) - r = r->next; - r->next = route; - } else - dhcp->routes = route; + if (! dhcp->routes) { + dhcp->routes = xmalloc (sizeof (*dhcp->routes)); + STAILQ_INIT (dhcp->routes); + } + STAILQ_INSERT_TAIL (dhcp->routes, route, entries); } else free (route); } @@ -443,13 +438,13 @@ bool read_info (const interface_t *iface, dhcp_t *dhcp) else if (strcmp (var, "DNSSEARCH") == 0) dhcp->dnssearch = xstrdup (value); else if (strcmp (var, "DNSSERVERS") == 0) - parse_addresses (&dhcp->dnsservers, value, "DNSSERVERS"); + dhcp->dnsservers = parse_addresses (value, "DNSSERVERS"); else if (strcmp (var, "NTPSERVERS") == 0) - parse_addresses (&dhcp->ntpservers, value, "NTPSERVERS"); + dhcp->ntpservers = parse_addresses (value, "NTPSERVERS"); else if (strcmp (var, "NISDOMAIN") == 0) dhcp->nisdomain = xstrdup (value); else if (strcmp (var, "NISSERVERS") == 0) - parse_addresses (&dhcp->nisservers, value, "NISSERVERS"); + dhcp->nisservers = parse_addresses (value, "NISSERVERS"); else if (strcmp (var, "ROOTPATH") == 0) dhcp->rootpath = xstrdup (value); else if (strcmp (var, "DHCPSID") == 0) diff --git a/interface.c b/interface.c index 0b608a97..1fd6f645 100644 --- a/interface.c +++ b/interface.c @@ -61,25 +61,33 @@ #include "interface.h" #include "logger.h" -void free_address (address_t *addresses) +void free_address (struct address_head *addresses) { - address_t *p = addresses; - address_t *n = NULL; + address_t *p; + address_t *n; + if (! addresses) + return; + + p = STAILQ_FIRST (addresses); while (p) { - n = p->next; + n = STAILQ_NEXT (p, entries); free (p); p = n; } } -void free_route (route_t *routes) +void free_route (struct route_head *routes) { - route_t *p = routes; - route_t *n = NULL; + route_t *p; + route_t *n; + + if (! routes) + return; + p = STAILQ_FIRST (routes); while (p) { - n = p->next; + n = STAILQ_NEXT (p, entries); free (p); p = n; } diff --git a/interface.h b/interface.h index 6e000241..9c42ec6f 100644 --- a/interface.h +++ b/interface.h @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -83,19 +84,24 @@ # define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR) #endif +#define NSTAILQ_FOREACH(var, head, field) \ + if (head) STAILQ_FOREACH (var, head, field) + typedef struct route_t { struct in_addr destination; struct in_addr netmask; struct in_addr gateway; - struct route_t *next; + STAILQ_ENTRY (route_t) entries; } route_t; +STAILQ_HEAD (route_head, route_t); typedef struct address_t { struct in_addr address; - struct address_t *next; + STAILQ_ENTRY (address_t) entries; } address_t; +STAILQ_HEAD (address_head, address_t); typedef struct interface_t { @@ -118,7 +124,7 @@ typedef struct interface_t unsigned short previous_mtu; struct in_addr previous_address; struct in_addr previous_netmask; - route_t *previous_routes; + struct route_head *previous_routes; time_t start_uptime; @@ -126,8 +132,8 @@ typedef struct interface_t size_t clientid_len; } interface_t; -void free_address (address_t *addresses); -void free_route (route_t *routes); +void free_address (struct address_head *addresses); +void free_route (struct route_head *routes); uint32_t get_netmask (uint32_t addr); char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen); size_t hwaddr_aton (unsigned char *hwaddr, const char *addr);