From patchwork Fri Jul 25 17:27:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4327 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:3644:b0:671:5a2c:6455 with SMTP id a4csp1641773mai; Fri, 25 Jul 2025 10:27:28 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWNMRYWXldrYi6B9wK1Q5xKmAHoVRyMWgthN1Huuut9+XhpDdzYsqndnUJEWWDWulBUEyFKQHtNdeY=@openvpn.net X-Google-Smtp-Source: AGHT+IGWOI1yvP7qAEovY8qVhH+H0Jtf2VscYrelMZI+N2DYBC09CizOMyZ+pYIMHZ/lVgo4u+P0 X-Received: by 2002:a05:6870:3b0a:b0:2bd:455e:c22e with SMTP id 586e51a60fabf-30701b1329dmr1937910fac.19.1753464447836; Fri, 25 Jul 2025 10:27:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1753464447; cv=none; d=google.com; s=arc-20240605; b=eI8G0I0YNMizHEfvPcU8ZmZ/feoXi0vLODdau8gBlFS18bAb72PHy8bNDAxO+HLL7L lbgvO48fhl+gIYS+z39dzEZERF220bcZ1rj9lgw6k9vDE+KeSd30XpdlksSPsvLf1z+H c5X1qBDW6FYfqjz0krK8LWyHnlrWm25LgMFhuTy+zvBzel0iZLLOBP49HTrH+0jtKymS 9IcvZNpRXE/sEZ6UKefmk6R2OqVj15FAbtlfb55qzkF5AvzALA3rvGErMBFiZ8N4zqAh kq+Jk82SNvuA1/2A3ZqFm5td8JM1aAv5ybxhpiLJQ7qokJvKsc9MtkEdWtQ6ybPjdKtv 0GoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=fWiTl6NgzbfOlMFfAD4o6EnKKDFWPtQp+OAMLRBSPaA=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=IrzvtaoEqkKUZO9UZ+jh6LFFAiaCfU5w6PZh+Xg9+3hN0vFJ9CtKbnfVJoffUhXiIz eAV/6HgDygUH02n+amo35QUoS7LN1JGrXVJAZhLmq+yDy0TZkoSPKcAZ9nW5HN+vIluI LAhhjhSHv8QodUGoGA7u6hxzFMAcyvYj84iQoOLqdaQOnZqpbhCwU0pgTbFnsCzesHSy IfOEcBJRkEF++rU5Tb/ZjiBD4z905KoIDs5f4q0QCn4Ldh/g9kNyHxPCmF3AfKenjr9A Nj++vjI1aGPRDkbuSHJfy61FxlvVlN8t2g0+HyNhx9ME44Reb7XJQYMUu0jw97UWCKNp Bc3Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DURRcmBe; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=BimmRtVt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ZswJ4iwL; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 586e51a60fabf-307133bb67bsi95403fac.126.2025.07.25.10.27.27 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jul 2025 10:27:27 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DURRcmBe; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=BimmRtVt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ZswJ4iwL; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fWiTl6NgzbfOlMFfAD4o6EnKKDFWPtQp+OAMLRBSPaA=; b=DURRcmBeZYGVHgGt9Rbd/VOa7E WMz+j5W61ymMSfpmnBZ+jC/yEUIEw3JTiugC1FGBaP5jcIdC28hST9BT3wZX6zHFOJ6pAeHW0qPyM jde0ZcVJ/QEHbrQuAw33T5CC0ji2TLInI5GSjhyr7FY0KgJuSndGFiJxsbyHdSuexUII=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1ufMCZ-0004CH-EN; Fri, 25 Jul 2025 17:27:23 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1ufMCY-0004C8-4S for openvpn-devel@lists.sourceforge.net; Fri, 25 Jul 2025 17:27:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; 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=sE5JkjuD9yg82O/URkiSKXSAIHrUvGU8xhPxPpKHAmU=; b=BimmRtVtSurO9ormeB2E3mjjU6 mj3awHMiF3Y9ZWI/FuC4bLeHkh2HFACZ6RzzBGwfBKf+qRizIiOtLwP2x0VAOBFVIOt5IPvlL6nG5 H72X8ZdOEEwUv5+edopAfkzeuVRJCnD0K2Lsl9BukMQwZaY2j96esZr5kl9bsONLT0IM=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; 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=sE5JkjuD9yg82O/URkiSKXSAIHrUvGU8xhPxPpKHAmU=; b=ZswJ4iwLlN1C2ndogkAWS5T3gk HR0pwYjS4Hr+TmtyizCkrhgkcN/XGMoa2TGr9qCnzcPssTBLW0DNVCjb3TvKnaNXUnqKWYFFc20Qs RIWfPNudWsC0LgkUFCu/jpKLYKEdkUDDllckxCZV19/kHMyp7mQ2EtxKBCWxh37+izIo=; Received: from [193.149.48.143] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1ufMCW-0004qX-Ny for openvpn-devel@lists.sourceforge.net; Fri, 25 Jul 2025 17:27:22 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 56PHR9JQ019480 for ; Fri, 25 Jul 2025 19:27:09 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 56PHR9Rg019477 for openvpn-devel@lists.sourceforge.net; Fri, 25 Jul 2025 19:27:09 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Fri, 25 Jul 2025 19:27:02 +0200 Message-ID: <20250725172708.19456-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Antonio Quartulli Currently whenever we send a PEER_GET request to ovpn, we also set the CB that is supposed to parse the reply. However, due to the async nature of netlink messages, we could get an unrelated notification, sent by ovpn upon some event, after having set the CB, but before parsing the awaited reply. Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1ufMCW-0004qX-Ny Subject: [Openvpn-devel] [PATCH v5] dco_linux: fix async message reception X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1838640736809917820?= X-GMAIL-MSGID: =?utf-8?q?1838640736809917820?= From: Antonio Quartulli Currently whenever we send a PEER_GET request to ovpn, we also set the CB that is supposed to parse the reply. However, due to the async nature of netlink messages, we could get an unrelated notification, sent by ovpn upon some event, after having set the CB, but before parsing the awaited reply. When this happens, the notification is then parsed with the configured CB instead of the notification parser, thus effectively rejecting the notification and losing the event. To fix this inconsistency, make ovpn_handle_msg() the default and only netlink parser CB. It is configured upon DCO initialization and is never removed. ovpn_handle_msg() will check the message type and will call the according parser. This way, no matter what message we get at what time, but we'll always parse it correctly. As a bonus we can also simplify the nl_sendmsg() API as we don't need to pass the cb and its argument anymore. The ID of the NLCTRL family is now also stored in the DCO context as we need it to check when we receive a mcast ID lookup message. Change-Id: I23ad79e14844aefde9ece34dadef0b75ff267201 Github: OpenVPN/openvpn#793 Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1100 This mail reflects revision 5 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c index 7c639d9..728fb7e 100644 --- a/src/openvpn/dco_linux.c +++ b/src/openvpn/dco_linux.c @@ -167,23 +167,19 @@ } /** - * Send a prepared netlink message and registers cb as callback if non-null. + * Send a prepared netlink message. * * The method will also free nl_msg * @param dco The dco context to use * @param nl_msg the message to use - * @param cb An optional callback if the caller expects an answer - * @param cb_arg An optional param to pass to the callback * @param prefix A prefix to report in the error message to give the user context * @return status of sending the message */ static int -ovpn_nl_msg_send(dco_context_t *dco, struct nl_msg *nl_msg, ovpn_nl_cb cb, - void *cb_arg, const char *prefix) +ovpn_nl_msg_send(dco_context_t *dco, struct nl_msg *nl_msg, const char *prefix) { dco->status = 1; - nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, cb, cb_arg); nl_send_auto(dco->nl_sock, nl_msg); while (dco->status == 1) @@ -285,7 +281,7 @@ } nla_nest_end(nl_msg, attr); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -385,6 +381,29 @@ } static void +ovpn_dco_register(dco_context_t *dco) +{ + msg(D_DCO_DEBUG, __func__); + ovpn_get_mcast_id(dco); + + if (dco->ovpn_dco_mcast_id < 0) + { + msg(M_FATAL, "cannot get mcast group: %s", nl_geterror(dco->ovpn_dco_mcast_id)); + } + + /* Register for ovpn-dco specific multicast messages that the kernel may + * send + */ + int ret = nl_socket_add_membership(dco->nl_sock, dco->ovpn_dco_mcast_id); + if (ret) + { + msg(M_FATAL, "%s: failed to join groups: %d", __func__, ret); + } +} + +static int ovpn_handle_msg(struct nl_msg *msg, void *arg); + +static void ovpn_dco_init_netlink(dco_context_t *dco) { dco->ovpn_dco_id = resolve_ovpn_netlink_id(M_FATAL); @@ -420,11 +439,15 @@ nl_socket_set_cb(dco->nl_sock, dco->nl_cb); + dco->dco_message_peer_id = -1; nl_cb_err(dco->nl_cb, NL_CB_CUSTOM, ovpn_nl_cb_error, &dco->status); nl_cb_set(dco->nl_cb, NL_CB_FINISH, NL_CB_CUSTOM, ovpn_nl_cb_finish, &dco->status); nl_cb_set(dco->nl_cb, NL_CB_ACK, NL_CB_CUSTOM, ovpn_nl_cb_finish, &dco->status); + nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, ovpn_handle_msg, dco); + + ovpn_dco_register(dco); /* The async PACKET messages confuse libnl and it will drop them with * wrong sequence numbers (NLE_SEQ_MISMATCH), so disable libnl's sequence @@ -476,27 +499,6 @@ CLEAR(dco); } -static void -ovpn_dco_register(dco_context_t *dco) -{ - msg(D_DCO_DEBUG, __func__); - ovpn_get_mcast_id(dco); - - if (dco->ovpn_dco_mcast_id < 0) - { - msg(M_FATAL, "cannot get mcast group: %s", nl_geterror(dco->ovpn_dco_mcast_id)); - } - - /* Register for ovpn-dco specific multicast messages that the kernel may - * send - */ - int ret = nl_socket_add_membership(dco->nl_sock, dco->ovpn_dco_mcast_id); - if (ret) - { - msg(M_FATAL, "%s: failed to join groups: %d", __func__, ret); - } -} - int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev) { @@ -516,10 +518,6 @@ msg(M_FATAL, "DCO: cannot retrieve ifindex for interface %s", dev); } - tt->dco.dco_message_peer_id = -1; - - ovpn_dco_register(&tt->dco); - return 0; } @@ -548,7 +546,7 @@ NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_PEER_ID, peerid); nla_nest_end(nl_msg, attr); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -572,7 +570,7 @@ NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peerid); nla_nest_end(nl_msg, attr); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -598,7 +596,7 @@ NLA_PUT_U32(nl_msg, OVPN_A_KEYCONF_SLOT, slot); nla_nest_end(nl_msg, keyconf); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -657,7 +655,7 @@ nla_nest_end(nl_msg, key_conf); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -686,7 +684,7 @@ keepalive_timeout); nla_nest_end(nl_msg, attr); - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -754,7 +752,7 @@ /* Even though 'nlctrl' is a constant, there seem to be no library * provided define for it */ - int ctrlid = genl_ctrl_resolve(dco->nl_sock, "nlctrl"); + dco->ctrlid = genl_ctrl_resolve(dco->nl_sock, "nlctrl"); struct nl_msg *nl_msg = nlmsg_alloc(); if (!nl_msg) @@ -762,12 +760,12 @@ return -ENOMEM; } - genlmsg_put(nl_msg, 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0); + genlmsg_put(nl_msg, 0, 0, dco->ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0); int ret = -EMSGSIZE; NLA_PUT_STRING(nl_msg, CTRL_ATTR_FAMILY_NAME, OVPN_FAMILY_NAME); - ret = ovpn_nl_msg_send(dco, nl_msg, mcast_family_handler, dco, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); @@ -879,31 +877,34 @@ } static int -dco_parse_peer_multi(struct nl_msg *msg, void *arg) +ovpn_handle_peer_multi(dco_context_t *dco, struct nlattr *attrs[]) { - struct nlattr *tb[OVPN_A_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - msg(D_DCO_DEBUG, "%s: parsing message...", __func__); - nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); + /* this function assumes openvpn is running in multipeer mode as + * it accesses c->multi + */ + if (dco->ifmode != OVPN_MODE_MP) + { + msg(M_WARN, "%s: can't parse 'multi-peer' message on P2P instance", __func__); + return NL_SKIP; + } - if (!tb[OVPN_A_PEER]) + if (!attrs[OVPN_A_PEER]) { return NL_SKIP; } struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1]; - nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL); + nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], NULL); if (!tb_peer[OVPN_A_PEER_ID]) { - msg(M_WARN, "%s: no peer-id provided in reply", __func__); + msg(M_WARN, "ovpn-dco: no peer-id provided in (MULTI) PEER_GET reply"); return NL_SKIP; } - struct multi_context *m = arg; + struct multi_context *m = dco->c->multi; uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]); if (peer_id >= m->max_clients || !m->instances[peer_id]) @@ -919,39 +920,53 @@ } static int -dco_parse_peer(struct nl_msg *msg, void *arg) +ovpn_handle_peer(dco_context_t *dco, struct nlattr *attrs[]) { - struct context *c = arg; - struct nlattr *tb[OVPN_A_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - msg(D_DCO_DEBUG, "%s: parsing message...", __func__); - nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (!tb[OVPN_A_PEER]) + if (!attrs[OVPN_A_PEER]) { msg(D_DCO_DEBUG, "%s: malformed reply", __func__); return NL_SKIP; } struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1]; - nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL); + nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], NULL); if (!tb_peer[OVPN_A_PEER_ID]) { - msg(M_WARN, "%s: no peer-id provided in reply", __func__); + msg(M_WARN, "ovpn-dco: no peer-id provided in PEER_GET reply"); return NL_SKIP; } uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]); - if (c->c2.tls_multi->dco_peer_id != peer_id) + struct context_2 *c2; + + if (dco->ifmode == OVPN_MODE_P2P) + { + c2 = &dco->c->c2; + } + else + { + struct multi_instance *mi = dco->c->multi->instances[peer_id]; + if (!mi) + { + msg(M_WARN, "%s: received data for a non-existing peer %u", __func__, peer_id); + return NL_SKIP; + } + + c2 = &mi->context.c2; + } + + /* at this point this check should never fail for MP mode, + * but it's still fully valid for P2P mode + */ + if (c2->tls_multi->dco_peer_id != peer_id) { return NL_SKIP; } - dco_update_peer_stat(&c->c2, tb_peer, peer_id); + dco_update_peer_stat(c2, tb_peer, peer_id); return NL_OK; } @@ -1120,9 +1135,22 @@ { dco_context_t *dco = arg; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct nlattr *attrs[OVPN_A_MAX + 1]; struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct genlmsghdr *gnlh = genlmsg_hdr(nlh); + + msg(D_DCO_DEBUG, "ovpn-dco: received netlink message type=%u cmd=%u flags=%#.4x", + nlh->nlmsg_type, gnlh->cmd, nlh->nlmsg_flags); + + /* if we get a message from the NLCTRL family, it means + * this is the reply to the mcast ID resolution request + * and we parse it accordingly. + */ + if (nlh->nlmsg_type == dco->ctrlid) + { + msg(D_DCO_DEBUG, "ovpn-dco: received CTRLID message"); + return mcast_family_handler(msg, dco); + } if (!genlmsg_valid_hdr(nlh, 0)) { @@ -1146,6 +1174,21 @@ */ switch (gnlh->cmd) { + case OVPN_CMD_PEER_GET: + { + /* this message is part of a peer list dump, hence triggered + * by a MP/server instance + */ + if (nlh->nlmsg_flags & NLM_F_MULTI) + { + return ovpn_handle_peer_multi(dco, attrs); + } + else + { + return ovpn_handle_peer(dco, attrs); + } + } + case OVPN_CMD_PEER_DEL_NTF: { return ovpn_handle_peer_del_ntf(dco, attrs); @@ -1174,7 +1217,6 @@ dco_do_read(dco_context_t *dco) { msg(D_DCO_DEBUG, __func__); - nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, ovpn_handle_msg, dco); return ovpn_nl_recvmsgs(dco, __func__); } @@ -1189,7 +1231,7 @@ nlmsg_hdr(nl_msg)->nlmsg_flags |= NLM_F_DUMP; - int ret = ovpn_nl_msg_send(dco, nl_msg, dco_parse_peer_multi, m, __func__); + int ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nlmsg_free(nl_msg); @@ -1227,7 +1269,7 @@ NLA_PUT_U32(nl_msg, OVPN_A_PEER_ID, peer_id); nla_nest_end(nl_msg, attr); - ret = ovpn_nl_msg_send(dco, nl_msg, dco_parse_peer, c, __func__); + ret = ovpn_nl_msg_send(dco, nl_msg, __func__); nla_put_failure: nlmsg_free(nl_msg); diff --git a/src/openvpn/dco_linux.h b/src/openvpn/dco_linux.h index 5e61cf1..cc14f45 100644 --- a/src/openvpn/dco_linux.h +++ b/src/openvpn/dco_linux.h @@ -66,6 +66,7 @@ int status; struct context *c; + int ctrlid; enum ovpn_mode ifmode;