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-2026 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 void
103helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
104{
106 add_route_to_option_list(o->routes, print_in_addr_t(network, 0, &o->gc),
107 print_in_addr_t(netmask, 0, &o->gc), NULL, NULL,
108 o->route_default_table_id);
109}
110
111static void
112verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
113{
114 struct gc_arena gc = gc_new();
115 if ((a & subnet) != (b & subnet))
116 {
117 msg(M_USAGE, "%s IP addresses %s and %s are not in the same %s subnet", opt,
118 print_in_addr_t(a, 0, &gc), print_in_addr_t(b, 0, &gc),
119 print_in_addr_t(subnet, 0, &gc));
120 }
121 gc_free(&gc);
122}
123
124
128void
130{
131 if (o->topology != TOP_UNDEF)
132 {
133 return;
134 }
135 int dev = dev_type_enum(o->dev, o->dev_type);
136 if (dev != DEV_TYPE_TUN)
137 {
138 return;
139 }
140 if (o->mode == MODE_SERVER)
141 {
142 o->topology = TOP_SUBNET;
143 }
144 else
145 {
146 o->topology = TOP_NET30;
147 }
148}
149
150
151/*
152 * Process server, server-bridge, and client helper
153 * directives after the parameters themselves have been
154 * parsed and placed in struct options.
155 */
156void
158{
159 struct gc_arena gc = gc_new();
160
161 /*
162 * Get tun/tap/null device type
163 */
164 const int dev = dev_type_enum(o->dev, o->dev_type);
165
166 /*
167 *
168 * HELPER DIRECTIVE for IPv6
169 *
170 * server-ipv6 2001:db8::/64
171 *
172 * EXPANDS TO:
173 *
174 * tun-ipv6
175 * push "tun-ipv6"
176 * ifconfig-ipv6 2001:db8::1 2001:db8::2
177 * if !nopool:
178 * ifconfig-ipv6-pool 2001:db8::1000/64
179 *
180 */
181 if (o->server_ipv6_defined)
182 {
183 if (o->client)
184 {
185 msg(M_USAGE, "--server-ipv6 and --client cannot be used together");
186 }
187
188 if (o->server_flags & SF_NOPOOL)
189 {
190 msg(M_USAGE, "--server-ipv6 is incompatible with 'nopool' option");
191 }
193 {
194 msg(M_USAGE,
195 "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
196 }
197
198 o->mode = MODE_SERVER;
199 o->tls_server = true;
200
201 /* local ifconfig is "base address + 1" and "+2" */
206
207 /* basic sanity check */
208 ASSERT(o->server_netbits_ipv6 >= 64 && o->server_netbits_ipv6 <= 124);
209
211 /* For large enough pools we keep the original behaviour of adding
212 * 0x1000 when computing the base.
213 *
214 * Smaller pools can't get that far, therefore we just increase by 2
215 */
217 add_in6_addr(o->server_network_ipv6, o->server_netbits_ipv6 < 112 ? 0x1000 : 2);
219
220 push_option(o, "tun-ipv6", M_USAGE);
221 }
222
223 /*
224 *
225 * HELPER DIRECTIVE:
226 *
227 * server 10.8.0.0 255.255.255.0
228 *
229 * EXPANDS TO:
230 *
231 * mode server
232 * tls-server
233 * push "topology [topology]"
234 *
235 * if tun AND (topology == net30 OR topology == p2p):
236 * ifconfig 10.8.0.1 10.8.0.2
237 * if !nopool:
238 * ifconfig-pool 10.8.0.4 10.8.0.251
239 * route 10.8.0.0 255.255.255.0
240 * if client-to-client:
241 * push "route 10.8.0.0 255.255.255.0"
242 * else if topology == net30:
243 * push "route 10.8.0.1"
244 *
245 * if tap OR (tun AND topology == subnet):
246 * ifconfig 10.8.0.1 255.255.255.0
247 * if !nopool:
248 * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
249 * push "route-gateway 10.8.0.1"
250 * if route-gateway unset:
251 * route-gateway 10.8.0.2
252 */
253
254 if (o->server_defined)
255 {
256 int netbits = -2;
257 bool status = false;
258
259 if (o->client)
260 {
261 msg(M_USAGE, "--server and --client cannot be used together");
262 }
263
265 {
266 msg(M_USAGE, "--server and --server-bridge cannot be used together");
267 }
268
269 if (o->shared_secret_file)
270 {
271 msg(M_USAGE,
272 "--server and --secret cannot be used together (you must use SSL/TLS keys)");
273 }
274
276 {
277 msg(M_USAGE,
278 "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
279 }
280
281 if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
282 {
283 msg(M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");
284 }
285
287 if (!status)
288 {
289 msg(M_USAGE, "--server directive network/netmask combination is invalid");
290 }
291
292 if (netbits < 0)
293 {
294 msg(M_USAGE, "--server directive netmask is invalid");
295 }
296
297 if (netbits < IFCONFIG_POOL_MIN_NETBITS)
298 {
299 msg(M_USAGE,
300 "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
302 }
303
304 if (dev == DEV_TYPE_TUN)
305 {
306 int pool_end_reserve = 4;
307
308 if (netbits > 29)
309 {
310 msg(M_USAGE,
311 "--server directive when used with --dev tun must define a subnet of %s or lower",
312 print_netmask(29, &gc));
313 }
314
315 if (netbits == 29)
316 {
317 pool_end_reserve = 0;
318 }
319
320 o->mode = MODE_SERVER;
321 o->tls_server = true;
322 /* Need to know topology now */
324
325 if (o->topology == TOP_NET30 || o->topology == TOP_P2P)
326 {
327 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
329
330 if (!(o->server_flags & SF_NOPOOL))
331 {
332 o->ifconfig_pool_defined = true;
335 (o->server_network | ~o->server_netmask) - pool_end_reserve;
338 }
339
341 if (o->enable_c2c)
342 {
344 M_USAGE);
345 }
346 else if (o->topology == TOP_NET30)
347 {
349 }
350 }
351 else if (o->topology == TOP_SUBNET)
352 {
353 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
355
356 if (!(o->server_flags & SF_NOPOOL))
357 {
358 o->ifconfig_pool_defined = true;
360 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
363 }
365
367 if (!o->route_default_gateway)
368 {
370 }
371 }
372 else
373 {
374 ASSERT(0);
375 }
376
378
379 if (o->topology == TOP_NET30 && !(o->server_flags & SF_NOPOOL))
380 {
381 msg(M_WARN, "WARNING: --topology net30 support for server "
382 "configs with IPv4 pools will be removed in a future "
383 "release. Please migrate to --topology subnet as soon "
384 "as possible.");
385 }
386 }
387 else if (dev == DEV_TYPE_TAP)
388 {
389 if (netbits > 30)
390 {
391 msg(M_USAGE,
392 "--server directive when used with --dev tap must define a subnet of %s or lower",
393 print_netmask(30, &gc));
394 }
395
396 o->mode = MODE_SERVER;
397 o->tls_server = true;
398 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
400
401 if (!(o->server_flags & SF_NOPOOL))
402 {
403 o->ifconfig_pool_defined = true;
405 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
407 }
409
411 }
412 else
413 {
414 ASSERT(0);
415 }
416
417 /* set push-ifconfig-constraint directive */
418 if ((dev == DEV_TYPE_TAP || o->topology == TOP_SUBNET))
419 {
423 }
424 }
425
426 /*
427 * HELPER DIRECTIVE:
428 *
429 * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
430 *
431 * EXPANDS TO:
432 *
433 * mode server
434 * tls-server
435 *
436 * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
437 * push "route-gateway 10.8.0.4"
438 *
439 * OR
440 *
441 * server-bridge
442 *
443 * EXPANDS TO:
444 *
445 * mode server
446 * tls-server
447 *
448 * if !nogw:
449 * push "route-gateway dhcp"
450 */
452 {
453 if (o->client)
454 {
455 msg(M_USAGE, "--server-bridge and --client cannot be used together");
456 }
457
459 {
460 msg(M_USAGE,
461 "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
462 }
463
464 if (o->shared_secret_file)
465 {
466 msg(M_USAGE,
467 "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");
468 }
469
470 if (dev != DEV_TYPE_TAP)
471 {
472 msg(M_USAGE, "--server-bridge directive only makes sense with --dev tap");
473 }
474
476 {
477 verify_common_subnet("--server-bridge", o->server_bridge_ip,
483 }
484
485 o->mode = MODE_SERVER;
486 o->tls_server = true;
487
489 {
490 o->ifconfig_pool_defined = true;
496 }
498 {
500 }
501 }
502
503 /*
504 * HELPER DIRECTIVE:
505 *
506 * client
507 *
508 * EXPANDS TO:
509 *
510 * pull
511 * tls-client
512 */
513 else if (o->client)
514 {
515 o->pull = true;
516 o->tls_client = true;
517 }
518
519 gc_free(&gc);
520}
521
522/*
523 *
524 * HELPER DIRECTIVE:
525 *
526 * keepalive 10 60
527 *
528 * EXPANDS TO:
529 *
530 * if mode server:
531 * ping 10
532 * ping-restart 120
533 * push "ping 10"
534 * push "ping-restart 60"
535 * else
536 * ping 10
537 * ping-restart 60
538 */
539void
541{
543 {
544 /*
545 * Sanity checks.
546 */
547 if (o->keepalive_ping * 2 > o->keepalive_timeout)
548 {
549 msg(M_USAGE,
550 "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.",
552 }
554 {
555 msg(M_USAGE,
556 "--keepalive conflicts with --ping, --ping-exit, or --ping-restart. If you use --keepalive, you don't need any of the other --ping directives.");
557 }
559 {
560 msg(M_USAGE,
561 "The second parameter to --keepalive must not exceed %d in server mode.",
562 PING_TIMEOUT_MAX / 2);
563 }
564
565 /*
566 * Expand.
567 */
568 if (o->mode == MODE_POINT_TO_POINT)
569 {
573 }
574 else if (o->mode == MODE_SERVER)
575 {
579 push_option(o, print_str_int("ping", o->keepalive_ping, &o->gc), M_USAGE);
580 push_option(o, print_str_int("ping-restart", o->keepalive_timeout, &o->gc), M_USAGE);
581 }
582 else
583 {
584 ASSERT(0);
585 }
586 }
587}
588
589/*
590 *
591 * HELPER DIRECTIVE:
592 *
593 * tcp-nodelay
594 *
595 * EXPANDS TO:
596 *
597 * if mode server:
598 * push "socket-flags TCP_NODELAY"
599 */
600void
602{
604 {
605 push_option(o, "socket-flags TCP_NODELAY", M_USAGE);
606 }
607}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:246
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
#define BSTR(buf)
Definition buffer.h:130
static void gc_free(struct gc_arena *a)
Definition buffer.h:1081
static struct gc_arena gc_new(void)
Definition buffer.h:1073
Interface functions to the internal and external multiplexers.
void helper_setdefault_topology(struct options *o)
Set –topology default depending on –mode.
Definition helper.c:129
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:601
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:112
static void helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
Definition helper.c:103
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
void helper_client_server(struct options *o)
Definition helper.c:157
void helper_keepalive(struct options *o)
Definition helper.c:540
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:52
#define M_USAGE
Definition error.h:107
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:219
#define M_WARN
Definition error.h:92
void rol_check_alloc(struct options *options)
Definition options.c:1557
const char * print_topology(const int topology)
Definition options.c:4791
#define MODE_POINT_TO_POINT
Definition options.h:264
#define SF_TCP_NODELAY_HELPER
Definition options.h:475
#define MODE_SERVER
Definition options.h:265
#define SF_NOPOOL
Definition options.h:474
#define PING_RESTART
Definition options.h:356
#define SF_NO_PUSH_ROUTE_GATEWAY
Definition options.h:476
#define PING_TIMEOUT_MAX
Definition options.h:59
bool ifconfig_pool_verify_range(const msglvl_t 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, msglvl_t msglevel)
Definition push.c:897
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:3858
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:494
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:401
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:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
const char * ifconfig_ipv6_remote
Definition options.h:331
in_addr_t push_ifconfig_constraint_network
Definition options.h:518
struct in6_addr server_network_ipv6
Definition options.h:471
in_addr_t server_network
Definition options.h:468
bool server_bridge_defined
Definition options.h:481
in_addr_t ifconfig_pool_netmask
Definition options.h:491
in_addr_t server_netmask
Definition options.h:469
bool server_bridge_proxy_dhcp
Definition options.h:479
const char * ifconfig_ipv6_local
Definition options.h:329
const char * dev_type
Definition options.h:323
bool ifconfig_pool_defined
Definition options.h:488
in_addr_t server_bridge_netmask
Definition options.h:483
in_addr_t ifconfig_pool_end
Definition options.h:490
int keepalive_timeout
Definition options.h:343
bool ifconfig_ipv6_pool_defined
Definition options.h:495
unsigned int server_flags
Definition options.h:477
bool server_defined
Definition options.h:467
const char * ifconfig_local
Definition options.h:327
const char * route_default_gateway
Definition options.h:426
int topology
Definition options.h:326
int mode
Definition options.h:266
bool tls_server
Definition options.h:591
bool client
Definition options.h:555
bool pull
Definition options.h:556
int ifconfig_ipv6_pool_netbits
Definition options.h:497
in_addr_t push_ifconfig_constraint_netmask
Definition options.h:519
bool tls_client
Definition options.h:592
int ping_rec_timeout_action
Definition options.h:357
struct gc_arena gc
Definition options.h:258
bool push_ifconfig_constraint_defined
Definition options.h:517
int ping_rec_timeout
Definition options.h:351
int ping_send_timeout
Definition options.h:350
bool server_ipv6_defined
Definition options.h:470
int keepalive_ping
Definition options.h:342
in_addr_t server_bridge_pool_start
Definition options.h:484
const char * ifconfig_remote_netmask
Definition options.h:328
bool enable_c2c
Definition options.h:526
in_addr_t server_bridge_pool_end
Definition options.h:485
in_addr_t ifconfig_pool_start
Definition options.h:489
unsigned int server_netbits_ipv6
Definition options.h:472
in_addr_t server_bridge_ip
Definition options.h:482
const char * shared_secret_file
Definition options.h:571
const char * dev
Definition options.h:322
struct in6_addr ifconfig_ipv6_pool_base
Definition options.h:496
int ifconfig_ipv6_netbits
Definition options.h:330
uint32_t in_addr_t
Definition syshead.h:52
struct gc_arena gc
Definition test_ssl.c:133
int dev_type_enum(const char *dev, const char *dev_type)
Definition tun.c:521