]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Test to see if the pid in the pidfile is actually running before claiming
authorRoy Marples <roy@marples.name>
Tue, 20 Feb 2007 22:57:10 +0000 (22:57 +0000)
committerRoy Marples <roy@marples.name>
Tue, 20 Feb 2007 22:57:10 +0000 (22:57 +0000)
that we are.
Fix the  error since 3.0.6.
We now ensure that our renewal and rebind times are sane.
Fix flushing interfaces for systems without getifaddrs and >1 interface.
All netlink error messages are now prefixed with netlink.

ChangeLog
Makefile
client.c
configure.c
dhcp.c
dhcpcd.c
interface.c
interface.h

index 229758edd854a5c0d781b312a5f0cd2e619a201b..f04c09040ae1d6069fc28c1f604d379473a34d1b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Test to see if the pid in the pidfile is actually running before claiming
+that we are.
+Fix the `netlink message truncated` error since 3.0.6.
+We now ensure that our renewal and rebind times are sane.
+Fix flushing interfaces for systems without getifaddrs and >1 interface.
+All netlink error messages are now prefixed with netlink.
 Add DHCP over FireWire 1394 (RFC 2855) and InfiniBand (RFC 4390) support.
 We should add support for DUIDs (RFC4361) as well.
 
index 551c000a225c022e45d86326f377d854ce5254e2..077c51cd11759ceadbaa0caee4a99f2cc3d22338 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Should work for both GNU make and BSD make
 
-VERSION = 3.0.12_pre1
+VERSION = 3.0.12_pre2
 
 CFLAGS ?= -O2 -pipe
 
