From patchwork Fri Jan 24 18:59:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949839 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9265B2248B7 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=RZDkOApjd0XqDkOAO+oFSdegC/KwMbsVIy7dM0+V604V4hmsUhtpRpuM8VcXwo4pLJDcLCX0Ww3fI9ML8JlH1ElE2il+tkEN/zY8NsJsIz2AinlLHJpXPtw1fRiKH4a6uQmy7DCAvInG16Fpq8cpthfZhl0alKWeAwW/7jFpgz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=5aBTMweiEV1rJDms5JN2dwKLgjtvp2HFmrOHwhfJbrA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KVDN/69hE76EcYU9+bzjOkLIVdzlJIr6vU2IGjQ0KRYL4NXRpLzuJD2s4r0Q3/c+T2kE6m+UgUfakxcQfSaYtRdo4nX+E5ATvLBzkojSP/Tld8q/CGu08rs0tPBxaEkT7RYUlkAxcCs2gV1kLh/9IxMDAuC4Wk/K75n7gPo0jsM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=Y8mVWLpL; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="Y8mVWLpL" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=J4jbWXLZw++O2aKnqH2VhsFPT9rT1du4s9TYt7PbQjQ=; b=Y8mVWLpLCangxRtDs4GRGB03RN m30qtSp9f2YLk+aFaMsnyOfh0ztiiCqj/HDpnw1/0AvbooNqaKj6sJTbFTIf+NB11R7kP378CZZeA RY0SO1iMUYszspVtfKfYuSImVbm+5qLZBEM45yorKHe+MD7/w8SPVCr6iVJyuojegKC9dMdy5f7sc +eTc55v/IQ/WfF+eE9FKGhiVkviQhG4ktBlhzeS7GGkIkDQhR2irjhKGQV8YAqAgLNmvhizpCz4wR PhQ/1jYcPs97NfRZpNs54N5ZNogmnItjU0+cINeWzbVPzXpW4Dm1mXQHOkL6QuYxu01uBjWgKt0sp cMLZkC4g==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-23 for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 01/12] wireguard: Add saving of provider properties Date: Fri, 24 Jan 2025 20:59:05 +0200 Message-Id: <20250124185916.1546471-2-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Save all provider properties to provider configuration file. This follows the example defined in doc/vpn-config-format.txt --- vpn/plugins/wireguard.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index 03658943..735bac58 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -50,6 +50,7 @@ #include "wireguard.h" #define DNS_RERESOLVE_TIMEOUT 20 +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) struct wireguard_info { struct wg_device device; @@ -67,6 +68,21 @@ struct sockaddr_u { }; }; +struct { + const char *opt; + bool save; +} wg_options[] = { + {"WireGuard.Address", true}, + {"WireGuard.ListenPort", true}, + {"WireGuard.DNS", true}, + {"WireGuard.PrivateKey", true}, // TODO set false after agent support + {"WireGuard.PresharedKey", true}, // TODO set false after agent support + {"WireGuard.PublicKey", true}, + {"WireGuard.AllowedIPs", true}, + {"WireGuard.EndpointPort", true}, + {"WireGuard.PersistentKeepalive", true} +}; + static int parse_key(const char *str, wg_key key) { unsigned char *buf; @@ -462,10 +478,32 @@ static void wg_disconnect(struct vpn_provider *provider) g_free(info); } +static int wg_save(struct vpn_provider *provider, GKeyFile *keyfile) +{ + const char *option; + int i; + + for (i = 0; i < (int)ARRAY_SIZE(wg_options); i++) { + if (!wg_options[i].save) + continue; + + option = vpn_provider_get_string(provider, wg_options[i].opt); + if (!option) + continue; + + g_key_file_set_string(keyfile, + vpn_provider_get_save_group(provider), + wg_options[i].opt, option); + } + + return 0; +} + static struct vpn_driver vpn_driver = { .flags = VPN_FLAG_NO_TUN | VPN_FLAG_NO_DAEMON, .connect = wg_connect, .disconnect = wg_disconnect, + .save = wg_save, }; static int wg_init(void) From patchwork Fri Jan 24 18:59:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949836 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 925D82248B6 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; cv=none; b=bypkPIFLggOCguGwI2oYPYdRU2hgO2Nla3VPWvou51De3PIkn2Tme4ooZ/h+9ZuX298sdZ8gnhTh8kzl+UqU4v5ZWy3GGmjzjkXueURtPXE1RiyzAAvThv32NXwI//hY1r9cw7GhoF4OtndDb9C5PKRpHeVBruWaQ9AMbIhQhi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; c=relaxed/simple; bh=BxwNBFGTWTpNMd/CS6Jxve7b6oLs7Sa/n4bQ+8GddKw=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JGEqq0o8iIOc1QrlhpuER99GnrwRWozJAs7ralYpJb/lqrkd4xR9iVlNu7rk6tOoSwvKy1l+m57W7Z0bXpWsPrcHtbsVyDBRyM5IYCo0xr2rbDlV6S2Gb0eWcEBTbdmAtNNBSOKGe8wXcgKZCYz/35wUz52JsfdaBR5PkTzVPyI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=wSeHWuBb; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="wSeHWuBb" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=zDxwBKl6ghQ/kZ/P8Gf8eyWdWpUO4WGvNgS2Wttr5Qc=; b=wSeHWuBbnj1IB8kRjywWr3O9GA Et2O+HTbqMEciI17TDUsntcXxc05EIFofLEhJj/G7DwW2SweFAZBJfL+e20TgUkVAtmjB7l5sUpZ7 fNEJixuYqcrjcwAaBJn5xoJfG2lFTSLpByPcN7F8z7m2KSj8+hEMLbS9r1Opj7U5cdkZN+dYH3wRh 7q2VWBiw9DVblAPeZFkNknnU1ihPH8q+qBoVWI98LRhiY8IGllC43/MOZH8SgPvkaa8d7CQMARlB/ ZFdKpRMjdjjAJ4ty7db/Oizbz+P5Oxx2ivZLiqk4BIZgg22z2wAV4Lc6jfWCMPFk2aADoXrp2Sore 21bJCoqg==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2C for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 02/12] wireguard: Use positive errors for VPN provider connect_cb Date: Fri, 24 Jan 2025 20:59:06 +0200 Message-Id: <20250124185916.1546471-3-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false The vpn-provider.c:connect_cb() expects the errors to be positive ints. Remove the sign when calling the cb. And add debug to see what is really causing the error. For example, when parsing fails. --- vpn/plugins/wireguard.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index 735bac58..de57b15f 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -349,8 +349,10 @@ static int wg_connect(struct vpn_provider *provider, option = vpn_provider_get_string(provider, "WireGuard.DNS"); if (option) { err = vpn_provider_set_nameservers(provider, option); - if (err) + if (err) { + DBG("Cannot set nameservers %s", option); goto done; + } } option = vpn_provider_get_string(provider, "WireGuard.PrivateKey"); @@ -359,8 +361,10 @@ static int wg_connect(struct vpn_provider *provider, goto done; } err = parse_key(option, info->device.private_key); - if (err) + if (err) { + DBG("Failed to parse private key"); goto done; + } option = vpn_provider_get_string(provider, "WireGuard.PublicKey"); if (!option) { @@ -368,15 +372,19 @@ static int wg_connect(struct vpn_provider *provider, goto done; } err = parse_key(option, info->peer.public_key); - if (err) + if (err) { + DBG("Failed to parse public key"); goto done; + } option = vpn_provider_get_string(provider, "WireGuard.PresharedKey"); if (option) { info->peer.flags |= WGPEER_HAS_PRESHARED_KEY; err = parse_key(option, info->peer.preshared_key); - if (err) + if (err) { + DBG("Failed to parse pre-shared key"); goto done; + } } option = vpn_provider_get_string(provider, "WireGuard.AllowedIPs"); @@ -385,8 +393,10 @@ static int wg_connect(struct vpn_provider *provider, goto done; } err = parse_allowed_ips(option, &info->peer); - if (err) + if (err) { + DBG("Failed to parse allowed IPs %s", option); goto done; + } option = vpn_provider_get_string(provider, "WireGuard.PersistentKeepalive"); @@ -404,8 +414,10 @@ static int wg_connect(struct vpn_provider *provider, gateway = vpn_provider_get_string(provider, "Host"); err = parse_endpoint(gateway, option, (struct sockaddr_u *)&info->peer.endpoint.addr); - if (err) + if (err) { + DBG("Failed to parse endpoint %s gateway %s", option, gateway); goto done; + } info->endpoint_fqdn = g_strdup(gateway); info->port = g_strdup(option); @@ -416,8 +428,10 @@ static int wg_connect(struct vpn_provider *provider, goto done; } err = parse_address(option, gateway, &ipaddress); - if (err) + if (err) { + DBG("Failed to parse address %s gateway %s", option, gateway); goto done; + } ifname = get_ifname(); if (!ifname) { @@ -446,7 +460,7 @@ static int wg_connect(struct vpn_provider *provider, done: if (cb) - cb(provider, user_data, err); + cb(provider, user_data, -err); connman_ipaddress_free(ipaddress); From patchwork Fri Jan 24 18:59:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949846 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9241F21ADAC for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745173; cv=none; b=I9ORG7D3ytO2hY35tf12mvOe40C7Fmd+PdRKIZA+catt1G499wfk/WPHSHXSi7HCAWQ+LkBELdmms1DBNthL6pW/nq2JdFMfz9kRb10IvPGspu4f4daZpBi++N3JcsdMJwD+DzANS15fG4dmGMjF38O/aFfoiVDoJe3oOe3zV5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745173; c=relaxed/simple; bh=ot0RsAa02vUfEh34alkEJaL9IXmt+/9VBHZsstHT8sg=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QtURNKDViY2ULGPhyWGc7WX0U1aw//Sla5hoOA0xxQjH27jXDPMdfo3CLt7f6e9y0p/bXDKcdr0BQ9w4gv5mKxQ6RkwXjsDiypJcxotUfMLe10OAycYqJ1GnlVWVTa9xs7xQJaIuXTl23UaZBCKz2sslHRXs53AU2hEIBBysyuQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=fN/5wgbT; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="fN/5wgbT" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=vk3YYEKMMkLnm+DVo5EU7+ayAx3M0sNBT6PfSuGpQqs=; b=fN/5wgbTGUXAIuIOv0Bci+a1oZ S99QWxkr2CQ0fOV+VpJGeecxzFhLMuXHwrlFhKhEObz9NjwrQEKxM5osqLiwTgzPAkau3aUbz/15Q n/wWGFzxQISmIw51aupcEKz0mq093dbHLasc7DDe3f32b63w+iB/rsdzHu4NxmgH7QzWy7TeVusEO SWviG6CeSfKA6ID5HnVT//g/po74/Z6fr18Yad+d1kTaCPPRWG2mVOjBf0pFaAsrcwIpyW5JuXeYl +B54bhE+LgrlCAUvIY6cOrnymOM4LSbzNR9A5USZcgwdK5PyPnb/rsZ4YDWuWQxdQoNTiX7mlZYIA Pv/ZXGXA==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2M for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 03/12] vpn: Fix VPN_FLAG_NO_DAEMON use in error cases Date: Fri, 24 Jan 2025 20:59:07 +0200 Message-Id: <20250124185916.1546471-4-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false The VPNs that have no daemon, WireGuard, should not be called to disconnect twice because in error situations the change of state from error case is overridden. This makes it impossible to track the state via an UI that relies on state notifications and uses autoconnect to toggle active VPN(s). Make vpn_died VPN_FLAG_NO_DAEMON friendly that can be called also by the VPNs without a task. This makes it possible to use vpn_died in WireGuard as final call to make state transitions complete. Make the state transitions of VPN_FLAG_NO_DAEMON to use the VPN_STATE_ASSOCIATION properly. This is the initial state when connecting, and the VPN_STATE_CONNECT is set by the update_provider_state() when driver replies that connection is ok. Also cleanup some code to use the same base more. --- vpn/plugins/vpn.c | 57 ++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index cb0d304b..d963b985 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -90,7 +90,13 @@ static int stop_vpn(struct vpn_provider *provider) if (vpn_driver_data && vpn_driver_data->vpn_driver && vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_TUN) { - vpn_driver_data->vpn_driver->disconnect(data->provider); + /* + * Disconnect only VPNs with daemon, otherwise in error return + * there is a double free with vpn_died() or the failure state + * is overridden by changes made by disconnect to state. + */ + if (!(vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_DAEMON)) + vpn_driver_data->vpn_driver->disconnect(data->provider); return 0; } @@ -130,16 +136,27 @@ 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); + struct vpn_driver_data *vpn_data = NULL; + const char *name; int state = VPN_STATE_FAILURE; enum vpn_provider_error ret; + bool no_daemon = false; + + 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) + no_daemon = vpn_data->vpn_driver->flags & + VPN_FLAG_NO_DAEMON; + } - DBG("provider %p data %p", provider, data); + DBG("provider %p data %p no_daemon %d", provider, data, no_daemon); if (!data) goto vpn_exit; /* The task may die after we have already started the new one */ - if (data->task != task) + if (!no_daemon && data->task != task) goto done; state = data->state; @@ -155,15 +172,7 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data) 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) + if (vpn_data && vpn_data->vpn_driver->error_code) ret = vpn_data->vpn_driver->error_code(provider, exit_code); else @@ -182,7 +191,8 @@ vpn_exit: } done: - connman_task_destroy(task); + if (!no_daemon) + connman_task_destroy(task); } int vpn_set_ifname(struct vpn_provider *provider, const char *ifname) @@ -524,6 +534,8 @@ static gboolean update_provider_state(gpointer data) vpn_data->watch = vpn_rtnl_add_newlink_watch(index, vpn_newlink, provider); connman_inet_ifup(index); + vpn_data->state = VPN_STATE_CONNECT; + vpn_provider_set_state(provider, VPN_PROVIDER_STATE_CONNECT); return FALSE; } @@ -598,18 +610,10 @@ static int vpn_connect(struct vpn_provider *provider, ret = vpn_driver_data->vpn_driver->connect(provider, NULL, NULL, cb, dbus_sender, user_data); - if (ret) { - stop_vpn(provider); - goto exist_err; - } + if (!ret) + g_timeout_add(1, update_provider_state, provider); - DBG("%s started with dev %s", - vpn_driver_data->provider_driver.name, data->if_name); - - data->state = VPN_STATE_CONNECT; - - g_timeout_add(1, update_provider_state, provider); - return -EINPROGRESS; + goto done; } vpn_plugin_data = @@ -635,9 +639,12 @@ static int vpn_connect(struct vpn_provider *provider, ret = vpn_driver_data->vpn_driver->connect(provider, data->task, data->if_name, cb, dbus_sender, user_data); + +done: if (ret < 0 && ret != -EINPROGRESS) { stop_vpn(provider); - connman_task_destroy(data->task); + if (data->task) + connman_task_destroy(data->task); data->task = NULL; goto exist_err; } From patchwork Fri Jan 24 18:59:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949847 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 924942248AE for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745173; cv=none; b=uk0W0xVMmppUIPpRwGftxmgkWEjPbcW4VI6bZ6hHm3P52U+cwyVoG3vZ9TmesMzPVVSRshbFoW+msiiSl/l+8N6m0BwQZc0m6mVYi+4P6bcIYGoTNDaBkVp17od2qt1TXFOrpFmpYi34NZMRp4hYW05q6ej4tFpztvplk0ZY8yE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745173; c=relaxed/simple; bh=cU3vzGLPRYLZU3B/BEHjuQTHeuhX/t/bRDfQgJXyvMo=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sx4lRc+aii8MCQqGsukfPqrzmDkioFsCVi8LgfEnuJEs2J82gm/YqZhDLYZtfpm6DD2l88xUmq7SAOqO77uZUu+FJMpky6A+pxmdKFwch9ucnlKy3FHyFSE/QBzZS3uh/19DRs0lgDM3xfhgnQ2n8aQf01K5yOevWvrGpBIzCQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=fNFwCzGi; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="fNFwCzGi" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=dJBCPRVmdT8RJE5QON5vewYXhbZN4G35qrBxido6ODE=; b=fNFwCzGih7PTVCS8TVxKesq3F6 aTguJyTJlml4QAX+v+ayxQSKRGhXtkiFd2umZ0Nuv5AunAIggJTDDCe7o6C4U1jNmNTWOSfd7k8Zo r3YLY1r11a6in721a5Ej3jrBxDbKUHNq5sY0v+SA0JJ+F4LXVXyQbEFd29bj0U7A8rbZ6dwo58Rx1 Yl24mM1ZZr0jYS60473wxjxwRKxkx3kANRlC5ZnnEMdlMPfBnjiyruUqXdsSgsv2I3NK0eg9azAnK ggCRW1DfhoOpSgDQVXRG1G9fHaEqvFtByrmgGKEvY7/5JAPoqtHe/WBwgJaJ8HmN7Z+TUxL98LWk0 nOAi6KNQ==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2W for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 04/12] wireguard: Handle disconnect, error and network errors better Date: Fri, 24 Jan 2025 20:59:08 +0200 Message-Id: <20250124185916.1546471-5-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Make the plugin to handle disconnect better by setting state, and calling vpn_died() with the exit code to make the states indicated properly to higher layers. This currently handles the ENODEV as an error code transformation to 0, since it can happen when the device is not up yet. When the parameters are wrong use login failed error with ECONNABORTED to indicate that autoconnect should be stopped on this VPN. It also, with other changes to vpn.c, makes it possible to keep the error for higher layers. Add a limit for the DNS reresolve attempts that makes WireGuard die after the limit is reached. This is for the cases when the IP configuration is wrong on the client and after connecting the endpoint cannot be resolved, and should be indicated as an error to higher layers. Also, in case the endpoint cannot be resolved, because of getaddrinfo()'s lengthy timeout vpnd becomes inoperable during that period. It performs a bit better when the timeout is recreated after every cb call, but not perfect. It should be running in a thread because of this deadlock but this is the first step on improving this with invalid configurations. --- vpn/plugins/wireguard.c | 115 +++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 24 deletions(-) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index de57b15f..2c5981f8 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -50,9 +50,11 @@ #include "wireguard.h" #define DNS_RERESOLVE_TIMEOUT 20 +#define DNS_RERESOLVE_ERROR_LIMIT 5 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) struct wireguard_info { + struct vpn_provider *provider; struct wg_device device; struct wg_peer peer; char *endpoint_fqdn; @@ -155,6 +157,7 @@ static int parse_endpoint(const char *host, const char *port, struct sockaddr_u struct addrinfo hints; struct addrinfo *result, *rp; int sk; + int err; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; @@ -162,8 +165,9 @@ static int parse_endpoint(const char *host, const char *port, struct sockaddr_u hints.ai_flags = 0; hints.ai_protocol = 0; - if (getaddrinfo(host, port, &hints, &result) < 0) { - DBG("Failed to resolve host address"); + err = getaddrinfo(host, port, &hints, &result); + if (err < 0) { + DBG("Failed to resolve host address: %s", gai_strerror(err)); return -EINVAL; } @@ -287,22 +291,38 @@ static bool sockaddr_cmp_addr(struct sockaddr_u *a, struct sockaddr_u *b) return false; } +static void run_dns_reresolve(struct wireguard_info *info); + static gboolean wg_dns_reresolve_cb(gpointer user_data) { struct wireguard_info *info = user_data; struct sockaddr_u addr; int err; - DBG(""); + if (vpn_provider_get_connection_errors(info->provider) >= + DNS_RERESOLVE_ERROR_LIMIT) { + connman_warn("reresolve error limit reached"); + vpn_died(NULL, -ENONET, info->provider); + return G_SOURCE_REMOVE; + } + /* If this fails after being connected it means configuration error + * that results in connection errors. */ err = parse_endpoint(info->endpoint_fqdn, info->port, &addr); - if (err) - return TRUE; + if (err) { + if (info->provider) + vpn_provider_add_error(info->provider, + VPN_PROVIDER_ERROR_CONNECT_FAILED); + run_dns_reresolve(info); + return G_SOURCE_REMOVE; + } if (sockaddr_cmp_addr(&addr, - (struct sockaddr_u *)&info->peer.endpoint.addr)) - return TRUE; + (struct sockaddr_u *)&info->peer.endpoint.addr)) { + run_dns_reresolve(info); + return G_SOURCE_REMOVE; + } if (addr.sa.sa_family == AF_INET) memcpy(&info->peer.endpoint.addr, &addr.sin, @@ -317,7 +337,17 @@ static gboolean wg_dns_reresolve_cb(gpointer user_data) DBG("Failed to update Endpoint address for WireGuard device %s", info->device.name); - return TRUE; + run_dns_reresolve(info); + return G_SOURCE_REMOVE; +} + +static void run_dns_reresolve(struct wireguard_info *info) +{ + if (info->reresolve_id) + g_source_remove(info->reresolve_id); + + info->reresolve_id = g_timeout_add_seconds(DNS_RERESOLVE_TIMEOUT, + wg_dns_reresolve_cb, info); } static int wg_connect(struct vpn_provider *provider, @@ -336,8 +366,12 @@ static int wg_connect(struct vpn_provider *provider, info->device.flags = WGDEVICE_HAS_PRIVATE_KEY; info->device.first_peer = &info->peer; info->device.last_peer = &info->peer; + info->provider = vpn_provider_ref(provider); + + DBG(""); vpn_provider_set_plugin_data(provider, info); + vpn_provider_set_auth_error_limit(provider, 1); option = vpn_provider_get_string(provider, "WireGuard.ListenPort"); if (option) { @@ -351,30 +385,30 @@ static int wg_connect(struct vpn_provider *provider, err = vpn_provider_set_nameservers(provider, option); if (err) { DBG("Cannot set nameservers %s", option); - goto done; + goto error; } } option = vpn_provider_get_string(provider, "WireGuard.PrivateKey"); if (!option) { DBG("WireGuard.PrivateKey is missing"); - goto done; + goto error; } err = parse_key(option, info->device.private_key); if (err) { DBG("Failed to parse private key"); - goto done; + goto error; } option = vpn_provider_get_string(provider, "WireGuard.PublicKey"); if (!option) { DBG("WireGuard.PublicKey is missing"); - goto done; + goto error; } err = parse_key(option, info->peer.public_key); if (err) { DBG("Failed to parse public key"); - goto done; + goto error; } option = vpn_provider_get_string(provider, "WireGuard.PresharedKey"); @@ -383,19 +417,19 @@ static int wg_connect(struct vpn_provider *provider, err = parse_key(option, info->peer.preshared_key); if (err) { DBG("Failed to parse pre-shared key"); - goto done; + goto error; } } option = vpn_provider_get_string(provider, "WireGuard.AllowedIPs"); if (!option) { DBG("WireGuard.AllowedIPs is missing"); - goto done; + goto error; } err = parse_allowed_ips(option, &info->peer); if (err) { DBG("Failed to parse allowed IPs %s", option); - goto done; + goto error; } option = vpn_provider_get_string(provider, @@ -415,8 +449,8 @@ static int wg_connect(struct vpn_provider *provider, err = parse_endpoint(gateway, option, (struct sockaddr_u *)&info->peer.endpoint.addr); if (err) { - DBG("Failed to parse endpoint %s gateway %s", option, gateway); - goto done; + DBG("Failed to parse endpoint %s:%s", gateway, option); + goto error; } info->endpoint_fqdn = g_strdup(gateway); @@ -425,12 +459,12 @@ static int wg_connect(struct vpn_provider *provider, option = vpn_provider_get_string(provider, "WireGuard.Address"); if (!option) { DBG("Missing WireGuard.Address configuration"); - goto done; + goto error; } err = parse_address(option, gateway, &ipaddress); if (err) { DBG("Failed to parse address %s gateway %s", option, gateway); - goto done; + goto error; } ifname = get_ifname(); @@ -465,16 +499,27 @@ done: connman_ipaddress_free(ipaddress); if (!err) - info->reresolve_id = - g_timeout_add_seconds(DNS_RERESOLVE_TIMEOUT, - wg_dns_reresolve_cb, info); + run_dns_reresolve(info); return err; + +error: + /* + * TODO: add own category for parameter errors. This is to avoid + * looping when parameters are incorrect and VPN stays in failed + * state. + */ + vpn_provider_add_error(provider, VPN_PROVIDER_ERROR_LOGIN_FAILED); + err = -ECONNABORTED; + goto done; } static void wg_disconnect(struct vpn_provider *provider) { struct wireguard_info *info; + int exit_code; + + DBG(""); info = vpn_provider_get_plugin_data(provider); if (!info) @@ -485,11 +530,32 @@ static void wg_disconnect(struct vpn_provider *provider) vpn_provider_set_plugin_data(provider, NULL); - wg_del_device(info->device.name); + vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT); + + exit_code = wg_del_device(info->device.name); + vpn_provider_unref(info->provider); g_free(info->endpoint_fqdn); g_free(info->port); g_free(info); + + DBG("exiting with %d", exit_code); + + /* No task for no daemon VPN - use VPN died with no task. */ + vpn_died(NULL, exit_code, provider); +} + +static int wg_error_code(struct vpn_provider *provider, int exit_code) +{ + DBG("exit_code %d", exit_code); + + switch (exit_code) { + /* Failed to parse configuration -> wg_del_device() has no to delete */ + case -ENODEV: + return 0; + default: + return exit_code; + } } static int wg_save(struct vpn_provider *provider, GKeyFile *keyfile) @@ -518,6 +584,7 @@ static struct vpn_driver vpn_driver = { .connect = wg_connect, .disconnect = wg_disconnect, .save = wg_save, + .error_code = wg_error_code }; static int wg_init(void) From patchwork Fri Jan 24 18:59:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949842 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9239A1D54D8 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=XxnAvS7boQpufag2yuiDHlq0QeUHlMciNAX59yVkLpxx4vaF5TzaUeaJxaM+hIiw8QCddGg+571LIoBxqZRLRMk0buDDWwfv0qahHbArkz4DjKvbm3PC0z5UPbyK3ZtPixdCPSk0cXd6k8xjK48bSps3P0MKlUosyF4SULkvNvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=xsjUFBMTwAqoOVx06aFuE/zprZB7psalZbvHzKRD8CQ=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XU2LRY6bbx0pXR3SCIpUhtmW0+2OcoEXWEoBWhrj/KyOQE1usyZ1G4D/XoyqLHsWv0yfwsNgyVec5hcx6kVcPmdtRfpBc7VVGcczpkgGp4VyduRKufAuqQMYL8h4dzb2XPjqpCuXEUd4DJaAsOh8myPPqOJge32Rz/1Lj7z9z8s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=HTncup/K; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="HTncup/K" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=JISa8J6dhFaTlcyGxUHT14JSFpMkHQQ8h8LOyC0vlIg=; b=HTncup/Kktg1er+d/R4/sv9uVU EYQ6Yx793piEAy5R1TLdCoXRoM6gaXfe09jxZn64f4chXo8V1EiPjTFzd0gp1yIR09FhYZyWJqlFv YlDNc7z82UUlVzrz1NPw7LZYkWJwCciMrfu0XtK9Rl/579vKRG0NHy/LZw0rSqX9eMUzqrsJgOFK6 UXJzJPAi+UZCMk87/E4VAq8dY/XkQSZj3F2Ik+ydfJkRaNd+e1dY488c4yU/O0XtMXI2qhuIdf2AE kTw+lVSCMgZS614Ex0Y86nuMdDnl7hNJaToLxPYQtmvk/0P78fN44Dx4orTp4D0By20qn9nxAGT/g zLOfWoGQ==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2f for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 05/12] gresolv: Add generic error for GResolv struct with getter Date: Fri, 24 Jan 2025 20:59:09 +0200 Message-Id: <20250124185916.1546471-6-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Add a error for the struct to be used with hostname lookup. The function should return either 0 in case of error or the source id, this fixes the wrong returns when error happens and makes it possible to retrieve the error afterwards. --- gweb/gresolv.c | 15 +++++++++++++-- gweb/gresolv.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gweb/gresolv.c b/gweb/gresolv.c index 8101d718..1f1db474 100644 --- a/gweb/gresolv.c +++ b/gweb/gresolv.c @@ -116,6 +116,7 @@ struct _GResolv { GResolvDebugFunc debug_func; gpointer debug_data; + int err; }; #define debug(resolv, format, arg...) \ @@ -1060,7 +1061,8 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname, if (resolv->result_family != AF_INET6) { if (add_query(lookup, hostname, ns_t_a)) { g_free(lookup); - return -EIO; + resolv->err = -EIO; + return 0; } } @@ -1073,7 +1075,8 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname, } g_free(lookup); - return -EIO; + resolv->err = -EIO; + return 0; } } @@ -1119,3 +1122,11 @@ bool g_resolv_set_address_family(GResolv *resolv, int family) return true; } + +int g_resolv_get_error(GResolv *resolv) +{ + if (!resolv) + return 0; + + return resolv->err; +} diff --git a/gweb/gresolv.h b/gweb/gresolv.h index 5e82c168..1994ac34 100644 --- a/gweb/gresolv.h +++ b/gweb/gresolv.h @@ -71,6 +71,8 @@ bool g_resolv_cancel_lookup(GResolv *resolv, guint id); bool g_resolv_set_address_family(GResolv *resolv, int family); +int g_resolv_get_error(GResolv *resolv); + #ifdef __cplusplus } #endif From patchwork Fri Jan 24 18:59:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949835 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 927262248B8 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; cv=none; b=Ncs2ZFEJPCEzfmEvWpK7kF47q2nOMKdfb3VeOKesAjC9VedzwpB10R10CxqHEf462t8pO2krSTaNf8WibitrEzzSJJ/GOOF0FnfNhD2QU5c95flyUK1t/ryGahRPpU+dTT9EvjP4nLUhDFoTi4ltXVn1y0JqjQjaWg8eLHKQRQY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; c=relaxed/simple; bh=oVetn3rdat80WPQ1XEQP8j2qBZZJqWCKnamalRp6Ngg=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nSNFUO53PXwC9opCRN0OjSReARjifN+Djj7ethW7RBvBZ6EXehQ6Lbq4Ds24Vs3fLaw4gyv+C6WLel7eq1fTWsG1R19ESy7pNpzNq8Kzk2UYBRvJMWj2GxOr91vCtzAwQkLDi9MP58sKc3M4uKoR35ENRiG5Y6ak/ShVnFYO6a8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=GFOijc0d; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="GFOijc0d" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=26idGT3rnLkga4oFKXzAQcA3UGfFIXE1bcmmrG6zgdA=; b=GFOijc0dRo9TdqYL0eryfa/Fxq S3y/wlgFzWJDP3/go81o6buevgc7kWnrrSkWk3ofFVZaStdWl/2nmA3wTbVtWa9R8pyBmPyCWeaek zWoZJxVQ0H/OV2ZAO9nwE4Y/sa3Zvyh/yBn5YPYW9NIDtquMZEvuXolf60ejSrR2pc8ut1gh/6A1A LewnN4vbBT4gZPVxJpMVvKUNmWu5GG0OXMBujSCmDNAYm2kxp506OROPGWeiWa2enqWd0bPdF5Y4U L/dSAFIiDgtt6a5RJV0ZLql/jFZiPxrXwV9foDhJMBje7XXyR5DgW4UhiP6skbjKANJNmYt3pzB27 ugX/hX0w==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2o for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 06/12] vpn-util: Add wrappers for GResolv hostname lookup use Date: Fri, 24 Jan 2025 20:59:10 +0200 Message-Id: <20250124185916.1546471-7-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false To avoid linking GResolv with every VPN plugin that uses it, add wrappers for the required calls in VPN utils. --- vpn/vpn-util.c | 30 ++++++++++++++++++++++++++++++ vpn/vpn.h | 10 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/vpn/vpn-util.c b/vpn/vpn-util.c index bc3b01dd..2e526701 100644 --- a/vpn/vpn-util.c +++ b/vpn/vpn-util.c @@ -222,3 +222,33 @@ out: return err; } +unsigned int vpn_util_resolve_hostname(GResolv *resolv, + const char *hostname, GResolvResultFunc func, + gpointer user_data) +{ + DBG("resolve %s", hostname); + + return g_resolv_lookup_hostname(resolv, hostname, func, user_data); +} + +bool vpn_util_cancel_resolve(GResolv *resolv, unsigned int id) +{ + DBG(""); + + return g_resolv_cancel_lookup(resolv, id); +} + +GResolv *vpn_util_resolve_new(int index) +{ + return g_resolv_new(index); +} + +void vpn_util_resolve_unref(GResolv *resolv) +{ + g_resolv_unref(resolv); +} + +int vpn_util_get_resolve_error(GResolv *resolv) +{ + return g_resolv_get_error(resolv); +} diff --git a/vpn/vpn.h b/vpn/vpn.h index 1f8c8fcd..88afce45 100644 --- a/vpn/vpn.h +++ b/vpn/vpn.h @@ -134,3 +134,13 @@ bool vpn_settings_is_system_user(const char *user); struct passwd *vpn_util_get_passwd(const char *username); struct group *vpn_util_get_group(const char *groupname); int vpn_util_create_path(const char *path, uid_t uid, gid_t grp, int mode); + +#include + +unsigned int vpn_util_resolve_hostname(GResolv *resolv, + const char *hostname, GResolvResultFunc func, + gpointer user_data); +bool vpn_util_cancel_resolve(GResolv *resolv, unsigned int id); +GResolv *vpn_util_resolve_new(int index); +void vpn_util_resolve_unref(GResolv *resolv); +int vpn_util_get_resolve_error(GResolv *resolv); From patchwork Fri Jan 24 18:59:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949838 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 922D2146A9B for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; cv=none; b=ORugBGk82ADVvZTnct2uPElt4A25RDtGJy8yz7aXVmGyx1LdhCrzl00lRt4wK8ID0nQuEwujCkApMA82GX9sjf0jdrWEiq5ka8IFW7YykXgVowwVXnYYApGbvbUrf0/DuvuasGUQBhb7DcTB3EpCy9dtMgeWLjkVmrMXYMqvImk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; c=relaxed/simple; bh=RQZ3EfTsn2nc9Ld5iHLKfXe0ruK6rRlGM3ZQCsZFvpI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=d7olHEAvf70+fHFpPc020tGpCnt9fAde7M3zY4boTZmBouQEJlDsURMC8fHOAqzjWlYQ0R1yziArDJsAMAKzGQXZk/r8Z7Pat4w0MFzNuck0IxJ+Z6/DZx2Ql95vTu0C2dRCXCjmYCsMu2EfME50zKZQ3A+QEHDjelBP8mrv32E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=F13o0Eth; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="F13o0Eth" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=W32G/exbWG9CXWy1HG9fl7YxXAcfrfgqJEu8gp6bKXo=; b=F13o0EthxnRn/YgqMQs8heZEXc zYeFSUJNHIGOt8HunYNF0oGe7QqHOKEJNxo5WeAH8ZLZ6Xs0biDPz2APoFQ2PjwlKZzkRCUhE4x1q 4mWYqp3SX43O46PpHwe53+Pxwv+lRJp16bayf9tOntTapQ9o9z9PQFgeZo6gICLUSv2Kt/R2f33au 24Ju9pW7aJtDy42kJLtUlSlU1B416KoBSfsOsgC3eQaB7hpBXRAlpfDbECoHRjmPX2Jkz5Elm26M5 UztSF2EHi+FDLlM+8PRJ2LOc+wGZJULDVxVcmXO/fYS8WK+vFGBR86+VwXbuvzays2q+zyQZODvW0 SdBZ5JFA==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-2x for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 07/12] wireguard: Use GResolv for DNS reresolve to avoid blocking Date: Fri, 24 Jan 2025 20:59:11 +0200 Message-Id: <20250124185916.1546471-8-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Change to use GResolv for the reresolve lookups as with broken configuration getaddrinfo() will block vpnd for the time it timeouts in a broken network. By using GResolv the resolving is done first and only after it is succesful getaddrinfo() is called. This is not done for the initial connection as the transport medium's network is used, thus it has no possibility of such misconfiguration as the network is at least in READY state. Check the GResolv lookup error and if it is set kill the VPN. This is because the set error is quite terminal on the connection, better just to die. Change reresolve_id to be guint as it should be and handle it properly. Document why the remove_resolv_cb() and resolv id is used like it is. --- vpn/plugins/wireguard.c | 162 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 147 insertions(+), 15 deletions(-) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index 2c5981f8..4a3d9ec7 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -43,6 +43,8 @@ #include #include +#include + #include "../vpn-provider.h" #include "../vpn.h" @@ -59,7 +61,10 @@ struct wireguard_info { struct wg_peer peer; char *endpoint_fqdn; char *port; - int reresolve_id; + guint reresolve_id; + GResolv *resolv; + guint resolv_id; + guint remove_resolv_id; }; struct sockaddr_u { @@ -293,43 +298,120 @@ static bool sockaddr_cmp_addr(struct sockaddr_u *a, struct sockaddr_u *b) static void run_dns_reresolve(struct wireguard_info *info); -static gboolean wg_dns_reresolve_cb(gpointer user_data) +static void remove_resolv(struct wireguard_info *info) +{ + DBG(""); + + if (info->remove_resolv_id) + g_source_remove(info->remove_resolv_id); + + if (info->resolv && info->resolv_id) { + DBG("cancel resolv lookup"); + vpn_util_cancel_resolve(info->resolv, info->resolv_id); + } + + info->resolv_id = 0; + info->remove_resolv_id = 0; + + vpn_util_resolve_unref(info->resolv); + info->resolv = NULL; +} + +static gboolean remove_resolv_cb(gpointer user_data) +{ + struct wireguard_info *info = user_data; + + remove_resolv(info); + + return G_SOURCE_REMOVE; +} + +static void resolve_endpoint_cb(GResolvResultStatus status, + char **results, gpointer user_data) { struct wireguard_info *info = user_data; struct sockaddr_u addr; int err; - if (vpn_provider_get_connection_errors(info->provider) >= - DNS_RERESOLVE_ERROR_LIMIT) { - connman_warn("reresolve error limit reached"); - vpn_died(NULL, -ENONET, info->provider); - return G_SOURCE_REMOVE; + DBG(""); + + if (!info->resolv && info->resolv_id) { + DBG("resolv already removed"); + return; } - /* If this fails after being connected it means configuration error - * that results in connection errors. */ - err = parse_endpoint(info->endpoint_fqdn, - info->port, &addr); + /* + * We cannot unref the resolver here as resolv struct is manipulated + * by gresolv.c after we return from this callback. By clearing the + * resolv_id no attempt to cancel the lookup that has been executed + * here is done. + */ + info->remove_resolv_id = g_timeout_add(0, remove_resolv_cb, info); + info->resolv_id = 0; + + switch (status) { + case G_RESOLV_RESULT_STATUS_SUCCESS: + if (!results || !g_strv_length(results)) { + DBG("no resolved results"); + if (info->provider) + vpn_provider_add_error(info->provider, + VPN_PROVIDER_ERROR_CONNECT_FAILED); + + return; + } + + DBG("resolv success, parse endpoint"); + break; + /* request timeouts or an server issue is not an error, try again */ + case G_RESOLV_RESULT_STATUS_NO_RESPONSE: + case G_RESOLV_RESULT_STATUS_SERVER_FAILURE: + DBG("retry DNS reresolve"); + if (info->provider) + vpn_provider_add_error(info->provider, + VPN_PROVIDER_ERROR_CONNECT_FAILED); + + run_dns_reresolve(info); + return; + /* Consider these as non-continuable errors */ + case G_RESOLV_RESULT_STATUS_ERROR: + case G_RESOLV_RESULT_STATUS_FORMAT_ERROR: + case G_RESOLV_RESULT_STATUS_NAME_ERROR: + case G_RESOLV_RESULT_STATUS_NOT_IMPLEMENTED: + case G_RESOLV_RESULT_STATUS_REFUSED: + case G_RESOLV_RESULT_STATUS_NO_ANSWER: + DBG("stop DNS reresolve"); + if (info->provider) + vpn_provider_add_error(info->provider, + VPN_PROVIDER_ERROR_CONNECT_FAILED); + + return; + } + + /* + * If this fails after being connected it means configuration error + * that results in connection errors. + */ + err = parse_endpoint(info->endpoint_fqdn, info->port, &addr); if (err) { if (info->provider) vpn_provider_add_error(info->provider, VPN_PROVIDER_ERROR_CONNECT_FAILED); run_dns_reresolve(info); - return G_SOURCE_REMOVE; + return; } if (sockaddr_cmp_addr(&addr, (struct sockaddr_u *)&info->peer.endpoint.addr)) { run_dns_reresolve(info); - return G_SOURCE_REMOVE; + return; } if (addr.sa.sa_family == AF_INET) memcpy(&info->peer.endpoint.addr, &addr.sin, - sizeof(info->peer.endpoint.addr4)); + sizeof(info->peer.endpoint.addr4)); else memcpy(&info->peer.endpoint.addr, &addr.sin6, - sizeof(info->peer.endpoint.addr6)); + sizeof(info->peer.endpoint.addr6)); DBG("Endpoint address has changed, udpate WireGuard device"); err = wg_set_device(&info->device); @@ -338,6 +420,39 @@ static gboolean wg_dns_reresolve_cb(gpointer user_data) info->device.name); run_dns_reresolve(info); +} + +static gboolean wg_dns_reresolve_cb(gpointer user_data) +{ + struct wireguard_info *info = user_data; + int err; + + DBG(""); + + info->reresolve_id = 0; + + if (info->resolv_id > 0) { + DBG("previous query was running, abort it"); + remove_resolv(info); + } + + info->resolv = vpn_util_resolve_new(0); + if (!info->resolv) { + connman_error("cannot create GResolv"); + return G_SOURCE_REMOVE; + } + + info->resolv_id = vpn_util_resolve_hostname(info->resolv, + info->endpoint_fqdn, + resolve_endpoint_cb, info); + + err = vpn_util_get_resolve_error(info->resolv); + if (!info->resolv_id && err) { + connman_error("failed to start hostname lookup for %s, err %d", + info->endpoint_fqdn, err); + vpn_died(NULL, err, info->provider); + } + return G_SOURCE_REMOVE; } @@ -346,6 +461,14 @@ static void run_dns_reresolve(struct wireguard_info *info) if (info->reresolve_id) g_source_remove(info->reresolve_id); + if (vpn_provider_get_connection_errors(info->provider) >= + DNS_RERESOLVE_ERROR_LIMIT) { + connman_warn("reresolve error limit reached"); + vpn_died(NULL, -ENONET, info->provider); + info->reresolve_id = 0; + return; + } + info->reresolve_id = g_timeout_add_seconds(DNS_RERESOLVE_TIMEOUT, wg_dns_reresolve_cb, info); } @@ -446,6 +569,12 @@ static int wg_connect(struct vpn_provider *provider, option = "51820"; gateway = vpn_provider_get_string(provider, "Host"); + /* + * Use the resolve timeout only with re-resolve. Here the network + * is setup as the transport is used. In succeeding attempts resolving + * is needed as it is done over potentially misconfigured WireGuard + * connection that may end up blocking vpnd with getaddrinfo(). + */ err = parse_endpoint(gateway, option, (struct sockaddr_u *)&info->peer.endpoint.addr); if (err) { @@ -528,6 +657,9 @@ static void wg_disconnect(struct vpn_provider *provider) if (info->reresolve_id > 0) g_source_remove(info->reresolve_id); + if (info->resolv || info->resolv_id) + remove_resolv(info); + vpn_provider_set_plugin_data(provider, NULL); vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT); From patchwork Fri Jan 24 18:59:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949840 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9227027726 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=iZ5TkiEbazSVxwgwR/B+cw9BvEpMZJMiQnQQj2NrJOcYEAMmuRySYFsPh6dc9R2ilZoD4g/9nEEPJYvVZtNx2fF7EEhxaSqf+OAsyXcBxZg0K1c7w8sJcYdKmPcrDcG8VfY92GuRKQL7JIBfSzIo0s45EP1GeT25xtR338lgXQU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=O86GMZZs4I/T71fJgzvpFcTa7Q/8PC0zDSDOAO+BkDQ=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PIfUVO5Kml2RVINOTARUykjqD4yMuRvQPF8Y9CWYkfUKIb4rloXwDF8/cvFGNbQ9hBtFjeFFHxEgqfABvR91nTOKkHl8EvW/xkC1ol4tDiEEHCWt5wYeTRW0Zftmh9l7DUULv1wg36EWVWElLv8PSVUpEAzJQ1BZDlCJoMgDkL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=VI/PadPS; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="VI/PadPS" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=zN+F6HNz3oxAc5t5CI6kUULAfxSD05D6d/BAmbOGbgk=; b=VI/PadPSI9uyi9CtDnqpv7F+Gz S6zEKzb4R9msLXzdT7RxvBVcnt9G2ekwGByJ7wFjghoSqsdfbAg3KRfuxAsxjbOLamOMlJvFLqHdJ ehnoR6LHfy8arIUmZJTZ0WXT08bwbDBrGvOvnstu3+62FdGhTT8X+Wyp5DsFumrhhFo7E29QU4Atm TjcuddYRqlhwXeLyp0u7bVJQ7G1fdhVh8x9dmct0PIeF2mEWJ+YGYY9pqSvXUeSftVVKDqAd8RQmH wL1eYN8a19s0vrF+hoZf4g/3SAgfaucebAV+ya8RWCUjBZBp+dwmvskBDxAWDQa3euei45YhecAl0 /KOo98Rw==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtq-006LTc-36 for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:26 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 08/12] vpn: Drop state changes from update_provider_state() Date: Fri, 24 Jan 2025 20:59:12 +0200 Message-Id: <20250124185916.1546471-9-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false It is not necessary to change the state in vpn.c for non-daemon VPNs because the vpn-provider.c:__vpn_provider_connect() changes the state according to the state machine. ASSOCIATION state will be assigned for every VPN after connect, then depending on VPN agent use the state changes either directly, or after the agent has finished, to CONNECT state. --- vpn/plugins/vpn.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index d963b985..18ec7ed3 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -534,8 +534,6 @@ static gboolean update_provider_state(gpointer data) vpn_data->watch = vpn_rtnl_add_newlink_watch(index, vpn_newlink, provider); connman_inet_ifup(index); - vpn_data->state = VPN_STATE_CONNECT; - vpn_provider_set_state(provider, VPN_PROVIDER_STATE_CONNECT); return FALSE; } From patchwork Fri Jan 24 18:59:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949843 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 923421BEF9E for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=sXJTD6DOJjXO2svFiJTpW2lwheJ3dbEP9/97Pyoq4EldsUuoPG1VUwEW/zRUES1+FuCrkYx5oaKHWB/FI9+soOQEDlVVa653fuvc9+D+ieuEljKwDn/2zvGKqqC8SRMnIeTDwCR8rT4E4iCt1bFEwvVsJFZ/LvbYfxYatOIw8MI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=a4qXbNBYe0KiC4MWXKpAAD6pOuM3nrCIz/CCODvzW9c=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TEq4eMzqB53y7wbOilJAlIw7wiNI2u15dvFCCxZj9o0nRcFvzsGB3L0eh9pv61nel0GCxYQun6iVcxIocWxqDO1S5qace7GCBBjyPPpjQwW0QWPSS9w6tgh4o4o9fjQP70iHHKovvgOwkbC+E8xaahAcPXYymPRJ1lxfJy6om2E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=Upc02kN9; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="Upc02kN9" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=D4m50OyfP8CvyajknZg5e3Go4s6Ia7Gun66AKp/+Lz8=; b=Upc02kN9MNtiL1darB+FnVN+Ot YfhD0BrB+lRH2C/QB6pa9u3zdZ562SoOxmqqC+y7ubYWgntGBaQU4tfJk5oujhroRqJsb1zDfII8x WVo1PcklCVNw4xp4dfGbjzObIUUHxEk1uXORZpxg2ENYeVW/mOrMxJD2DmN2awqZ0Z5QuVzlr0aWT x+1ECG8UBNDEAq/KoUdlaRGZFp+uFRJGjkOJHRQx0LbE0LawqwjY4ZEk7aVW2ssjr+BpvtmwFXsGP 4q4qDfXCFSFr8F8kKmL47aAI7qiJJCG5txs7ZDhT+oyrrx61/uAn35/k3qu4Nrwht9LhF1QHWo4Ds pdAwJUsg==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtr-006LTc-00 for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:27 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 09/12] wireguard: Fix shutdown, ensure one exit and set no agent is used Date: Fri, 24 Jan 2025 20:59:13 +0200 Message-Id: <20250124185916.1546471-10-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Split disconnect into wg_disconnect() and disconnect(). Use disconnect() to properly disconnect when error occurs with the appropriate error code. Do the same in wg_disconnect() by using the error code to be from device removal. The shutdown process requires, that in order to do the proper transition to IDLE, vpn_died() is to be called. This is normally called by the task that has been killed so simulate this behavior in WireGuard by adding a delayed call for that. It is to be executed only once as all the cleanup is to be done at that last step. Add a function to declare that WireGuard does not use a VPN agent. This ensures that the state transition is done according to state machine by __vpn_provider_connect(). Add separate create/free for struct wireguard_info for VPN consistency. --- vpn/plugins/wireguard.c | 106 ++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 20 deletions(-) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index 4a3d9ec7..307b3b37 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -65,6 +65,7 @@ struct wireguard_info { GResolv *resolv; guint resolv_id; guint remove_resolv_id; + guint dying_id; }; struct sockaddr_u { @@ -90,6 +91,31 @@ struct { {"WireGuard.PersistentKeepalive", true} }; +static struct wireguard_info *create_private_data(struct vpn_provider *provider) +{ + struct wireguard_info *info; + + info = g_malloc0(sizeof(struct wireguard_info)); + info->peer.flags = WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS; + info->device.flags = WGDEVICE_HAS_PRIVATE_KEY; + info->device.first_peer = &info->peer; + info->device.last_peer = &info->peer; + info->provider = vpn_provider_ref(provider); + + return info; +} + +static void free_private_data(struct wireguard_info *info) +{ + if (vpn_provider_get_plugin_data(info->provider) == info) + vpn_provider_set_plugin_data(info->provider, NULL); + + vpn_provider_unref(info->provider); + g_free(info->endpoint_fqdn); + g_free(info->port); + g_free(info); +} + static int parse_key(const char *str, wg_key key) { unsigned char *buf; @@ -422,6 +448,8 @@ static void resolve_endpoint_cb(GResolvResultStatus status, run_dns_reresolve(info); } +static int disconnect(struct vpn_provider *provider, int error); + static gboolean wg_dns_reresolve_cb(gpointer user_data) { struct wireguard_info *info = user_data; @@ -450,7 +478,7 @@ static gboolean wg_dns_reresolve_cb(gpointer user_data) if (!info->resolv_id && err) { connman_error("failed to start hostname lookup for %s, err %d", info->endpoint_fqdn, err); - vpn_died(NULL, err, info->provider); + disconnect(info->provider, err); } return G_SOURCE_REMOVE; @@ -464,7 +492,7 @@ static void run_dns_reresolve(struct wireguard_info *info) if (vpn_provider_get_connection_errors(info->provider) >= DNS_RERESOLVE_ERROR_LIMIT) { connman_warn("reresolve error limit reached"); - vpn_died(NULL, -ENONET, info->provider); + disconnect(info->provider, -ENONET); info->reresolve_id = 0; return; } @@ -484,12 +512,7 @@ static int wg_connect(struct vpn_provider *provider, char *ifname; int err = -EINVAL; - info = g_malloc0(sizeof(struct wireguard_info)); - info->peer.flags = WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS; - info->device.flags = WGDEVICE_HAS_PRIVATE_KEY; - info->device.first_peer = &info->peer; - info->device.last_peer = &info->peer; - info->provider = vpn_provider_ref(provider); + info = create_private_data(provider); DBG(""); @@ -643,8 +666,34 @@ error: goto done; } -static void wg_disconnect(struct vpn_provider *provider) +struct wireguard_exit_data { + struct vpn_provider *provider; + int err; +}; + +static gboolean wg_died(gpointer user_data) { + struct wireguard_exit_data *data = user_data; + struct wireguard_info *info; + + DBG(""); + + /* No task for no daemon VPN - use vpn_died() with no task. */ + vpn_died(NULL, data->err, data->provider); + + info = vpn_provider_get_plugin_data(data->provider); + if (info) + free_private_data(info); + + g_free(data); + + return G_SOURCE_REMOVE; +} + +/* Allow to overrule the exit code for vpn_died */ +static int disconnect(struct vpn_provider *provider, int err) +{ + struct wireguard_exit_data *data; struct wireguard_info *info; int exit_code; @@ -652,7 +701,10 @@ static void wg_disconnect(struct vpn_provider *provider) info = vpn_provider_get_plugin_data(provider); if (!info) - return; + return -ENODATA; + + if (info->dying_id) + return -EALREADY; if (info->reresolve_id > 0) g_source_remove(info->reresolve_id); @@ -660,21 +712,29 @@ static void wg_disconnect(struct vpn_provider *provider) if (info->resolv || info->resolv_id) remove_resolv(info); - vpn_provider_set_plugin_data(provider, NULL); - vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT); exit_code = wg_del_device(info->device.name); - vpn_provider_unref(info->provider); - g_free(info->endpoint_fqdn); - g_free(info->port); - g_free(info); + /* Simulate a task-running VPN to issue vpn_died after exiting this */ + data = g_malloc0(sizeof(struct wireguard_exit_data)); + data->provider = provider; + data->err = err ? err : exit_code; - DBG("exiting with %d", exit_code); + info->dying_id = g_timeout_add(1, wg_died, data); - /* No task for no daemon VPN - use VPN died with no task. */ - vpn_died(NULL, exit_code, provider); + return exit_code; +} + +static void wg_disconnect(struct vpn_provider *provider) +{ + int exit_code; + + DBG(""); + + exit_code = disconnect(provider, 0); + + DBG("exited with %d", exit_code); } static int wg_error_code(struct vpn_provider *provider, int exit_code) @@ -711,12 +771,18 @@ static int wg_save(struct vpn_provider *provider, GKeyFile *keyfile) return 0; } +bool wg_uses_vpn_agent(struct vpn_provider *provider) +{ + return false; +} + static struct vpn_driver vpn_driver = { .flags = VPN_FLAG_NO_TUN | VPN_FLAG_NO_DAEMON, .connect = wg_connect, .disconnect = wg_disconnect, .save = wg_save, - .error_code = wg_error_code + .error_code = wg_error_code, + .uses_vpn_agent = wg_uses_vpn_agent }; static int wg_init(void) From patchwork Fri Jan 24 18:59:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949837 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 925742248B4 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; cv=none; b=FLbrp9nN0OpdlkBM2AVjJ5k24tLXW/h9Y0sbsAHzjhS2/Zv6k9ODI6d5gEgzLwrreszgzBNnGADs618Badv6b90ZwFUf0yYjLEuEpqoGw/KL+wdUhZ6FL5RFde/31bmrCRtQP2gQFqkwa7uMtoURI3d/kfTARlOnpP0072pjmcI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745171; c=relaxed/simple; bh=/mw3fnbkOwLA2+fFtxioe+3h1hdSNPceu4E+phSCe00=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fW97QS/QvpHl1w59vbbMsdUncvocEcP+OZtVeGdAB0Qe7JrTM5RXG4YVLuSqlM15SigBPbs1TZpVHLVy24waLDhIr+FXi96PzOvZuL19K9Fvz9nrcQcz+rgt+IDVAFWZdGW2d+X5HDs7kFmVdpuATjOs4XE1k6NEpUoTKPPfBAE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=ueNOCv0d; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="ueNOCv0d" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=51PFvVzKehKDalSmdjqxXpcfKI4pu9Af+uC3o36wgWI=; b=ueNOCv0d1Zaj336LWll6ejfeIS viRa3s0Zjf+OPHbLlpm2TulRXX5knSOTzzmi6XJJwJVA7H+BJF+qoI23lGnr4yorevgfAIHf9Ahnu 5zI/oFB9v4fWPhEFdLQfuhBhYLzCGiai5bepm0FGAorwuuczGvgehATCZmIqbUSenaaTnjE/q+MEu HjG6iD1x+oMinWmYliAsVPloTnByMCZqssQzWqxV+L4oxBLXZyIlXRJubEmyt7E5H0EnXykfjQjBJ KDHcIssWNdE1Uh6sAZIOnE+RxDKe6hA8mm/xIwVZ48gAt8CBwOsW6dnhiMDxnN/RZlxjNwteoX8V1 BIfsCi5g==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtr-006LTc-0A for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:27 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 10/12] vpn: Check if disconnect is implemented before calling in stop_vpn() Date: Fri, 24 Jan 2025 20:59:14 +0200 Message-Id: <20250124185916.1546471-11-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Check if the disconnect() is implemented for the vpn_driver before attempting to call it when stopping a VPN. Also cleanup the code a bit. Amends changes made in ffec305c1c93301534144774fffebb25fb9c6c7a --- vpn/plugins/vpn.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index 18ec7ed3..16d11b4e 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -75,6 +75,7 @@ static int stop_vpn(struct vpn_provider *provider) { struct vpn_data *data = vpn_provider_get_data(provider); struct vpn_driver_data *vpn_driver_data; + const struct vpn_driver *vpn_driver = NULL; const char *name; struct ifreq ifr; int fd, err; @@ -87,16 +88,19 @@ static int stop_vpn(struct vpn_provider *provider) return -EINVAL; vpn_driver_data = g_hash_table_lookup(driver_hash, name); + if (vpn_driver_data) + vpn_driver = vpn_driver_data->vpn_driver; - if (vpn_driver_data && vpn_driver_data->vpn_driver && - vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_TUN) { + if (vpn_driver && vpn_driver->flags & VPN_FLAG_NO_TUN) { /* * Disconnect only VPNs with daemon, otherwise in error return * there is a double free with vpn_died() or the failure state * is overridden by changes made by disconnect to state. */ - if (!(vpn_driver_data->vpn_driver->flags & VPN_FLAG_NO_DAEMON)) - vpn_driver_data->vpn_driver->disconnect(data->provider); + if (!(vpn_driver->flags & VPN_FLAG_NO_DAEMON) && + vpn_driver->disconnect) + vpn_driver->disconnect(data->provider); + return 0; } From patchwork Fri Jan 24 18:59:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949844 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94ECD2248B9 for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=S+jHAtG1dKrkE2LcTPkOEX1N9FNTN+Ds1tBXLXoO2sAWrrf5/xj5d55n+zrUxTFzBj7oPRthXyB4aDychJPvx0pfqdnpoohV/lkdCHRwnF7QMdSQkJTRGUV9bSXRS1r6E3MDrHizojLfWHU/gSGJMa4M1KdqFGSEewjV9o0nNzw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=kGg2qWt+ykTsG3RF9QbCzSciXkyqfLn8AudO9baa18o=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bhyNdfLNHAqEfILCTHP5+NW7pxL+Y3Zg+zzyLnWeCmYGLgNR96J9z45iaH8adtQX5DfHbk4GUqZyhT1cvasf1mDRFAE8CvopeBszz9CpisoI1nNedqSAOWEE2HQbE9ULH7KrYKvJS9dFLJpFpiiNNMMZSpfTuSRuQLo3MibLTRo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=mRVg9KbH; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="mRVg9KbH" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Jbk/YfV5SJ4dASxqwDMjByhbYPDOLHDLKsjpHTCKh1c=; b=mRVg9KbHUjGRezyEJ/N9peRM+m Ro/ga3q3mO7zFVMFqcqgiqd4IqZSNI+DVgkJwwrDNlNIUu0vvfoJpfvFagMwRg1ZXHzI5yBd8cvPe iCCL8k/l0j2UI4WWlu8cmeKUA2I8xGSFZB23Xh4wF2RqwvD5JMnD+HegBbDvOK44V+3QOF2ThIc+f mc9QkxrimZuF+cBLYigSJWR4Gr7ww/RxKQMztxg+bragN258cJNKrTes4NSzlhmQxEVlxWGR3oHhZ UtqMdmRN9lAcb9cOM2Zec6F5civvj4I/sy2t7pQkLKzhhdMT3PNRaCVFwrzn8eZHf7UUrHkNlX8h+ xeYv8NVg==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtr-006LTc-0J for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:27 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 11/12] vpn: Fix extracting of PrefixLength D-Bus value Date: Fri, 24 Jan 2025 20:59:15 +0200 Message-Id: <20250124185916.1546471-12-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false The PrefixLength value is stored as a DBUS_TYPE_BYTE, and is an unsigned char, thus should be read as such. This fixes crash when trying to read the value into a char*. --- plugins/vpn.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/vpn.c b/plugins/vpn.c index 42396d2a..332d8e83 100644 --- a/plugins/vpn.c +++ b/plugins/vpn.c @@ -412,8 +412,8 @@ static int extract_ip(DBusMessageIter *array, int family, dbus_message_iter_get_basic(&value, &netmask); DBG("netmask %s", netmask); } else if (g_str_equal(key, "PrefixLength")) { - dbus_message_iter_get_basic(&value, &netmask); - DBG("prefix length %s", netmask); + dbus_message_iter_get_basic(&value, &prefix_len); + DBG("prefix length %u", prefix_len); } else if (g_str_equal(key, "Peer")) { dbus_message_iter_get_basic(&value, &peer); DBG("peer %s", peer); @@ -436,7 +436,6 @@ static int extract_ip(DBusMessageIter *array, int family, gateway); break; case AF_INET6: - prefix_len = atoi(netmask); connman_ipaddress_set_ipv6(data->ip, address, prefix_len, gateway); break; From patchwork Fri Jan 24 18:59:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Laakkonen X-Patchwork-Id: 13949845 Received: from mail.kapsi.fi (mail-auth.kapsi.fi [91.232.154.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E8902248BA for ; Fri, 24 Jan 2025 18:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.232.154.24 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; cv=none; b=b3W0/6WVd9woHe09GMbh1VSlcoln/WQSMvQQicx2BFibQl6h/NX2bQ76xvyxyPjUXx01AGRZIWJ68rYB5kfJ0qDH7051SlvMYHYcT76kljcxJt4QE6rslozoqoWC+gt2JxhF4SvPf3SZcS80p3hUL3rkWivZJ3vGmksCnUNlIT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737745172; c=relaxed/simple; bh=h4f47qvxj66aiSbRd0LrXsVrSiFb8ZIChsz178gmrsU=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DAOfgza5O/UH4At4nbZUot9m689IBkdQBn1Vs94p2oxvbaSfifLzOGCEcQgnN/Vb7Pug7vILAKSbRBVm1UiH9t6C3VPk6qkkEcQ0UON+Ev5m71ehI7XZaM0qT812uhHaxvx6zP91n/N282k3j4JqEYylPhDShNewrSg2ZPyNsPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com; spf=pass smtp.mailfrom=kapsi.fi; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b=GYfGrzpa; arc=none smtp.client-ip=91.232.154.24 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=jolla.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kapsi.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="GYfGrzpa" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=IMVf7t9XK6FVY0qRTEmZvst0spMdPyYwKxMOqUy7AD4=; b=GYfGrzpaPV0Kedv4I0mHOh0/tl utDHXYpVR8Wlwt//WcGiZCWLHabsTmK50hsQgOLcqcKcjEc+B22PGPwVfF7Dnvh0lUbE8Qff8Qovw IkqrBrK1xbPlZn3rSLnHh5XGOFpU5dgb71DpAHk4uaoGiiN7hbUb0lyqx5MGk7idhQiliyihLhurw NK9cpdA7jXtGKYENrjnkXJQjUi1Q/v4QubWZdHj3ejL8b+WjeE7ekhL2BcUN7Y0JHQtEFZLiARpmD dYkD9lUoschxBHyljw1+8TqtKk7jAL0jIsFz+VX9fgUaQX7MVF09xJ9/R/3t6imUZuWwOOR4IbT4u j5pKrHDA==; Received: from [2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9] (helo=jl-x230.local) by mail.kapsi.fi with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tbOtr-006LTc-0T for connman@lists.linux.dev; Fri, 24 Jan 2025 20:59:27 +0200 From: Jussi Laakkonen To: connman@lists.linux.dev Subject: [PATCH 12/12] wireguard: Tokenize host for getaddrinfo() Date: Fri, 24 Jan 2025 20:59:16 +0200 Message-Id: <20250124185916.1546471-13-jussi.laakkonen@jolla.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> References: <20250124185916.1546471-1-jussi.laakkonen@jolla.com> Precedence: bulk X-Mailing-List: connman@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a10:a5c0:2c1:9f00:b95c:6569:8d10:e7e9 X-SA-Exim-Mail-From: jussi.laakkonen@jolla.com X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false The host parameter contains the address and netmask in CIDR notation with IPv6 to define also the PrefixLength to be used in D-Bus for connmand. getaddrinfo() relies inet_pton() that does not work with the notation so tokenize host before passing it to getaddrinfo(). --- vpn/plugins/wireguard.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/vpn/plugins/wireguard.c b/vpn/plugins/wireguard.c index 307b3b37..549969c7 100644 --- a/vpn/plugins/wireguard.c +++ b/vpn/plugins/wireguard.c @@ -187,8 +187,25 @@ static int parse_endpoint(const char *host, const char *port, struct sockaddr_u { struct addrinfo hints; struct addrinfo *result, *rp; + char **tokens; int sk; int err; + unsigned int len; + + /* + * getaddrinfo() relies on inet_pton() that suggests using addresses + * without CIDR notation. Host should contain the address in CIDR + * notation to be able to pass the prefix length to ConnMan via D-Bus. + */ + tokens = g_strsplit(host, "/", -1); + len = g_strv_length(tokens); + if (len > 2 || len < 1) { + DBG("Failure tokenizing host %s", host); + g_strfreev(tokens); + return -EINVAL; + } + + DBG("using host %s", tokens[0]); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; @@ -196,7 +213,9 @@ static int parse_endpoint(const char *host, const char *port, struct sockaddr_u hints.ai_flags = 0; hints.ai_protocol = 0; - err = getaddrinfo(host, port, &hints, &result); + err = getaddrinfo(tokens[0], port, &hints, &result); + g_strfreev(tokens); + if (err < 0) { DBG("Failed to resolve host address: %s", gai_strerror(err)); return -EINVAL;