statefiles: remove hosts entries from statefile
authorDavid Härdeman <[email protected]>
Sun, 23 Nov 2025 22:38:04 +0000 (23:38 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Sun, 30 Nov 2025 15:59:53 +0000 (16:59 +0100)
Further simplify statefiles.c by removing the hosts entries from the
statefile (they can be found in the dedicated hosts files instead).

Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/331
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
README.md
src/dhcpv6-ia.c
src/odhcpd.h
src/statefiles.c
src/ubus.c

index 390708952d9522ec5373810d4ccb10efcf88991c..c375450c13d103f94279472e0b608578736f489e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -62,9 +62,9 @@ and may also receive information from ubus
 | Option       | Type  |Default| Description |
 | :------------ | :---- | :----        | :---------- |
 | maindhcp     | bool  | 0     | Use odhcpd as the main DHCPv4 service |
-| leasefile    | string|       | DHCP/v6 lease/hostfile |
+| leasefile    | string|       | DHCPv4/6 lease file |
 | leasetrigger | string|       | Lease trigger script |
-| hostsdir     | string|       | DHCP/v6 hostfile directory (one file per interface will be created) |
+| hostsdir     | string|       | DHCPv4/v6 hostfile directory (one file per interface will be created) |
 | loglevel     |integer| 6     | Syslog level priority (0-7) |
 | piofolder    |string |       | Folder to store IPv6 prefix information (to detect stale prefixes, see RFC9096, §3.5) |
 | enable_tz |bool | 1 | Toggle whether RFC4833 timezone information is sent to clients, if set in system  |
index ca3f89d9811b6295a4ccb488b3efb18a93f9bddd..34b088b47de8193d8f64f428b7ec46eb2fc3bc32 100644 (file)
@@ -820,7 +820,7 @@ struct log_ctxt {
        int buf_idx;
 };
 
-static void dhcpv6_log_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_addr *addr, int prefix,
+static void dhcpv6_log_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_addr *addr, uint8_t prefix_len,
                               _o_unused uint32_t pref_lt, _o_unused uint32_t valid_lt, void *arg)
 {
        struct log_ctxt *ctxt = (struct log_ctxt *)arg;
@@ -828,7 +828,7 @@ static void dhcpv6_log_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_
 
        inet_ntop(AF_INET6, addr, addrbuf, sizeof(addrbuf));
        ctxt->buf_idx += snprintf(ctxt->buf + ctxt->buf_idx, ctxt->buf_len - ctxt->buf_idx,
-                                       "%s/%d ", addrbuf, prefix);
+                                 " %s/%" PRIu8, addrbuf, prefix_len);
 }
 
 static void dhcpv6_log(uint8_t msgtype, struct interface *iface, time_t now,
@@ -889,7 +889,7 @@ static void dhcpv6_log(uint8_t msgtype, struct interface *iface, time_t now,
                odhcpd_enum_addr6(iface, a, now, dhcpv6_log_ia_addr, &ctxt);
        }
 
-       info("DHCPV6 %s %s from %s on %s: %s %s", type, (is_pd) ? "IA_PD" : "IA_NA",
+       info("DHCPV6 %s %s from %s on %s: %s%s", type, (is_pd) ? "IA_PD" : "IA_NA",
             duidbuf, iface->name, status, leasebuf);
 }
 
index 8a6461cbe1d99db48c9764f5bba280d554f1c8d7..6265c9472301f6658f1b1130f2a5c737b1f16b35 100644 (file)
@@ -559,7 +559,7 @@ int odhcpd_bmemcmp(const void *av, const void *bv, size_t bits);
 void odhcpd_bmemcpy(void *av, const void *bv, size_t bits);
 
 typedef void (*odhcpd_enum_addr6_cb_t)(struct dhcpv6_lease *lease,
-                                      struct in6_addr *addr, int prefix,
+                                      struct in6_addr *addr, uint8_t prefix_len,
                                       uint32_t pref, uint32_t valid,
                                       void *arg);
 void odhcpd_enum_addr6(struct interface *iface, struct dhcpv6_lease *lease,
index 8862f1b435ebc0ff1d275972bfc257112f7dbafe..0c82a6d7116a444266f9b4fa2730c5d9b43a416f 100644 (file)
@@ -21,6 +21,7 @@
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 #include <resolv.h>
+#include <spawn.h>
 
 #include <libubox/md5.h>
 
@@ -36,9 +37,6 @@ struct write_ctxt {
        struct interface *iface;
        time_t now; // CLOCK_MONOTONIC
        time_t wall_time;
-       char *buf;
-       int buf_len;
-       int buf_idx;
 };
 
 static void statefiles_write_host(const char *ipbuf, const char *hostname, struct write_ctxt *ctxt)
@@ -68,7 +66,7 @@ static bool statefiles_write_host6(struct write_ctxt *ctxt, struct dhcpv6_lease
        return true;
 }
 
-static void statefiles_write_host6_cb(struct dhcpv6_lease *lease, struct in6_addr *addr, _o_unused int prefix,
+static void statefiles_write_host6_cb(struct dhcpv6_lease *lease, struct in6_addr *addr, _o_unused uint8_t prefix_len,
                                      _o_unused uint32_t pref_lt, _o_unused uint32_t valid_lt, void *arg)
 {
        struct write_ctxt *ctxt = (struct write_ctxt *)arg;
@@ -161,53 +159,50 @@ err:
        close(fd);
 }
 
-static void statefiles_write_state6_addr(struct dhcpv6_lease *lease, struct in6_addr *addr, int prefix,
+static void statefiles_write_state6_addr(struct dhcpv6_lease *lease, struct in6_addr *addr, uint8_t prefix_len,
                                         _o_unused uint32_t pref_lt, _o_unused uint32_t valid_lt, void *arg)
 {
        struct write_ctxt *ctxt = (struct write_ctxt *)arg;
        char ipbuf[INET6_ADDRSTRLEN];
 
-       inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf));
-
-       if (statefiles_write_host6(ctxt, lease, addr)) {
-               md5_hash(ipbuf, strlen(ipbuf), &ctxt->md5);
+       if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME) && lease->flags & OAF_DHCPV6_NA) {
+               md5_hash(addr, sizeof(*addr), &ctxt->md5);
                md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
        }
 
        if (!ctxt->fp)
                return;
 
-       ctxt->buf_idx += snprintf(ctxt->buf + ctxt->buf_idx,
-                                 ctxt->buf_len - ctxt->buf_idx,
-                                 " %s/%d", ipbuf, prefix);
+       inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf));
+       fprintf(ctxt->fp, " %s/%" PRIu8, ipbuf, prefix_len);
 }
 
 static void statefiles_write_state6(struct write_ctxt *ctxt, struct dhcpv6_lease *lease)
 {
        char duidbuf[DUID_HEXSTRLEN];
 
-       ctxt->buf_idx = 0;
-       odhcpd_enum_addr6(ctxt->iface, lease, ctxt->now, statefiles_write_state6_addr, ctxt);
-
-       if (!ctxt->fp)
-               return;
+       if (ctxt->fp) {
+               odhcpd_hexlify(duidbuf, lease->duid, lease->duid_len);
+
+               /* # <iface> <hexduid> <hexiaid> <hostname> <valid_until> <assigned_[host|subnet]_id> <pfx_length> [<addrs> ...] */
+               fprintf(ctxt->fp,
+                       "# %s %s %x %s%s %" PRId64 " %" PRIx64 " %" PRIu8,
+                       ctxt->iface->ifname, duidbuf, ntohl(lease->iaid),
+                       (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
+                       (lease->hostname ? lease->hostname : "-"),
+                       (lease->valid_until > ctxt->now ?
+                        (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
+                        (INFINITE_VALID(lease->valid_until) ? -1 : 0)),
+                       (lease->flags & OAF_DHCPV6_NA ?
+                        lease->assigned_host_id :
+                        (uint64_t)lease->assigned_subnet_id),
+                       lease->length);
+       }
 
-       odhcpd_hexlify(duidbuf, lease->duid, lease->duid_len);
+       odhcpd_enum_addr6(ctxt->iface, lease, ctxt->now, statefiles_write_state6_addr, ctxt);
 
-       /* # <iface> <hexduid> <hexiaid> <hostname> <valid_until> <assigned_[host|subnet]_id> <pfx_length> [<addrs> ...] */
-       fprintf(ctxt->fp,
-               "# %s %s %x %s%s %" PRId64 " %" PRIx64 " %" PRIu8 "%s\n",
-               ctxt->iface->ifname, duidbuf, ntohl(lease->iaid),
-               (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
-               (lease->hostname ? lease->hostname : "-"),
-               (lease->valid_until > ctxt->now ?
-                (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
-                (INFINITE_VALID(lease->valid_until) ? -1 : 0)),
-               (lease->flags & OAF_DHCPV6_NA ?
-                lease->assigned_host_id :
-                (uint64_t)lease->assigned_subnet_id),
-               lease->length,
-               ctxt->buf);
+       if (ctxt->fp)
+               putc('\n', ctxt->fp);
 }
 
 static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease *lease)
@@ -215,16 +210,15 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease
        char hexhwaddr[sizeof(lease->hwaddr) * 2 + 1];
        char ipbuf[INET6_ADDRSTRLEN];
 
-       inet_ntop(AF_INET, &lease->ipv4, ipbuf, sizeof(ipbuf));
-
-       if (statefiles_write_host4(ctxt, lease)) {
-               md5_hash(ipbuf, strlen(ipbuf), &ctxt->md5);
+       if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME)) {
+               md5_hash(&lease->ipv4, sizeof(lease->ipv4), &ctxt->md5);
                md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
        }
 
        if (!ctxt->fp)
                return;
 
+       inet_ntop(AF_INET, &lease->ipv4, ipbuf, sizeof(ipbuf));
        odhcpd_hexlify(hexhwaddr, lease->hwaddr, sizeof(lease->hwaddr));
 
        /* # <iface> <hexhwaddr> "ipv4" <hostname> <valid_until> <hexaddr> "32" <addrstr>"/32" */
@@ -242,11 +236,8 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease
 /* Returns true if there are changes to be written to the hosts file(s) */
 static bool statefiles_write_state(time_t now)
 {
-       char leasebuf[512];
        struct write_ctxt ctxt = {
                .fp = NULL,
-               .buf = leasebuf,
-               .buf_len = sizeof(leasebuf),
                .now = now,
                .wall_time = time(NULL),
        };
@@ -338,10 +329,9 @@ bool statefiles_write()
 
        if (config.dhcp_cb) {
                char *argv[2] = { config.dhcp_cb, NULL };
-               if (!vfork()) {
-                       execv(argv[0], argv);
-                       _exit(128);
-               }
+               pid_t pid;
+
+               posix_spawn(&pid, argv[0], NULL, NULL, argv, environ);
        }
 
        return true;
index 5b6cf223f37a44be3535adad5367bed484a6dcdc..2f2f2060ba46387365d8c71387d7a189df5e5918 100644 (file)
@@ -90,7 +90,7 @@ static int handle_dhcpv4_leases(struct ubus_context *ctx, _o_unused struct ubus_
 }
 #endif /* DHCPV4_SUPPORT */
 
-static void dhcpv6_blobmsg_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_addr *addr, int prefix,
+static void dhcpv6_blobmsg_ia_addr(_o_unused struct dhcpv6_lease *lease, struct in6_addr *addr, uint8_t prefix_len,
                                   uint32_t pref_lt, uint32_t valid_lt, _o_unused void *arg)
 {
        void *a = blobmsg_open_table(&b, NULL);
@@ -103,8 +103,8 @@ static void dhcpv6_blobmsg_ia_addr(_o_unused struct dhcpv6_lease *lease, struct
        blobmsg_add_u32(&b, "valid-lifetime",
                        valid_lt == UINT32_MAX ? (uint32_t)-1 : valid_lt);
 
-       if (prefix != 128)
-               blobmsg_add_u32(&b, "prefix-length", prefix);
+       if (prefix_len != 128)
+               blobmsg_add_u32(&b, "prefix-length", prefix_len);
 
        blobmsg_close_table(&b, a);
 }