dhcpv4: offer a valid configuration with DHCP NAK
[project/odhcpd.git] / src / dhcpv4.c
index 9746aa2..0d75730 100644 (file)
@@ -334,7 +334,16 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
        } else if (reqmsg == DHCPV4_MSG_REQUEST && reqaddr.s_addr &&
                        reqaddr.s_addr != htonl(lease->addr)) {
                msg = DHCPV4_MSG_NAK;
        } else if (reqmsg == DHCPV4_MSG_REQUEST && reqaddr.s_addr &&
                        reqaddr.s_addr != htonl(lease->addr)) {
                msg = DHCPV4_MSG_NAK;
-               lease = NULL;
+               /*
+                * DHCP client requested an IP which we can't offer to him. Probably the
+                * client changed the network. The reply type is set to DHCPV4_MSG_NAK,
+                * because the client should not use that IP.
+                *
+                * For modern devices we build an answer that includes a valid IP, like
+                * a DHCPV4_MSG_ACK. The client will use that IP and doesn't need to
+                * perform additional DHCP round trips.
+                *
+                */
        }
 
        if (reqmsg == DHCPV4_MSG_DECLINE || reqmsg == DHCPV4_MSG_RELEASE)
        }
 
        if (reqmsg == DHCPV4_MSG_DECLINE || reqmsg == DHCPV4_MSG_RELEASE)
@@ -491,7 +500,6 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
                }
        }
 
                }
        }
 
-       bool update_state = false;
        if (msg == DHCPV4_MSG_DISCOVER || msg == DHCPV4_MSG_REQUEST) {
                bool assigned = !!a;
                size_t hostlen = strlen(hostname) + 1;
        if (msg == DHCPV4_MSG_DISCOVER || msg == DHCPV4_MSG_REQUEST) {
                bool assigned = !!a;
                size_t hostlen = strlen(hostname) + 1;
@@ -530,24 +538,18 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
                        a = NULL;
                }
 
                        a = NULL;
                }
 
-               if (a)
-                       update_state = true;
-
                if (assigned && a)
                        lease = a;
        } else if (msg == DHCPV4_MSG_RELEASE) {
                if (a) {
                        a->valid_until = 0;
                if (assigned && a)
                        lease = a;
        } else if (msg == DHCPV4_MSG_RELEASE) {
                if (a) {
                        a->valid_until = 0;
-                       update_state = true;
                }
        } else if (msg == DHCPV4_MSG_DECLINE) {
                memset(a->hwaddr, 0, sizeof(a->hwaddr));
                a->valid_until = now + 3600; // Block address for 1h
                }
        } else if (msg == DHCPV4_MSG_DECLINE) {
                memset(a->hwaddr, 0, sizeof(a->hwaddr));
                a->valid_until = now + 3600; // Block address for 1h
-               update_state = true;
        }
 
        }
 
-       if (update_state)
-               dhcpv6_write_statefile();
+       dhcpv6_write_statefile();
 
        return lease;
 }
 
        return lease;
 }