Пример #1
0
void vpn_died(struct connman_task *task, int exit_code, void *user_data)
{
	struct vpn_provider *provider = user_data;
	struct vpn_data *data = vpn_provider_get_data(provider);
	int state = VPN_STATE_FAILURE;
	enum vpn_provider_error ret;

	DBG("provider %p data %p", provider, data);

	if (!data)
		goto vpn_exit;

	state = data->state;

	stop_vpn(provider);
	vpn_provider_set_data(provider, NULL);

	if (data->watch != 0) {
		vpn_rtnl_remove_watch(data->watch);
		data->watch = 0;
		vpn_provider_unref(provider);
	}

vpn_exit:
	if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
		const char *name;
		struct vpn_driver_data *vpn_data = NULL;

		name = vpn_provider_get_driver_name(provider);
		if (name)
			vpn_data = g_hash_table_lookup(driver_hash, name);

		if (vpn_data &&
				vpn_data->vpn_driver->error_code)
			ret = vpn_data->vpn_driver->error_code(provider,
					exit_code);
		else
			ret = VPN_PROVIDER_ERROR_UNKNOWN;

		vpn_provider_indicate_error(provider, ret);
	} else
		vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);

	vpn_provider_set_index(provider, -1);

	if (data) {
		vpn_provider_unref(data->provider);
		g_free(data->if_name);
		g_free(data);
	}

	connman_task_destroy(task);
}
Пример #2
0
static int vpn_disconnect(struct vpn_provider *provider)
{
	struct vpn_data *data = vpn_provider_get_data(provider);
	struct vpn_driver_data *vpn_driver_data;
	const char *name;

	DBG("disconnect provider %p:", provider);

	if (!data)
		return 0;

	name = vpn_provider_get_driver_name(provider);
	if (!name)
		return 0;

	vpn_driver_data = g_hash_table_lookup(driver_hash, name);
	if (vpn_driver_data->vpn_driver->disconnect)
		vpn_driver_data->vpn_driver->disconnect(provider);

	if (data->watch != 0) {
		vpn_provider_unref(provider);
		vpn_rtnl_remove_watch(data->watch);
		data->watch = 0;
	}

	data->state = VPN_STATE_DISCONNECT;
	connman_task_stop(data->task);

	return 0;
}
Пример #3
0
static void resolv_result(GResolvResultStatus status,
					char **results, gpointer user_data)
{
	struct vpn_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);

	vpn_provider_unref(provider);
}
Пример #4
0
static int vpn_remove(struct vpn_provider *provider)
{
	struct vpn_data *data;

	data = vpn_provider_get_data(provider);
	if (!data)
		return 0;

	if (data->watch != 0) {
		vpn_provider_unref(provider);
		vpn_rtnl_remove_watch(data->watch);
		data->watch = 0;
	}

	connman_task_stop(data->task);

	g_usleep(G_USEC_PER_SEC);
	stop_vpn(provider);
	return 0;
}
Пример #5
0
static int vpn_connect(struct vpn_provider *provider,
			vpn_provider_connect_cb_t cb,
			const char *dbus_sender, void *user_data)
{
	struct vpn_data *data = vpn_provider_get_data(provider);
	struct vpn_driver_data *vpn_driver_data;
	const char *name;
	int ret = 0;
	enum vpn_state state = VPN_STATE_UNKNOWN;

	if (data)
		state = data->state;

	DBG("data %p state %d", data, state);

	switch (state) {
	case VPN_STATE_UNKNOWN:
		data = g_try_new0(struct vpn_data, 1);
		if (!data)
			return -ENOMEM;

		data->provider = vpn_provider_ref(provider);
		data->watch = 0;
		data->flags = 0;
		data->task = NULL;

		vpn_provider_set_data(provider, data);
		/* fall through */

	case VPN_STATE_DISCONNECT:
	case VPN_STATE_IDLE:
	case VPN_STATE_FAILURE:
	case VPN_STATE_AUTH_FAILURE:
		data->state = VPN_STATE_IDLE;
		break;

	case VPN_STATE_CONNECT:
		return -EINPROGRESS;

	case VPN_STATE_READY:
		return -EISCONN;
	}

	name = vpn_provider_get_driver_name(provider);
	if (!name)
		return -EINVAL;

	vpn_driver_data = g_hash_table_lookup(driver_hash, name);

	if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
		ret = -EINVAL;
		goto exist_err;
	}

	if (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) {
		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, cb, dbus_sender,
						user_data);
	if (ret < 0 && ret != -EINPROGRESS) {
		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:
	vpn_provider_set_index(provider, -1);
	vpn_provider_set_data(provider, NULL);
	vpn_provider_unref(data->provider);
	g_free(data->if_name);
	g_free(data);

	return ret;
}