index d069d5a29be58630b794af06f31b118f60d87b7c..ec60f3abf4c8dcb60a7d2de4de0026b5709d1a51 100644 (file)
--- a/client.c
+++ b/client.c
@@ -174,7 +174,8 @@ int dhcp_run (const options_t *options)
       if (timeout > 0 || (options->timeout == 0 &&
                          (state != STATE_INIT || xid)))
        {
-         if (options->timeout == 0 || dhcp->leasetime == (unsigned) -1)
+         if (options->timeout == 0 ||
+             (dhcp->leasetime == (unsigned) -1 && state == STATE_BOUND))
            {
              int retry = 0;
              logger (LOG_DEBUG, "waiting on select for infinity");
@@ -471,8 +472,15 @@ int dhcp_run (const options_t *options)
            case STATE_INIT:
              if (type == DHCP_OFFER)
                {
-                 logger (LOG_INFO, "offered lease of %s",
-                         inet_ntoa (dhcp->address));
+                 char *addr = strdup (inet_ntoa (dhcp->address));
+                 if (dhcp->servername)
+                   logger (LOG_INFO, "offered %s from %s `%s'",
+                           addr, inet_ntoa (dhcp->serveraddress),
+                           dhcp->servername);
+                 else
+                   logger (LOG_INFO, "offered %s from %s",
+                           addr, inet_ntoa (dhcp->serveraddress));
+                 free (addr);
 
                  SEND_MESSAGE (DHCP_REQUEST);
                  state = STATE_REQUESTING;
@@ -512,40 +520,69 @@ int dhcp_run (const options_t *options)
                        }
                    }
 
-                 if (! dhcp->leasetime)
+                 if (dhcp->leasetime == (unsigned) -1)
                    {
-                     dhcp->leasetime = DEFAULT_TIMEOUT;
-                     logger(LOG_INFO,
-                            "no lease time supplied, assuming %d seconds",
-                            dhcp->leasetime);
+                     dhcp->renewaltime = dhcp->rebindtime = dhcp->leasetime;
+                     timeout = 1; /* So we select on infinity */
+                     logger (LOG_INFO, "leased %s for infinity",
+                             inet_ntoa (dhcp->address));
                    }
-
-                 if (! dhcp->renewaltime) 
+                 else
                    {
-                     dhcp->renewaltime = dhcp->leasetime / 2;
-                     logger (LOG_INFO,
-                             "no renewal time supplied, assuming %d seconds",
-                             dhcp->renewaltime);
-                   }
+                     if (! dhcp->leasetime)
+                       {
+                         dhcp->leasetime = DEFAULT_TIMEOUT;
+                         logger(LOG_INFO,
+                                "no lease time supplied, assuming %d seconds",
+                                dhcp->leasetime);
+                       }
+                     else
+                       logger (LOG_INFO, "leased %s for %u seconds",
+                               inet_ntoa (dhcp->address), dhcp->leasetime);
 
-                 if (! dhcp->rebindtime)
-                   {
-                     dhcp->rebindtime = (dhcp->leasetime * 0x7) >> 3;
-                     logger (LOG_INFO,
-                             "no rebind time supplied, assuming %d seconds",
-                             dhcp->rebindtime);
-                   }
+                     if (dhcp->rebindtime >= dhcp->leasetime)
+                       {
+                         dhcp->rebindtime = (dhcp->leasetime * 0.875);
+                         logger (LOG_ERR, "rebind time greater than lease "
+                                 "time, forcing to %u seconds",
+                                 dhcp->rebindtime);
+                       }
 
-                 if (dhcp->leasetime == (unsigned) -1)
-                   logger (LOG_INFO, "leased %s for infinity",
-                           inet_ntoa (dhcp->address));
-                 else
-                   logger (LOG_INFO, "leased %s for %u seconds",
-                           inet_ntoa (dhcp->address),
-                           dhcp->leasetime, dhcp->renewaltime);
+                     if (dhcp->renewaltime > dhcp->rebindtime)
+                       {
+                       
+                         dhcp->renewaltime = (dhcp->leasetime * 0.5);
+                         logger (LOG_ERR, "renewal time greater than rebind time, "
+                                 "forcing to %u seconds",
+                                 dhcp->renewaltime);
+                       }
+
+                     if (! dhcp->renewaltime) 
+                       {
+                         dhcp->renewaltime = (dhcp->leasetime * 0.5);
+                         logger (LOG_INFO,
+                                 "no renewal time supplied, assuming %d seconds",
+                                 dhcp->renewaltime);
+                       }
+                     else
+                       logger (LOG_DEBUG, "renew in %u seconds",
+                               dhcp->renewaltime);
+
+                     if (! dhcp->rebindtime)
+                       {
+                         dhcp->rebindtime = (dhcp->leasetime * 0.875);
+                         logger (LOG_INFO,
+                                 "no rebind time supplied, assuming %d seconds",
+                                 dhcp->rebindtime);
+                       }
+                     else
+                       logger (LOG_DEBUG, "rebind in %u seconds",
+                               dhcp->rebindtime);
+
+                     timeout = dhcp->renewaltime;
+                   }
 
                  state = STATE_BOUND;
-                 timeout = dhcp->renewaltime;
                  xid = 0;
 
                  if (configure (options, iface, dhcp) < 0 && ! daemonised)
