52 unsigned long tmp = strtoul(port_str, &endptr, 10);
53 if (errno || *endptr !=
'\0' || tmp == 0 || tmp > UINT16_MAX)
57 *port = (in_port_t)tmp;
69 char addrcopy[INET6_ADDRSTRLEN] = {0};
74 char *first_colon = strchr(addr,
':');
75 char *last_colon = strrchr(addr,
':');
77 if (!first_colon || first_colon == last_colon)
86 copylen = first_colon - addr;
96 char *bracket = last_colon - 1;
101 copylen = bracket - addr;
109 if (copylen >=
sizeof(addrcopy))
113 strncpy(addrcopy, addr, copylen);
117 struct addrinfo *ai = NULL;
128 if (ai->ai_family == AF_INET)
130 struct sockaddr_in *sin = (
struct sockaddr_in *)ai->ai_addr;
135 struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)ai->ai_addr;
153 entry = &((*entry)->next);
161 new->
name = *domains++;
170 const long min = pulled ? 0 : INT8_MIN;
171 const long max = INT8_MAX;
172 long prio = strtol(str, &endptr, 10);
173 if (*endptr !=
'\0' || prio < min || prio > max)
190 (*entry)->next = obj;
212 msg(msglevel,
"ERROR: dns server %ld does not have an address assigned", server->
priority);
215 server = server->
next;
230 *new_domain = *domain;
231 new_entry = &new_domain->
next;
232 domain = domain->
next;
248 *new_server = *server;
250 new_entry = &new_server->
next;
251 server = server->
next;
262 memset(&clone, 0,
sizeof(clone));
286 while (server && server_pp)
292 server_pp->
next = server;
300 server_pp = server_pp->
next;
302 entry = &server->
next;
357 bool nrpt_domains,
char *dst,
size_t dst_size)
361 size_t term_size = nrpt_domains ? 2 : 1;
362 size_t leading_dot = nrpt_domains ? 1 : 0;
365 memset(dst, 0, dst_size);
369 size_t len = strlen(src->
name);
370 if (offset + leading_dot + len + term_size > dst_size)
372 msg(
M_WARN,
"WARNING: %s truncated", what);
376 *(dst + offset - 1) =
'\0';
383 *(dst + offset++) =
'.';
385 strncpy(dst + offset, src->
name, len);
391 *(dst + offset++) =
',';
408 msg(
M_WARN,
"WARNING: setting DNS failed, no compatible server profile");
413 bool only_standard_server_ports =
true;
418 only_standard_server_ports =
false;
423 && only_standard_server_ports)
428 server = server->
next;
454 msg(
M_WARN,
"WARNING: could not convert dns server address");
471 const char *format,
int i,
int j,
475 bool name_ok =
false;
479 name_ok = snprintf(
name,
sizeof(
name), format, i);
483 name_ok = snprintf(
name,
sizeof(
name), format, i, j);
488 msg(
M_WARN,
"WARNING: dns option setenv name buffer overflow");
504 setenv_dns_option(
es,
"dns_search_domain_%d", i, -1, d->
name);
507 for (i = 1, s = o->
servers; s != NULL; i++, s = s->
next)
513 setenv_dns_option(
es,
"dns_server_%d_address_%d", i, j + 1,
518 setenv_dns_option(
es,
"dns_server_%d_address_%d", i, j + 1,
523 setenv_dns_option(
es,
"dns_server_%d_port_%d", i, j + 1,
530 for (j = 1, d = s->
domains; d != NULL; j++, d = d->
next)
532 setenv_dns_option(
es,
"dns_server_%d_resolve_domain_%d", i, j, d->name);
538 setenv_dns_option(
es,
"dns_server_%d_dnssec", i, -1,
544 setenv_dns_option(
es,
"dns_server_%d_transport", i, -1,
549 setenv_dns_option(
es,
"dns_server_%d_sni", i, -1, s->
sni);
560 setenv_str(
es,
"script_type", up ?
"dns-up" :
"dns-down");
561 setenv_dns_options(o,
es);
565do_run_up_down_command(
bool up,
const char *vars_file,
const struct dns_options *o,
const struct tuntap *tt)
577 updown_env_set(up, o, tt,
es);
601 if (pipe(dns_pipe_fd) != 0
602 || pipe(ack_pipe_fd) != 0)
607 updown_runner->pid = fork();
608 if (updown_runner->pid == -1)
611 close(dns_pipe_fd[0]);
612 close(dns_pipe_fd[1]);
613 close(ack_pipe_fd[0]);
614 close(ack_pipe_fd[1]);
617 else if (updown_runner->pid > 0)
620 close(dns_pipe_fd[0]);
621 close(ack_pipe_fd[1]);
622 updown_runner->
fds[0] = ack_pipe_fd[0];
623 updown_runner->
fds[1] = dns_pipe_fd[1];
628 for (
int fd = 3; fd < 100; ++fd)
630 if (fd != dns_pipe_fd[0]
631 && fd != ack_pipe_fd[1])
638 signal(SIGINT, SIG_IGN);
639 signal(SIGHUP, SIG_IGN);
640 signal(SIGTERM, SIG_IGN);
641 signal(SIGUSR1, SIG_IGN);
642 signal(SIGUSR2, SIG_IGN);
643 signal(SIGPIPE, SIG_IGN);
651 rlen =
read(dns_pipe_fd[0], &path,
sizeof(path));
654 if (rlen == -1 && errno == EINTR)
658 close(dns_pipe_fd[0]);
659 close(ack_pipe_fd[1]);
663 path[
sizeof(path) - 1] =
'\0';
664 int res = do_run_up_down_command(up, path, &o->
dns_options, tt);
670 wlen =
write(ack_pipe_fd[1], &res,
sizeof(res));
671 if ((wlen == -1 && errno != EINTR) || wlen <
sizeof(res))
674 close(dns_pipe_fd[0]);
675 close(ack_pipe_fd[1]);
678 else if (wlen ==
sizeof(res))
708 if (updown_runner->pid < 1)
711 if (!run_updown_runner(up, o, tt, updown_runner))
721 msg(
M_ERR,
"could not create dns vars file");
729 int wfd = updown_runner->
fds[1];
730 size_t dvf_size = strlen(dvf) + 1;
733 ssize_t len =
write(wfd, dvf, dvf_size);
736 if (len == -1 && errno == EINTR)
745 int rfd = updown_runner->
fds[0];
751 if (len == -1 && errno == EINTR)
764 msg(
M_INFO,
"dns %s command exited with status %d", up ?
"up" :
"down",
status);
783 const char *fmt_port;
787 fmt_port =
" address = %s:%s";
792 fmt_port =
" address = [%s]:%s";
827 domain = domain->
next;
831 server = server->
next;
838 while (search_domain)
841 search_domain = search_domain->
next;
860 size_t bad_count = 0;
871 msg(
M_WARN,
"DNS server %ld only has address(es) from a family "
872 "the tunnel is not configured for - it will not be reachable",
877 msg(
M_WARN,
"DNS server %ld has address(es) from a family "
878 "the tunnel is not configured for", s->
priority);
886 run_up_down_command(up, o, tt, duri);
void argv_msg(const int msglev, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
static void strncpynt(char *dest, const char *src, size_t maxlen)
static void gc_free(struct gc_arena *a)
static struct gc_arena gc_new(void)
bool dns_options_verify(int msglevel, const struct dns_options *o)
Checks validity of DNS options.
void dns_domain_list_append(struct dns_domain **entry, char **domains, struct gc_arena *gc)
Appends DNS domain parameters to a linked list.
static const char * dnssec_value(const enum dns_security dnssec)
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.
void dns_options_postprocess_pull(struct dns_options *o)
Merges pulled DNS servers with static ones into an ordered list.
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...
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.
static void run_up_down_service(bool add, const struct options *o, const struct tuntap *tt)
static void make_domain_list(const char *what, const struct dns_domain *src, bool nrpt_domains, char *dst, size_t dst_size)
static struct dns_server * clone_dns_servers(const struct dns_server *server, struct gc_arena *gc)
static struct dns_domain * clone_dns_domains(const struct dns_domain *domain, struct gc_arena *gc)
static const char * transport_value(const enum dns_server_transport transport)
bool dns_server_priority_parse(long *priority, const char *str, bool pulled)
Parses a string DNS server priority and validates it.
struct dns_options clone_dns_options(const struct dns_options *o, struct gc_arena *gc)
Makes a deep copy of the passed DNS options.
void show_dns_options(const struct dns_options *o)
Prints configured DNS options.
static bool dns_server_port_parse(in_port_t *port, char *port_str)
Parses a string as port and stores it.
void dns_options_preprocess_pull(struct dns_options *o)
Saves and resets the server options, so that pulled ones don't mix in.
void env_set_write_file(const char *path, const struct env_set *es)
Write a struct env_set to a file.
void setenv_str(struct env_set *es, const char *name, const char *value)
struct env_set * env_set_create(struct gc_arena *gc)
static SERVICE_STATUS status
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.
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.
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)
struct dns_server * servers
struct dns_server * servers_prepull
struct dns_domain * search_domains
union dns_server_addr::@0 in
struct dns_server_addr addr[8]
struct dns_domain * domains
enum dns_server_transport transport
Garbage collection arena used to keep track of dynamically allocated memory.
char resolve_domains[512]
nrpt_address_t addresses[NRPT_ADDR_NUM]
struct dns_options dns_options
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
unsigned short sa_family_t
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)