X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Fvpn.c;h=d33d7c1feed1f63a4a1ea39f2d2052858b2019da;hb=ff0d2b9c6e427035d5fdf1d412b80892294b6ead;hp=c7f59a98845706ee302f92c5e3e3a4abe49b03f2;hpb=dd7b675f82fa3626c73088f785f948d359a0d853;p=platform%2Fupstream%2Fconnman.git diff --git a/plugins/vpn.c b/plugins/vpn.c index c7f59a9..d33d7c1 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -47,7 +47,6 @@ static DBusConnection *connection; static GHashTable *vpn_connections = NULL; -static gboolean starting_vpnd = TRUE; static guint watch; static guint added_watch; static guint removed_watch; @@ -82,6 +81,7 @@ struct connection_data { char **host_ip; char *domain; char **nameservers; + gboolean immutable; GHashTable *server_routes; GHashTable *user_routes; @@ -252,6 +252,8 @@ static void set_provider_state(struct connection_data *data) enum connman_provider_state state = CONNMAN_PROVIDER_STATE_UNKNOWN; int err = 0; + DBG("provider %p new state %s", data->provider, data->state); + if (g_str_equal(data->state, "ready") == TRUE) { state = CONNMAN_PROVIDER_STATE_READY; goto set; @@ -301,6 +303,7 @@ static int create_provider(struct connection_data *data, void *user_data) err = connman_provider_create_service(data->provider); if (err == 0) { + connman_provider_set_immutable(data->provider, data->immutable); if (g_str_equal(data->state, "ready") == TRUE) { connman_provider_set_index(data->provider, data->index); @@ -450,11 +453,22 @@ static int extract_nameservers(DBusMessageIter *array, return 0; } +static int errorstr2val(const char *error) { + if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".InProgress") == 0) + return -EINPROGRESS; + + if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".AlreadyConnected") == 0) + return -EISCONN; + + return -ECONNREFUSED; +} + static void connect_reply(DBusPendingCall *call, void *user_data) { DBusMessage *reply; DBusError error; - struct config_create_data *cb_data = user_data; + struct connection_data *data = user_data; + struct config_create_data *cb_data = data->cb_data; if (dbus_pending_call_get_completed(call) == FALSE) return; @@ -466,16 +480,17 @@ static void connect_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&error); if (dbus_set_error_from_message(&error, reply) == TRUE) { - if (dbus_error_has_name(&error, CONNMAN_ERROR_INTERFACE - ".InProgress") == FALSE) { + int err = errorstr2val(error.name); + if (err != -EINPROGRESS) { connman_error("Connect reply: %s (%s)", error.message, error.name); dbus_error_free(&error); + DBG("data %p cb_data %p", data, cb_data); if (cb_data != NULL) { - cb_data->callback(cb_data->message, - ECONNREFUSED, NULL); + cb_data->callback(cb_data->message, err, NULL); free_config_cb_data(cb_data); + data->cb_data = NULL; } goto done; } @@ -502,6 +517,8 @@ static int connect_provider(struct connection_data *data, void *user_data) DBG("data %p user %p path %s", data, cb_data, data->path); + data->connect_pending = FALSE; + message = dbus_message_new_method_call(VPN_SERVICE, data->path, VPN_CONNECTION_INTERFACE, VPN_CONNECT); @@ -526,7 +543,7 @@ static int connect_provider(struct connection_data *data, void *user_data) cb_data->path = g_strdup(data->path); } - dbus_pending_call_set_notify(call, connect_reply, cb_data, NULL); + dbus_pending_call_set_notify(call, connect_reply, data, NULL); dbus_message_unref(message); @@ -586,6 +603,8 @@ static void add_connection(const char *path, DBusMessageIter *properties, } else if (g_str_equal(key, "Type") == TRUE) { dbus_message_iter_get_basic(&value, &str); data->type = g_strdup(str); + } else if (g_str_equal(key, "Immutable") == TRUE) { + dbus_message_iter_get_basic(&value, &data->immutable); } else if (g_str_equal(key, "Host") == TRUE) { dbus_message_iter_get_basic(&value, &str); data->host = g_strdup(str); @@ -596,6 +615,10 @@ static void add_connection(const char *path, DBusMessageIter *properties, extract_nameservers(&value, data); } else if (g_str_equal(key, "Index") == TRUE) { dbus_message_iter_get_basic(&value, &data->index); + } else if (g_str_equal(key, "ServerRoutes") == TRUE) { + /* Ignored */ + } else if (g_str_equal(key, "UserRoutes") == TRUE) { + /* Ignored */ } else { if (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { @@ -620,6 +643,10 @@ static void add_connection(const char *path, DBusMessageIter *properties, resolv_host_addr(data); + if (data->nameservers != NULL) + connman_provider_set_nameservers(data->provider, + data->nameservers); + if (data->connect_pending == TRUE) connect_provider(data, data->cb_data); @@ -773,6 +800,14 @@ static int provider_remove(struct connman_provider *provider) DBG("provider %p data %p", provider, data); + if (data == NULL) { + /* + * This means the provider is already removed, + * just ignore the dbus in this case. + */ + return -EALREADY; + } + /* * When provider.c:provider_remove() calls this function, * it will remove the provider itself after the call. @@ -1232,8 +1267,8 @@ static int create_configuration(DBusMessage *msg, connection_ready_cb callback) data = g_hash_table_lookup(vpn_connections, ident); if (data != NULL) { - if (data->call != NULL) { - connman_error("Dbus call already pending"); + if (data->call != NULL || data->cb_data != NULL) { + DBG("create configuration call already pending"); err = -EINPROGRESS; goto done; } @@ -1263,6 +1298,18 @@ static int create_configuration(DBusMessage *msg, connection_ready_cb callback) dbus_message_set_sender(new_msg, me); dbus_message_set_member(new_msg, "Create"); + user_data = g_try_new0(struct config_create_data, 1); + if (user_data == NULL) { + err = -ENOMEM; + goto done; + } + + user_data->callback = callback; + user_data->message = dbus_message_ref(msg); + user_data->path = NULL; + + DBG("cb %p msg %p", user_data, msg); + result = dbus_connection_send_with_reply(connection, new_msg, &call, DBUS_TIMEOUT); if (result == FALSE || call == NULL) { @@ -1270,20 +1317,6 @@ static int create_configuration(DBusMessage *msg, connection_ready_cb callback) goto done; } - if (data->cb_data == NULL) { - user_data = g_try_new(struct config_create_data, 1); - if (user_data != NULL) { - user_data->callback = callback; - user_data->message = dbus_message_ref(msg); - user_data->path = NULL; - - DBG("cb %p msg %p", user_data, msg); - } - } else { - DBG("Configuration callback data already pending, " - "discarding new data."); - } - dbus_pending_call_set_notify(call, configuration_create_reply, user_data, NULL); data->call = call; @@ -1419,7 +1452,9 @@ static void destroy_provider(struct connection_data *data) if (data->call != NULL) dbus_pending_call_cancel(data->call); - connman_provider_put(data->provider); + connman_provider_set_data(data->provider, NULL); + + connman_provider_remove(data->provider); data->provider = NULL; } @@ -1455,22 +1490,14 @@ static void vpnd_created(DBusConnection *conn, void *user_data) { DBG("connection %p", conn); - if (starting_vpnd == TRUE) { - vpn_connections = g_hash_table_new_full(g_str_hash, - g_str_equal, - g_free, connection_destroy); - get_connections(user_data); - starting_vpnd = FALSE; - } + get_connections(user_data); } static void vpnd_removed(DBusConnection *conn, void *user_data) { DBG("connection %p", conn); - g_hash_table_destroy(vpn_connections); - vpn_connections = NULL; - starting_vpnd = TRUE; + g_hash_table_remove_all(vpn_connections); } static void remove_connection(DBusConnection *conn, const char *path) @@ -1485,6 +1512,7 @@ static gboolean connection_removed(DBusConnection *conn, DBusMessage *message, { const char *path; const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING; + struct connection_data *data; if (dbus_message_has_signature(message, signature) == FALSE) { connman_error("vpn removed signature \"%s\" does not match " @@ -1495,7 +1523,11 @@ static gboolean connection_removed(DBusConnection *conn, DBusMessage *message, dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); - remove_connection(conn, path); + + data = g_hash_table_lookup(vpn_connections, get_ident(path)); + if (data != NULL) + remove_connection(conn, path); + return TRUE; } @@ -1728,7 +1760,10 @@ static gboolean property_changed(DBusConnection *conn, set_routes(data->provider, CONNMAN_PROVIDER_ROUTE_USER); } else if (g_str_equal(key, "Nameservers") == TRUE) { - extract_nameservers(&value, data); + if (extract_nameservers(&value, data) == 0 && + data->nameservers != NULL) + connman_provider_set_nameservers(data->provider, + data->nameservers); } if (ip_set == TRUE && err == 0) { @@ -1773,8 +1808,13 @@ static int vpn_init(void) } err = connman_provider_driver_register(&provider_driver); - if (err == 0) + if (err == 0) { + vpn_connections = g_hash_table_new_full(g_str_hash, + g_str_equal, + g_free, connection_destroy); + vpnd_created(connection, &provider_driver); + } return err; @@ -1798,7 +1838,8 @@ static void vpn_exit(void) connman_provider_driver_unregister(&provider_driver); - g_hash_table_destroy(vpn_connections); + if (vpn_connections != NULL) + g_hash_table_destroy(vpn_connections); dbus_connection_unref(connection); }