Skip to content

Commit

Permalink
Merge branch 'jb47868' into 'master'
Browse files Browse the repository at this point in the history
[vpn] Track connection requests and always reply to one. Fixes JB#47868

See merge request mer-core/connman!238
  • Loading branch information
LaakkonenJussi committed Nov 11, 2019
2 parents 1443f82 + 8601958 commit 07bbb30
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 91 deletions.
42 changes: 38 additions & 4 deletions connman/plugins/vpn.c
Expand Up @@ -500,9 +500,18 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
if (!dbus_pending_call_get_completed(call))
return;

if (call != data->call) {
connman_error("invalid call %p to VPN connect_reply data %p "
" call %p ", call, data, data->call);
dbus_pending_call_unref(call);
return;
}

DBG("user_data %p path %s", user_data, cb_data ? cb_data->path : NULL);

reply = dbus_pending_call_steal_reply(call);
if (!reply)
goto out;

dbus_error_init(&error);

Expand Down Expand Up @@ -545,7 +554,11 @@ static void connect_reply(DBusPendingCall *call, void *user_data)

dbus_message_unref(reply);

dbus_pending_call_unref(call);
out:
dbus_pending_call_unref(data->call);

data->call = NULL;
data->connect_pending = false;
}

static int connect_provider(struct connection_data *data, void *user_data,
Expand All @@ -564,7 +577,10 @@ static int connect_provider(struct connection_data *data, void *user_data,
return -EINVAL;
}

data->connect_pending = false;
if (data->connect_pending && data->call) {
DBG("connect already pending");
return -EALREADY;
}

/* We need to pass original dbus sender to connman-vpnd,
* use a Connect2 method for that if the original dbus sender is set.
Expand Down Expand Up @@ -599,6 +615,14 @@ static int connect_provider(struct connection_data *data, void *user_data,
return -EINVAL;
}

if (data->call) {
dbus_pending_call_cancel(data->call);
dbus_pending_call_unref(data->call);
}

data->call = call;
data->connect_pending = true;

if (cb_data) {
g_free(cb_data->path);
cb_data->path = g_strdup(data->path);
Expand Down Expand Up @@ -1009,6 +1033,8 @@ static int disconnect_provider(struct connection_data *data)

static int provider_disconnect(struct connman_provider *provider)
{
int err = 0;

struct connection_data *data;

DBG("provider %p", provider);
Expand All @@ -1018,9 +1044,17 @@ static int provider_disconnect(struct connman_provider *provider)
return -EINVAL;

if (provider_is_connected(data))
return disconnect_provider(data);
err = disconnect_provider(data);

return 0;
if (data->call) {
dbus_pending_call_cancel(data->call);
dbus_pending_call_unref(data->call);
data->call = NULL;
}

data->connect_pending = false;

return err;
}

static void configuration_create_reply(DBusPendingCall *call, void *user_data)
Expand Down
17 changes: 12 additions & 5 deletions connman/src/provider.c
Expand Up @@ -186,17 +186,24 @@ int __connman_provider_connect(struct connman_provider *provider,
else
return -EOPNOTSUPP;

if (err < 0) {
if (err != -EINPROGRESS)
return err;
switch (err) {
case 0:
return 0;

case -EINPROGRESS:
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_ASSOCIATION);

/* fall through */
/*
* Return EINPROGRESS also for when there is an existing pending call.
* The state should not be indicated again but the real state is
* still in progress for the provider.
*/
case -EALREADY:
return -EINPROGRESS;
}

return 0;
return err;
}

int __connman_provider_remove_by_path(const char *path)
Expand Down
34 changes: 24 additions & 10 deletions connman/src/service.c
Expand Up @@ -4410,6 +4410,9 @@ static void disable_autoconnect_for_services(struct connman_service *exclude,
}
}

static void set_error(struct connman_service *service,
enum connman_service_error error);

static DBusMessage *set_property(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
Expand Down Expand Up @@ -4444,6 +4447,27 @@ static DBusMessage *set_property(DBusConnection *conn,

dbus_message_iter_get_basic(&value, &autoconnect);

if (autoconnect && service->type == CONNMAN_SERVICE_TYPE_VPN) {
/*
* Changing the autoconnect flag on VPN to "on" should
* have the same effect as user connecting the VPN =
* clear previous error and change state to idle.
*/
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);

if (service->state == CONNMAN_SERVICE_STATE_FAILURE) {
service->state = CONNMAN_SERVICE_STATE_IDLE;
state_changed(service);
}

/* Disable autoconnect for all other VPN providers
* if autoconnect is set true. Only one VPN can have
* autoconnect enabled.
*/
disable_autoconnect_for_services(service,
service->type);
}

if (connman_service_set_autoconnect(service, autoconnect)) {
/* AutoConnect explicitly set, ensure service is
* saved by clearing the new-service flag.
Expand All @@ -4455,16 +4479,6 @@ static DBusMessage *set_property(DBusConnection *conn,
do_auto_connect(service,
CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}

/* Disable autoconnect for all other VPN providers
* if autoconnect is set true. Only one VPN can have
* autoconnect enabled.
*/
if (autoconnect && service->type == CONNMAN_SERVICE_TYPE_VPN) {
disable_autoconnect_for_services(service,
service->type);
}

} else if (g_str_equal(name, "Nameservers.Configuration")) {
DBusMessageIter entry;
GString *str;
Expand Down

0 comments on commit 07bbb30

Please sign in to comment.