[PATCH] config: Fix memory leak when realloc fails
by Nishant Chaprana
This patch fixes realloc failure case, when realloc fails it
returns NULL and previously allocated memory was getting lost in
this scenario, So all memory should be freed before returning.
---
src/config.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/config.c b/src/config.c
index 344b8ce..e3108eb 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1550,13 +1550,16 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
g_hash_table_iter_init(&iter_file, config_table);
while (g_hash_table_iter_next(&iter_file, &key, &value)) {
struct connman_config *config_file = value;
+ struct connman_config_entry *tmp_entries = entries;
count = g_hash_table_size(config_file->service_table);
entries = g_try_realloc(entries, (i + count + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
g_hash_table_iter_init(&iter_config,
config_file->service_table);
@@ -1589,10 +1592,14 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
}
if (entries) {
+ struct connman_config_entry *tmp_entries = entries;
+
entries = g_try_realloc(entries, (i + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
entries[i] = NULL;
--
1.9.1
4 years, 11 months
[PATCH] Add AlwaysUseFallbackNameservers flag in the configuration file. When it is enabled, the fallback name servers will be used even though some name servers are provided by the service.
by Feng Wang
---
src/dhcp.c | 23 +++++++++++++++++++++--
src/main.c | 39 ++++++++++++++++++++++++++-------------
src/main.conf | 4 ++++
src/service.c | 3 ++-
4 files changed, 53 insertions(+), 16 deletions(-)
diff --git a/src/dhcp.c b/src/dhcp.c
index 4040ad1..ba14ae7 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -312,11 +312,11 @@ static bool compare_string_arrays(char **array_a, char **array_b)
static bool apply_lease_available_on_network(GDHCPClient *dhcp_client,
struct connman_dhcp *dhcp)
{
- char **nameservers, **timeservers, *pac = NULL;
+ char **nameservers, **timeservers, *pac = NULL, **ns;
struct connman_service *service;
GList *list, *option = NULL;
int ns_entries;
- int i;
+ int i, j, len;
if (!dhcp->network)
return true;
@@ -366,6 +366,25 @@ static bool apply_lease_available_on_network(GDHCPClient *dhcp_client,
g_strfreev(dhcp->nameservers);
}
+ /* Append fallback name servers to the name server list */
+ if (connman_setting_get_bool("AlwaysUseFallbackNameservers")) {
+ ns = connman_setting_get_string_list("FallbackNameservers");
+ if (ns) {
+ if (nameservers) {
+ i = g_strv_length(nameservers);
+ len = i + g_strv_length(ns);
+ nameservers = g_try_renew(char *, nameservers, len + 1);
+ } else {
+ i = 0;
+ len = g_strv_length(ns);
+ nameservers = g_try_new0(char *, len + 1);
+ }
+ for (j = 0; ns[j]; j++, i++)
+ nameservers[i] = g_strdup(ns[j]);
+ nameservers[i] = NULL;
+ }
+ }
+
dhcp->nameservers = nameservers;
for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) {
diff --git a/src/main.c b/src/main.c
index e46fa7b..87d11a7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -74,6 +74,7 @@ static struct {
char **tethering_technologies;
bool persistent_tethering_mode;
bool enable_6to4;
+ bool always_use_fallback_nameservers;
} connman_settings = {
.bg_scan = true,
.pref_timeservers = NULL,
@@ -88,21 +89,23 @@ static struct {
.tethering_technologies = NULL,
.persistent_tethering_mode = false,
.enable_6to4 = false,
+ .always_use_fallback_nameservers = false,
};
-#define CONF_BG_SCAN "BackgroundScanning"
-#define CONF_PREF_TIMESERVERS "FallbackTimeservers"
-#define CONF_AUTO_CONNECT "DefaultAutoConnectTechnologies"
-#define CONF_PREFERRED_TECHS "PreferredTechnologies"
-#define CONF_FALLBACK_NAMESERVERS "FallbackNameservers"
-#define CONF_TIMEOUT_INPUTREQ "InputRequestTimeout"
-#define CONF_TIMEOUT_BROWSERLAUNCH "BrowserLaunchTimeout"
-#define CONF_BLACKLISTED_INTERFACES "NetworkInterfaceBlacklist"
-#define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates"
-#define CONF_SINGLE_TECH "SingleConnectedTechnology"
-#define CONF_TETHERING_TECHNOLOGIES "TetheringTechnologies"
-#define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode"
-#define CONF_ENABLE_6TO4 "Enable6to4"
+#define CONF_BG_SCAN "BackgroundScanning"
+#define CONF_PREF_TIMESERVERS "FallbackTimeservers"
+#define CONF_AUTO_CONNECT "DefaultAutoConnectTechnologies"
+#define CONF_PREFERRED_TECHS "PreferredTechnologies"
+#define CONF_FALLBACK_NAMESERVERS "FallbackNameservers"
+#define CONF_TIMEOUT_INPUTREQ "InputRequestTimeout"
+#define CONF_TIMEOUT_BROWSERLAUNCH "BrowserLaunchTimeout"
+#define CONF_BLACKLISTED_INTERFACES "NetworkInterfaceBlacklist"
+#define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates"
+#define CONF_SINGLE_TECH "SingleConnectedTechnology"
+#define CONF_TETHERING_TECHNOLOGIES "TetheringTechnologies"
+#define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode"
+#define CONF_ENABLE_6TO4 "Enable6to4"
+#define CONF_ALWAYS_USE_FALLBACK_NAMESERVERS "AlwaysUseFallbackNameservers"
static const char *supported_options[] = {
CONF_BG_SCAN,
@@ -365,6 +368,13 @@ static void parse_config(GKeyFile *config)
connman_settings.enable_6to4 = boolean;
g_clear_error(&error);
+
+ boolean = __connman_config_get_bool(config, "General",
+ CONF_ALWAYS_USE_FALLBACK_NAMESERVERS, &error);
+ if (!error)
+ connman_settings.always_use_fallback_nameservers = boolean;
+
+ g_clear_error(&error);
}
static int config_init(const char *file)
@@ -542,6 +552,9 @@ bool connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_ENABLE_6TO4))
return connman_settings.enable_6to4;
+ if (g_str_equal(key, CONF_ALWAYS_USE_FALLBACK_NAMESERVERS))
+ return connman_settings.always_use_fallback_nameservers;
+
return false;
}
diff --git a/src/main.conf b/src/main.conf
index eb352fb..a4ea083 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -33,6 +33,10 @@
# names are ignored.
# FallbackNameservers =
+# Always use fallback name servers even though the name
+# servers are provided by the service. i.e from DHCP reply.
+# AlwaysUseFallbackNameservers = true
+
# List of technologies that are marked autoconnectable
# by default, separated by commas ",". The default value
# for this entry when empty is ethernet,wifi,cellular.
diff --git a/src/service.c b/src/service.c
index 8e07337..3beb828 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1692,7 +1692,8 @@ static void append_dns(DBusMessageIter *iter, void *user_data)
append_nameservers(iter, service,
service->nameservers_auto);
- if (!service->nameservers && !service->nameservers_auto) {
+ if ((!service->nameservers && !service->nameservers_auto) ||
+ connman_setting_get_bool("AlwaysUseFallbackNameservers")) {
char **ns;
DBG("append fallback nameservers");
--
2.7.0.rc3.207.g0ac5344
4 years, 11 months
Configuration file for Connman AP mode
by Lamsoge, Abhijit
Hi Patrick,
I have a few queries regarding connman's configuration file.
I am trying to configure connman as access point using tether commands.
But What I want to do is change the range of IP-Address's for the clients connecting it.
I mentioned some options in wifi.config file dumped in /var/lib/connman,
Like
[General]
TetheringTechnologies = wifi
Now how do I mention a DHCP IP address range in this.
As far as options in the config-format.txt is concerned, I believe, in wifi context it talks about STAtion role and not AP/Tether mode.
Let me know how to specify IP-Address Pool for DHCP server for wifi AP mode ?
Abhijit
4 years, 11 months
Disabling the network on Disconnect Notification
by Naveen Singh
Hi All
On the disconnect notification from wpa_supplicant (when the interface
state becomes G_SUPPLICANT_STATE_DISCONNECTED), connman disables the
network (SSID). This is done from interface_state function in
plugins/wifi.c:
if (g_supplicant_interface_enable_selected_network(interface,
FALSE) != 0)
DBG("Could not disable selected network");
This severely impacts wpa_supplicant's attempt of getting device
connected back to WiFi. Lot of enterprise AP now have band steering
and/or load balancing enabled as a result of which they keep sending
deauth frames to client till it picks the correct BSSID for
connection. Now if wpa_supplicant is left alone, it would properly
converge to the right BSSID where the association would stick (by
blacklisting a BSSID if it does not allow or deny the connection and
trying the next one)
But now with the very first disconnect notification, connman disables
the whole network which ends up disabling the whole SSID and
wpa_supplicant does not continue with its connection attempts.
Next time when this SSID gets enabled from connman (as a part of next
connect), the same story repeats. End result device sometimes never
get connected. The above piece of code is impacting L2 level roaming
decisions in connman. And I do not think connman has any intention or
desire to interfere in any BSSID level roaming decision of
wpa_supplicant.
Even for the AP which sends deauth with reason code 6/7/4,
wpa_supplicant has internal logic to get device connected fast. This
also gets impacted quite a bit because of disable logic.
Even logs look very confusing at the time of disconnection. You see a
successful association (because of wpa_s connection attempt) followed
by an internally generated disconnect.
I did a test by removing this code and following are the events that
happened on receiving deauth:
1) Client receives deauth frame (reason code 15)
2) wpa_supplicant blacklists the current AP and schedule a scan.
3) It generates disconnect notification to connman
4) Connman released its current IP.
5) wpa_supplicant gets the scan result and finds all the AP
advertising the same SSID.
6) It proceeds with the connection with next BSSID.
7) It connects back with this BSSID
8) Connman gets device the IP address
If deauth is received with reason code 6 or 7 or 4 then there is even
no scan and device gets connected real fast.
Let me know your thoughts on this. I will send my patch soon
Regards
Naveen
4 years, 11 months
[PATCH] delete STORAGEDIR folders when services are removed
by MANIEZZO Marco (MM)
Hello,
currently when a service is removed (Remove d-bus method) some of its properties are cleared but its folder and files in STORAGEDIR are not deleted. This patch removes such data.
Immutable services have a .config file in STORAGEDIR, and if they have been connected at least once they also have the same folder of mutable services: the Remove method will delete the folder and force a re-provision of the service: this will act as a reset of the service to its default.
Please find below the modifications (also attached in case of issues in email indentation):
doc/service-api.txt | 13 ++++++++-----
include/provision.h | 1 +
src/config.c | 9 +++++++++
src/service.c | 35 +++++++++++++++++++++++++++++++----
4 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/doc/service-api.txt b/doc/service-api.txt
index e2e9e84..cb9021c 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -94,11 +94,14 @@ Methodsdict GetProperties() [deprecated]
service is in the State=failure, this method can
also be used to reset the service.
-Calling this method on Ethernet devices, hidden WiFi
-services or provisioned services will cause an error
-message. It is not possible to remove these kind of
-services.
-
+Calling this method on Ethernet devices and hidden WiFi
+services will cause an error message. It is not possible
+to remove these kind ofservices.
+
+For the other services the removal will cause the
+deletion of their folder inSTORAGEDIR. Immutable
+services will be reprovisioned reading their .config file.
+
Possible Errors: [service].Error.InvalidArguments
void MoveBefore(object service)
diff --git a/include/provision.h b/include/provision.h
index 3eb80a8..040f152 100644
--- a/include/provision.h
+++ b/include/provision.h
@@ -42,6 +42,7 @@ struct connman_config_entry {
bool hidden;
};
+void reload_config(const char * ident);
int connman_config_provision_mutable_service(GKeyFile *keyfile);
struct connman_config_entry **connman_config_get_entries(const char *type);
void connman_config_free_entries(struct connman_config_entry **entries);
diff --git a/src/config.c b/src/config.c
index 344b8ce..da95817 100644
--- a/src/config.c
+++ b/src/config.c
@@ -942,6 +942,15 @@ static void config_notify_handler(struct inotify_event *event,
g_hash_table_remove(config_table, ident);
}
+void reload_config(const char * ident)
+{
+struct inotify_event event;
+
+event.mask = IN_MODIFY;
+
+config_notify_handler(&event,ident);
+}
+
int __connman_config_init(void)
{
DBG("");
diff --git a/src/service.c b/src/service.c
index 8e07337..e73f38e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -34,7 +34,7 @@
#include <connman/storage.h>
#include <connman/setting.h>
#include <connman/agent.h>
-
+#include <connman/provision.h>
#include "connman.h"
#define CONNECT_TIMEOUT120
@@ -4081,11 +4081,15 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
bool __connman_service_remove(struct connman_service *service)
{
+unsigned int *auto_connect_types;
+char *ident;
+int i;
+
if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
service->type == CONNMAN_SERVICE_TYPE_GADGET)
return false;
-if (service->immutable || service->hidden ||
+if (service->hidden ||
__connman_provider_is_immutable(service->provider))
return false;
@@ -4116,9 +4120,32 @@ bool __connman_service_remove(struct connman_service *service)
__connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
-service_save(service);
+__connman_storage_remove_service(service->identifier);
-return true;
+if (service->immutable == true && service->config_file)
+{/* force reprovision of immutable services */
+
+/* reset autoconnect to default, because it is not currently (connman 1.31)
+ * managed by .config files
+ */
+auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
+service->autoconnect = false;
+for (i = 0; auto_connect_types &&
+auto_connect_types[i] != 0; i++) {
+if (service->type == auto_connect_types[i]) {
+service->autoconnect = true;
+break;
+}
+}
+
+DBG("reloading service %s", service->config_file);
+
+ident = g_strdup_printf("%s.config", service->config_file);
+reload_config(ident);
+g_free(ident);
+}
+
+return(true);
}
static DBusMessage *remove_service(DBusConnection *conn,
--
1.9.1
Regards,
Marco
________________________________
VISITA IL NOSTRO NUOVO SITO WEB! - VISIT OUR NEW WEB SITE! www.magnetimarelli.com
Confidential Notice: This message - including its attachments - may contain proprietary, confidential and/or legally protected information and is intended solely for the use of the designated addressee(s) above. If you are not the intended recipient be aware that any downloading, copying, disclosure, distribution or use of the contents of the above information is strictly prohibited.
If you have received this communication by mistake, please forward the message back to the sender at the email address above, delete the message from all mailboxes and any other electronic storage medium and destroy all copies.
Disclaimer Notice: Internet communications cannot be guaranteed to be safe or error-free. Therefore we do not assure that this message is complete or accurate and we do not accept liability for any errors or omissions in the contents of this message.
4 years, 11 months
tether question
by Zheng, Wu
Hi partik,
I am trying to enable tether of connman in kernel-3.10 of edison.
Meet some issues. Please help, thanks.
I want to make sure if kernel-3.10 support the tethering feature of connman or not?
Best Regards
Zheng Wu
4 years, 11 months
[PATCH] ofono: Fix inconsitent use of g_try_newo and free
by Niraj Kumar Goit
As context structure is allocated memory using g_try_new0 it should
be freed using g_free, since these allocators may use different
memory pools.
---
plugins/ofono.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/ofono.c b/plugins/ofono.c
index 635f3fc..ad7b2e4 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -284,7 +284,7 @@ static void network_context_free(struct network_context *context)
connman_ipaddress_free(context->ipv6_address);
g_free(context->ipv6_nameservers);
- free(context);
+ g_free(context);
}
static void set_connected(struct modem_data *modem,
--
1.7.9.5
4 years, 11 months
[PATCH] bridge: corrected the format specifier for unsigned int
by Nishant Chaprana
---
src/bridge.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bridge.c b/src/bridge.c
index ba20096..cd2d9ce 100644
--- a/src/bridge.c
+++ b/src/bridge.c
@@ -56,7 +56,7 @@ static int set_forward_delay(const char *name, unsigned int delay)
if (!f)
return -errno;
- fprintf(f, "%d", delay);
+ fprintf(f, "%u", delay);
fclose(f);
--
1.9.1
4 years, 11 months
[PATCH] Removed false null check because context will not be null
by Nishant Chaprana
---
plugins/ofono.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/plugins/ofono.c b/plugins/ofono.c
index 635f3fc..b11d3cc 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -361,19 +361,17 @@ static void set_disconnected(struct network_context *context)
if (context->network)
connman_network_set_connected(context->network, false);
- if (context) {
- g_free(context->ipv4_nameservers);
- context->ipv4_nameservers = NULL;
- if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
- context->ipv4_method =
- CONNMAN_IPCONFIG_METHOD_UNKNOWN;
-
- g_free(context->ipv6_nameservers);
- context->ipv6_nameservers = NULL;
- if (context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
- context->ipv6_method =
- CONNMAN_IPCONFIG_METHOD_UNKNOWN;
- }
+ g_free(context->ipv4_nameservers);
+ context->ipv4_nameservers = NULL;
+ if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
+ context->ipv4_method =
+ CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+
+ g_free(context->ipv6_nameservers);
+ context->ipv6_nameservers = NULL;
+ if (context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
+ context->ipv6_method =
+ CONNMAN_IPCONFIG_METHOD_UNKNOWN;
}
typedef void (*set_property_cb)(struct modem_data *data,
--
1.9.1
4 years, 11 months
[PATCH v4] gsupplicant: Mem leak in wpa_s because "RemoveNetwork" not called
by Naveen Singh
From: nasingh <naveensingh0977(a)gmail.com>
Connman did not call netwok_remove in case AP deauthenticated client causing
wpa_s to re-allocate the ssid pointer even if the next connection attempt
is for the same SSID. This change ensures that at the time of connection
(DBUS Method call AddNetwork) if the network is found not removed, it calls
the dbus API to remove the network and once network is removed, proceed with
the connection.
By the time there is a request for connect and the network path is not NULL it
means that connman has not removed the previous network pointer. This can happen
in the case AP deauthenticated client and connman does not remove the previously
connected network pointer. This causes supplicant to reallocate the memory for
struct wpa_ssid again even if it is the same SSID. This causes memory usage of
wpa_supplicnat to go high. The idea here is that if the previously connected network
is not removed at the time of next connection attempt check if the network path is not
NULL. In case it is non-NULL first remove the network and then once removal is successful,
add the network.
Tested by running a deauth loop script at the AP end and ensure that wpa_s does
not allocate memory for struct wpa_ssid for all the subsequent
connection attempts. During the test memory usage of wpa_s is monitored.
---
gsupplicant/supplicant.c | 153 ++++++++++++++++++++++++++++++++---------------
1 file changed, 105 insertions(+), 48 deletions(-)
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 342cb01..ff1d998 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -249,6 +249,47 @@ struct _GSupplicantGroup {
GSList *members;
};
+struct interface_data {
+ GSupplicantInterface *interface;
+ char *path; /* Interface path cannot be taken from interface (above) as
+ * it might have been freed already.
+ */
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+ bool network_remove_in_progress;
+ GSupplicantSSID *ssid;
+};
+
+struct interface_create_data {
+ char *ifname;
+ char *driver;
+ char *bridge;
+ GSupplicantInterface *interface;
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+};
+
+struct interface_connect_data {
+ GSupplicantInterface *interface;
+ char *path;
+ GSupplicantInterfaceCallback callback;
+ void *user_data;
+ union {
+ GSupplicantSSID *ssid;
+ GSupplicantPeerParams *peer;
+ };
+};
+
+struct interface_scan_data {
+ GSupplicantInterface *interface;
+ char *path;
+ GSupplicantInterfaceCallback callback;
+ GSupplicantScanParams *scan_params;
+ void *user_data;
+};
+
+static int network_remove(struct interface_data *data);
+
static inline void debug(const char *format, ...)
{
char str[256];
@@ -3476,43 +3517,6 @@ GSupplicantPeer *g_supplicant_interface_peer_lookup(GSupplicantInterface *interf
return peer;
}
-struct interface_data {
- GSupplicantInterface *interface;
- char *path; /* Interface path cannot be taken from interface (above) as
- * it might have been freed already.
- */
- GSupplicantInterfaceCallback callback;
- void *user_data;
-};
-
-struct interface_create_data {
- char *ifname;
- char *driver;
- char *bridge;
- GSupplicantInterface *interface;
- GSupplicantInterfaceCallback callback;
- void *user_data;
-};
-
-struct interface_connect_data {
- GSupplicantInterface *interface;
- char *path;
- GSupplicantInterfaceCallback callback;
- union {
- GSupplicantSSID *ssid;
- GSupplicantPeerParams *peer;
- };
- void *user_data;
-};
-
-struct interface_scan_data {
- GSupplicantInterface *interface;
- char *path;
- GSupplicantInterfaceCallback callback;
- GSupplicantScanParams *scan_params;
- void *user_data;
-};
-
static void interface_create_data_free(struct interface_create_data *data)
{
g_free(data->ifname);
@@ -4105,7 +4109,6 @@ static void interface_add_network_result(const char *error,
SUPPLICANT_DBG("PATH: %s", path);
- g_free(interface->network_path);
interface->network_path = g_strdup(path);
supplicant_dbus_method_call(data->interface->path,
@@ -4656,7 +4659,8 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
void *user_data)
{
struct interface_connect_data *data;
- int ret;
+ struct interface_data *intf_data;
+ int ret = 0;
if (!interface)
return -EINVAL;
@@ -4685,12 +4689,44 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
SUPPLICANT_INTERFACE ".Interface.WPS",
"ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING,
wps_process_credentials, wps_start, data, interface);
- } else
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
- interface_add_network_params,
- interface_add_network_result, data,
- interface);
+ } else {
+ /* By the time there is a request for connect and the network
+ * path is not NULL it means that connman has not removed the
+ * previous network pointer. This can happen in the case AP
+ * deauthenticated client and connman does not remove the
+ * previously connected network pointer. This causes supplicant
+ * to reallocate the memory for struct wpa_ssid again even if it
+ * is the same SSID. This causes memory usage of wpa_supplicnat
+ * to go high. The idea here is that if the previously connected
+ * network is not removed at the time of next connection attempt
+ * check if the network path is not NULL. In case it is non-NULL
+ * first remove the network and then once removal is successful, add
+ * the network.
+ */
+
+ if (interface->network_path != NULL) {
+ g_free(data->path);
+ dbus_free(data);
+
+ intf_data = dbus_malloc0(sizeof(*intf_data));
+ if (!intf_data)
+ return -ENOMEM;
+
+ intf_data->interface = interface;
+ intf_data->path = g_strdup(interface->path);
+ intf_data->callback = callback;
+ intf_data->ssid = ssid;
+ intf_data->user_data = user_data;
+ intf_data->network_remove_in_progress = TRUE;
+ network_remove(intf_data);
+ } else {
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, data,
+ interface);
+ }
+ }
if (ret < 0) {
g_free(data->path);
@@ -4705,6 +4741,7 @@ static void network_remove_result(const char *error,
DBusMessageIter *iter, void *user_data)
{
struct interface_data *data = user_data;
+ struct interface_connect_data * connect_data;
int result = 0;
SUPPLICANT_DBG("");
@@ -4716,11 +4753,31 @@ static void network_remove_result(const char *error,
result = -ECONNABORTED;
}
- g_free(data->path);
+ g_free(data->interface->network_path);
+ data->interface->network_path = NULL;
- if (data->callback)
- data->callback(result, data->interface, data->user_data);
+ if (data->network_remove_in_progress == TRUE) {
+ data->network_remove_in_progress = FALSE;
+ connect_data = dbus_malloc0(sizeof(*connect_data));
+ if (!connect_data)
+ return;
+
+ connect_data->interface = data->interface;
+ connect_data->path = g_strdup(data->path);
+ connect_data->callback = data->callback;
+ connect_data->ssid = data->ssid;
+ connect_data->user_data = data->user_data;
+ supplicant_dbus_method_call(data->interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, connect_data,
+ connect_data->interface);
+ } else {
+ if (data->callback)
+ data->callback(result, data->interface, data->user_data);
+ }
+ g_free(data->path);
dbus_free(data);
}
--
2.7.0.rc3.207.g0ac5344
4 years, 11 months