OpenVPN
helper.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include "forward.h"
30#include "helper.h"
31#include "pool.h"
32#include "push.h"
33
34#include "memdbg.h"
35
36
37static const char *
38print_netmask(int netbits, struct gc_arena *gc)
39{
40 struct buffer out = alloc_buf_gc(128, gc);
41 const in_addr_t netmask = netbits_to_netmask(netbits);
42
43 buf_printf(&out, "%s (/%d)", print_in_addr_t(netmask, 0, gc), netbits);
44
45 return BSTR(&out);
46}
47
48static const char *
50{
51 struct buffer out = alloc_buf_gc(128, gc);
53 buf_printf(&out, "route-gateway %s", print_in_addr_t(route_gateway, 0, gc));
54 return BSTR(&out);
55}
56
57static const char *
59{
60 struct buffer out = alloc_buf_gc(32, gc);
61 buf_printf(&out, "route-gateway dhcp");
62 return BSTR(&out);
63}
64
65static const char *
66print_opt_route(const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
67{
68 struct buffer out = alloc_buf_gc(128, gc);
69 ASSERT(network);
70
71 if (netmask)
72 {
73 buf_printf(&out, "route %s %s", print_in_addr_t(network, 0, gc),
74 print_in_addr_t(netmask, 0, gc));
75 }
76 else
77 {
78 buf_printf(&out, "route %s", print_in_addr_t(network, 0, gc));
79 }
80
81 return BSTR(&out);
82}
83
84static const char *
85print_opt_topology(const int topology, struct gc_arena *gc)
86{
87 struct buffer out = alloc_buf_gc(128, gc);
88
89 buf_printf(&out, "topology %s", print_topology(topology));
90
91 return BSTR(&out);
92}
93
94static const char *
95print_str_int(const char *str, const int i, struct gc_arena *gc)
96{
97 struct buffer out = alloc_buf_gc(128, gc);
98 buf_printf(&out, "%s %d", str, i);
99 return BSTR(&out);
100}
101
102static const char *
103print_str(const char *str, struct gc_arena *gc)
104{
105 struct buffer out = alloc_buf_gc(128, gc);
106 buf_printf(&out, "%s", str);
107 return BSTR(&out);
108}
109
110static void
111helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
112{
114 add_route_to_option_list(o->routes, print_in_addr_t(network, 0, &o->gc),
115 print_in_addr_t(netmask, 0, &o->gc), NULL, NULL,
116 o->route_default_table_id);
117}
118
119static void
120verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
121{
122 struct gc_arena gc = gc_new();
123 if ((a & subnet) != (b & subnet))
124 {
125 msg(M_USAGE, "%s IP addresses %s and %s are not in the same %s subnet", opt,
126 print_in_addr_t(a, 0, &gc), print_in_addr_t(b, 0, &gc),
127 print_in_addr_t(subnet, 0, &gc));
128 }
129 gc_free(&gc);
130}
131
132
136void
138{
139 if (o->topology != TOP_UNDEF)
140 {
141 return;
142 }
143 int dev = dev_type_enum(o->dev, o->dev_type);
144 if (dev != DEV_TYPE_TUN)
145 {
146 return;
147 }
148 if (o->mode == MODE_SERVER)
149 {
150 o->topology = TOP_SUBNET;
151 }
152 else
153 {
154 o->topology = TOP_NET30;
155 }
156}
157
158
159/*
160 * Process server, server-bridge, and client helper
161 * directives after the parameters themselves have been
162 * parsed and placed in struct options.
163 */
164void
166{
167 struct gc_arena gc = gc_new();
168
169 /*
170 * Get tun/tap/null device type
171 */
172 const int dev = dev_type_enum(o->dev, o->dev_type);
173
174 /*
175 *
176 * HELPER DIRECTIVE for IPv6
177 *
178 * server-ipv6 2001:db8::/64
179 *
180 * EXPANDS TO:
181 *
182 * tun-ipv6
183 * push "tun-ipv6"
184 * ifconfig-ipv6 2001:db8::1 2001:db8::2
185 * if !nopool:
186 * ifconfig-ipv6-pool 2001:db8::1000/64
187 *
188 */
189 if (o->server_ipv6_defined)
190 {
191 if (o->client)
192 {
193 msg(M_USAGE, "--server-ipv6 and --client cannot be used together");
194 }
195
196 if (o->server_flags & SF_NOPOOL)
197 {
198 msg(M_USAGE, "--server-ipv6 is incompatible with 'nopool' option");
199 }
201 {
202 msg(M_USAGE,
203 "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
204 }
205
206 o->mode = MODE_SERVER;
207 o->tls_server = true;
208
209 /* local ifconfig is "base address + 1" and "+2" */
214
215 /* basic sanity check */
216 ASSERT(o->server_netbits_ipv6 >= 64 && o->server_netbits_ipv6 <= 124);
217
219 /* For large enough pools we keep the original behaviour of adding
220 * 0x1000 when computing the base.
221 *
222 * Smaller pools can't get that far, therefore we just increase by 2
223 */
225 add_in6_addr(o->server_network_ipv6, o->server_netbits_ipv6 < 112 ? 0x1000 : 2);
227
228 push_option(o, "tun-ipv6", M_USAGE);
229 }
230
231 /*
232 *
233 * HELPER DIRECTIVE:
234 *
235 * server 10.8.0.0 255.255.255.0
236 *
237 * EXPANDS TO:
238 *
239 * mode server
240 * tls-server
241 * push "topology [topology]"
242 *
243 * if tun AND (topology == net30 OR topology == p2p):
244 * ifconfig 10.8.0.1 10.8.0.2
245 * if !nopool:
246 * ifconfig-pool 10.8.0.4 10.8.0.251
247 * route 10.8.0.0 255.255.255.0
248 * if client-to-client:
249 * push "route 10.8.0.0 255.255.255.0"
250 * else if topology == net30:
251 * push "route 10.8.0.1"
252 *
253 * if tap OR (tun AND topology == subnet):
254 * ifconfig 10.8.0.1 255.255.255.0
255 * if !nopool:
256 * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
257 * push "route-gateway 10.8.0.1"
258 * if route-gateway unset:
259 * route-gateway 10.8.0.2
260 */
261
262 if (o->server_defined)
263 {
264 int netbits = -2;
265 bool status = false;
266
267 if (o->client)
268 {
269 msg(M_USAGE, "--server and --client cannot be used together");
270 }
271
273 {
274 msg(M_USAGE, "--server and --server-bridge cannot be used together");
275 }
276
277 if (o->shared_secret_file)
278 {
279 msg(M_USAGE,
280 "--server and --secret cannot be used together (you must use SSL/TLS keys)");
281 }
282
284 {
285 msg(M_USAGE,
286 "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
287 }
288
289 if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
290 {
291 msg(M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");
292 }
293
295 if (!status)
296 {
297 msg(M_USAGE, "--server directive network/netmask combination is invalid");
298 }
299
300 if (netbits < 0)
301 {
302 msg(M_USAGE, "--server directive netmask is invalid");
303 }
304
305 if (netbits < IFCONFIG_POOL_MIN_NETBITS)
306 {
307 msg(M_USAGE,
308 "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
310 }
311
312 if (dev == DEV_TYPE_TUN)
313 {
314 int pool_end_reserve = 4;
315
316 if (netbits > 29)
317 {
318 msg(M_USAGE,
319 "--server directive when used with --dev tun must define a subnet of %s or lower",
320 print_netmask(29, &gc));
321 }
322
323 if (netbits == 29)
324 {
325 pool_end_reserve = 0;
326 }
327
328 o->mode = MODE_SERVER;
329 o->tls_server = true;
330 /* Need to know topology now */
332
333 if (o->topology == TOP_NET30 || o->topology == TOP_P2P)
334 {
335 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
337
338 if (!(o->server_flags & SF_NOPOOL))
339 {
340 o->ifconfig_pool_defined = true;
343 (o->server_network | ~o->server_netmask) - pool_end_reserve;
346 }
347
349 if (o->enable_c2c)
350 {
352 M_USAGE);
353 }
354 else if (o->topology == TOP_NET30)
355 {
357 }
358 }
359 else if (o->topology == TOP_SUBNET)
360 {
361 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
363
364 if (!(o->server_flags & SF_NOPOOL))
365 {
366 o->ifconfig_pool_defined = true;
368 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
371 }
373
375 if (!o->route_default_gateway)
376 {
378 }
379 }
380 else
381 {
382 ASSERT(0);
383 }
384
386
387 if (o->topology == TOP_NET30 && !(o->server_flags & SF_NOPOOL))
388 {
389 msg(M_WARN, "WARNING: --topology net30 support for server "
390 "configs with IPv4 pools will be removed in a future "
391 "release. Please migrate to --topology subnet as soon "
392 "as possible.");
393 }
394 }
395 else if (dev == DEV_TYPE_TAP)
396 {
397 if (netbits > 30)
398 {
399 msg(M_USAGE,
400 "--server directive when used with --dev tap must define a subnet of %s or lower",
401 print_netmask(30, &gc));
402 }
403
404 o->mode = MODE_SERVER;
405 o->tls_server = true;
406 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
408
409 if (!(o->server_flags & SF_NOPOOL))
410 {
411 o->ifconfig_pool_defined = true;
413 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
415 }
417
419 }
420 else
421 {
422 ASSERT(0);
423 }
424
425 /* set push-ifconfig-constraint directive */
426 if ((dev == DEV_TYPE_TAP || o->topology == TOP_SUBNET))
427 {
431 }
432 }
433
434 /*
435 * HELPER DIRECTIVE:
436 *
437 * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
438 *
439 * EXPANDS TO:
440 *
441 * mode server
442 * tls-server
443 *
444 * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
445 * push "route-gateway 10.8.0.4"
446 *
447 * OR
448 *
449 * server-bridge
450 *
451 * EXPANDS TO:
452 *
453 * mode server
454 * tls-server
455 *
456 * if !nogw:
457 * push "route-gateway dhcp"
458 */
460 {
461 if (o->client)
462 {
463 msg(M_USAGE, "--server-bridge and --client cannot be used together");
464 }
465
467 {
468 msg(M_USAGE,
469 "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
470 }
471
472 if (o->shared_secret_file)
473 {
474 msg(M_USAGE,
475 "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");
476 }
477
478 if (dev != DEV_TYPE_TAP)
479 {
480 msg(M_USAGE, "--server-bridge directive only makes sense with --dev tap");
481 }
482
484 {
485 verify_common_subnet("--server-bridge", o->server_bridge_ip,
491 }
492
493 o->mode = MODE_SERVER;
494 o->tls_server = true;
495
497 {
498 o->ifconfig_pool_defined = true;
504 }
506 {
508 }
509 }
510
511 /*
512 * HELPER DIRECTIVE:
513 *
514 * client
515 *
516 * EXPANDS TO:
517 *
518 * pull
519 * tls-client
520 */
521 else if (o->client)
522 {
523 o->pull = true;
524 o->tls_client = true;
525 }
526
527 gc_free(&gc);
528}
529
530/*
531 *
532 * HELPER DIRECTIVE:
533 *
534 * keepalive 10 60
535 *
536 * EXPANDS TO:
537 *
538 * if mode server:
539 * ping 10
540 * ping-restart 120
541 * push "ping 10"
542 * push "ping-restart 60"
543 * else
544 * ping 10
545 * ping-restart 60
546 */
547void
549{
551 {
552 /*
553 * Sanity checks.
554 */
555 if (o->keepalive_ping <= 0 || o->keepalive_timeout <= 0)
556 {
557 msg(M_USAGE, "--keepalive parameters must be > 0");
558 }
559 if (o->keepalive_ping * 2 > o->keepalive_timeout)
560 {
561 msg(M_USAGE,
562 "the second parameter to --keepalive (restart timeout=%d) must be at least twice the value of the first parameter (ping interval=%d). A ratio of 1:5 or 1:6 would be even better. Recommended setting is --keepalive 10 60.",
564 }
566 {
567 msg(M_USAGE,
568 "--keepalive conflicts with --ping, --ping-exit, or --ping-restart. If you use --keepalive, you don't need any of the other --ping directives.");
569 }
570
571 /*
572 * Expand.
573 */
574 if (o->mode == MODE_POINT_TO_POINT)
575 {
579 }
580 else if (o->mode == MODE_SERVER)
581 {
585 push_option(o, print_str_int("ping", o->keepalive_ping, &o->gc), M_USAGE);
586 push_option(o, print_str_int("ping-restart", o->keepalive_timeout, &o->gc), M_USAGE);
587 }
588 else
589 {
590 ASSERT(0);
591 }
592 }
593}
594
595/*
596 *
597 * HELPER DIRECTIVE:
598 *
599 * tcp-nodelay
600 *
601 * EXPANDS TO:
602 *
603 * if mode server:
604 * socket-flags TCP_NODELAY
605 * push "socket-flags TCP_NODELAY"
606 */
607void
609{
611 {
612 if (o->mode == MODE_SERVER)
613 {
615 push_option(o, print_str("socket-flags TCP_NODELAY", &o->gc), M_USAGE);
616 }
617 else
618 {
620 }
621 }
622}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
#define BSTR(buf)
Definition buffer.h:128
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static struct gc_arena gc_new(void)
Definition buffer.h:1007
Interface functions to the internal and external multiplexers.
void helper_setdefault_topology(struct options *o)
Set –topology default depending on –mode.
Definition helper.c:137
static const char * print_opt_route_gateway_dhcp(struct gc_arena *gc)
Definition helper.c:58
void helper_tcp_nodelay(struct options *o)
Definition helper.c:608
static void verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
Definition helper.c:120
static void helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
Definition helper.c:111
static const char * print_opt_route_gateway(const in_addr_t route_gateway, struct gc_arena *gc)
Definition helper.c:49
static const char * print_opt_route(const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
Definition helper.c:66
static const char * print_str(const char *str, struct gc_arena *gc)
Definition helper.c:103
void helper_client_server(struct options *o)
Definition helper.c:165
void helper_keepalive(struct options *o)
Definition helper.c:548
static const char * print_str_int(const char *str, const int i, struct gc_arena *gc)
Definition helper.c:95
static const char * print_netmask(int netbits, struct gc_arena *gc)
Definition helper.c:38
static const char * print_opt_topology(const int topology, struct gc_arena *gc)
Definition helper.c:85
static SERVICE_STATUS status
Definition interactive.c:51
#define M_USAGE
Definition error.h:105
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
void rol_check_alloc(struct options *options)
Definition options.c:1566
const char * print_topology(const int topology)
Definition options.c:4754
#define MODE_POINT_TO_POINT
Definition options.h:260
#define SF_TCP_NODELAY_HELPER
Definition options.h:478
#define MODE_SERVER
Definition options.h:261
#define SF_NOPOOL
Definition options.h:477
#define PING_RESTART
Definition options.h:356
#define SF_NO_PUSH_ROUTE_GATEWAY
Definition options.h:479
bool ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
Definition pool.c:117
#define IFCONFIG_POOL_MIN_NETBITS
Definition pool.h:32
#define DEV_TYPE_TAP
Definition proto.h:36
#define TOP_UNDEF
Definition proto.h:40
#define TOP_NET30
Definition proto.h:41
#define DEV_TYPE_TUN
Definition proto.h:35
#define TOP_P2P
Definition proto.h:42
#define TOP_SUBNET
Definition proto.h:43
void push_option(struct options *o, const char *opt, int msglevel)
Definition push.c:884
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:3860
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric, int table_id)
Definition route.c:492
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:399
#define SF_TCP_NODELAY
Definition socket.h:192
struct in6_addr add_in6_addr(struct in6_addr base, uint32_t add)
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
const char * ifconfig_ipv6_remote
Definition options.h:327
in_addr_t push_ifconfig_constraint_network
Definition options.h:521
struct in6_addr server_network_ipv6
Definition options.h:474
in_addr_t server_network
Definition options.h:471
bool server_bridge_defined
Definition options.h:484
in_addr_t ifconfig_pool_netmask
Definition options.h:494
in_addr_t server_netmask
Definition options.h:472
bool server_bridge_proxy_dhcp
Definition options.h:482
const char * ifconfig_ipv6_local
Definition options.h:325
const char * dev_type
Definition options.h:319
bool ifconfig_pool_defined
Definition options.h:491
in_addr_t server_bridge_netmask
Definition options.h:486
in_addr_t ifconfig_pool_end
Definition options.h:493
int keepalive_timeout
Definition options.h:343
bool ifconfig_ipv6_pool_defined
Definition options.h:498
unsigned int server_flags
Definition options.h:480
bool server_defined
Definition options.h:470
const char * ifconfig_local
Definition options.h:323
const char * route_default_gateway
Definition options.h:429
int topology
Definition options.h:322
int mode
Definition options.h:262
bool tls_server
Definition options.h:595
bool client
Definition options.h:558
bool pull
Definition options.h:559
int ifconfig_ipv6_pool_netbits
Definition options.h:500
in_addr_t push_ifconfig_constraint_netmask
Definition options.h:522
bool tls_client
Definition options.h:596
int ping_rec_timeout_action
Definition options.h:357
struct gc_arena gc
Definition options.h:253
bool push_ifconfig_constraint_defined
Definition options.h:520
int ping_rec_timeout
Definition options.h:351
unsigned int sockflags
Definition options.h:424
int ping_send_timeout
Definition options.h:350
bool server_ipv6_defined
Definition options.h:473
int keepalive_ping
Definition options.h:342
in_addr_t server_bridge_pool_start
Definition options.h:487
const char * ifconfig_remote_netmask
Definition options.h:324
bool enable_c2c
Definition options.h:529
in_addr_t server_bridge_pool_end
Definition options.h:488
in_addr_t ifconfig_pool_start
Definition options.h:492
unsigned int server_netbits_ipv6
Definition options.h:475
in_addr_t server_bridge_ip
Definition options.h:485
const char * shared_secret_file
Definition options.h:572
const char * dev
Definition options.h:318
struct in6_addr ifconfig_ipv6_pool_base
Definition options.h:499
int ifconfig_ipv6_netbits
Definition options.h:326
struct gc_arena gc
Definition test_ssl.c:154
int dev_type_enum(const char *dev, const char *dev_type)
Definition tun.c:517