Hi,

My (residential) ISP assigns me an IP address using DHCP. The lease time is 7
days or so. I just put "dhcp" in hostname.re1 and everything works, except for
a minor annoyance.

When re1 goes down (e.g. because of a reboot) the ISP *requires* a successful
DHCP exchange to occur before it enables the link on a layer 3 level. It does
not matter whether there still is a valid lease or not: after re1 goes down,
there *has* to be a DHCP exchange otherwise the link won't work.

What makes this worse is that the DHCP server does not always immediately
respond after re1 comes back up. It regularly happens that dhclient concludes
that the DHCP server is unreachable, finds that it still has a valid lease
in the lease file, and it'll use that. The problem with this is that dhclient
doesn't seem to try to contact the server anymore. With long lease times, it
could take days for dhclient to try to renew the lease.

I've tried using "timeout 0" in dhclient.conf, but that only causes dhclient
to immediately using the lease from the lease file (after trying to reacquire
its previous address for ten seconds). Using an arbitrarily high timeout
value doesn't seem right.

The retry setting doesn't seem to help in this case: by default it's set to
5 minutes, but in my testing I noticed that once dhclient is bound to a lease
from the lease file, this setting doesn't seem to be used anymore. 


Perhaps I've missed something, but I concluded that in my scenario lease
files are never useful. I modified dhclient to accept a new option called
"no-lease-file" in dhclient.conf. A diff against -current is below. I've
tested it lightly on a laptop, and it seems to work OK. I've been using
roughly the same diff against -stable for a day or two.


Index: sbin/dhclient/clparse.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/clparse.c,v
retrieving revision 1.90
diff -u -p -r1.90 clparse.c
--- sbin/dhclient/clparse.c     3 Nov 2014 22:06:39 -0000       1.90
+++ sbin/dhclient/clparse.c     8 Dec 2014 10:07:39 -0000
@@ -67,6 +67,7 @@ read_client_conf(void)
        new_parse(path_dhclient_conf);
 
        /* Set some defaults. */
+       config->use_lease_file = 1;
        config->link_timeout = 10;
        config->timeout = 60;
        config->select_interval = 0;
@@ -153,6 +154,7 @@ read_client_leases(void)
  *     TOK_BACKOFF_CUTOFF number |
  *     TOK_INITIAL_INTERVAL number |
  *     interface-declaration |
+ *     TOK_NO_LEASE_FILE |
  *     TOK_LEASE client-lease-statement |
  *     TOK_ALIAS client-lease-statement |
  *     TOK_REJECT reject-statement
@@ -240,6 +242,10 @@ parse_client_statement(FILE *cfile)
                break;
        case TOK_INTERFACE:
                parse_interface_declaration(cfile);
+               break;
+       case TOK_NO_LEASE_FILE:
+               config->use_lease_file = 0;
+               parse_semi(cfile);
                break;
        case TOK_LEASE:
                parse_client_lease_statement(cfile, 1);
Index: sbin/dhclient/conflex.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/conflex.c,v
retrieving revision 1.29
diff -u -p -r1.29 conflex.c
--- sbin/dhclient/conflex.c     5 May 2014 18:02:49 -0000       1.29
+++ sbin/dhclient/conflex.c     8 Dec 2014 10:07:39 -0000
@@ -352,6 +352,7 @@ static const struct keywords {
        { "media",                              TOK_MEDIA },
        { "medium",                             TOK_MEDIUM },
        { "next-server",                        TOK_NEXT_SERVER },
+       { "no-lease-file",                      TOK_NO_LEASE_FILE },
        { "option",                             TOK_OPTION },
        { "prepend",                            TOK_PREPEND },
        { "rebind",                             TOK_REBIND },
Index: sbin/dhclient/dhclient.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
retrieving revision 1.343
diff -u -p -r1.343 dhclient.c
--- sbin/dhclient/dhclient.c    8 Dec 2014 02:04:58 -0000       1.343
+++ sbin/dhclient/dhclient.c    8 Dec 2014 10:07:39 -0000
@@ -549,15 +549,17 @@ main(int argc, char *argv[])
                close(tailfd);
        }
 
