As the dhcp structure is not freed when removed from the hash table,
check whether the structure already exists when calling
__connman_dhcp_start(). Only initialize callbacks and other data on
newly created objects. As dhcp_request() now only handles
initialization, rename it to dhcp_initialize().
---
 src/dhcp.c | 47 +++++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index 03200f1..83d7dfb 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -492,10 +492,9 @@ static void ipv4ll_available_cb(GDHCPClient 
*ipv4ll_client, gpointer user_data)
        g_free(netmask);
 }
 
-static int dhcp_request(struct connman_dhcp *dhcp)
+static int dhcp_initialize(struct connman_dhcp *dhcp)
 {
        struct connman_service *service;
-       struct connman_ipconfig *ipconfig;
        GDHCPClient *dhcp_client;
        GDHCPClientError error;
        const char *hostname;
@@ -547,16 +546,7 @@ static int dhcp_request(struct connman_dhcp *dhcp)
 
        dhcp->dhcp_client = dhcp_client;
 
-       ipconfig = __connman_service_get_ip4config(service);
-
-       /*
-        * Clear the addresses at startup so that lease callback will
-        * take the lease and set ip address properly.
-        */
-       __connman_ipconfig_clear_address(ipconfig);
-
-       return g_dhcp_client_start(dhcp_client,
-                               __connman_ipconfig_get_dhcp_address(ipconfig));
+       return 0;
 }
 
 static int dhcp_release(struct connman_dhcp *dhcp)
@@ -583,22 +573,39 @@ static int dhcp_release(struct connman_dhcp *dhcp)
 
 int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback)
 {
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig;
+       const char *last_addr = NULL;
        struct connman_dhcp *dhcp;
 
        DBG("");
 
-       dhcp = g_try_new0(struct connman_dhcp, 1);
-       if (!dhcp)
-               return -ENOMEM;
+       service = connman_service_lookup_from_network(network);
+       if (!service)
+               return -EINVAL;
 
-       dhcp->network = network;
-       dhcp->callback = callback;
+       ipconfig = __connman_service_get_ip4config(service);
+       if (ipconfig)
+               last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
+
+       dhcp = g_hash_table_lookup(network_table, network);
+       if (!dhcp) {
 
-       connman_network_ref(network);
+               dhcp = g_try_new0(struct connman_dhcp, 1);
+               if (!dhcp)
+                       return -ENOMEM;
 
-       g_hash_table_replace(network_table, network, dhcp);
+               dhcp->network = network;
+               connman_network_ref(network);
+
+               g_hash_table_insert(network_table, network, dhcp);
+
+               dhcp_initialize(dhcp);
+       }
+
+       dhcp->callback = callback;
 
-       return dhcp_request(dhcp);
+       return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
 }
 
 void __connman_dhcp_stop(struct connman_network *network)
-- 
1.9.1

_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to