summaryrefslogtreecommitdiff
path: root/src/option.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/option.c')
-rw-r--r--src/option.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/src/option.c b/src/option.c
index 53df70a..85bc876 100644
--- a/src/option.c
+++ b/src/option.c
@@ -855,7 +855,7 @@ static char *parse_mysockaddr(char *arg, union mysockaddr *addr)
return NULL;
}
-char *parse_server(char *arg, struct server_details *sdetails, const int can_resolve)
+char *parse_server(char *arg, struct server_details *sdetails)
{
sdetails->serv_port = NAMESERVER_PORT;
char *portno;
@@ -901,11 +901,10 @@ char *parse_server(char *arg, struct server_details *sdetails, const int can_res
sdetails->addr_type = AF_INET;
else if (inet_pton(AF_INET6, arg, &sdetails->addr->in6.sin6_addr) > 0)
sdetails->addr_type = AF_INET6;
- /* if the argument is neither an IPv4 not an IPv6 address, it might be a
- hostname and we should try to resolve it to a suitable address.
- However, we don't try this in domain_rev4/6 (can_resolve = 0) */
- else if (can_resolve)
+ else
{
+ /* if the argument is neither an IPv4 not an IPv6 address, it might be a
+ hostname and we should try to resolve it to a suitable address. */
memset(&hints, 0, sizeof(hints));
/* The AI_ADDRCONFIG flag ensures that then IPv4 addresses are returned in
the result only if the local system has at least one IPv4 address
@@ -927,8 +926,10 @@ char *parse_server(char *arg, struct server_details *sdetails, const int can_res
that can be used with node <arg> and service "domain". */
hints.ai_family = AF_UNSPEC;
- /* Get addresses suitable for sending datagrams or TCP connections. */
- hints.ai_socktype = 0;
+ /* Get addresses suitable for sending datagrams. We assume that we can use the
+ same addresses for TCP connections. Settting this to zero gets each address
+ threes times, for SOCK_STREAM, SOCK_RAW and SOCK_DGRAM, which is not useful. */
+ hints.ai_socktype = SOCK_DGRAM;
/* Get address associated with this hostname */
ecode = getaddrinfo(arg, NULL, &hints, &sdetails->hostinfo);
@@ -952,8 +953,6 @@ char *parse_server(char *arg, struct server_details *sdetails, const int can_res
return _((char*)gai_strerror(ecode));
}
}
- else
- return _("bad address");
sdetails->valid = 1;
return NULL;
@@ -984,7 +983,7 @@ char *parse_server_addr(struct server_details *sdetails)
/* When resolving a server IP by hostname, we can simply skip mismatching
server / source IP pairs. Otherwise, when an IP address is given directly,
this is a fatal error. */
- if(!sdetails->resolved)
+ if (!sdetails->resolved)
return _("cannot use IPv4 server address with IPv6 source address");
}
else
@@ -1104,20 +1103,19 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
if (!server)
flags = SERV_LITERAL_ADDRESS;
- else if ((string = parse_server(server, &sdetails, 0)) ||
- (string = parse_server_addr(&sdetails)))
+ else if ((string = parse_server(server, &sdetails)))
return string;
-
+
if (from_file)
flags |= SERV_FROM_FILE;
-
+
rem = size & 0x7;
addrbytes = (32 - size) >> 3;
addrbits = (32 - size) & 7;
if (size > 32 || size < 1)
return _("bad IPv4 prefix length");
-
+
/* Zero out last address bits according to CIDR mask */
((u8 *)addr4)[3-addrbytes] &= ~((1 << addrbits)-1);
@@ -1131,23 +1129,37 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
*domain = 0;
string = domain;
msize = size/8;
-
+
for (j = (rem == 0) ? msize-1 : msize; j >= 0; j--)
{
int dig = ((unsigned char *)addr4)[j];
-
+
if (j == msize)
dig += i;
-
+
string += sprintf(string, "%d.", dig);
}
-
+
sprintf(string, "in-addr.arpa");
- if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
- return _("error");
+ if (flags & SERV_LITERAL_ADDRESS)
+ {
+ if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
+ return _("error");
+ }
+ else
+ {
+ while (parse_server_next(&sdetails))
+ {
+ if ((string = parse_server_addr(&sdetails)))
+ return string;
+
+ if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
+ return _("error");
+ }
+ }
}
-
+
return NULL;
}
@@ -1169,8 +1181,7 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
if (!server)
flags = SERV_LITERAL_ADDRESS;
- else if ((string = parse_server(server, &sdetails, 0)) ||
- (string = parse_server_addr(&sdetails)))
+ else if ((string = parse_server(server, &sdetails)))
return string;
if (from_file)
@@ -1211,10 +1222,24 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
sprintf(string, "ip6.arpa");
- if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
- return _("error");
+ if (flags & SERV_LITERAL_ADDRESS)
+ {
+ if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
+ return _("error");
+ }
+ else
+ {
+ while (parse_server_next(&sdetails))
+ {
+ if ((string = parse_server_addr(&sdetails)))
+ return string;
+
+ if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
+ return _("error");
+ }
+ }
}
-
+
return NULL;
}
@@ -2970,7 +2995,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
else
{
- if ((err = parse_server(arg, &sdetails, 1)))
+ if ((err = parse_server(arg, &sdetails)))
ret_err(err);
}