chiark / gitweb /
networkd/sd-dhcp-server: only start dhcp server when necessary
[elogind.git] / src / libsystemd-network / sd-dhcp-server.c
index d9495024ab9476c5990238b97abfee1b50337b9d..5c32fdfffa9053c3d239cfd6ed506c5acd3ce271 100644 (file)
@@ -29,7 +29,7 @@
 #include "dhcp-server-internal.h"
 #include "dhcp-internal.h"
 
-#define DHCP_DEFAULT_LEASE_TIME         60
+#define DHCP_DEFAULT_LEASE_TIME         3600 /* one hour */
 
 int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *address,
                                   size_t size) {
@@ -62,6 +62,12 @@ int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address)
         return 0;
 }
 
+bool sd_dhcp_server_is_running(sd_dhcp_server *server) {
+        assert_return(server, -EINVAL);
+
+        return !!server->receive_message;
+}
+
 sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
         if (server)
                 assert_se(REFCNT_INC(server->n_ref) >= 2);
@@ -105,29 +111,27 @@ static void dhcp_lease_free(DHCPLease *lease) {
         free(lease);
 }
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPLease*, dhcp_lease_free);
-#define _cleanup_dhcp_lease_free_ _cleanup_(dhcp_lease_freep)
-
 sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
-        if (server && REFCNT_DEC(server->n_ref) <= 0) {
-                DHCPLease *lease;
-                Iterator i;
+        DHCPLease *lease;
+
+        if (!server)
+                return NULL;
 
-                log_dhcp_server(server, "UNREF");
+        if (REFCNT_DEC(server->n_ref) > 0)
+                return NULL;
 
-                sd_dhcp_server_stop(server);
+        log_dhcp_server(server, "UNREF");
 
-                sd_event_unref(server->event);
+        sd_dhcp_server_stop(server);
 
-                HASHMAP_FOREACH(lease, server->leases_by_client_id, i) {
-                        hashmap_remove(server->leases_by_client_id, lease);
-                        dhcp_lease_free(lease);
-                }
+        sd_event_unref(server->event);
 
-                hashmap_free(server->leases_by_client_id);
-                free(server->bound_leases);
-                free(server);
-        }
+        while ((lease = hashmap_steal_first(server->leases_by_client_id)))
+                dhcp_lease_free(lease);
+        hashmap_free(server->leases_by_client_id);
+
+        free(server->bound_leases);
+        free(server);
 
         return NULL;
 }
@@ -342,9 +346,12 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
         } else if (req->message->ciaddr && type != DHCP_NAK)
                 destination = req->message->ciaddr;
 
-        if (destination || requested_broadcast(req) || type == DHCP_NAK)
+        if (destination != INADDR_ANY)
                 return dhcp_server_send_udp(server, destination, &packet->dhcp,
                                             sizeof(DHCPMessage) + optoffset);
+        else if (requested_broadcast(req) || type == DHCP_NAK)
+                return dhcp_server_send_udp(server, INADDR_BROADCAST, &packet->dhcp,
+                                            sizeof(DHCPMessage) + optoffset);
         else
                 /* we cannot send UDP packet to specific MAC address when the address is
                    not yet configured, so must fall back to raw packets */