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);
159 char *domain = *domains++;
178 const long min = pulled ? 0 : INT8_MIN;
179 const long max = INT8_MAX;
180 long prio = strtol(str, &endptr, 10);
181 if (*endptr !=
'\0' || prio < min || prio > max)
198 (*entry)->next = obj;
219 msg(msglevel,
"ERROR: dns server %ld does not have an address assigned",
223 server = server->
next;
238 *new_domain = *domain;
239 new_entry = &new_domain->
next;
240 domain = domain->
next;
256 *new_server = *server;
258 new_entry = &new_server->
next;
259 server = server->
next;
270 memset(&clone, 0,
sizeof(clone));
295 while (server && server_pp)
301 server_pp->
next = server;
309 server_pp = server_pp->
next;
311 entry = &server->
next;
370 size_t term_size = nrpt_domains ? 2 : 1;
371 size_t leading_dot = nrpt_domains ? 1 : 0;
374 memset(dst, 0, dst_size);
378 size_t len = strlen(src->
name);
379 if (offset + leading_dot + len + term_size > dst_size)
381 msg(
M_WARN,
"WARNING: %s truncated", what);
385 *(dst + offset - 1) =
'\0';
392 *(dst + offset++) =
'.';
394 strncpy(dst + offset, src->
name, len);
400 *(dst + offset++) =
',';
417 msg(
M_WARN,
"WARNING: setting DNS failed, no compatible server profile");
422 bool only_standard_server_ports =
true;
427 only_standard_server_ports =
false;
432 && only_standard_server_ports)
437 server = server->
next;
461 msg(
M_WARN,
"WARNING: could not convert dns server address");
471 msg(
D_LOW,
"%s NRPT DNS%s%s on '%s' (if_index = %d) using service",
472 (add ?
"Setting" :
"Deleting"), nrpt.
resolve_domains[0] != 0 ?
", resolve domains" :
"",
481setenv_dns_option(
struct env_set *
es,
const char *format,
int i,
int j,
const char *value)
484 bool name_ok =
false;
488 name_ok = snprintf(
name,
sizeof(
name), format,
i);
492 name_ok = snprintf(
name,
sizeof(
name), format,
i, j);
497 msg(
M_WARN,
"WARNING: dns option setenv name buffer overflow");
513 setenv_dns_option(
es,
"dns_search_domain_%d",
i, -1, d->
name);
522 setenv_dns_option(
es,
"dns_server_%d_address_%d",
i, j + 1,
527 setenv_dns_option(
es,
"dns_server_%d_address_%d",
i, j + 1,
532 setenv_dns_option(
es,
"dns_server_%d_port_%d",
i, j + 1,
539 for (j = 1, d = s->
domains; d != NULL; j++, d = d->
next)
541 setenv_dns_option(
es,
"dns_server_%d_resolve_domain_%d",
i, j, d->name);
556 setenv_dns_option(
es,
"dns_server_%d_sni",
i, -1, s->
sni);
567 setenv_str(
es,
"script_type", up ?
"dns-up" :
"dns-down");
568 setenv_dns_options(o,
es);
572do_run_up_down_command(
bool up,
const char *vars_file,
const struct dns_options *o,
585 updown_env_set(up, o, tt,
es);
605run_updown_runner(
bool up,
struct options *o,
const struct tuntap *tt,
610 if (pipe(dns_pipe_fd) != 0 || pipe(ack_pipe_fd) != 0)
615 updown_runner->pid = fork();
616 if (updown_runner->pid == -1)
619 close(dns_pipe_fd[0]);
620 close(dns_pipe_fd[1]);
621 close(ack_pipe_fd[0]);
622 close(ack_pipe_fd[1]);
625 else if (updown_runner->pid > 0)
628 close(dns_pipe_fd[0]);
629 close(ack_pipe_fd[1]);
630 updown_runner->
fds[0] = ack_pipe_fd[0];
631 updown_runner->
fds[1] = dns_pipe_fd[1];
636 for (
int fd = 3; fd < 100; ++fd)
638 if (fd != dns_pipe_fd[0] && fd != ack_pipe_fd[1])
645 signal(SIGINT, SIG_IGN);
646 signal(SIGHUP, SIG_IGN);
647 signal(SIGTERM, SIG_IGN);
648 signal(SIGUSR1, SIG_IGN);
649 signal(SIGUSR2, SIG_IGN);
650 signal(SIGPIPE, SIG_IGN);
657 ssize_t rlen =
read(dns_pipe_fd[0], &path,
sizeof(path));
660 if (rlen == -1 && errno == EINTR)
664 close(dns_pipe_fd[0]);
665 close(ack_pipe_fd[1]);
669 path[
sizeof(path) - 1] =
'\0';
676 ssize_t wlen =
write(ack_pipe_fd[1], &
res,
sizeof(
res));
677 if ((wlen == -1 && errno != EINTR) || wlen < (ssize_t)
sizeof(
res))
680 close(dns_pipe_fd[0]);
681 close(ack_pipe_fd[1]);
684 else if (wlen ==
sizeof(
res))
698run_up_down_command(
bool up,
struct options *o,
const struct tuntap *tt,
712 status = do_run_up_down_command(up, NULL, dns, tt);
716 if (updown_runner->pid < 1)
719 if (!run_updown_runner(up, o, tt, updown_runner))
729 msg(
M_ERR,
"could not create dns vars file");
737 int wfd = updown_runner->
fds[1];
738 ssize_t dvf_size = strlen(dvf) + 1;
741 ssize_t len =
write(wfd, dvf, dvf_size);
744 if (len == -1 && errno == EINTR)
753 int rfd = updown_runner->
fds[0];
757 if (len < (ssize_t)
sizeof(
status))
759 if (len == -1 && errno == EINTR)
772 msg(
M_INFO,
"dns %s command exited with status %d", up ?
"up" :
"down",
status);
791 const char *fmt_port;
795 fmt_port =
" address = %s:%s";
800 fmt_port =
" address = [%s]:%s";
835 domain = domain->
next;
839 server = server->
next;
846 while (search_domain)
849 search_domain = search_domain->
next;
877 size_t bad_count = 0;
889 "DNS server %ld only has address(es) from a family "
890 "the tunnel is not configured for - it will not be reachable",
896 "DNS server %ld has address(es) from a family "
897 "the tunnel is not configured for",
906 run_up_down_command(up, o, tt, duri);
void argv_msg(const msglvl_t msglevel, 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(msglvl_t msglevel, const struct dns_options *o)
Checks validity of DNS options.
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...
bool dns_domain_list_append(struct dns_domain **entry, char **domains, struct gc_arena *gc)
Appends safe DNS domain parameters to a linked list.
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.
static bool dns_updown_user_set(const struct dns_options *o)
Returns whether dns-updown is user defined.
static bool dns_updown_forced(const struct dns_options *o)
Returns whether dns-updown is forced to run.
static bool validate_domain(const char *domain)
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 dhcp_options from_dhcp
struct dns_server * servers_prepull
enum dns_updown_flags updown_flags
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 tuntap_options tuntap_options
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
#define IPW32_SET_ADAPTIVE
#define IPW32_SET_DHCP_MASQ
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)