Failover + infinite leases

Alessandro Gherardi alessandro.gherardi at yahoo.com
Sat Mar 19 00:46:53 UTC 2016


OK I found the issue. It's a bug in dhcpd, failover.c source file.
With reference to version 4.3.3-P1:
On line 5504, the pot_expire local variable is defined as a u_int32_t, which on my 64-bit Ubuntu is a 4-byte integer. 
On line 5546, pot_expire is assigned lease->tstp, which is defined as a TIME, which is a time_t, which is an 8-byte integer.
This causes truncation and tsfp to NOT be set to the potential expiry time acknowledged by the partner.
To fix, define pot_expire as a TIME instead:
> diff dhcp-4.3.3-P1/server/failover.c ../dhcp-4.3.3-P1/server/failover.c
5504c5504
<       u_int32_t pot_expire;
---
>       TIME pot_expire;

      From: Alessandro Gherardi <alessandro.gherardi at yahoo.com>
 To: "dhcp-users at lists.isc.org" <dhcp-users at lists.isc.org> 
 Sent: Friday, March 18, 2016 12:41 PM
 Subject: Failover + infinite leases
   



Hi,I'm trying to configure dhcpd to dole out infinite leases + failover.
I set both default-lease-time and max-lease-time to -1 (full dhcpd.conf's are below). The problem is that dhcpd never doles out infinite leases. I understand that, because of the failover protocol, the very first leave expires after MCLT. However, when the client renews, the server should return an infinite lease.
I downloaded and built dhcp-4.3.3-P1, and added some log statements in dhcp.c to try and understand what's going on. Here's the modified code:
#if defined (FAILOVER_PROTOCOL)
                /* Okay, we know the lease duration.   Now check the
                   failover state, if any. */
                if (lease -> pool && lease -> pool -> failover_peer) {
                        TIME new_lease_time = lease_time;
                        dhcp_failover_state_t *peer =
                            lease -> pool -> failover_peer;                        /* Copy previous lease failover ack-state. */
                        lt->tsfp = lease->tsfp;
                        lt->atsfp = lease->atsfp;                        /* cltt set below */                        /* Lease times less than MCLT are not a concern. */
                        if (lease_time > peer->mclt) {log_info("==> lease_time %ld MCLT %ld cur_time %ld tsfp %ld",
        (long int)lease_time, (long int)peer->mclt, (long int)cur_time, (long int)lt->tsfp);                                /* Each server can only offer a lease time
                                 * that is either equal to MCLT (at least),
                                 * or up to TSFP+MCLT.  Only if the desired
                                 * lease time falls within TSFP+MCLT, can
                                 * the server allow it.
                                 */
                                if (lt->tsfp <= cur_time) {log_info("==> setting new_lease_time to MCLT %ld", (long int)peer->mclt);                                        new_lease_time = peer->mclt;
                                }
                                else if ((cur_time + lease_time) > (lt->tsfp + peer->mclt)) {
                                        new_lease_time = (lt->tsfp - cur_time) + peer->mclt;log_info("==> new_lease_time %ld", (long int)new_lease_time);                                }
                        }

Here's the output of dhcpd on the primary when a new client subscribes. I deleted the dhcpd.leases file from both primary and secondary before starting dhcpd and client:
==> lease_time 4294967295 MCLT 120 cur_time 1458325225 tsfp 0
==> setting new_lease_time to MCLT 120
DHCPDISCOVER from 08:00:27:5c:f4:e5 via eth1
DHCPOFFER on 192.168.56.132 to 08:00:27:5c:f4:e5 (dhcpclient) via eth1
==> lease_time 4294967295 MCLT 120 cur_time 1458325226 tsfp 0
==> setting new_lease_time to MCLT 120
DHCPREQUEST for 192.168.56.132 (192.168.56.2) from 08:00:27:5c:f4:e5 (dhcpclient) via eth1
DHCPACK on 192.168.56.132 to 08:00:27:5c:f4:e5 (dhcpclient) via eth1
==> lease_time 4294967295 MCLT 120 cur_time 1458325281 tsfp 1458325285
==> new_lease_time 124
DHCPREQUEST for 192.168.56.132 from 08:00:27:5c:f4:e5 (dhcpclient) via eth1
DHCPACK on 192.168.56.132 to 08:00:27:5c:f4:e5 (dhcpclient) via eth1
==> lease_time 4294967295 MCLT 120 cur_time 1458325332 tsfp 1458325342
==> new_lease_time 130
DHCPREQUEST for 192.168.56.132 from 08:00:27:5c:f4:e5 (dhcpclient) via eth1
DHCPACK on 192.168.56.132 to 08:00:27:5c:f4:e5 (dhcpclient) via eth1
I see this in the leases file:
lease 192.168.56.132 {
  starts 5 2016/03/18 18:20:26;
  ends 5 2016/03/18 18:22:26;
  tstp 2 2152/04/25 00:49:41;
  tsfp 5 2016/03/18 18:21:25;
  atsfp 5 2016/03/18 18:21:25;
  cltt 5 2016/03/18 18:20:26;
  binding state active;
  next binding state expired;
  hardware ethernet 08:00:27:5c:f4:e5;
  client-hostname "dhcpclient";
}
Since tstp is (basically) infinite but tsfp is always small, it appears that the secondary never acknowledges the infinite tsfp. 
Any suggestions?
Thank you in advance.
dhcpd.conf on the primary:

ddns-update-style none;
default-lease-time -1;
max-lease-time -1;
authoritative;
log-facility local7;failover peer "dhcp-failover" {
        primary;
        address 192.168.56.2;
        port 647;
        peer address 192.168.56.3;
        peer port 648;
        max-response-delay 30;
        max-unacked-updates 10;
        load balance max seconds 3;
        mclt 120;
        split 128;
}
omapi-port 7911;
subnet 192.168.56.0 netmask 255.255.255.0 {
        option routers 192.168.56.1;
        option broadcast-address 192.168.56.255;
        pool {
                failover peer "dhcp-failover";
                range 192.168.56.10 192.168.56.254;
        }
        default-lease-time -1;
        max-lease-time -1;
}

Here's dhcpd.conf on the secondary:
ddns-update-style none;
default-lease-time -1;
max-lease-time -1;
authoritative;
log-facility local7;
failover peer "dhcp-failover" {
        secondary;
        address 192.168.56.3;
        port 648;
        peer address 192.168.56.2;
        peer port 647;
        max-response-delay 30;
        max-unacked-updates 10;
        load balance max seconds 3;
}
omapi-port 7911;

subnet 192.168.56.0 netmask 255.255.255.0 {
        option routers 192.168.56.1;
        option broadcast-address 192.168.56.255;
        pool {
                failover peer "dhcp-failover";
                range 192.168.56.10 192.168.56.254;
        }
        default-lease-time -1;
        max-lease-time -1;
}
Here's a snippet from /var/lib/dhcp/dhcpd.leases on the primary:
failover peer "dhcp-failover" state {
  my state normal at 4 2016/03/17 15:32:28;
  partner state normal at 4 2016/03/17 15:32:25;
}
lease 192.168.56.132 {
  starts 4 2016/03/17 16:03:03;
  ends 4 2016/03/17 16:05:03;
  tstp 0 2152/04/23 22:32:18;
  tsfp 4 2016/03/17 16:04:02;
  atsfp 4 2016/03/17 16:04:02;
  cltt 4 2016/03/17 16:03:03;
  binding state active;
  next binding state expired;
  hardware ethernet 08:00:27:5c:f4:e5;
  client-hostname "dhcpclient";
}


   

   

  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/dhcp-users/attachments/20160319/a0cfc82a/attachment-0001.html>


More information about the dhcp-users mailing list