From eb4a4ea46c7707f061d734b5f0ceb4ca7465fa47 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 19 Mar 2012 13:50:41 +0100 Subject: [PATCH] service: Fix refcount leak on ipconfigs In __connman_service_connect() we call __connman_ipconfig_enable() which takes a ref on the ipconfig object. Later when the service state machine is updated service takes another ref. When the device disapears during operation (the user didn't call Service.Disconnect()), we do not call __connman_ipconfig_disable() anymore which would drop one ref. --- src/service.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/service.c b/src/service.c index 529a1a0..ba35dc9 100644 --- a/src/service.c +++ b/src/service.c @@ -740,6 +740,25 @@ static connman_bool_t is_connected_state(const struct connman_service *service, return FALSE; } +static connman_bool_t is_idle_state(const struct connman_service *service, + enum connman_service_state state) +{ + switch (state) { + case CONNMAN_SERVICE_STATE_UNKNOWN: + case CONNMAN_SERVICE_STATE_ASSOCIATION: + case CONNMAN_SERVICE_STATE_CONFIGURATION: + case CONNMAN_SERVICE_STATE_READY: + case CONNMAN_SERVICE_STATE_ONLINE: + case CONNMAN_SERVICE_STATE_DISCONNECT: + case CONNMAN_SERVICE_STATE_FAILURE: + break; + case CONNMAN_SERVICE_STATE_IDLE: + return TRUE; + } + + return FALSE; +} + static connman_bool_t is_connecting(struct connman_service *service) { return is_connecting_state(service, service->state); @@ -4946,6 +4965,12 @@ static void service_lower_down(struct connman_ipconfig *ipconfig) DBG("%s lower down", __connman_ipconfig_get_ifname(ipconfig)); + if (is_idle_state(service, service->state_ipv4) == FALSE) + __connman_ipconfig_disable(service->ipconfig_ipv4); + + if (is_idle_state(service, service->state_ipv6) == FALSE) + __connman_ipconfig_disable(service->ipconfig_ipv6); + stats_stop(service); service_save(service); } -- 2.7.4