OpenVPN
dns.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single 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) 2022-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 "dns.h"
30#include "socket_util.h"
31#include "options.h"
32#include "run_command.h"
33
34#ifdef _WIN32
35#include "win32.h"
36#include "openvpn-msg.h"
37#endif
38
46static bool
47dns_server_port_parse(in_port_t *port, char *port_str)
48{
49 char *endptr;
50 errno = 0;
51 unsigned long tmp = strtoul(port_str, &endptr, 10);
52 if (errno || *endptr != '\0' || tmp == 0 || tmp > UINT16_MAX)
53 {
54 return false;
55 }
56 *port = (in_port_t)tmp;
57 return true;
58}
59
60bool
61dns_server_addr_parse(struct dns_server *server, const char *addr)
62{
63 if (!addr)
64 {
65 return false;
66 }
67
68 char addrcopy[INET6_ADDRSTRLEN] = { 0 };
69 size_t copylen = 0;
70 in_port_t port = 0;
71 sa_family_t af;
72
73 char *first_colon = strchr(addr, ':');
74 char *last_colon = strrchr(addr, ':');
75
76 if (!first_colon || first_colon == last_colon)
77 {
78 /* IPv4 address with optional port, e.g. 1.2.3.4 or 1.2.3.4:853 */
79 if (last_colon)
80 {
81 if (last_colon == addr || !dns_server_port_parse(&port, last_colon + 1))
82 {
83 return false;
84 }
85 copylen = first_colon - addr;
86 }
87 af = AF_INET;
88 }
89 else
90 {
91 /* IPv6 address with optional port, e.g. ab::cd or [ab::cd]:853 */
92 if (addr[0] == '[')
93 {
94 addr += 1;
95 char *bracket = last_colon - 1;
96 if (*bracket != ']' || bracket == addr || !dns_server_port_parse(&port, last_colon + 1))
97 {
98 return false;
99 }
100 copylen = bracket - addr;
101 }
102 af = AF_INET6;
103 }
104
105 /* Copy the address part into a temporary buffer and use that */
106 if (copylen)
107 {
108 if (copylen >= sizeof(addrcopy))
109 {
110 return false;
111 }
112 strncpy(addrcopy, addr, copylen);
113 addr = addrcopy;
114 }
115
116 struct addrinfo *ai = NULL;
117 if (openvpn_getaddrinfo(0, addr, NULL, 0, NULL, af, &ai) != 0)
118 {
119 return false;
120 }
121
122 if (server->addr_count >= SIZE(server->addr))
123 {
124 return false;
125 }
126
127 if (ai->ai_family == AF_INET)
128 {
129 struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
130 server->addr[server->addr_count].in.a4.s_addr = sin->sin_addr.s_addr;
131 }
132 else
133 {
134 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
135 server->addr[server->addr_count].in.a6 = sin6->sin6_addr;
136 }
137
138 server->addr[server->addr_count].family = af;
139 server->addr[server->addr_count].port = port;
140 server->addr_count += 1;
141
142 freeaddrinfo(ai);
143 return true;
144}
145
146void
147dns_domain_list_append(struct dns_domain **entry, char **domains, struct gc_arena *gc)
148{
149 /* Fast forward to the end of the list */
150 while (*entry)
151 {
152 entry = &((*entry)->next);
153 }
154
155 /* Append all domains to the end of the list */
156 while (*domains)
157 {
158 ALLOC_OBJ_CLEAR_GC(*entry, struct dns_domain, gc);
159 struct dns_domain *new = *entry;
160 new->name = *domains++;
161 entry = &new->next;
162 }
163}
164
165bool
166dns_server_priority_parse(long *priority, const char *str, bool pulled)
167{
168 char *endptr;
169 const long min = pulled ? 0 : INT8_MIN;
170 const long max = INT8_MAX;
171 long prio = strtol(str, &endptr, 10);
172 if (*endptr != '\0' || prio < min || prio > max)
173 {
174 return false;
175 }
176 *priority = prio;
177 return true;
178}
179
180struct dns_server *
181dns_server_get(struct dns_server **entry, long priority, struct gc_arena *gc)
182{
183 struct dns_server *obj = *entry;
184 while (true)
185 {
186 if (!obj || obj->priority > priority)
187 {
188 ALLOC_OBJ_CLEAR_GC(*entry, struct dns_server, gc);
189 (*entry)->next = obj;
190 (*entry)->priority = priority;
191 return *entry;
192 }
193 else if (obj->priority == priority)
194 {
195 return obj;
196 }
197 entry = &obj->next;
198 obj = *entry;
199 }
200}
201
202bool
203dns_options_verify(int msglevel, const struct dns_options *o)
204{
205 const struct dns_server *server = o->servers ? o->servers : o->servers_prepull;
206 while (server)
207 {
208 if (server->addr_count == 0)
209 {
210 msg(msglevel, "ERROR: dns server %ld does not have an address assigned",
211 server->priority);
212 return false;
213 }
214 server = server->next;
215 }
216 return true;
217}
218
219static struct dns_domain *
220clone_dns_domains(const struct dns_domain *domain, struct gc_arena *gc)
221{
222 struct dns_domain *new_list = NULL;
223 struct dns_domain **new_entry = &new_list;
224
225 while (domain)
226 {
227 ALLOC_OBJ_CLEAR_GC(*new_entry, struct dns_domain, gc);
228 struct dns_domain *new_domain = *new_entry;
229 *new_domain = *domain;
230 new_entry = &new_domain->next;
231 domain = domain->next;
232 }
233
234 return new_list;
235}
236
237static struct dns_server *
238clone_dns_servers(const struct dns_server *server, struct gc_arena *gc)
239{
240 struct dns_server *new_list = NULL;
241 struct dns_server **new_entry = &new_list;
242
243 while (server)
244 {
245 ALLOC_OBJ_CLEAR_GC(*new_entry, struct dns_server, gc);
246 struct dns_server *new_server = *new_entry;
247 *new_server = *server;
248 new_server->domains = clone_dns_domains(server->domains, gc);
249 new_entry = &new_server->next;
250 server = server->next;
251 }
252
253 return new_list;
254}
255
256struct dns_options
257clone_dns_options(const struct dns_options *o, struct gc_arena *gc)
258{
259 struct dns_options clone;
260
261 memset(&clone, 0, sizeof(clone));
263 clone.servers = clone_dns_servers(o->servers, gc);
265 clone.updown = o->updown;
266 clone.updown_flags = o->updown_flags;
267
268 return clone;
269}
270
271void
273{
274 o->servers_prepull = o->servers;
275 o->servers = NULL;
276}
277
278void
280{
281 struct dns_server **entry = &o->servers;
282 struct dns_server *server = *entry;
283 struct dns_server *server_pp = o->servers_prepull;
284
285 while (server && server_pp)
286 {
287 if (server->priority > server_pp->priority)
288 {
289 /* Merge static server in front of pulled one */
290 struct dns_server *next_pp = server_pp->next;
291 server_pp->next = server;
292 *entry = server_pp;
293 server = *entry;
294 server_pp = next_pp;
295 }
296 else if (server->priority == server_pp->priority)
297 {
298 /* Pulled server overrides static one */
299 server_pp = server_pp->next;
300 }
301 entry = &server->next;
302 server = *entry;
303 }
304
305 /* Append remaining local servers */
306 if (server_pp)
307 {
308 *entry = server_pp;
309 }
310
311 o->servers_prepull = NULL;
312}
313
314static const char *
316{
317 switch (dnssec)
318 {
319 case DNS_SECURITY_YES:
320 return "yes";
321
323 return "optional";
324
325 case DNS_SECURITY_NO:
326 return "no";
327
328 default:
329 return "unset";
330 }
331}
332
333static const char *
335{
336 switch (transport)
337 {
339 return "DoH";
340
342 return "DoT";
343
345 return "plain";
346
347 default:
348 return "unset";
349 }
350}
351
352#ifdef _WIN32
353
354static void
355make_domain_list(const char *what, const struct dns_domain *src, bool nrpt_domains, char *dst,
356 size_t dst_size)
357{
358 /* NRPT domains need two \0 at the end for REG_MULTI_SZ
359 * and a leading '.' added in front of the domain name */
360 size_t term_size = nrpt_domains ? 2 : 1;
361 size_t leading_dot = nrpt_domains ? 1 : 0;
362 size_t offset = 0;
363
364 memset(dst, 0, dst_size);
365
366 while (src)
367 {
368 size_t len = strlen(src->name);
369 if (offset + leading_dot + len + term_size > dst_size)
370 {
371 msg(M_WARN, "WARNING: %s truncated", what);
372 if (offset)
373 {
374 /* Remove trailing comma */
375 *(dst + offset - 1) = '\0';
376 }
377 break;
378 }
379
380 if (leading_dot)
381 {
382 *(dst + offset++) = '.';
383 }
384 strncpy(dst + offset, src->name, len);
385 offset += len;
386
387 src = src->next;
388 if (src)
389 {
390 *(dst + offset++) = ',';
391 }
392 }
393}
394
395static void
396run_up_down_service(bool add, const struct options *o, const struct tuntap *tt)
397{
398 const struct dns_server *server = o->dns_options.servers;
399 const struct dns_domain *search_domains = o->dns_options.search_domains;
400
401 while (true)
402 {
403 if (!server)
404 {
405 if (add)
406 {
407 msg(M_WARN, "WARNING: setting DNS failed, no compatible server profile");
408 }
409 return;
410 }
411
412 bool only_standard_server_ports = true;
413 for (size_t i = 0; i < NRPT_ADDR_NUM; ++i)
414 {
415 if (server->addr[i].port && server->addr[i].port != 53)
416 {
417 only_standard_server_ports = false;
418 break;
419 }
420 }
421 if ((server->transport == DNS_TRANSPORT_UNSET || server->transport == DNS_TRANSPORT_PLAIN)
422 && only_standard_server_ports)
423 {
424 break; /* found compatible server */
425 }
426
427 server = server->next;
428 }
429
430 ack_message_t ack;
433 0 },
434 .iface = { .index = tt->adapter_index, .name = "" },
435 .flags = server->dnssec == DNS_SECURITY_NO ? 0 : nrpt_dnssec,
436 };
437 strncpynt(nrpt.iface.name, tt->actual_name, sizeof(nrpt.iface.name));
438
439 for (size_t i = 0; i < NRPT_ADDR_NUM; ++i)
440 {
441 if (server->addr[i].family == AF_UNSPEC)
442 {
443 /* No more addresses */
444 break;
445 }
446
447 if (inet_ntop(server->addr[i].family, &server->addr[i].in, nrpt.addresses[i],
449 == NULL)
450 {
451 msg(M_WARN, "WARNING: could not convert dns server address");
452 }
453 }
454
455 make_domain_list("dns server resolve domains", server->domains, true, nrpt.resolve_domains,
456 sizeof(nrpt.resolve_domains));
457
458 make_domain_list("dns search domains", search_domains, false, nrpt.search_domains,
459 sizeof(nrpt.search_domains));
460
461 msg(D_LOW, "%s NRPT DNS%s%s on '%s' (if_index = %d) using service",
462 (add ? "Setting" : "Deleting"), nrpt.resolve_domains[0] != 0 ? ", resolve domains" : "",
463 nrpt.search_domains[0] != 0 ? ", search domains" : "", nrpt.iface.name, nrpt.iface.index);
464
465 send_msg_iservice(o->msg_channel, &nrpt, sizeof(nrpt), &ack, "DNS");
466}
467
468#else /* ifdef _WIN32 */
469
470static void
471setenv_dns_option(struct env_set *es, const char *format, int i, int j, const char *value)
472{
473 char name[64];
474 bool name_ok = false;
475
476 if (j < 0)
477 {
478 name_ok = snprintf(name, sizeof(name), format, i);
479 }
480 else
481 {
482 name_ok = snprintf(name, sizeof(name), format, i, j);
483 }
484
485 if (!name_ok)
486 {
487 msg(M_WARN, "WARNING: dns option setenv name buffer overflow");
488 }
489
490 setenv_str(es, name, value);
491}
492
493static void
494setenv_dns_options(const struct dns_options *o, struct env_set *es)
495{
496 struct gc_arena gc = gc_new();
497 const struct dns_server *s;
498 const struct dns_domain *d;
499 int i, j;
500
501 for (i = 1, d = o->search_domains; d != NULL; i++, d = d->next)
502 {
503 setenv_dns_option(es, "dns_search_domain_%d", i, -1, d->name);
504 }
505
506 for (i = 1, s = o->servers; s != NULL; i++, s = s->next)
507 {
508 for (j = 0; j < s->addr_count; ++j)
509 {
510 if (s->addr[j].family == AF_INET)
511 {
512 setenv_dns_option(es, "dns_server_%d_address_%d", i, j + 1,
513 print_in_addr_t(s->addr[j].in.a4.s_addr, IA_NET_ORDER, &gc));
514 }
515 else
516 {
517 setenv_dns_option(es, "dns_server_%d_address_%d", i, j + 1,
518 print_in6_addr(s->addr[j].in.a6, 0, &gc));
519 }
520 if (s->addr[j].port)
521 {
522 setenv_dns_option(es, "dns_server_%d_port_%d", i, j + 1,
523 print_in_port_t(s->addr[j].port, &gc));
524 }
525 }
526
527 if (s->domains)
528 {
529 for (j = 1, d = s->domains; d != NULL; j++, d = d->next)
530 {
531 setenv_dns_option(es, "dns_server_%d_resolve_domain_%d", i, j, d->name);
532 }
533 }
534
535 if (s->dnssec)
536 {
537 setenv_dns_option(es, "dns_server_%d_dnssec", i, -1, dnssec_value(s->dnssec));
538 }
539
540 if (s->transport)
541 {
542 setenv_dns_option(es, "dns_server_%d_transport", i, -1, transport_value(s->transport));
543 }
544 if (s->sni)
545 {
546 setenv_dns_option(es, "dns_server_%d_sni", i, -1, s->sni);
547 }
548 }
549
550 gc_free(&gc);
551}
552
553static void
554updown_env_set(bool up, const struct dns_options *o, const struct tuntap *tt, struct env_set *es)
555{
556 setenv_str(es, "dev", tt->actual_name);
557 setenv_str(es, "script_type", up ? "dns-up" : "dns-down");
558 setenv_dns_options(o, es);
559}
560
561static int
562do_run_up_down_command(bool up, const char *vars_file, const struct dns_options *o,
563 const struct tuntap *tt)
564{
565 struct gc_arena gc = gc_new();
566 struct argv argv = argv_new();
567 struct env_set *es = env_set_create(&gc);
568
569 if (vars_file)
570 {
571 setenv_str(es, "dns_vars_file", vars_file);
572 }
573 else
574 {
575 updown_env_set(up, o, tt, es);
576 }
577
578 argv_printf(&argv, "%s", o->updown);
580 int res;
581 if (dns_updown_user_set(o))
582 {
583 res = openvpn_run_script(&argv, es, S_EXITCODE, "dns updown");
584 }
585 else
586 {
587 res = openvpn_execve_check(&argv, es, S_EXITCODE, "WARNING: Failed running dns updown");
588 }
589 argv_free(&argv);
590 gc_free(&gc);
591 return res;
592}
593
594static bool
595run_updown_runner(bool up, struct options *o, const struct tuntap *tt,
596 struct dns_updown_runner_info *updown_runner)
597{
598 int dns_pipe_fd[2];
599 int ack_pipe_fd[2];
600 if (pipe(dns_pipe_fd) != 0 || pipe(ack_pipe_fd) != 0)
601 {
602 msg(M_ERR | M_ERRNO, "run_dns_up_down: unable to create pipes");
603 return false;
604 }
605 updown_runner->pid = fork();
606 if (updown_runner->pid == -1)
607 {
608 msg(M_ERR | M_ERRNO, "run_dns_up_down: unable to fork");
609 close(dns_pipe_fd[0]);
610 close(dns_pipe_fd[1]);
611 close(ack_pipe_fd[0]);
612 close(ack_pipe_fd[1]);
613 return false;
614 }
615 else if (updown_runner->pid > 0)
616 {
617 /* Parent process */
618 close(dns_pipe_fd[0]);
619 close(ack_pipe_fd[1]);
620 updown_runner->fds[0] = ack_pipe_fd[0];
621 updown_runner->fds[1] = dns_pipe_fd[1];
622 }
623 else
624 {
625 /* Script runner process, close unused FDs */
626 for (int fd = 3; fd < 100; ++fd)
627 {
628 if (fd != dns_pipe_fd[0] && fd != ack_pipe_fd[1])
629 {
630 close(fd);
631 }
632 }
633
634 /* Ignore signals */
635 signal(SIGINT, SIG_IGN);
636 signal(SIGHUP, SIG_IGN);
637 signal(SIGTERM, SIG_IGN);
638 signal(SIGUSR1, SIG_IGN);
639 signal(SIGUSR2, SIG_IGN);
640 signal(SIGPIPE, SIG_IGN);
641
642 while (1)
643 {
644 ssize_t rlen, wlen;
645 char path[PATH_MAX];
646
647 /* Block here until parent sends a path */
648 rlen = read(dns_pipe_fd[0], &path, sizeof(path));
649 if (rlen < 1)
650 {
651 if (rlen == -1 && errno == EINTR)
652 {
653 continue;
654 }
655 close(dns_pipe_fd[0]);
656 close(ack_pipe_fd[1]);
657 exit(0);
658 }
659
660 path[sizeof(path) - 1] = '\0';
661 int res = do_run_up_down_command(up, path, &o->dns_options, tt);
662 platform_unlink(path);
663
664 /* Unblock parent process */
665 while (1)
666 {
667 wlen = write(ack_pipe_fd[1], &res, sizeof(res));
668 if ((wlen == -1 && errno != EINTR) || wlen < sizeof(res))
669 {
670 /* Not much we can do about errors but exit */
671 close(dns_pipe_fd[0]);
672 close(ack_pipe_fd[1]);
673 exit(0);
674 }
675 else if (wlen == sizeof(res))
676 {
677 break;
678 }
679 }
680
681 up = !up; /* do the opposite next time */
682 }
683 }
684
685 return true;
686}
687
688static void
689run_up_down_command(bool up, struct options *o, const struct tuntap *tt,
690 struct dns_updown_runner_info *updown_runner)
691{
692 struct dns_options *dns = &o->dns_options;
693 if (!dns->updown || (o->up_script && !dns_updown_user_set(dns) && !dns_updown_forced(dns)))
694 {
695 return;
696 }
697
698 int status = -1;
699
700 if (!updown_runner->required)
701 {
702 /* Run dns updown directly */
703 status = do_run_up_down_command(up, NULL, dns, tt);
704 }
705 else
706 {
707 if (updown_runner->pid < 1)
708 {
709 /* Need to set up privilege preserving child first */
710 if (!run_updown_runner(up, o, tt, updown_runner))
711 {
712 return;
713 }
714 }
715
716 struct gc_arena gc = gc_new();
717 const char *dvf = platform_create_temp_file(o->tmp_dir, "dvf", &gc);
718 if (!dvf)
719 {
720 msg(M_ERR, "could not create dns vars file");
721 goto out_free;
722 }
723
724 struct env_set *es = env_set_create(&gc);
725 updown_env_set(up, &o->dns_options, tt, es);
727
728 int wfd = updown_runner->fds[1];
729 size_t dvf_size = strlen(dvf) + 1;
730 while (1)
731 {
732 ssize_t len = write(wfd, dvf, dvf_size);
733 if (len < dvf_size)
734 {
735 if (len == -1 && errno == EINTR)
736 {
737 continue;
738 }
739 msg(M_ERR | M_ERRNO, "could not send dns vars filename");
740 }
741 break;
742 }
743
744 int rfd = updown_runner->fds[0];
745 while (1)
746 {
747 ssize_t len = read(rfd, &status, sizeof(status));
748 if (len < sizeof(status))
749 {
750 if (len == -1 && errno == EINTR)
751 {
752 continue;
753 }
754 msg(M_ERR | M_ERRNO, "could not receive dns updown status");
755 }
756 break;
757 }
758
759out_free:
760 gc_free(&gc);
761 }
762
763 msg(M_INFO, "dns %s command exited with status %d", up ? "up" : "down", status);
764}
765
766#endif /* _WIN32 */
767
768void
770{
771 struct gc_arena gc = gc_new();
772
773 int i = 1;
774 struct dns_server *server = o->servers_prepull ? o->servers_prepull : o->servers;
775 while (server)
776 {
777 msg(D_SHOW_PARMS, " DNS server #%d:", i++);
778
779 for (int j = 0; j < server->addr_count; ++j)
780 {
781 const char *addr;
782 const char *fmt_port;
783 if (server->addr[j].family == AF_INET)
784 {
785 addr = print_in_addr_t(server->addr[j].in.a4.s_addr, IA_NET_ORDER, &gc);
786 fmt_port = " address = %s:%s";
787 }
788 else
789 {
790 addr = print_in6_addr(server->addr[j].in.a6, 0, &gc);
791 fmt_port = " address = [%s]:%s";
792 }
793
794 if (server->addr[j].port)
795 {
796 const char *port = print_in_port_t(server->addr[j].port, &gc);
797 msg(D_SHOW_PARMS, fmt_port, addr, port);
798 }
799 else
800 {
801 msg(D_SHOW_PARMS, " address = %s", addr);
802 }
803 }
804
805 if (server->dnssec)
806 {
807 msg(D_SHOW_PARMS, " dnssec = %s", dnssec_value(server->dnssec));
808 }
809
810 if (server->transport)
811 {
812 msg(D_SHOW_PARMS, " transport = %s", transport_value(server->transport));
813 }
814 if (server->sni)
815 {
816 msg(D_SHOW_PARMS, " sni = %s", server->sni);
817 }
818
819 struct dns_domain *domain = server->domains;
820 if (domain)
821 {
822 msg(D_SHOW_PARMS, " resolve domains:");
823 while (domain)
824 {
825 msg(D_SHOW_PARMS, " %s", domain->name);
826 domain = domain->next;
827 }
828 }
829
830 server = server->next;
831 }
832
833 struct dns_domain *search_domain = o->search_domains;
834 if (search_domain)
835 {
836 msg(D_SHOW_PARMS, " DNS search domains:");
837 while (search_domain)
838 {
839 msg(D_SHOW_PARMS, " %s", search_domain->name);
840 search_domain = search_domain->next;
841 }
842 }
843
844 gc_free(&gc);
845}
846
847void
848run_dns_up_down(bool up, struct options *o, const struct tuntap *tt,
849 struct dns_updown_runner_info *duri)
850{
851 if (!o->dns_options.servers)
852 {
853 return;
854 }
855#ifdef _WIN32
856 /* Don't use iservice in DHCP mode */
857 struct tuntap_options *tto = &o->tuntap_options;
859 {
860 return;
861 }
862#endif
863
864 /* Warn about adding servers of unsupported AF */
865 const struct dns_server *s = o->dns_options.servers;
866 while (up && s)
867 {
868 size_t bad_count = 0;
869 for (size_t i = 0; i < s->addr_count; ++i)
870 {
871 if ((s->addr[i].family == AF_INET6 && !tt->did_ifconfig_ipv6_setup)
872 || (s->addr[i].family == AF_INET && !tt->did_ifconfig_setup))
873 {
874 ++bad_count;
875 }
876 }
877 if (bad_count == s->addr_count)
878 {
879 msg(M_WARN,
880 "DNS server %ld only has address(es) from a family "
881 "the tunnel is not configured for - it will not be reachable",
882 s->priority);
883 }
884 else if (bad_count)
885 {
886 msg(M_WARN,
887 "DNS server %ld has address(es) from a family "
888 "the tunnel is not configured for",
889 s->priority);
890 }
891 s = s->next;
892 }
893
894#ifdef _WIN32
895 run_up_down_service(up, o, tt);
896#else
897 run_up_down_command(up, o, tt, duri);
898#endif /* ifdef _WIN32 */
899}
void argv_msg(const int msglev, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
Definition argv.c:242
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:101
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:438
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:87
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1079
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static struct gc_arena gc_new(void)
Definition buffer.h:1007
bool dns_options_verify(int msglevel, const struct dns_options *o)
Checks validity of DNS options.
Definition dns.c:203
void dns_domain_list_append(struct dns_domain **entry, char **domains, struct gc_arena *gc)
Appends DNS domain parameters to a linked list.
Definition dns.c:147
static const char * dnssec_value(const enum dns_security dnssec)
Definition dns.c:315
void run_dns_up_down(bool up, struct options *o, const struct tuntap *tt, struct dns_updown_runner_info *duri)
Invokes the action associated with bringing DNS up or down.
Definition dns.c:848
void dns_options_postprocess_pull(struct dns_options *o)
Merges pulled DNS servers with static ones into an ordered list.
Definition dns.c:279
bool dns_server_addr_parse(struct dns_server *server, const char *addr)
Parses a string IPv4 or IPv6 address and optional colon separated port, into a in_addr or in6_addr re...
Definition dns.c:61
struct dns_server * dns_server_get(struct dns_server **entry, long priority, struct gc_arena *gc)
Find or create DNS server with priority in a linked list.
Definition dns.c:181
static void run_up_down_service(bool add, const struct options *o, const struct tuntap *tt)
Definition dns.c:396
static void make_domain_list(const char *what, const struct dns_domain *src, bool nrpt_domains, char *dst, size_t dst_size)
Definition dns.c:355
static struct dns_server * clone_dns_servers(const struct dns_server *server, struct gc_arena *gc)
Definition dns.c:238
static struct dns_domain * clone_dns_domains(const struct dns_domain *domain, struct gc_arena *gc)
Definition dns.c:220
static const char * transport_value(const enum dns_server_transport transport)
Definition dns.c:334
bool dns_server_priority_parse(long *priority, const char *str, bool pulled)
Parses a string DNS server priority and validates it.
Definition dns.c:166
struct dns_options clone_dns_options(const struct dns_options *o, struct gc_arena *gc)
Makes a deep copy of the passed DNS options.
Definition dns.c:257
void show_dns_options(const struct dns_options *o)
Prints configured DNS options.
Definition dns.c:769
static bool dns_server_port_parse(in_port_t *port, char *port_str)
Parses a string as port and stores it.
Definition dns.c:47
void dns_options_preprocess_pull(struct dns_options *o)
Saves and resets the server options, so that pulled ones don't mix in.
Definition dns.c:272
static bool dns_updown_user_set(const struct dns_options *o)
Returns whether dns-updown is user defined.
Definition dns.h:217
dns_security
Definition dns.h:31
@ DNS_SECURITY_NO
Definition dns.h:33
@ DNS_SECURITY_YES
Definition dns.h:34
@ DNS_SECURITY_OPTIONAL
Definition dns.h:35
static bool dns_updown_forced(const struct dns_options *o)
Returns whether dns-updown is forced to run.
Definition dns.h:228
dns_server_transport
Definition dns.h:39
@ DNS_TRANSPORT_PLAIN
Definition dns.h:41
@ DNS_TRANSPORT_UNSET
Definition dns.h:40
@ DNS_TRANSPORT_TLS
Definition dns.h:43
@ DNS_TRANSPORT_HTTPS
Definition dns.h:42
void env_set_write_file(const char *path, const struct env_set *es)
Write a struct env_set to a file.
Definition env_set.c:238
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:307
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
#define D_SHOW_PARMS
Definition errlevel.h:95
#define D_LOW
Definition errlevel.h:96
#define M_INFO
Definition errlevel.h:54
static SERVICE_STATUS status
Definition interactive.c:51
@ write
@ read
@ nrpt_dnssec
@ msg_add_nrpt_cfg
Definition openvpn-msg.h:38
@ msg_del_nrpt_cfg
Definition openvpn-msg.h:39
#define NRPT_ADDR_SIZE
#define NRPT_ADDR_NUM
#define SIZE(x)
Definition basic.h:29
#define M_ERR
Definition error.h:104
#define msg(flags,...)
Definition error.h:150
#define M_WARN
Definition error.h:90
#define M_ERRNO
Definition error.h:93
const char * platform_create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
Create a temporary file in directory, returns the filename of the created file.
Definition platform.c:544
bool platform_unlink(const char *filename)
Definition platform.c:491
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
#define S_EXITCODE
Instead of returning 1/0 for success/fail, return exit code when between 0 and 255 and -1 otherwise.
Definition run_command.h:53
static int openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook)
Will run a script and return the exit code of the script if between 0 and 255, -1 otherwise.
Definition run_command.h:89
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)
const char * print_in_port_t(in_port_t port, struct gc_arena *gc)
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)
#define IA_NET_ORDER
Definition socket_util.h:90
Definition argv.h:35
struct dns_domain * next
Definition dns.h:55
const char * name
Definition dns.h:56
struct dns_server * servers
Definition dns.h:117
const char * updown
Definition dns.h:119
struct dns_server * servers_prepull
Definition dns.h:116
enum dns_updown_flags updown_flags
Definition dns.h:120
struct dns_domain * search_domains
Definition dns.h:115
struct in_addr a4
Definition dns.h:63
union dns_server_addr::@0 in
sa_family_t family
Definition dns.h:66
struct in6_addr a6
Definition dns.h:64
in_port_t port
Definition dns.h:67
struct dns_server_addr addr[8]
Definition dns.h:75
enum dns_security dnssec
Definition dns.h:77
struct dns_server * next
Definition dns.h:72
long priority
Definition dns.h:73
size_t addr_count
Definition dns.h:74
struct dns_domain * domains
Definition dns.h:76
enum dns_server_transport transport
Definition dns.h:78
const char * sni
Definition dns.h:79
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
char name[256]
Definition openvpn-msg.h:70
message_header_t header
nrpt_address_t addresses[NRPT_ADDR_NUM]
const char * tmp_dir
Definition options.h:469
const char * up_script
Definition options.h:385
HANDLE msg_channel
Definition options.h:695
struct tuntap_options tuntap_options
Definition options.h:371
struct dns_options dns_options
Definition options.h:314
int ip_win32_type
Definition tun.h:85
Definition tun.h:183
DWORD adapter_index
Definition tun.h:234
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
Definition tun.h:201
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
Definition tun.h:197
char * actual_name
Definition tun.h:207
unsigned short sa_family_t
Definition syshead.h:396
struct env_set * es
char ** res
struct gc_arena gc
Definition test_ssl.c:154
#define IPW32_SET_ADAPTIVE
Definition tun.h:83
#define IPW32_SET_DHCP_MASQ
Definition tun.h:82
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
Definition win32.c:1422