@@ -124,7 +124,17 @@ static const char usage_message[] =
124124 "--version : Show copyright and version information.\n"
125125 "\n"
126126 "Tunnel Options:\n"
127- "--local host : Local host name or ip address. Implies --bind.\n"
127+ "--local host|* [port]: Local host name or IP address and port for bind.\n"
128+ " If specified, OpenVPN will bindto this address. If unspecified,\n"
129+ " OpenVPN will bind to all interfaces. '*' can be used as hostname\n"
130+ " and means 'any host' (OpenVPN will listen on what is returned by the OS).\n"
131+ " On a client, or in point-to-point mode, this can only be specified once (1 socket).\n"
132+ " On an OpenVPN setup running as ``--server``, this can be specified multiple times\n"
133+ " to open multiple listening sockets on different addresses and/or different ports.\n"
134+ " In order to specify multiple listen ports without specifying an address, use '*'\n"
135+ " to signal 'use what the operating system gives you as default', for\n"
136+ " 'all IPv4 addresses' use '0.0.0.0', for 'all IPv6 addresses' use '::'.\n"
137+ " ``--local`` implies ``--bind``.\n"
128138 "--remote host [port] : Remote host name or ip address.\n"
129139 "--remote-random : If multiple --remote options specified, choose one randomly.\n"
130140 "--remote-random-hostname : Add a random string to remote DNS name.\n"
@@ -988,8 +998,9 @@ setenv_connection_entry(struct env_set *es,
988998 const int i )
989999{
9901000 setenv_str_i (es , "proto" , proto2ascii (e -> proto , e -> af , false), i );
991- setenv_str_i (es , "local" , e -> local , i );
992- setenv_str_i (es , "local_port" , e -> local_port , i );
1001+ /* expected to be for single socket contexts only */
1002+ setenv_str_i (es , "local" , e -> local_list -> array [0 ]-> local , i );
1003+ setenv_str_i (es , "local_port" , e -> local_list -> array [0 ]-> port , i );
9931004 setenv_str_i (es , "remote" , e -> remote , i );
9941005 setenv_str_i (es , "remote_port" , e -> remote_port , i );
9951006
@@ -1713,8 +1724,12 @@ static void
17131724show_connection_entry (const struct connection_entry * o )
17141725{
17151726 msg (D_SHOW_PARMS , " proto = %s" , proto2ascii (o -> proto , o -> af , false));
1716- SHOW_STR (local );
1717- SHOW_STR (local_port );
1727+ msg (D_SHOW_PARMS , " Local Sockets:" );
1728+ for (int i = 0 ; i < o -> local_list -> len ; i ++ )
1729+ {
1730+ msg (D_SHOW_PARMS , " [%s]:%s" , o -> local_list -> array [i ]-> local ,
1731+ o -> local_list -> array [i ]-> port );
1732+ }
17181733 SHOW_STR (remote );
17191734 SHOW_STR (remote_port );
17201735 SHOW_BOOL (remote_float );
@@ -2162,6 +2177,37 @@ options_postprocess_http_proxy_override(struct options *o)
21622177
21632178#endif /* ifdef ENABLE_MANAGEMENT */
21642179
2180+ static struct local_list *
2181+ alloc_local_list_if_undef (struct connection_entry * ce , struct gc_arena * gc )
2182+ {
2183+ if (!ce -> local_list )
2184+ {
2185+ ALLOC_OBJ_CLEAR_GC (ce -> local_list , struct local_list , gc );
2186+ }
2187+ return ce -> local_list ;
2188+ }
2189+
2190+ static struct local_entry *
2191+ alloc_local_entry (struct connection_entry * ce , const int msglevel ,
2192+ struct gc_arena * gc )
2193+ {
2194+ struct local_list * l = alloc_local_list_if_undef (ce , gc );
2195+ struct local_entry * e ;
2196+
2197+ if (l -> len >= CONNECTION_LIST_SIZE )
2198+ {
2199+ msg (msglevel , "Maximum number of 'local' options (%d) exceeded" ,
2200+ CONNECTION_LIST_SIZE );
2201+
2202+ return NULL ;
2203+ }
2204+
2205+ ALLOC_OBJ_CLEAR_GC (e , struct local_entry , gc );
2206+ l -> array [l -> len ++ ] = e ;
2207+
2208+ return e ;
2209+ }
2210+
21652211static struct connection_list *
21662212alloc_connection_list_if_undef (struct options * options )
21672213{
@@ -2354,6 +2400,15 @@ options_postprocess_verify_ce(const struct options *options,
23542400 "--proto tcp-server or --proto tcp-client" );
23552401 }
23562402
2403+ /*
2404+ * Sanity check on Client mode
2405+ */
2406+
2407+ if (options -> mode != MODE_SERVER && ce -> local_list -> len > 1 )
2408+ {
2409+ msg (M_USAGE , "multiple --local statements only allowed in --server mode" );
2410+ }
2411+
23572412 if (options -> lladdr && dev != DEV_TYPE_TAP )
23582413 {
23592414 msg (M_USAGE , "--lladdr can only be used in --dev tap mode" );
@@ -2379,13 +2434,6 @@ options_postprocess_verify_ce(const struct options *options,
23792434 * Sanity check on --local, --remote, and --ifconfig
23802435 */
23812436
2382- if (proto_is_net (ce -> proto )
2383- && string_defined_equal (ce -> local , ce -> remote )
2384- && string_defined_equal (ce -> local_port , ce -> remote_port ))
2385- {
2386- msg (M_USAGE , "--remote and --local addresses are the same" );
2387- }
2388-
23892437 if (string_defined_equal (ce -> remote , options -> ifconfig_local )
23902438 || string_defined_equal (ce -> remote , options -> ifconfig_remote_netmask ))
23912439 {
@@ -2394,13 +2442,6 @@ options_postprocess_verify_ce(const struct options *options,
23942442 "addresses" );
23952443 }
23962444
2397- if (string_defined_equal (ce -> local , options -> ifconfig_local )
2398- || string_defined_equal (ce -> local , options -> ifconfig_remote_netmask ))
2399- {
2400- msg (M_USAGE ,
2401- "--local addresses must be distinct from --ifconfig addresses" );
2402- }
2403-
24042445 if (string_defined_equal (options -> ifconfig_local ,
24052446 options -> ifconfig_remote_netmask ))
24062447 {
@@ -2413,12 +2454,6 @@ options_postprocess_verify_ce(const struct options *options,
24132454 msg (M_USAGE , "--bind and --nobind can't be used together" );
24142455 }
24152456
2416- if (ce -> local && !ce -> bind_local )
2417- {
2418- msg (M_USAGE ,
2419- "--local and --nobind don't make sense when used together" );
2420- }
2421-
24222457 if (ce -> local_port_defined && !ce -> bind_local )
24232458 {
24242459 msg (M_USAGE ,
@@ -2430,6 +2465,29 @@ options_postprocess_verify_ce(const struct options *options,
24302465 msg (M_USAGE , "--nobind doesn't make sense unless used with --remote" );
24312466 }
24322467
2468+ for (int i = 0 ; i < ce -> local_list -> len ; i ++ )
2469+ {
2470+ struct local_entry * le = ce -> local_list -> array [i ];
2471+
2472+ if (proto_is_net (ce -> proto )
2473+ && string_defined_equal (le -> local , ce -> remote )
2474+ && string_defined_equal (le -> port , ce -> remote_port ))
2475+ {
2476+ msg (M_USAGE , "--remote and one of the --local addresses are the same" );
2477+ }
2478+
2479+ if (string_defined_equal (le -> local , options -> ifconfig_local )
2480+ || string_defined_equal (le -> local , options -> ifconfig_remote_netmask ))
2481+ {
2482+ msg (M_USAGE , "--local addresses must be distinct from --ifconfig addresses" );
2483+ }
2484+
2485+ if (le -> local && !ce -> bind_local )
2486+ {
2487+ msg (M_USAGE , "--local and --nobind don't make sense when used together" );
2488+ }
2489+ }
2490+
24332491 /*
24342492 * Check for consistency of management options
24352493 */
@@ -3128,7 +3186,7 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce)
31283186 }
31293187
31303188 /* an option is present that requires local bind to enabled */
3131- bool need_bind = ce -> local || ce -> local_port_defined || ce -> bind_defined ;
3189+ bool need_bind = ce -> local_port_defined || ce -> bind_defined || ce -> local_list ;
31323190
31333191 /* socks proxy is enabled */
31343192 bool uses_socks = ce -> proto == PROTO_UDP && ce -> socks_proxy_server ;
@@ -3264,6 +3322,16 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce)
32643322 }
32653323}
32663324
3325+ static void
3326+ options_postprocess_mutate_le (struct connection_entry ce , struct local_entry * le )
3327+ {
3328+ /* use the global port if none is specified */
3329+ if (!le -> port )
3330+ {
3331+ le -> port = ce .local_port ;
3332+ }
3333+ }
3334+
32673335#ifdef _WIN32
32683336/* If iservice is in use, we need def1 method for redirect-gateway */
32693337static void
@@ -3705,6 +3773,28 @@ options_postprocess_mutate(struct options *o, struct env_set *es)
37053773 options_postprocess_mutate_ce (o , o -> connection_list -> array [i ]);
37063774 }
37073775
3776+ if (o -> ce .local_list )
3777+ {
3778+ for (i = 0 ; i < o -> ce .local_list -> len ; i ++ )
3779+ {
3780+ options_postprocess_mutate_le (o -> ce , o -> ce .local_list -> array [i ]);
3781+ }
3782+ }
3783+ else
3784+ {
3785+ /* if no 'local' directive was specified, convert the global port
3786+ * setting to a listen entry */
3787+ struct local_entry * e = alloc_local_entry (& o -> ce , M_USAGE , & o -> gc );
3788+ ASSERT (e );
3789+ e -> port = o -> ce .local_port ;
3790+ }
3791+
3792+ /* use the same listen list for every outgoing connection */
3793+ for (i = 0 ; i < o -> connection_list -> len ; ++ i )
3794+ {
3795+ o -> connection_list -> array [i ]-> local_list = o -> ce .local_list ;
3796+ }
3797+
37083798 if (o -> tls_server )
37093799 {
37103800 /* Check that DH file is specified, or explicitly disabled */
@@ -6100,10 +6190,27 @@ add_option(struct options *options,
61006190 VERIFY_PERMISSION (OPT_P_UP );
61016191 options -> ifconfig_nowarn = true;
61026192 }
6103- else if (streq (p [0 ], "local ") && p [1 ] && !p [2 ])
6193+ else if (streq (p [0 ], "local ") && p [1 ] && !p [3 ])
61046194 {
6195+ struct local_entry * e ;
6196+
61056197 VERIFY_PERMISSION (OPT_P_GENERAL |OPT_P_CONNECTION );
6106- options -> ce .local = p [1 ];
6198+
6199+ e = alloc_local_entry (& options -> ce , M_USAGE , & options -> gc );
6200+ ASSERT (e );
6201+
6202+ /* '*' is treated as 'ask the system to get some socket',
6203+ * therefore force binding on a particular address only when
6204+ * actually specified. */
6205+ if (strcmp (p [1 ], "*" ) != 0 )
6206+ {
6207+ e -> local = p [1 ];
6208+ }
6209+
6210+ if (p [2 ])
6211+ {
6212+ e -> port = p [2 ];
6213+ }
61076214 }
61086215 else if (streq (p [0 ], "remote - random ") && !p [1 ])
61096216 {
0 commit comments