-       if ((fd = open(path_dhclient_db,
-           O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640)) == -1)
-               error("can't open and lock %s: %s", path_dhclient_db,
-                   strerror(errno));
-       read_client_leases();
-       if ((leaseFile = fopen(path_dhclient_db, "w")) == NULL)
-               error("can't open %s: %s", path_dhclient_db, strerror(errno));
-       rewrite_client_leases();
-       close(fd);
+       if (config->use_lease_file) {
+               if ((fd = open(path_dhclient_db,
+               O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640)) == -1)
+                       error("can't open and lock %s: %s", path_dhclient_db,
+                       strerror(errno));
+               read_client_leases();
+               if ((leaseFile = fopen(path_dhclient_db, "w")) == NULL)
+                       error("can't open %s: %s", path_dhclient_db, 
strerror(errno));
+               rewrite_client_leases();
+               close(fd);
+       }
 
        if ((routefd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
                error("socket(PF_ROUTE, SOCK_RAW): %s", strerror(errno));
@@ -986,7 +988,8 @@ newlease:
        client->state = S_BOUND;
 
        /* Write out new leases file. */
-       rewrite_client_leases();
+       if (config->use_lease_file)
+               rewrite_client_leases();
 
        /* Set timeout to start the renewal process. */
        set_timeout(client->active->renewal, state_bound);
Index: sbin/dhclient/dhclient.conf.5
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhclient.conf.5,v
retrieving revision 1.31
diff -u -p -r1.31 dhclient.conf.5
--- sbin/dhclient/dhclient.conf.5       11 Nov 2013 15:39:20 -0000      1.31
+++ sbin/dhclient/dhclient.conf.5       8 Dec 2014 10:07:39 -0000
@@ -406,6 +406,14 @@ specified name.
 Interfaces for which there is no interface declaration will use the
 parameters declared outside of any interface declaration,
 or the default settings.
+.It Ic no-lease-file ;
+The
+.Ic no-lease-file
+statement causes the DHCP client to not write a lease file on being
+assigned a lease, and to ignore an existing lease file.
+This should be used when the other end of a link requires a successful
+DHCP exchange before making the link fully functional, even when a
+valid lease from a previous DHCP exchange still exists.
 .El
 .Sh EXAMPLES
 The following configuration file is used on a laptop
Index: sbin/dhclient/dhcpd.h
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
retrieving revision 1.145
diff -u -p -r1.145 dhcpd.h
--- sbin/dhclient/dhcpd.h       5 Dec 2014 15:47:05 -0000       1.145
+++ sbin/dhclient/dhcpd.h       8 Dec 2014 10:07:39 -0000
@@ -136,6 +136,7 @@ struct client_config {
        int                      requested_option_count;
        int                      required_option_count;
        int                      ignored_option_count;
+       u_int8_t                 use_lease_file;
        time_t                   timeout;
        time_t                   initial_interval;
        time_t                   link_timeout;
Index: sbin/dhclient/dhctoken.h
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhctoken.h,v
retrieving revision 1.9
diff -u -p -r1.9 dhctoken.h
--- sbin/dhclient/dhctoken.h    5 Dec 2013 22:31:35 -0000       1.9
+++ sbin/dhclient/dhctoken.h    8 Dec 2014 10:07:39 -0000
@@ -78,6 +78,7 @@
 #define TOK_REJECT             292
 #define TOK_LINK_TIMEOUT       294
 #define TOK_IGNORE             295
+#define TOK_NO_LEASE_FILE      296
 
 #define is_identifier(x)       ((x) >= TOK_FIRST_TOKEN &&      \
                                 (x) != TOK_STRING &&   \








Regards,

Jurjen Oskam

Reply via email to