]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Use tailq from queue.h instead of rolling our down linked lists.
authorRoy Marples <roy@marples.name>
Wed, 20 Feb 2008 17:04:56 +0000 (17:04 +0000)
committerRoy Marples <roy@marples.name>
Wed, 20 Feb 2008 17:04:56 +0000 (17:04 +0000)
configure.c
dhcp.c
dhcp.h
info.c
interface.c
interface.h

index e23735582576be70837c470d771b8a0b35ab72d2..131f771a2f7030c69c0d4b48eed4ac24788291c6 100644 (file)
@@ -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 8620c5be2303a65286635775e2cf64f0080f4434..7f467f1c669e66e1d4b60887e05878906395aa33 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
 #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 1d9e781d4dea27c7197968ce8b5a649a8a6df854..cc66d13782185b1cf9d28be65c66281fccfd855f 100644 (file)
--- 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 9c788b33ae7dc07145b62fa13f4867d8572d1593..8369b43f37cb9f081266f99a060b271a2a05e478 100644 (file)
--- 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)
index 0b608a97039a4e757942da3ccfae1324828a8091..1fd6f645efc323754c605645d0a1212e3af00c2e 100644 (file)
 #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;
        }
index 6e000241d4fa4cb77e80f8fa88f39a5f1616dd13..9c42ec6fe31e0e87a9fcebccc240d3805e20a49f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/queue.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <netinet/in.h>
 # 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);