[PATCH 4/4] wps: add new WPS API for technology
by Natsuki.Itaya@sony.com
This implementation is follow the the original patch.
https://lists.01.org/pipermail/connman/2018-January/022367.html
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
include/technology.h | 20 +++-
src/technology.c | 233 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 252 insertions(+), 1 deletion(-)
diff --git a/include/technology.h b/include/technology.h
index 97db6607..febf6685 100644
--- a/include/technology.h
+++ b/include/technology.h
@@ -34,10 +34,19 @@ extern "C" {
* @short_description: Functions for handling technology details
*/
+enum connman_technology_wps_mode {
+ CONNMAN_TECHNOLOGY_WPS_STA_MODE = 0,
+ CONNMAN_TECHNOLOGY_WPS_AP_MODE = 1,
+};
+
struct connman_technology;
int connman_technology_tethering_notify(struct connman_technology *technology,
- bool enabled);
+ bool enabled);
+
+void connman_technology_wps_state_change_notify
+(struct connman_technology *technology, const char *state);
+
int connman_technology_set_regdom(const char *alpha2);
void connman_technology_regdom_notify(struct connman_technology *technology,
const char *alpha2);
@@ -46,6 +55,11 @@ bool connman_technology_get_wifi_tethering(const char **ssid,
const char **psk);
bool connman_technology_is_tethering_allowed(enum connman_service_type type);
+void connman_technology_add_wps_offered(struct connman_technology *technology,
+ const char *path);
+void connman_technology_reply_start_sta_wps
+(struct connman_technology *technology, int error);
+
struct connman_technology_driver {
const char *name;
enum connman_service_type type;
@@ -62,6 +76,10 @@ struct connman_technology_driver {
const char *bridge, bool enabled);
int (*set_regdom) (struct connman_technology *technology,
const char *alpha2);
+ int (*start_wps)(struct connman_technology *technology,
+ enum connman_technology_wps_mode mode,
+ const char *wps_pin);
+ int (*cancel_wps)(struct connman_technology *technology);
};
int connman_technology_driver_register(struct connman_technology_driver *driver);
diff --git a/src/technology.c b/src/technology.c
index 4c1cbbbb..906a6ec3 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -74,6 +74,14 @@ struct connman_technology {
DBusMessage *pending_reply;
guint pending_timeout;
+ /*
+ * Used to handle WPS errors within the two-minute interval.
+ * It is done only for WPS in STA mode, because for AP the
+ * wpa_supplicant does not report any events/errors.
+ */
+ DBusMessage *wps_reply;
+ GSList *wps_offered;
+
GSList *scan_pending;
bool rfkill_driven;
@@ -277,6 +285,15 @@ static int set_tethering(struct connman_technology *technology,
return result;
}
+void connman_technology_wps_state_change_notify(
+ struct connman_technology *technology,
+ const char *state)
+{
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "WpsState",
+ DBUS_TYPE_STRING, &state);
+}
+
void connman_technology_regdom_notify(struct connman_technology *technology,
const char *alpha2)
{
@@ -576,6 +593,214 @@ static void technology_removed_signal(struct connman_technology *technology)
DBUS_TYPE_INVALID);
}
+void connman_technology_add_wps_offered(struct connman_technology *technology,
+ const char *path)
+{
+ char *dup_path = g_strdup(path);
+
+ if (!dup_path)
+ return;
+ technology->wps_offered =
+ g_slist_append(technology->wps_offered, dup_path);
+}
+
+static void append_wps_service_structs(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ GSList *list;
+
+ for (list = technology->wps_offered; list; list = list->next) {
+ const char *ident = list->data;
+ struct connman_service *service;
+
+ service = __connman_service_lookup_from_ident(ident);
+ if (!service)
+ continue;
+ __connman_service_append_struct(service, iter);
+ }
+}
+
+static DBusMessage
+*create_reply_start_sta_wps_success(
+ struct connman_technology *technology,
+ DBusMessage *reply)
+{
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_return(reply);
+ if (!msg)
+ return NULL;
+
+ __connman_dbus_append_objpath_dict_array(msg,
+ append_wps_service_structs,
+ technology);
+
+ return msg;
+}
+
+static void free_wps_offered(gpointer data, gpointer user_data)
+{
+ if (!data)
+ return;
+
+ g_free(data);
+}
+
+void
+connman_technology_reply_start_sta_wps(struct connman_technology *technology,
+ int error)
+{
+ DBusMessage *reply;
+
+ if (!technology->wps_reply)
+ return;
+
+ if (error < 0)
+ reply = __connman_error_failed(technology->wps_reply, -error);
+ else {
+ reply = create_reply_start_sta_wps_success(technology,
+ technology->wps_reply);
+ }
+
+ g_dbus_send_message(connection, reply);
+
+ dbus_message_unref(technology->wps_reply);
+ technology->wps_reply = NULL;
+
+ g_slist_foreach(technology->wps_offered, free_wps_offered, NULL);
+ g_slist_free(technology->wps_offered);
+ technology->wps_offered = NULL;
+}
+
+static int start_wps(struct connman_technology *technology,
+ DBusMessage *msg, enum connman_technology_wps_mode mode)
+{
+ GSList *tech_drivers;
+ DBusMessageIter iter;
+ enum connman_peer_wps_method wps_method;
+ const char *auth;
+ int err, result = -EOPNOTSUPP;
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return -EOPNOTSUPP;
+
+ __sync_synchronize();
+ if (!technology->enabled)
+ return -EACCES;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return -EINVAL;
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &auth);
+
+ wps_method = __connman_check_wps_method(auth);
+ if (wps_method == CONNMAN_PEER_WPS_UNKNOWN)
+ return -EINVAL;
+ if (wps_method == CONNMAN_PEER_WPS_PBC)
+ auth = NULL;
+
+ for (tech_drivers = technology->driver_list; tech_drivers;
+ tech_drivers = g_slist_next(tech_drivers)) {
+ struct connman_technology_driver *driver = tech_drivers->data;
+
+ if (!driver ||
+ !driver->start_wps ||
+ driver->type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+
+ err = driver->start_wps(technology, mode, auth);
+
+ if (result == -EINPROGRESS)
+ continue;
+
+ if (err == -EINPROGRESS)
+ result = err;
+ }
+
+ return result;
+}
+
+static DBusMessage *start_ap_wps(DBusConnection *conn, DBusMessage *msg,
+ void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ int err;
+
+ /* It is required to enable tethering before starting WPS in AP mode */
+ if (!technology->tethering) {
+ DBG("Error: Tethering is required");
+ return __connman_error_permission_denied(msg);
+ }
+
+ err = start_wps(technology, msg, CONNMAN_TECHNOLOGY_WPS_AP_MODE);
+ if (err == -EINPROGRESS)
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+ return __connman_error_failed(msg, -err);
+}
+
+static DBusMessage *start_sta_wps(DBusConnection *conn, DBusMessage *msg,
+ void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ int err;
+
+ if (technology->wps_reply)
+ connman_technology_reply_start_sta_wps(technology,
+ -ECONNABORTED);
+
+ err = start_wps(technology, msg, CONNMAN_TECHNOLOGY_WPS_STA_MODE);
+ if (err == -EINPROGRESS) {
+ technology->wps_reply = dbus_message_ref(msg);
+ return NULL;
+ }
+
+ return __connman_error_failed(msg, -err);
+}
+
+static DBusMessage *cancel_wps(DBusConnection *conn, DBusMessage *msg,
+ void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ GSList *tech_drivers;
+ int err = 0, result = -EOPNOTSUPP;
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ __sync_synchronize();
+ if (!technology->enabled)
+ return __connman_error_permission_denied(msg);
+
+ if (technology->wps_reply)
+ connman_technology_reply_start_sta_wps(technology,
+ -ECONNABORTED);
+
+ for (tech_drivers = technology->driver_list; tech_drivers;
+ tech_drivers = g_slist_next(tech_drivers)) {
+ struct connman_technology_driver *driver = tech_drivers->data;
+
+ if (!driver || !driver->cancel_wps ||
+ driver->type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+
+ err = driver->cancel_wps(technology);
+ if (result == -EINPROGRESS)
+ continue;
+
+ if (err == -EINPROGRESS)
+ result = err;
+ }
+
+ if (result == -EINPROGRESS)
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+ return __connman_error_failed(msg, -result);
+}
+
static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *message, void *user_data)
{
@@ -1098,6 +1323,14 @@ static const GDBusMethodTable technology_methods[] = {
GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
NULL, set_property) },
{ GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+ { GDBUS_ASYNC_METHOD("Start_AP_WPS",
+ GDBUS_ARGS({ "authentication", "s" }),
+ NULL, start_ap_wps) },
+ { GDBUS_ASYNC_METHOD("Start_STA_WPS",
+ GDBUS_ARGS({ "authentication", "s" }),
+ NULL, start_sta_wps) },
+ { GDBUS_ASYNC_METHOD("Cancel_WPS",
+ NULL, NULL, cancel_wps) },
{ },
};
--
2.17.1
3 years, 8 months
[PATCH] iwd: Remove device state property
by Daniel Wagner
iwd has moved parts of the Device API into the Station API. Among
those properties is the state of device. So far we haven't used this
property at all, therefore we can just remove it.
---
plugins/iwd.c | 52 +---------------------------------------------------
1 file changed, 1 insertion(+), 51 deletions(-)
diff --git a/plugins/iwd.c b/plugins/iwd.c
index 6a017b2e90d0..ddc9201d03bc 100644
--- a/plugins/iwd.c
+++ b/plugins/iwd.c
@@ -55,14 +55,6 @@ static bool agent_registered;
#define IWD_AGENT_ERROR_INTERFACE "net.connman.iwd.Agent.Error"
#define AGENT_PATH "/net/connman/iwd_agent"
-enum iwd_device_state {
- IWD_DEVICE_STATE_UNKNOWN,
- IWD_DEVICE_STATE_CONNECTED,
- IWD_DEVICE_STATE_DISCONNECTED,
- IWD_DEVICE_STATE_CONNECTING,
- IWD_DEVICE_STATE_DISCONNECTING,
-};
-
struct iwd_adapter {
GDBusProxy *proxy;
char *path;
@@ -77,7 +69,6 @@ struct iwd_device {
char *adapter;
char *name;
char *address;
- enum iwd_device_state state;
bool powered;
bool scanning;
@@ -96,38 +87,6 @@ struct iwd_network {
struct connman_network *network;
};
-static enum iwd_device_state string2state(const char *str)
-{
- if (!strcmp(str, "connected"))
- return IWD_DEVICE_STATE_CONNECTED;
- else if (!strcmp(str, "disconnected"))
- return IWD_DEVICE_STATE_DISCONNECTED;
- else if (!strcmp(str, "connecting"))
- return IWD_DEVICE_STATE_CONNECTING;
- else if (!strcmp(str, "disconnecting"))
- return IWD_DEVICE_STATE_DISCONNECTING;
-
- return IWD_DEVICE_STATE_UNKNOWN;
-}
-
-static const char *state2string(enum iwd_device_state state)
-{
- switch (state) {
- case IWD_DEVICE_STATE_CONNECTED:
- return "connected";
- case IWD_DEVICE_STATE_DISCONNECTED:
- return "disconnected";
- case IWD_DEVICE_STATE_CONNECTING:
- return "connecting";
- case IWD_DEVICE_STATE_DISCONNECTING:
- return "disconnecting";
- default:
- break;
- }
-
- return "unknown";
-}
-
static const char *proxy_get_string(GDBusProxy *proxy, const char *property)
{
DBusMessageIter iter;
@@ -664,13 +623,6 @@ static void device_property_change(GDBusProxy *proxy, const char *name,
iwdd->name = g_strdup(name);
DBG("%p name %s", path, iwdd->name);
- } else if (!strcmp(name, "State")) {
- const char *state;
-
- dbus_message_iter_get_basic(iter, &state);
- iwdd->state = string2state(state);
-
- DBG("%s state %s", path, state2string(iwdd->state));
} else if (!strcmp(name, "Powered")) {
dbus_bool_t powered;
@@ -829,13 +781,11 @@ static void create_device(GDBusProxy *proxy)
iwdd->adapter = g_strdup(proxy_get_string(proxy, "Adapter"));
iwdd->name = g_strdup(proxy_get_string(proxy, "Name"));
iwdd->address = g_strdup(proxy_get_string(proxy, "Address"));
- iwdd->state = string2state(proxy_get_string(proxy, "State"));
iwdd->powered = proxy_get_bool(proxy, "Powered");
iwdd->scanning = proxy_get_bool(proxy, "Scanning");
- DBG("adapter %s name %s address %s state %s powered %d scanning %d",
+ DBG("adapter %s name %s address %s powered %d scanning %d",
iwdd->adapter, iwdd->name, iwdd->address,
- state2string(iwdd->state),
iwdd->powered, iwdd->scanning);
g_dbus_proxy_set_property_watch(iwdd->proxy,
--
2.14.4
3 years, 8 months
Wrong state of a service if only IPv6 is enabled
by Marek Szanyi
Hi,
I have a device running connman v 1.35. For the Ethernet service if IPv4 is enabled or both IPv4 and IPv6 is enabled the state of the Ethernet service is reported correctly. Because the device have internet access the state is "online". However if I disable IPv4 and leave only IPv6 enabled the state of the service reported by connman is "idle", which is wrong, because I still have internet access (verified by using curl). Is this an expected behavior or is this a bug in connman?
Kind Regards,
Marek Szanyi
SW Developer
Kistler Bratislava, s.r.o.
Ševčenkova 34, 851 01 Bratislava, Slovakia
Direct+421232272624, Main Office+421 2 32 272 900
marek.szanyi(a)kistler.com, www.kistler.com
3 years, 9 months
[PATCH] vpn: Save provider configuration when properties are changed
by Jussi Laakkonen
This commit adds saving of provider configuration when a property
is added, changed or cleared via net.connman.vpn D-Bus interface
net.connman.vpn.Connection using SetProperty or ClearProperty
methods.
---
vpn/vpn-provider.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index dd54ac08..adc41754 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -91,6 +91,7 @@ struct vpn_provider {
static void append_properties(DBusMessageIter *iter,
struct vpn_provider *provider);
+static int vpn_provider_save(struct vpn_provider *provider);
static void free_route(gpointer data)
{
@@ -456,6 +457,8 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
vpn_provider_set_string(provider, name, str);
}
+ vpn_provider_save(provider);
+
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -484,6 +487,8 @@ static DBusMessage *clear_property(DBusConnection *conn, DBusMessage *msg,
return __connman_error_invalid_property(msg);
}
+ vpn_provider_save(provider);
+
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
--
2.11.0
3 years, 9 months
[PATCH 1/3] vpn: Use Connect2 method only when D-Bus sender is set
by Jussi Laakkonen
This fix addresses the issue of not being able to connect a VPN if it
has autoconnect set and connection is triggered by connmand. In such
case dbus_sender is not set and call to Connect2 method of
net.connman.vpn.Connection cannot be done.
Also, print correct D-Bus method called in case of error. If the
dbus_sender is not set or is empty Connect() will be used instead of
Connect2().
This amends changes of commit 3997c1595fe44d7c85215fd1cd89ecf778c62206.
---
plugins/vpn.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/plugins/vpn.c b/plugins/vpn.c
index 3d067a49..2064bfc0 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -546,15 +546,18 @@ static int connect_provider(struct connection_data *data, void *user_data,
#define VPN_CONNECT2 "Connect2"
/* We need to pass original dbus sender to connman-vpnd,
- * use a Connect2 method for that.
+ * use a Connect2 method for that if the original dbus sender is set.
+ * Connect method requires no parameter, Connect2 requires dbus sender
+ * name to be set.
*/
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
VPN_CONNECTION_INTERFACE,
- VPN_CONNECT2);
+ dbus_sender && *dbus_sender ?
+ VPN_CONNECT2 : VPN_CONNECT);
if (!message)
return -ENOMEM;
- if (dbus_sender)
+ if (dbus_sender && *dbus_sender)
dbus_message_append_args(message, DBUS_TYPE_STRING,
&dbus_sender, NULL);
else
@@ -563,7 +566,8 @@ static int connect_provider(struct connection_data *data, void *user_data,
if (!dbus_connection_send_with_reply(connection, message,
&call, DBUS_TIMEOUT)) {
connman_error("Unable to call %s.%s()",
- VPN_CONNECTION_INTERFACE, VPN_CONNECT2);
+ VPN_CONNECTION_INTERFACE, dbus_sender && *dbus_sender ?
+ VPN_CONNECT2 : VPN_CONNECT);
dbus_message_unref(message);
return -EINVAL;
}
--
2.11.0
3 years, 9 months
[PATCH] vpn: Use Connect2 method only when D-Bus sender is set
by Jussi Laakkonen
This fix addresses the issue of not being able to connect a VPN if it
has autoconnect set and connection is triggered by connmand. In such
case dbus_sender is not set and call to Connect2 method of
net.connman.vpn.Connection cannot be done.
This amends changes of commit 3997c1595fe44d7c85215fd1cd89ecf778c62206.
---
plugins/vpn.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/plugins/vpn.c b/plugins/vpn.c
index 3d067a49..5282cb0f 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -546,15 +546,18 @@ static int connect_provider(struct connection_data *data, void *user_data,
#define VPN_CONNECT2 "Connect2"
/* We need to pass original dbus sender to connman-vpnd,
- * use a Connect2 method for that.
+ * use a Connect2 method for that if the original dbus sender is set.
+ * Connect method requires no parameter, Connect2 requires dbus sender
+ * name to be set.
*/
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
VPN_CONNECTION_INTERFACE,
- VPN_CONNECT2);
+ dbus_sender && *dbus_sender ?
+ VPN_CONNECT2 : VPN_CONNECT);
if (!message)
return -ENOMEM;
- if (dbus_sender)
+ if (dbus_sender && *dbus_sender)
dbus_message_append_args(message, DBUS_TYPE_STRING,
&dbus_sender, NULL);
else
--
2.11.0
3 years, 9 months
[PATCH] vpn: Add remove function callback to VPN driver
by Jussi Laakkonen
This commit adds remove function callback to the VPN driver structure.
The prototype is int (remove*) (struct vpn_provider *provider) and is to
be registered within the VPN plugin.
This function is called from vpn/plugins/vpn.c when removing a provider
after it has been stopped. It is meant for VPNs that need to cleanup
some VPN specific content when removed or to notify other services after
removal.
---
vpn/plugins/vpn.c | 22 ++++++++++++++++++++--
vpn/plugins/vpn.h | 1 +
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 6ce8f45d..dd686492 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -562,10 +562,15 @@ static int vpn_disconnect(struct vpn_provider *provider)
static int vpn_remove(struct vpn_provider *provider)
{
struct vpn_data *data;
+ struct vpn_driver_data *driver_data;
+ const char *name;
+ int err = 0;
data = vpn_provider_get_data(provider);
+ name = vpn_provider_get_driver_name(provider);
+
if (!data)
- return 0;
+ goto call_remove;
if (data->watch != 0) {
vpn_provider_unref(provider);
@@ -577,7 +582,20 @@ static int vpn_remove(struct vpn_provider *provider)
g_usleep(G_USEC_PER_SEC);
stop_vpn(provider);
- return 0;
+
+call_remove:
+ if (!name)
+ return 0;
+
+ driver_data = g_hash_table_lookup(driver_hash, name);
+
+ if (driver_data && driver_data->vpn_driver->remove)
+ err = driver_data->vpn_driver->remove(provider);
+
+ if (err)
+ DBG("%p vpn_driver->remove() returned %d", provider, err);
+
+ return err;
}
static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h
index 863576db..265fd82f 100644
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -48,6 +48,7 @@ struct vpn_driver {
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data);
void (*disconnect) (struct vpn_provider *provider);
+ int (*remove) (struct vpn_provider *provider);
int (*error_code) (struct vpn_provider *provider, int exit_code);
int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
int (*device_flags) (struct vpn_provider *provider);
--
2.11.0
3 years, 9 months
[PATCH 0/4] VPN tweaks
by Slava Monich
These are basically follow-ups to the recent VPN auto-disconnect
changes, on top of the memory leak fix that was sent separately.
Slava Monich (4):
vpn: More informative debug trace
vpn: Do not call Disconnect too many times
vpn: Refuse to connect if there's no default service
service: service_indicate_state() doesn't need to disconnect VPN
plugins/vpn.c | 113 ++++++++++++++++++++++++++++++++++------------------------
src/service.c | 7 ----
2 files changed, 67 insertions(+), 53 deletions(-)
--
1.9.1
3 years, 9 months
[PATCH] vpn: Fix memory leak
by Slava Monich
==8003== 14 bytes in 1 blocks are definitely lost in loss record 844 of 3,229
==8003== at 0x483F3EC: malloc (vg_replace_malloc.c)
==8003== by 0x4CD30DF: g_malloc (gmem.c)
==8003== by 0x4CEA185: g_strdup (gstrfuncs.c)
==8003== by 0x4CEB78B: g_strdupv (gstrfuncs.c)
==8003== by 0x4949B: resolv_result (vpn.c)
==8003== by 0x2ACC3: sort_and_return_results (gresolv.c)
==8003== by 0x2B667: parse_response (gresolv.c)
==8003== by 0x2B773: received_udp_data (gresolv.c)
==8003== by 0x4CCE06F: g_main_dispatch (gmain.c)
==8003== by 0x4CCE06F: g_main_context_dispatch (gmain.c)
==8003== by 0x4CCE58F: g_main_loop_run (gmain.c)
==8003== by 0x5430B: main (main.c)
---
plugins/vpn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/vpn.c b/plugins/vpn.c
index 0ff5b37..e55c4b8 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1535,7 +1535,7 @@ static void connection_destroy(gpointer hash_data)
g_free(data->type);
g_free(data->name);
g_free(data->host);
- g_free(data->host_ip);
+ g_strfreev(data->host_ip);
g_free(data->domain);
g_hash_table_destroy(data->server_routes);
g_hash_table_destroy(data->user_routes);
--
1.9.1
3 years, 9 months
[PATCH] vpn: Reset flags before calling vpn_newlink() if VPN interface was up
by Jussi Laakkonen
This fixes the issue of VPN provider not being set ready as VPN
interface was already up when vpn_notify() was called. It is required to
reset the flags before calling vpn_newlink(), otherwise the state of the
VPN provider is not changed.
This would result in a situation where VPN provider settings were not
sent to connmand and later adding the routes of a VPN will fail as the
interface index was not updated. Also other information (interface type,
nameservers, domain) of the VPN provider is outdated. This happens when
same VPN is re-connected after transport service has been changed.
---
vpn/plugins/vpn.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index a26bcc60..6ce8f45d 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -308,19 +308,22 @@ static DBusMessage *vpn_notify(struct connman_task *task,
vpn_newlink, provider);
err = connman_inet_ifup(index);
if (err < 0) {
- if (err == -EALREADY)
+ if (err == -EALREADY) {
/*
* So the interface is up already, that is just
* great. Unfortunately in this case the
* newlink watch might not have been called at
* all. We must manually call it here so that
* the provider can go to ready state and the
- * routes are setup properly.
+ * routes are setup properly. Also reset flags
+ * so vpn_newlink() can handle the change.
*/
+ data->flags = 0;
vpn_newlink(IFF_UP, 0, provider);
- else
+ } else {
DBG("Cannot take interface %d up err %d/%s",
index, -err, strerror(-err));
+ }
}
break;
--
2.11.0
3 years, 9 months