static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data) { struct connman_provider *provider = user_data; DBG("status %d", status); if (status == G_RESOLV_RESULT_STATUS_SUCCESS && results != NULL && g_strv_length(results) > 0) provider->host_ip = g_strdupv(results); connman_provider_unref(provider); }
void vpn_died(struct connman_task *task, int exit_code, void *user_data) { struct connman_provider *provider = user_data; struct vpn_data *data = connman_provider_get_data(provider); int state = VPN_STATE_FAILURE; enum connman_provider_error ret; DBG("provider %p data %p", provider, data); if (data == NULL) goto vpn_exit; state = data->state; stop_vpn(provider); connman_provider_set_data(provider, NULL); connman_rtnl_remove_watch(data->watch); vpn_exit: if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) { const char *name; struct vpn_driver_data *vpn_data = NULL; name = connman_provider_get_driver_name(provider); if (name != NULL) vpn_data = g_hash_table_lookup(driver_hash, name); if (vpn_data != NULL && vpn_data->vpn_driver->error_code != NULL) ret = vpn_data->vpn_driver->error_code(exit_code); else ret = CONNMAN_PROVIDER_ERROR_UNKNOWN; connman_provider_indicate_error(provider, ret); } else connman_provider_set_state(provider, CONNMAN_PROVIDER_STATE_IDLE); connman_provider_set_index(provider, -1); connman_provider_unref(data->provider); g_free(data->if_name); g_free(data); connman_task_destroy(task); }
static int vpn_connect(struct connman_provider *provider) { struct vpn_data *data = connman_provider_get_data(provider); struct vpn_driver_data *vpn_driver_data; const char *name; int ret = 0; if (data != NULL) return -EISCONN; data = g_try_new0(struct vpn_data, 1); if (data == NULL) return -ENOMEM; data->provider = connman_provider_ref(provider); data->watch = 0; data->flags = 0; data->task = NULL; data->state = VPN_STATE_IDLE; connman_provider_set_data(provider, data); name = connman_provider_get_driver_name(provider); if (name == NULL) return -EINVAL; vpn_driver_data = g_hash_table_lookup(driver_hash, name); if (vpn_driver_data != NULL && vpn_driver_data->vpn_driver != NULL && vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) { ret = vpn_create_tun(provider); if (ret < 0) goto exist_err; } data->task = connman_task_create(vpn_driver_data->program); if (data->task == NULL) { ret = -ENOMEM; stop_vpn(provider); goto exist_err; } if (connman_task_set_notify(data->task, "notify", vpn_notify, provider)) { ret = -ENOMEM; stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } ret = vpn_driver_data->vpn_driver->connect(provider, data->task, data->if_name); if (ret < 0) { stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } DBG("%s started with dev %s", vpn_driver_data->provider_driver.name, data->if_name); data->state = VPN_STATE_CONNECT; return -EINPROGRESS; exist_err: connman_provider_set_index(provider, -1); connman_provider_set_data(provider, NULL); connman_provider_unref(data->provider); g_free(data->if_name); g_free(data); return ret; }