OpenVPN
resolve.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 "buffer.h"
30#include "crypto.h"
31#include "manage.h"
32#include "openvpn.h"
33#include "socket.h"
34#include "socket_util.h"
35
36#include "resolve.h"
37
38/*
39 * Convert sockflags/getaddr_flags into getaddr_flags
40 */
41unsigned int
42sf2gaf(const unsigned int getaddr_flags, const unsigned int sockflags)
43{
44 if (sockflags & SF_HOST_RANDOMIZE)
45 {
46 return getaddr_flags | GETADDR_RANDOMIZE;
47 }
48 else
49 {
50 return getaddr_flags;
51 }
52}
53
54/*
55 * Functions related to the translation of DNS names to IP addresses.
56 */
57
62static const char *
64{
65 switch (af)
66 {
67 case AF_INET:
68 return "[AF_INET]";
69
70 case AF_INET6:
71 return "[AF_INET6]";
72 }
73 return "";
74}
75
76/*
77 * Prepend a random string to hostname to prevent DNS caching.
78 * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
79 * Of course, this requires explicit support in the DNS server (wildcard).
80 */
81static const char *
82hostname_randomize(const char *hostname, struct gc_arena *gc)
83{
84#define n_rnd_bytes 6
85
86 uint8_t rnd_bytes[n_rnd_bytes];
87 const char *rnd_str;
88 struct buffer hname = alloc_buf_gc(strlen(hostname) + sizeof(rnd_bytes) * 2 + 4, gc);
89
90 prng_bytes(rnd_bytes, sizeof(rnd_bytes));
91 rnd_str = format_hex_ex(rnd_bytes, sizeof(rnd_bytes), 40, 0, NULL, gc);
92 buf_printf(&hname, "%s.%s", rnd_str, hostname);
93 return BSTR(&hname);
94#undef n_rnd_bytes
95}
96
97/*
98 * Translate IPv4/IPv6 addr or hostname into struct addrinfo
99 * If resolve error, try again for resolve_retry_seconds seconds.
100 */
101int
102openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname,
103 int resolve_retry_seconds, struct signal_info *sig_info, int ai_family,
104 struct addrinfo **res)
105{
106 struct addrinfo hints;
107 int status;
108 struct signal_info sigrec = { 0 };
109 msglvl_t msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS;
110 struct gc_arena gc = gc_new();
111 const char *print_hostname;
112 const char *print_servname;
113
114 ASSERT(res);
115
116 ASSERT(hostname || servname);
117 ASSERT(!(flags & GETADDR_HOST_ORDER));
118
119 if (servname)
120 {
121 print_servname = servname;
122 }
123 else
124 {
125 print_servname = "";
126 }
127
128 if (flags & GETADDR_MSG_VIRT_OUT)
129 {
130 msglevel |= M_MSG_VIRT_OUT;
131 }
132
133 if ((flags & (GETADDR_FATAL_ON_SIGNAL | GETADDR_WARN_ON_SIGNAL)) && !sig_info)
134 {
135 sig_info = &sigrec;
136 }
137
138 /* try numeric ip addr first */
139 CLEAR(hints);
140 hints.ai_flags = AI_NUMERICHOST;
141
142 if (flags & GETADDR_PASSIVE)
143 {
144 hints.ai_flags |= AI_PASSIVE;
145 }
146
147 if (flags & GETADDR_DATAGRAM)
148 {
149 hints.ai_socktype = SOCK_DGRAM;
150 }
151 else
152 {
153 hints.ai_socktype = SOCK_STREAM;
154 }
155
156 /* if hostname is not set, we want to bind to 'ANY', with
157 * the correct address family - v4-only or v6/v6-dual-stack */
158 if (!hostname)
159 {
160 hints.ai_family = ai_family;
161 }
162
163 status = getaddrinfo(hostname, servname, &hints, res);
164
165 if (status != 0) /* parse as numeric address failed? */
166 {
167 const int fail_wait_interval = 5; /* seconds */
168 /* Add +4 to cause integer division rounding up (1 + 4) = 5, (0+4)/5=0 */
169 int resolve_retries =
170 (flags & GETADDR_TRY_ONCE) ? 1 : ((resolve_retry_seconds + 4) / fail_wait_interval);
171 const char *fmt;
172 msglvl_t level = 0;
173
174 /* this is not a numeric IP, therefore force resolution using the
175 * provided ai_family */
176 hints.ai_family = ai_family;
177
178 if (hostname && (flags & GETADDR_RANDOMIZE))
179 {
180 hostname = hostname_randomize(hostname, &gc);
181 }
182
183 if (hostname)
184 {
185 print_hostname = hostname;
186 }
187 else
188 {
189 print_hostname = "undefined";
190 }
191
192 fmt = "RESOLVE: Cannot resolve host address: %s:%s%s (%s)";
193 if ((flags & GETADDR_MENTION_RESOLVE_RETRY) && !resolve_retry_seconds)
194 {
195 fmt = "RESOLVE: Cannot resolve host address: %s:%s%s (%s)"
196 "(I would have retried this name query if you had "
197 "specified the --resolv-retry option.)";
198 }
199
200 if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL)
201 {
202 msg(msglevel, "RESOLVE: Cannot parse IP address: %s:%s (%s)", print_hostname,
203 print_servname, gai_strerror(status));
204 goto done;
205 }
206
207#ifdef ENABLE_MANAGEMENT
209 {
210 if (management)
211 {
213 NULL);
214 }
215 }
216#endif
217
218 /*
219 * Resolve hostname
220 */
221 while (true)
222 {
223#ifndef _WIN32
224 /* force resolv.conf reload */
225 res_init();
226#endif
227 /* try hostname lookup */
228 hints.ai_flags &= ~AI_NUMERICHOST;
229 dmsg(D_SOCKET_DEBUG, "GETADDRINFO flags=0x%04x ai_family=%d ai_socktype=%d", flags,
230 hints.ai_family, hints.ai_socktype);
231 status = getaddrinfo(hostname, servname, &hints, res);
232
233 if (sig_info)
234 {
235 get_signal(&sig_info->signal_received);
236 if (sig_info->signal_received) /* were we interrupted by a signal? */
237 {
238 /* why are we overwriting SIGUSR1 ? */
239 if (signal_reset(sig_info, SIGUSR1) == SIGUSR1) /* ignore SIGUSR1 */
240 {
241 msg(level, "RESOLVE: Ignored SIGUSR1 signal received during "
242 "DNS resolution attempt");
243 }
244 else
245 {
246 /* turn success into failure (interrupted syscall) */
247 if (0 == status)
248 {
249 ASSERT(res);
250 freeaddrinfo(*res);
251 *res = NULL;
252 status = EAI_AGAIN; /* = temporary failure */
253 errno = EINTR;
254 }
255 goto done;
256 }
257 }
258 }
259
260 /* success? */
261 if (0 == status)
262 {
263 break;
264 }
265
266 /* resolve lookup failed, should we
267 * continue or fail? */
268 level = msglevel;
269 if (resolve_retries > 0)
270 {
271 level = D_RESOLVE_ERRORS;
272 }
273
274 msg(level, fmt, print_hostname, print_servname, getaddrinfo_addr_family_name(ai_family),
275 gai_strerror(status));
276
277 if (--resolve_retries <= 0)
278 {
279 goto done;
280 }
281
282 management_sleep(fail_wait_interval);
283 }
284
285 ASSERT(res);
286
287 /* hostname resolve succeeded */
288
289 /*
290 * Do not choose an IP Addresse by random or change the order *
291 * of IP addresses, doing so will break RFC 3484 address selection *
292 */
293 }
294 else
295 {
296 /* IP address parse succeeded */
297 if (flags & GETADDR_RANDOMIZE)
298 {
299 msg(M_WARN, "WARNING: ignoring --remote-random-hostname because the "
300 "hostname is an IP address");
301 }
302 }
303
304done:
305 if (sig_info && sig_info->signal_received)
306 {
307 msglvl_t level = 0;
308 if (flags & GETADDR_FATAL_ON_SIGNAL)
309 {
310 level = M_FATAL;
311 }
312 else if (flags & GETADDR_WARN_ON_SIGNAL)
313 {
314 level = M_WARN;
315 }
316 msg(level, "RESOLVE: signal received during DNS resolution attempt");
317 }
318
319 gc_free(&gc);
320 return status;
321}
322
323static int
324get_addr_generic(sa_family_t af, unsigned int flags, const char *hostname, void *network,
325 unsigned int *netbits, int resolve_retry_seconds, struct signal_info *sig_info,
326 msglvl_t msglevel)
327{
328 char *endp, *sep, *var_host = NULL;
329 struct addrinfo *ai = NULL;
330 unsigned long bits;
331 uint8_t max_bits;
332 int ret = -1;
333
334 if (!hostname)
335 {
336 msg(M_NONFATAL, "Can't resolve null hostname!");
337 goto out;
338 }
339
340 /* assign family specific default values */
341 switch (af)
342 {
343 case AF_INET:
344 bits = 0;
345 max_bits = sizeof(in_addr_t) * 8;
346 break;
347
348 case AF_INET6:
349 bits = 64;
350 max_bits = sizeof(struct in6_addr) * 8;
351 break;
352
353 default:
354 msg(M_WARN, "Unsupported AF family passed to getaddrinfo for %s (%d)", hostname, af);
355 goto out;
356 }
357
358 /* we need to modify the hostname received as input, but we don't want to
359 * touch it directly as it might be a constant string.
360 *
361 * Therefore, we clone the string here and free it at the end of the
362 * function */
363 var_host = strdup(hostname);
364 if (!var_host)
365 {
366 msg(M_NONFATAL | M_ERRNO, "Can't allocate hostname buffer for getaddrinfo");
367 goto out;
368 }
369
370 /* check if this hostname has a /bits suffix */
371 sep = strchr(var_host, '/');
372 if (sep)
373 {
374 bits = strtoul(sep + 1, &endp, 10);
375 if ((*endp != '\0') || (bits > max_bits))
376 {
377 msg(msglevel, "IP prefix '%s': invalid '/bits' spec (%s)", hostname, sep + 1);
378 goto out;
379 }
380 *sep = '\0';
381 }
382
383 ret = openvpn_getaddrinfo(flags & ~GETADDR_HOST_ORDER, var_host, NULL, resolve_retry_seconds,
384 sig_info, af, &ai);
385 if ((ret == 0) && network)
386 {
387 struct in6_addr *ip6;
388 in_addr_t *ip4;
389
390 if (af != ai->ai_family)
391 {
392 msg(msglevel, "Can't parse %s as IPv%d address", var_host, (af == AF_INET) ? 4 : 6);
393 ret = -1;
394 goto out;
395 }
396
397 switch (af)
398 {
399 case AF_INET:
400 ip4 = network;
401 *ip4 = ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr;
402
403 if (flags & GETADDR_HOST_ORDER)
404 {
405 *ip4 = ntohl(*ip4);
406 }
407 break;
408
409 case AF_INET6:
410 ip6 = network;
411 *ip6 = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
412 break;
413
414 default:
415 /* can't get here because 'af' was previously checked */
416 msg(M_WARN, "Unsupported AF family for %s (%d)", var_host, af);
417 goto out;
418 }
419 }
420
421 if (netbits)
422 {
423 *netbits = (unsigned int)bits;
424 }
425
426 /* restore '/' separator, if any */
427 if (sep)
428 {
429 *sep = '/';
430 }
431out:
432 if (ai)
433 {
434 freeaddrinfo(ai);
435 }
436 free(var_host);
437
438 return ret;
439}
440
442getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded,
443 struct signal_info *sig_info)
444{
445 in_addr_t addr = { 0 };
446 int status;
447
448 status = get_addr_generic(AF_INET, flags, hostname, &addr, NULL, resolve_retry_seconds,
449 sig_info, M_WARN);
450 if (status == 0)
451 {
452 if (succeeded)
453 {
454 *succeeded = true;
455 }
456 return addr;
457 }
458 else
459 {
460 if (succeeded)
461 {
462 *succeeded = false;
463 }
464 return 0;
465 }
466}
467
469get_ip_addr(const char *ip_string, msglvl_t msglevel, bool *error)
470{
471 unsigned int flags = GETADDR_HOST_ORDER;
472 bool succeeded = false;
473 in_addr_t ret;
474
475 if (msglevel & M_FATAL)
476 {
477 flags |= GETADDR_FATAL;
478 }
479
480 ret = getaddr(flags, ip_string, 0, &succeeded, NULL);
481 if (!succeeded && error)
482 {
483 *error = true;
484 }
485 return ret;
486}
487
488bool
489get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits,
490 msglvl_t msglevel)
491{
492 if (get_addr_generic(AF_INET6, GETADDR_RESOLVE, hostname, network, netbits, 0, NULL, msglevel)
493 < 0)
494 {
495 return false;
496 }
497
498 return true; /* parsing OK, values set */
499}
500
501/*
502 * get_cached_dns_entry return 0 on success and -1
503 * otherwise. (like getaddrinfo)
504 */
505int
506get_cached_dns_entry(struct cached_dns_entry *dns_cache, const char *hostname, const char *servname,
507 int ai_family, unsigned int resolve_flags, struct addrinfo **ai)
508{
509 struct cached_dns_entry *ph;
510 unsigned int flags;
511
512 /* Only use flags that are relevant for the structure */
513 flags = resolve_flags & GETADDR_CACHE_MASK;
514
515 for (ph = dns_cache; ph; ph = ph->next)
516 {
518 && ph->ai_family == ai_family && ph->flags == flags)
519 {
520 *ai = ph->ai;
521 return 0;
522 }
523 }
524 return -1;
525}
526
527
528static int
529do_preresolve_host(struct context *c, const char *hostname, const char *servname, const int af,
530 const unsigned int flags)
531{
532 struct addrinfo *ai;
533 int status;
534
535 if (get_cached_dns_entry(c->c1.dns_cache, hostname, servname, af, flags, &ai) == 0)
536 {
537 /* entry already cached, return success */
538 return 0;
539 }
540
541 status = openvpn_getaddrinfo(flags, hostname, servname, c->options.resolve_retry_seconds, NULL,
542 af, &ai);
543 if (status == 0)
544 {
545 struct cached_dns_entry *ph;
546
547 ALLOC_OBJ_CLEAR_GC(ph, struct cached_dns_entry, &c->gc);
548 ph->ai = ai;
549 ph->hostname = hostname;
550 ph->servname = servname;
552
553 if (!c->c1.dns_cache)
554 {
555 c->c1.dns_cache = ph;
556 }
557 else
558 {
559 struct cached_dns_entry *prev = c->c1.dns_cache;
560 while (prev->next)
561 {
562 prev = prev->next;
563 }
564 prev->next = ph;
565 }
566
568 }
569 return status;
570}
571
572void
574{
576 const unsigned int preresolve_flags = GETADDR_RESOLVE | GETADDR_UPDATE_MANAGEMENT_STATE
578
579
580 for (int i = 0; i < l->len; ++i)
581 {
582 int status;
583 const char *remote;
584 unsigned int flags = preresolve_flags;
585
586 struct connection_entry *ce = l->array[i];
587
588 if (proto_is_dgram(ce->proto))
589 {
591 }
592
594 {
596 }
597
598 if (c->options.ip_remote_hint)
599 {
601 }
602 else
603 {
604 remote = ce->remote;
605 }
606
607 /* HTTP remote hostname does not need to be resolved */
608 if (!ce->http_proxy_options)
609 {
611 if (status != 0)
612 {
613 goto err;
614 }
615 }
616
617 /* Preresolve proxy */
618 if (ce->http_proxy_options)
619 {
621 ce->http_proxy_options->port, ce->af, preresolve_flags);
622
623 if (status != 0)
624 {
625 goto err;
626 }
627 }
628
629 if (ce->socks_proxy_server)
630 {
631 status =
633 if (status != 0)
634 {
635 goto err;
636 }
637 }
638
639 if (ce->bind_local)
640 {
643
644 for (int j = 0; j < ce->local_list->len; j++)
645 {
646 const struct local_entry *le = ce->local_list->array[j];
647
648 if (!le->local)
649 {
650 continue;
651 }
652
653 status = do_preresolve_host(c, le->local, le->port, ce->af, flags);
654 if (status != 0)
655 {
656 goto err;
657 }
658 }
659 }
660 }
661 return;
662
663err:
664 throw_signal_soft(SIGHUP, "Preresolving failed");
665}
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
Definition buffer.c:226
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
char * format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Format a binary buffer as a hex string.
Definition buffer.c:447
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Register an address with a custom free function in a garbage collection arena.
Definition buffer.c:406
bool streqnull(const char *a, const char *b)
compare two strings which might be NULL
Definition buffer.c:1087
Buffer management functions and garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:157
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
Definition buffer.h:2123
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1965
static void gc_freeaddrinfo_callback(void *addr)
Callback to free a struct addrinfo, suitable for use with gc_addspecial().
Definition buffer.h:377
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1949
void prng_bytes(uint8_t *output, int len)
Definition crypto.c:1727
Data Channel Cryptography Module.
#define D_SOCKET_DEBUG
Definition errlevel.h:139
#define D_RESOLVE_ERRORS
Definition errlevel.h:59
static SERVICE_STATUS status
Definition interactive.c:52
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
Definition manage.c:2882
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
Definition manage.c:4237
#define OPENVPN_STATE_RESOLVE
Definition manage.h:462
#define CLEAR(x)
Definition basic.h:32
#define M_FATAL
Definition error.h:90
#define M_NONFATAL
Definition error.h:91
#define dmsg(flags,...)
Definition error.h:164
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:221
#define M_WARN
Definition error.h:92
#define M_MSG_VIRT_OUT
Definition error.h:100
#define M_ERRNO
Definition error.h:95
int openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname, int resolve_retry_seconds, struct signal_info *sig_info, int ai_family, struct addrinfo **res)
Definition resolve.c:102
#define n_rnd_bytes
static int do_preresolve_host(struct context *c, const char *hostname, const char *servname, const int af, const unsigned int flags)
Definition resolve.c:529
in_addr_t get_ip_addr(const char *ip_string, msglvl_t msglevel, bool *error)
Definition resolve.c:469
static const char * hostname_randomize(const char *hostname, struct gc_arena *gc)
Definition resolve.c:82
static int get_addr_generic(sa_family_t af, unsigned int flags, const char *hostname, void *network, unsigned int *netbits, int resolve_retry_seconds, struct signal_info *sig_info, msglvl_t msglevel)
Definition resolve.c:324
bool get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits, msglvl_t msglevel)
Translate an IPv6 addr or hostname from string form to in6_addr.
Definition resolve.c:489
int get_cached_dns_entry(struct cached_dns_entry *dns_cache, const char *hostname, const char *servname, int ai_family, unsigned int resolve_flags, struct addrinfo **ai)
get_cached_dns_entry return 0 on success and -1 otherwise.
Definition resolve.c:506
void do_preresolve(struct context *c)
Definition resolve.c:573
static const char * getaddrinfo_addr_family_name(int af)
Small helper function for openvpn_getaddrinfo to print the address family when resolving fails.
Definition resolve.c:63
unsigned int sf2gaf(const unsigned int getaddr_flags, const unsigned int sockflags)
Convert sockflags/getaddr_flags into getaddr_flags.
Definition resolve.c:42
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition resolve.c:442
DNS resolution.
#define GETADDR_CACHE_MASK
Definition resolve.h:51
#define GETADDR_MSG_VIRT_OUT
Definition resolve.h:44
#define GETADDR_TRY_ONCE
Definition resolve.h:45
#define GETADDR_PASSIVE
Definition resolve.h:48
#define GETADDR_FATAL
Definition resolve.h:39
#define GETADDR_UPDATE_MANAGEMENT_STATE
Definition resolve.h:46
#define GETADDR_HOST_ORDER
Definition resolve.h:40
#define GETADDR_RANDOMIZE
Definition resolve.h:47
#define GETADDR_DATAGRAM
Definition resolve.h:49
#define GETADDR_FATAL_ON_SIGNAL
Definition resolve.h:42
#define GETADDR_RESOLVE
Definition resolve.h:38
#define GETADDR_MENTION_RESOLVE_RETRY
Definition resolve.h:41
#define GETADDR_WARN_ON_SIGNAL
Definition resolve.h:43
void throw_signal_soft(const int signum, const char *signal_text)
Throw a soft global signal.
Definition sig.c:204
int signal_reset(struct signal_info *si, int signum)
Clear the signal if its current value equals signum.
Definition sig.c:262
static void get_signal(volatile int *sig)
Copy the global signal_received (if non-zero) to the passed-in argument sig.
Definition sig.h:109
#define SF_HOST_RANDOMIZE
Definition socket.h:202
static bool proto_is_dgram(int proto)
Return if the protocol is datagram (UDP).
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
Definition resolve.h:89
const char * hostname
Definition resolve.h:90
int ai_family
Definition resolve.h:92
const char * servname
Definition resolve.h:91
unsigned int flags
Definition resolve.h:93
struct addrinfo * ai
Definition resolve.h:94
struct cached_dns_entry * next
Definition resolve.h:95
Definition options.h:109
struct local_list * local_list
Definition options.h:110
bool bind_local
Definition options.h:120
const char * remote
Definition options.h:116
const char * socks_proxy_port
Definition options.h:126
struct http_proxy_options * http_proxy_options
Definition options.h:124
const char * remote_port
Definition options.h:115
const char * socks_proxy_server
Definition options.h:125
int proto
Definition options.h:111
sa_family_t af
Definition options.h:112
unsigned int flags
Definition options.h:164
struct connection_entry ** array
Definition options.h:206
struct cached_dns_entry * dns_cache
Definition openvpn.h:168
Contains all state information for one tunnel.
Definition openvpn.h:471
struct options options
Options loaded from command line or configuration file.
Definition openvpn.h:472
struct gc_arena gc
Garbage collection arena for allocations done in the scope of this context structure.
Definition openvpn.h:492
struct context_1 c1
Level 1 context.
Definition openvpn.h:515
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
const char * port
Definition proxy.h:47
const char * server
Definition proxy.h:46
Definition options.h:102
const char * port
Definition options.h:104
const char * local
Definition options.h:103
struct local_entry ** array
Definition options.h:198
int resolve_retry_seconds
Definition options.h:367
struct connection_list * connection_list
Definition options.h:295
const char * ip_remote_hint
Definition options.h:369
unsigned int sockflags
Definition options.h:421
volatile int signal_received
Definition sig.h:42
#define SIGHUP
Definition syshead.h:55
unsigned short sa_family_t
Definition syshead.h:409
#define SIGUSR1
Definition syshead.h:57
uint32_t in_addr_t
Definition syshead.h:52
struct gc_arena gc
Definition test_ssl.c:122