index 184a9be92545be1aa586c1735e593c64e673c2d0..79877eb9fca2bdd3d977b63d8c1d6653aeebea5b 100644 (file)
@@ -468,8 +468,10 @@ int configure (const options_t *options, interface_t *iface,
       /* Only reset things if we had set them before */
       if (iface->previous_address.s_addr != 0)
        {
-         del_address (iface->name, iface->previous_address);
+         del_address (iface->name, iface->previous_address,
+                      iface->previous_netmask);
          memset (&iface->previous_address, 0, sizeof (struct in_addr));
+         memset (&iface->previous_netmask, 0, sizeof (struct in_addr));
 
          restore_resolv (iface->name);
 
@@ -486,7 +488,7 @@ int configure (const options_t *options, interface_t *iface,
   /* Now delete the old address if different */
   if (iface->previous_address.s_addr != dhcp->address.s_addr
       && iface->previous_address.s_addr != 0)
-    del_address (iface->name, iface->previous_address);
+    del_address (iface->name, iface->previous_address, iface->previous_netmask);
 
 #ifdef __linux__
   /* On linux, we need to change the subnet route to have our metric. */
@@ -602,10 +604,13 @@ int configure (const options_t *options, interface_t *iface,
 
   write_info (iface, dhcp, options);
 
-  if (iface->previous_address.s_addr != dhcp->address.s_addr)
+  if (iface->previous_address.s_addr != dhcp->address.s_addr ||
+      iface->previous_netmask.s_addr != dhcp->netmask.s_addr)
     {
       memcpy (&iface->previous_address,
              &dhcp->address, sizeof (struct in_addr));
+      memcpy (&iface->previous_netmask,
+             &dhcp->netmask, sizeof (struct in_addr));
       exec_script (options->script, iface->infofile, "new");
     }
   else
diff --git a/dhcp.c b/dhcp.c
index 3b81b48639d43e16f94d835e824ba77370d488a0..6f3c071775c3f4816b7baa479be60bceab13852b 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -296,9 +296,9 @@ static unsigned long getnetmask (unsigned long ip_in)
    seperated string. Returns length of string (including 
    terminating zero) or zero on error. out may be NULL
    to just determine output length. */
-static unsigned int decode_search (u_char *p, int len, char *out)
+static unsigned int decode_search (const unsigned char *p, int len, char *out)
 {
-  u_char *r, *q = p;
+  const unsigned char *r, *q = p;
   unsigned int count = 0, l, hops;
 
   while (q - p < len)
@@ -358,9 +358,9 @@ static unsigned int decode_search (u_char *p, int len, char *out)
 
 /* Add our classless static routes to the routes variable
  * and return the last route set */
-static route_t *decodeCSR(unsigned char *p, int len)
+static route_t *decodeCSR(const unsigned char *p, int len)
 {
-  unsigned char *q = p;
+  const unsigned char *q = p;
   int cidr;
   int ocets;
   route_t *first;
@@ -455,7 +455,7 @@ void free_dhcp (dhcp_t *dhcp)
     }
 }
 
-static void dhcp_add_address(address_t *address, unsigned char *data, int length)
+static void dhcp_add_address(address_t *address, const unsigned char *data, int length)
 {
   int i;
   address_t *p = address;
@@ -474,8 +474,8 @@ static void dhcp_add_address(address_t *address, unsigned char *data, int length
 
 int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
 {
-  unsigned char *p = message->options;
-  unsigned char *end = message->options; /* Add size later for gcc-3 issue */
+  const unsigned char *p = message->options;
+  const unsigned char *end = p; /* Add size later for gcc-3 issue */
   unsigned char option;
   unsigned char length;
   unsigned int len = 0;
index 2dcb5537646b3c91a9465101c2b4449349a5ed50..24c5c16010834554a7e73c280f3b04d0f2aa03a7 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -100,7 +100,6 @@ static void usage ()
          "              [-u userclass] [-F [none | ptr | both]] [-I clientID]\n");
 }
 
-
 int main(int argc, char **argv)
 {
   options_t options;
@@ -110,6 +109,7 @@ int main(int argc, char **argv)
   int ch;
   int option_index = 0;
   char prefix[IF_NAMESIZE + 3];
+  pid_t pid;
 
   const struct option longopts[] =
     {
@@ -344,7 +344,7 @@ int main(int argc, char **argv)
   if (options.signal != 0)
     {
       int killed = -1;
-      pid_t pid = read_pid (options.pidfile);
+      pid = read_pid (options.pidfile);
       if (pid != 0)
         logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid);
 
@@ -377,7 +377,7 @@ int main(int argc, char **argv)
       exit (EXIT_FAILURE);
     }
 
-  if (read_pid (options.pidfile))
+  if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0)
     {
       logger (LOG_ERR, ""PACKAGE" already running (%s)", options.pidfile);
       exit (EXIT_FAILURE);
index 3da3eaf9a273666d5e9f9feff2002c909052eb50..bb40864bfdbc892423a0b2125c0eb4a19430ed91 100644 (file)
@@ -181,6 +181,7 @@ interface_t *read_interface (const char *ifname, int metric)
 #ifdef __linux__
   /* Do something with the metric parameter to satisfy the compiler warning */
   metric = 0;
+  strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   if (ioctl (s, SIOCGIFHWADDR, &ifr) <0)
     {
       logger (LOG_ERR, "ioctl SIOCGIFHWADDR: %s", strerror (errno));
@@ -207,6 +208,7 @@ interface_t *read_interface (const char *ifname, int metric)
   family = ifr.ifr_hwaddr.sa_family;
 #else
   ifr.ifr_metric = metric;
+  strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   if (ioctl (s, SIOCSIFMETRIC, &ifr) < 0)
     {
       logger (LOG_ERR, "ioctl SIOCSIFMETRIC: %s", strerror (errno));
@@ -215,6 +217,7 @@ interface_t *read_interface (const char *ifname, int metric)
     }
 #endif
 
+  strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
     {
       logger (LOG_ERR, "ioctl SIOCGIFFLAGS: %s", strerror (errno));
@@ -223,6 +226,7 @@ interface_t *read_interface (const char *ifname, int metric)
     }
 
   ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+  strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
   if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
     {
       logger (LOG_ERR, "ioctl SIOCSIFFLAGS: %s", strerror (errno));
@@ -281,9 +285,9 @@ static int do_address (const char *ifname, struct in_addr address,
     }
 
   ADDADDR (ifa.ifra_addr, address);
+  ADDADDR (ifa.ifra_mask, netmask);
   if (! del)
     {
-      ADDADDR (ifa.ifra_mask, netmask);
       ADDADDR (ifa.ifra_broadaddr, broadcast);
     }
 
@@ -448,7 +452,8 @@ static int send_netlink(struct nlmsghdr *hdr)
   struct iovec iov;
   struct msghdr msg;
   static unsigned int seq;
-  char buffer[16384];
+  char buffer[256];
+  int bytes;
   union
     {
       char *buffer;
@@ -496,25 +501,25 @@ static int send_netlink(struct nlmsghdr *hdr)
 
   while (1) 
     {
-      int bytes = recvmsg(s, &msg, 0);
       iov.iov_len = sizeof (buffer);
+      bytes = recvmsg(s, &msg, 0);
 
       if (bytes < 0)
        {
          if (errno != EINTR)
-           logger (LOG_ERR, "overrun");
+           logger (LOG_ERR, "netlink: overrun");
          continue;
        }
 
       if (bytes == 0)
        {
-         logger (LOG_ERR, "EOF on netlink");
+         logger (LOG_ERR, "netlink: EOF");
          goto eexit;
        }
 
       if (msg.msg_namelen != sizeof (nl))
        {
-         logger (LOG_ERR, "sender address length == %d", msg.msg_namelen);
+         logger (LOG_ERR, "netlink: sender address length mismatch");
          goto eexit;
        }
 
@@ -526,9 +531,9 @@ static int send_netlink(struct nlmsghdr *hdr)
          if (l < 0 || len > bytes)
            {
              if (msg.msg_flags & MSG_TRUNC)
-               logger (LOG_ERR, "truncated message");
+               logger (LOG_ERR, "netlink: truncated message");
              else
-               logger (LOG_ERR, "malformed message");
+               logger (LOG_ERR, "netlink: malformed message");
              goto eexit;
            }
 
@@ -543,7 +548,7 @@ static int send_netlink(struct nlmsghdr *hdr)
            {
              struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h.nlm);
              if ((unsigned) l < sizeof (struct nlmsgerr))
-               logger (LOG_ERR, "truncated error message");
+               logger (LOG_ERR, "netlink: truncated error message");
              else
                {
                  errno = -err->error;
@@ -555,12 +560,12 @@ static int send_netlink(struct nlmsghdr *hdr)
 
                  /* Don't report on something already existing */
                  if (errno != EEXIST)
-                   logger (LOG_ERR, "RTNETLINK answers: %s", strerror (errno));
+                   logger (LOG_ERR, "netlink: %s", strerror (errno));
                }
              goto eexit;
            }
 
-         logger (LOG_ERR, "unexpected reply");
+         logger (LOG_ERR, "netlink: unexpected reply");
 next:
          bytes -= NLMSG_ALIGN (len);
          h.buffer += NLMSG_ALIGN (len);
@@ -568,13 +573,13 @@ next:
 
       if (msg.msg_flags & MSG_TRUNC)
        {
-         logger (LOG_ERR, "message truncated");
+         logger (LOG_ERR, "netlink: truncated message");
          continue;
        }
 
       if (bytes)
        {
-         logger (LOG_ERR, "remnant of size %d", bytes);
+         logger (LOG_ERR, "netlink: remnant of size %d", bytes);
          goto eexit;
        }
     }
@@ -637,7 +642,7 @@ static int do_address(const char *ifname,
     {
       struct nlmsghdr hdr;
       struct ifaddrmsg ifa;
-      char buffer[256];
+      char buffer[64];
     }
   nlm;
   uint32_t mask = htonl (netmask.s_addr);
@@ -649,6 +654,8 @@ static int do_address(const char *ifname,
 
   nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
   nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
+  if (! del)
+    nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
   nlm.hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
   nlm.ifa.ifa_index = if_nametoindex (ifname);
   nlm.ifa.ifa_family = AF_INET;
@@ -772,14 +779,18 @@ int add_address (const char *ifname, struct in_addr address,
   return (do_address (ifname, address, netmask, broadcast, 0));
 }
 
-int del_address (const char *ifname, struct in_addr address)
+int del_address (const char *ifname,
+                struct in_addr address, struct in_addr netmask)
 {
   struct in_addr t;
+  char *addr = strdup (inet_ntoa (address));
 
-  logger (LOG_INFO, "deleting IP address %s", inet_ntoa (address));
+  logger (LOG_INFO, "deleting IP address %s netmask %s", addr,
+         inet_ntoa (netmask));
+  free (addr);
 
   memset (&t, 0, sizeof (t));
-  return (do_address (ifname, address, t, t, 1));
+  return (do_address (ifname, address, netmask, t, 1));
 }
 
 int add_route (const char *ifname, struct in_addr destination,
@@ -818,15 +829,16 @@ int flush_addresses (const char *ifname)
        {
          struct sockaddr *sa;
          struct sockaddr_in *sin;
-       } us;
+       } us_a, us_m;
 
       if (strcmp (p->ifa_name, ifname) != 0)
        continue;
 
-      us.sa = p->ifa_addr;
+      us_a.sa = p->ifa_addr;
+      us_m.sa = p->ifa_netmask;
 
-      if (us.sin->sin_family == AF_INET)
-       if (del_address (ifname, us.sin->sin_addr) < 0)
+      if (us_a.sin->sin_family == AF_INET)
+       if (del_address (ifname, us_a.sin->sin_addr, us_m.sin->sin_addr) < 0)
          retval = -1;
     }
   freeifaddrs (ifap);
@@ -874,14 +886,13 @@ int flush_addresses (const char *ifname)
   ifr = ifrs;
   for (i = 0; i < nifs; i++)
     {
-      struct sockaddr_in *in = (struct sockaddr_in *) &ifr->ifr_addr;
+      struct sockaddr_in *addr = (struct sockaddr_in *) &ifr->ifr_addr;
+      struct sockaddr_in *netm = (struct sockaddr_in *) &ifr->ifr_netmask;
 
-      if (ifr->ifr_addr.sa_family != AF_INET
-         || strcmp (ifname, ifr->ifr_name) != 0)
-       continue;
-
-      if (del_address (ifname, in->sin_addr) < 0)
-       retval = -1;
+      if (ifr->ifr_addr.sa_family == AF_INET
+         && strcmp (ifname, ifr->ifr_name) == 0)
+       if (del_address (ifname, addr->sin_addr, netm->sin_addr) < 0)
+         retval = -1;
       ifr++;
     }
 
index d174dc8deb55f91b47f5bb092fabcc86961d7a59..3d96537a5cabf8869ab1b7bbd0f7a310416e2262 100644 (file)
@@ -71,6 +71,7 @@ typedef struct interface_t
   char infofile[PATH_MAX];
 
   struct in_addr previous_address;
+  struct in_addr previous_netmask;
   route_t *previous_routes;
 
   long start_uptime;
@@ -82,7 +83,8 @@ interface_t *read_interface (const char *ifname, int metric);
 
 int add_address (const char *ifname, struct in_addr address,
                 struct in_addr netmask, struct in_addr broadcast);
-int del_address (const char *ifname, struct in_addr address);
+int del_address (const char *ifname, struct in_addr address,
+                struct in_addr netmask);
 int flush_addresses (const char *ifname);
 
 int add_route (const char *ifname, struct in_addr destination,