From patchwork Wed Nov 15 13:45:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3444 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7300:3c06:b0:f2:62eb:61c1 with SMTP id e6csp2926302dys; Wed, 15 Nov 2023 05:46:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IGGU5SWrCI9FLDNIAHFBKwCPp9H6f6omIdR5J42ABq8wFFDfMFXO8l2NAZrtWMNResg05uK X-Received: by 2002:a17:90a:a412:b0:274:60c7:e15a with SMTP id y18-20020a17090aa41200b0027460c7e15amr2902771pjp.4.1700055977159; Wed, 15 Nov 2023 05:46:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700055977; cv=none; d=google.com; s=arc-20160816; b=InO9O48Icy9JxIouSAqfpv5Qz9KWzCHnpJ8q7mhE71DUzZ2JpdKtwjiMs0ZWhMQTPQ zv0PjHzUogQW/rsBx9KmaQnYSzvxIus3VN5hgeUxJPP/wpLlqZUjRNtKmcmYmaBidH7k GHTBmet+H2MK3p2uLmwLvIUR61dG0sUaQv1HSof8QVs7kkZDqMF9IxafLO6qkuLBosvE AeGjU20RtNouTfVVlDWHnTKN7KNf0YGd2j0Oi3Z5x60QAgFk51FkDFIe8aTyUyQ4Rtt6 rKBEFw2OcZrK+0f4NKg4N22YWzkBYdGL8MxrLZZNvIytyknofuLMmsnLgvDw+EbvKg1j CJWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=MsF7H4XhNwrXRBf24hbQSE/Zkvj92p+tAdyPaQW3pKw=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=myqtwJ12PF2RgnQiqv3m8+sIEm+NdJME+roOl3AzDK52ltio83kzj1cL5nQ5KYz3Vv 8C+jEreqSlH6m4rvxUD6v7YogIpuEjm7vPTL+KRttUsq/osvYNTFE6cwGOC+eyolkxse jQIR/z5PCPjfBmv8v1qM4XuHq2HaGDbG7vyBHa3dysNKp/XlbLLYAdzC4l0Ff8B6vK1k PH/I0fVdgpp8jAj47Qw2lQIk2XmdzByvL6+kor7vvqzn4gVmWICRC5d/EiSJjvsLOSIm uwzWwkHyzlPva9G0Tp+2eXH+tMPDS+jeOSa710qQKxQVqS7Qh/SP71QmhO/62PDaXLPj oHeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=kVUh7Pi4; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=e5zJeHBH; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=bw8sGr1f; 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=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id a12-20020a17090abe0c00b00282ec3a397esi14450664pjs.82.2023.11.15.05.46.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Nov 2023 05:46:17 -0800 (PST) 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=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=kVUh7Pi4; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=e5zJeHBH; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=bw8sGr1f; 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=openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1r3GCw-0008Iw-1N; Wed, 15 Nov 2023 13:45:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1r3GCt-0008IV-PU for openvpn-devel@lists.sourceforge.net; Wed, 15 Nov 2023 13:45:26 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=vG1A839yqpTeCrJDA3Tch1XEs15ByNeb0lqQvodiqEQ=; b=kVUh7Pi49j9COqeuZHIBAhzKw8 iCjNY9NjbiZq0VKzvJd6k3d3qIlBRnea2o/h3jqrWxVFpDGbpli/IW7ZYy45hpnitIofxaZ9oB6WD BFbkI5OUgCJMwVb6mtjwVJKx31tcHKEFm1An11XDLUZMxwxx5Ksd02kjeNcBsIqEkX28=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=vG1A839yqpTeCrJDA3Tch1XEs15ByNeb0lqQvodiqEQ=; b=e 5zJeHBHR0ZQV0kL7KETN5OAqQeEw9uLYqYViqv21LVJfR86YChG+jHzj7SPEge41G07A843Nu9TYw XBt4tn28VLR5/qPioGIb5/TQ44ebjeKDAP+3pkN3MhPFS/y5Pr1qjKaTklQ9MttK25CFHBCB1gNvx Lv8XozyZXXEqCVtc=; Received: from mail-wm1-f47.google.com ([209.85.128.47]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1r3GCn-006Vpb-2B for openvpn-devel@lists.sourceforge.net; Wed, 15 Nov 2023 13:45:26 +0000 Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4083f61312eso56058415e9.3 for ; Wed, 15 Nov 2023 05:45:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1700055914; x=1700660714; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=vG1A839yqpTeCrJDA3Tch1XEs15ByNeb0lqQvodiqEQ=; b=bw8sGr1f/PMWe9RRU22OS1Neuk9o8iszyeuk1ZNIIxREVfCutrKsbR3EKLiu9kRAgr mjwQZGoJ6L+47AwUPkIHQOCkRahy+TpEvhxYTcN3Q0Xz67dUa+WXuU+SwsOb0k49UHVE 75hP2dR7OJ64elJvLzQRbEQHGOADo5fBXqiIJRhWM48z7fv5Cu271/q91ERoI7R6U/Bv 9kO313v3IiUDDLkKIFvF/D9zbq8eedNPckEMcucC1X0BYaTsy73XGZjI8OvfkBgtrkHE eUflIyqLR/fDCgPCtTF+xAkAWJ7BPXcxnSC56quuwyKhv55qPL5uBiR6SDDK76dmSQ7q mT9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700055914; x=1700660714; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vG1A839yqpTeCrJDA3Tch1XEs15ByNeb0lqQvodiqEQ=; b=aZv2Ft69cTKkLqqnbNBBOtvOQ/UIE8k6u2gBzEQULmZXM+HTNcvwEo78Qe79MnL7BV W6CRqPxKS0v3VSP+FPQdBqnY6BQfT+k3Fo0wBkTKzIaBFRYasGud2AWe72megA5HOjuf R3WB+rtymO9G5H71a4rpUWUiUbh65iZ1DnxWLTeesCkgacc3Mv5ta2X+C5EApPZyvrtH EReVkK+KrnJl9ZD/gn5IactYutqOIHfdrvhA4pk9rSSxHVqG4a7rG/9gn5d0hH4PSKXD GreLQTXQ9/dF23599fksrUFdEokBm8VXVbYneviuQLeEYMKFB0lRlgMIKkIMTwp6W1jP JRkA== X-Gm-Message-State: AOJu0YxorrdaJsy6L3z+0TbN/wazkWSYIKjJ84HtkLB9M4HfGx/LqZoF IfVHWgddfuBFBaRVOcAsJ/sfuQ== X-Received: by 2002:a05:600c:1d19:b0:40a:4c7e:6f3e with SMTP id l25-20020a05600c1d1900b0040a4c7e6f3emr9754623wms.21.1700055914478; Wed, 15 Nov 2023 05:45:14 -0800 (PST) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id z12-20020a1c4c0c000000b003fe61c33df5sm20568249wmf.3.2023.11.15.05.45.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Nov 2023 05:45:14 -0800 (PST) From: "ordex (Code Review)" X-Google-Original-From: "ordex (Code Review)" X-Gerrit-PatchSet: 1 Date: Wed, 15 Nov 2023 13:45:13 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I4d1c96662c5a8c750d883e3b20adde09529e2764 X-Gerrit-Change-Number: 436 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 92ee48216639376305fe3460656089c9f3938024 References: Message-ID: <13d3eb64cbd8db5e2a30be372713eb8710bfa4ea-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", 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: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.47 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.47 listed in wl.mailspike.net] 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 T_SCC_BODY_TEXT_LINE No description available. 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML X-Headers-End: 1r3GCn-006Vpb-2B Subject: [Openvpn-devel] [M] Change in openvpn[master]: allow user to specify 'local' multiple times in config files 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: , Reply-To: a@unstable.cc, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1782637896138038790?= X-GMAIL-MSGID: =?utf-8?q?1782637896138038790?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/436?usp=email to review the following change. Change subject: allow user to specify 'local' multiple times in config files ...................................................................... allow user to specify 'local' multiple times in config files It is now possible to specify 'local' multiple times in a server config to let it listen on multiple sockets (address:port) of the same protocol. Change-Id: I4d1c96662c5a8c750d883e3b20adde09529e2764 Signed-off-by: Antonio Quartulli --- M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/socket.c 4 files changed, 171 insertions(+), 39 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/36/436/1 diff --git a/src/openvpn/init.c b/src/openvpn/init.c index f8dd01f..659c9e3 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -745,7 +745,7 @@ init_connection_list(c); - c->c1.link_sockets_num = 1; + c->c1.link_sockets_num = c->options.ce.local_list->len; do_link_socket_addr_new(c); @@ -3821,8 +3821,8 @@ /* init each socket with its specific port */ link_socket_init_phase1(c->c2.link_sockets[i], - c->options.ce.local, - c->options.ce.local_port, + c->options.ce.local_list->array[i]->local, + c->options.ce.local_list->array[i]->port, c->options.ce.remote, c->options.ce.remote_port, c->c1.dns_cache, @@ -3836,7 +3836,7 @@ #ifdef ENABLE_DEBUG c->options.gremlin, #endif - c->options.ce.bind_local, + c->options.ce.local_list->array[i]->bind_local, c->options.ce.remote_float, &c->c1.link_socket_addrs[i], c->options.ipchange, @@ -4978,6 +4978,7 @@ if (dest->mode == CM_CHILD_UDP) { ASSERT(!dest->c2.link_sockets); + ASSERT(dest->options.ce.local_list); /* inherit buffers */ dest->c2.buffers = src->c2.buffers; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index b88fea9..9611423 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -124,7 +124,13 @@ "--version : Show copyright and version information.\n" "\n" "Tunnel Options:\n" - "--local host : Local host name or ip address. Implies --bind.\n" + "--local host|* [port] : Local host name or ip address and port. '*' can be used\n" + " as hostname and means 'any host' (openvpn will listen on\n" + " what is returned by the OS). Implies --bind.\n" + " 0.0.0.0 or :: can be used to specifically open a socket\n" + " listening on any IPv4 or IPv6 address respectively.\n" + " The user can specify multiple --local entries to have\n" + " a server listen on multiple sockets at the same time.\n" "--remote host [port] : Remote host name or ip address.\n" "--remote-random : If multiple --remote options specified, choose one randomly.\n" "--remote-random-hostname : Add a random string to remote DNS name.\n" @@ -982,8 +988,9 @@ const int i) { setenv_str_i(es, "proto", proto2ascii(e->proto, e->af, false), i); - setenv_str_i(es, "local", e->local, i); - setenv_str_i(es, "local_port", e->local_port, i); + /* expected to befor single socket contexts only */ + setenv_str_i(es, "local", e->local_list->array[0]->local, i); + setenv_str_i(es, "local_port", e->local_list->array[0]->port, i); setenv_str_i(es, "remote", e->remote, i); setenv_str_i(es, "remote_port", e->remote_port, i); @@ -1701,8 +1708,12 @@ show_connection_entry(const struct connection_entry *o) { msg(D_SHOW_PARMS, " proto = %s", proto2ascii(o->proto, o->af, false)); - SHOW_STR(local); - SHOW_STR(local_port); + msg(D_SHOW_PARMS, " Local Sockets:"); + for (int i = 0; i < o->local_list->len; i++) + { + msg(D_SHOW_PARMS, " [%s]:%s", o->local_list->array[i]->local, + o->local_list->array[i]->port); + } SHOW_STR(remote); SHOW_STR(remote_port); SHOW_BOOL(remote_float); @@ -2151,6 +2162,37 @@ #endif /* ifdef ENABLE_MANAGEMENT */ +static struct local_list * +alloc_local_list_if_undef(struct connection_entry *ce, struct gc_arena *gc) +{ + if (!ce->local_list) + { + ALLOC_OBJ_CLEAR_GC(ce->local_list, struct local_list, gc); + } + return ce->local_list; +} + +static struct local_entry * +alloc_local_entry(struct connection_entry *ce, const int msglevel, + struct gc_arena *gc) +{ + struct local_list *l = alloc_local_list_if_undef(ce, gc); + struct local_entry *e; + + if (l->len >= CONNECTION_LIST_SIZE) + { + msg(msglevel, "Maximum number of 'local' options (%d) exceeded", + CONNECTION_LIST_SIZE); + + return NULL; + } + + ALLOC_OBJ_CLEAR_GC(e, struct local_entry, gc); + l->array[l->len++] = e; + + return e; +} + static struct connection_list * alloc_connection_list_if_undef(struct options *options) { @@ -2343,6 +2385,15 @@ "--proto tcp-server or --proto tcp-client"); } + /* + * Sanity check on daemon mode + */ + + if (ce->remote && ce->local_list->len > 1) + { + msg(M_USAGE, "multiple --local do not make sense in Client mode"); + } + if (options->lladdr && dev != DEV_TYPE_TAP) { msg(M_USAGE, "--lladdr can only be used in --dev tap mode"); @@ -2368,13 +2419,6 @@ * Sanity check on --local, --remote, and --ifconfig */ - if (proto_is_net(ce->proto) - && string_defined_equal(ce->local, ce->remote) - && string_defined_equal(ce->local_port, ce->remote_port)) - { - msg(M_USAGE, "--remote and --local addresses are the same"); - } - if (string_defined_equal(ce->remote, options->ifconfig_local) || string_defined_equal(ce->remote, options->ifconfig_remote_netmask)) { @@ -2383,13 +2427,6 @@ "addresses"); } - if (string_defined_equal(ce->local, options->ifconfig_local) - || string_defined_equal(ce->local, options->ifconfig_remote_netmask)) - { - msg(M_USAGE, - "--local addresses must be distinct from --ifconfig addresses"); - } - if (string_defined_equal(options->ifconfig_local, options->ifconfig_remote_netmask)) { @@ -2402,12 +2439,6 @@ msg(M_USAGE, "--bind and --nobind can't be used together"); } - if (ce->local && !ce->bind_local) - { - msg(M_USAGE, - "--local and --nobind don't make sense when used together"); - } - if (ce->local_port_defined && !ce->bind_local) { msg(M_USAGE, @@ -2419,6 +2450,29 @@ msg(M_USAGE, "--nobind doesn't make sense unless used with --remote"); } + for (int i = 0; i < ce->local_list->len; i++) + { + struct local_entry *le = ce->local_list->array[i]; + + if (proto_is_net(ce->proto) + && string_defined_equal(le->local, ce->remote) + && string_defined_equal(le->port, ce->remote_port)) + { + msg(M_USAGE, "--remote and a --local addresses are the same"); + } + + if (string_defined_equal(le->local, options->ifconfig_local) + || string_defined_equal(le->local, options->ifconfig_remote_netmask)) + { + msg(M_USAGE, "--local addresses must be distinct from --ifconfig addresses"); + } + + if (le->local && !ce->bind_local) + { + msg(M_USAGE, "--local and --nobind don't make sense when used together"); + } + } + /* * Check for consistency of management options */ @@ -3112,7 +3166,7 @@ } /* an option is present that requires local bind to enabled */ - bool need_bind = ce->local || ce->local_port_defined || ce->bind_defined; + bool need_bind = ce->local_port_defined || ce->bind_defined; /* socks proxy is enabled */ bool uses_socks = ce->proto == PROTO_UDP && ce->socks_proxy_server; @@ -3125,6 +3179,11 @@ ce->bind_local = false; } + if (ce->proto == PROTO_UDP && ce->socks_proxy_server && !ce->local_list && !ce->local_port_defined && !ce->bind_defined) + { + ce->bind_local = false; + } + if (!ce->bind_local) { ce->local_port = NULL; @@ -3245,6 +3304,16 @@ } } +static void +options_postprocess_mutate_le(struct options *o, struct local_entry *le) +{ + /* use the global port if none is specified */ + if (!le->port) + { + le->port = o->ce.local_port; + } +} + #ifdef _WIN32 /* If iservice is in use, we need def1 method for redirect-gateway */ static void @@ -3691,6 +3760,29 @@ options_postprocess_mutate_ce(o, o->connection_list->array[i]); } + if (o->ce.local_list) + { + for (i = 0; i < o->ce.local_list->len; i++) + { + options_postprocess_mutate_le(o, o->ce.local_list->array[i]); + } + } + else + { + /* if no 'local' directive was specified, convert the global port + * setting to a listen entry */ + struct local_entry *e = alloc_local_entry(&o->ce, M_USAGE, &o->gc); + ASSERT(e); + e->port = o->ce.local_port; + e->bind_local = o->ce.bind_local; + } + + /* use the same listen list for every outgoing connection */ + for (i = 0; i < o->connection_list->len; ++i) + { + o->connection_list->array[i]->local_list = o->ce.local_list; + } + if (o->tls_server) { /* Check that DH file is specified, or explicitly disabled */ @@ -6072,10 +6164,29 @@ VERIFY_PERMISSION(OPT_P_UP); options->ifconfig_nowarn = true; } - else if (streq(p[0], "local") && p[1] && !p[2]) + else if (streq(p[0], "local") && p[1] && !p[3]) { + struct local_entry *e; + VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); - options->ce.local = p[1]; + + e = alloc_local_entry(&options->ce, M_USAGE, &options->gc); + ASSERT(e); + + /* '*' is treated as 'ask the system to get some socket', + * therefore force binding on a particular address only when + * actually specified. */ + if (strcmp(p[1], "*") != 0) + { + e->local = p[1]; + e->bind_local = true; + } + + if (p[2]) + { + e->port = p[2]; + e->bind_local = true; + } } else if (streq(p[0], "remote-random") && !p[1]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 5a37316..747ed56 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -94,14 +94,21 @@ #error "At least one of OpenSSL or mbed TLS needs to be defined." #endif +struct local_entry +{ + const char *local; + const char *port; + bool bind_local; +}; + struct connection_entry { + struct local_list *local_list; int proto; sa_family_t af; const char *local_port; bool local_port_defined; const char *remote_port; - const char *local; const char *remote; bool remote_float; bool bind_defined; @@ -179,6 +186,12 @@ #define CONNECTION_LIST_SIZE 64 +struct local_list +{ + int len; + struct local_entry *array[CONNECTION_LIST_SIZE]; +}; + struct connection_list { int capacity; diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index 17bd263..5d9e111 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -342,7 +342,7 @@ void do_preresolve(struct context *c) { - int i; + int i, j; struct connection_list *l = c->options.connection_list; const unsigned int preresolve_flags = GETADDR_RESOLVE |GETADDR_UPDATE_MANAGEMENT_STATE @@ -416,12 +416,19 @@ } } - if (ce->bind_local) + flags |= GETADDR_PASSIVE; + flags &= ~GETADDR_RANDOMIZE; + + for (j = 0; j < ce->local_list->len; j++) { - flags |= GETADDR_PASSIVE; - flags &= ~GETADDR_RANDOMIZE; - status = do_preresolve_host(c, ce->local, ce->local_port, - ce->af, flags); + struct local_entry *le = ce->local_list->array[j]; + + if (!le->local) + { + continue; + } + + status = do_preresolve_host(c, le->local, le->port, ce->af, flags); if (status != 0) { goto err;