51 unsigned long tmp = strtoul(port_str, &endptr, 10);
52 if (errno || *endptr !=
'\0' || tmp == 0 || tmp > UINT16_MAX)
56 *port = (in_port_t)tmp;
68 char addrcopy[INET6_ADDRSTRLEN] = { 0 };
73 char *first_colon = strchr(addr,
':');
74 char *last_colon = strrchr(addr,
':');
76 if (!first_colon || first_colon == last_colon)
85 copylen = first_colon - addr;
95 char *bracket = last_colon - 1;
100 copylen = bracket - addr;
108 if (copylen >=
sizeof(addrcopy))
112 strncpy(addrcopy, addr, copylen);
116 struct addrinfo *ai = NULL;
127 if (ai->ai_family == AF_INET)
129 struct sockaddr_in *sin = (
struct sockaddr_in *)ai->ai_addr;
134 struct sockaddr_in6 *sin6 = (
struct sockaddr_in6 *)ai->ai_addr;
152 entry = &((*entry)->next);
160 new->
name = *domains++;
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)
189 (*entry)->next = obj;
210 msg(msglevel,
"ERROR: dns server %ld does not have an address assigned",
214 server = server->
next;
229 *new_domain = *domain;
230 new_entry = &new_domain->
next;
231 domain = domain->
next;
247 *new_server = *server;
249 new_entry = &new_server->
next;
250 server = server->
next;
261 memset(&clone, 0,
sizeof(clone));
285 while (server && server_pp)
291 server_pp->
next = server;
299 server_pp = server_pp->
next;
301 entry = &server->
next;
360 size_t term_size = nrpt_domains ? 2 : 1;
361 size_t leading_dot = nrpt_domains ? 1 : 0;
364 memset(dst, 0, dst_size);
368 size_t len = strlen(src->
name);
369 if (offset + leading_dot + len + term_size > dst_size)
371 msg(
M_WARN,
"WARNING: %s truncated", what);
375 *(dst + offset - 1) =
'\0';
382 *(dst + offset++) =
'.';
384 strncpy(dst + offset, src->
name, len);
390 *(dst + offset++) =
',';
407 msg(
M_WARN,
"WARNING: setting DNS failed, no compatible server profile");
412 bool only_standard_server_ports =
true;
417 only_standard_server_ports =
false;
422 && only_standard_server_ports)
427 server = server->
next;
451 msg(
M_WARN,
"WARNING: could not convert dns server address");
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" :
"",
471setenv_dns_option(
struct env_set *
es,
const char *format,
int i,
int j,
const char *value)
474 bool name_ok =
false;
478 name_ok = snprintf(
name,
sizeof(
name), format,
i);
482 name_ok = snprintf(
name,
sizeof(
name), format,
i, j);
487 msg(
M_WARN,
"WARNING: dns option setenv name buffer overflow");
503 setenv_dns_option(
es,
"dns_search_domain_%d",
i, -1, d->
name);
512 setenv_dns_option(
es,
"dns_server_%d_address_%d",
i, j + 1,
517 setenv_dns_option(
es,
"dns_server_%d_address_%d",
i, j + 1,
522 setenv_dns_option(
es,
"dns_server_%d_port_%d",
i, j + 1,
529 for (j = 1, d = s->
domains; d != NULL; j++, d = d->
next)
531 setenv_dns_option(
es,
"dns_server_%d_resolve_domain_%d",
i, j, d->name);
546 setenv_dns_option(
es,
"dns_server_%d_sni",
i, -1, s->
sni);
557 setenv_str(
es,
"script_type", up ?
"dns-up" :
"dns-down");
558 setenv_dns_options(o,
es);
562do_run_up_down_command(
bool up,
const char *vars_file,
const struct dns_options *o,
575 updown_env_set(up, o, tt,
es);
595run_updown_runner(
bool up,
struct options *o,
const struct tuntap *tt,
600 if (pipe(dns_pipe_fd) != 0 || pipe(ack_pipe_fd) != 0)
605 updown_runner->pid = fork();
606 if (updown_runner->pid == -1)
609 close(dns_pipe_fd[0]);
610 close(dns_pipe_fd[1]);
611 close(ack_pipe_fd[0]);
612 close(ack_pipe_fd[1]);
615 else if (updown_runner->pid > 0)
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];
626 for (
int fd = 3; fd < 100; ++fd)
628 if (fd != dns_pipe_fd[0] && fd != ack_pipe_fd[1])
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);
648 rlen =
read(dns_pipe_fd[0], &path,
sizeof(path));
651 if (rlen == -1 && errno == EINTR)
655 close(dns_pipe_fd[0]);
656 close(ack_pipe_fd[1]);
660 path[
sizeof(path) - 1] =
'\0';
668 if ((wlen == -1 && errno != EINTR) || wlen <
sizeof(
res))
671 close(dns_pipe_fd[0]);
672 close(ack_pipe_fd[1]);
675 else if (wlen ==
sizeof(
res))
689run_up_down_command(
bool up,
struct options *o,
const struct tuntap *tt,
703 status = do_run_up_down_command(up, NULL, dns, tt);
707 if (updown_runner->pid < 1)
710 if (!run_updown_runner(up, o, tt, updown_runner))
720 msg(
M_ERR,
"could not create dns vars file");
728 int wfd = updown_runner->
fds[1];
729 size_t dvf_size = strlen(dvf) + 1;
732 ssize_t len =
write(wfd, dvf, dvf_size);
735 if (len == -1 && errno == EINTR)
744 int rfd = updown_runner->
fds[0];
750 if (len == -1 && errno == EINTR)
763 msg(
M_INFO,
"dns %s command exited with status %d", up ?
"up" :
"down",
status);
782 const char *fmt_port;
786 fmt_port =
" address = %s:%s";
791 fmt_port =
" address = [%s]:%s";
826 domain = domain->
next;
830 server = server->
next;
837 while (search_domain)
840 search_domain = search_domain->
next;
868 size_t bad_count = 0;
880 "DNS server %ld only has address(es) from a family "
881 "the tunnel is not configured for - it will not be reachable",
887 "DNS server %ld has address(es) from a family "
888 "the tunnel is not configured for",
897 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.
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.
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
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)