summaryrefslogtreecommitdiffstats
path: root/lib/libc/net
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2000-06-11 15:43:34 +0000
committerume <ume@FreeBSD.org>2000-06-11 15:43:34 +0000
commit74d273c06d22b21c6b4f7efca5873b0724e1e88d (patch)
tree4f87d6a6b05484f544170703f08ac79ca818544e /lib/libc/net
parentf916881111a73eeedeeba06a92022b0b932826d8 (diff)
downloadFreeBSD-src-74d273c06d22b21c6b4f7efca5873b0724e1e88d.zip
FreeBSD-src-74d273c06d22b21c6b4f7efca5873b0724e1e88d.tar.gz
DNS IPv6 transport support.
It is nessesary for IPv6 only life. Obtained from: KAME
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/res_init.c61
-rw-r--r--lib/libc/net/res_send.c105
2 files changed, 110 insertions, 56 deletions
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index d1e6249..8adcd27 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -87,6 +87,7 @@ static char rcsid[] = "$FreeBSD$";
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <netdb.h>
#include "res_config.h"
@@ -112,9 +113,7 @@ struct __res_state _res
# endif
;
-#ifdef INET6
struct __res_state_ext _res_ext;
-#endif /* INET6 */
/*
* Set up default settings. If the configuration file exist, the values
@@ -154,6 +153,7 @@ res_init()
#ifndef RFC1535
int dots;
#endif
+ struct sockaddr_in6 *sin6;
/*
* These three fields used to be statically initialized. This made
@@ -188,13 +188,15 @@ res_init()
if (!_res.id)
_res.id = res_randomid();
+ sin6 = (struct sockaddr_in6 *)&_res_ext.nsaddr;
#ifdef USELOOPBACK
- _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+ sin6->sin6_addr = in6addr_loopback;
#else
- _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+ sin6->sin6_addr = in6addr_any;
#endif
- _res.nsaddr.sin_family = AF_INET;
- _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = htons(NAMESERVER_PORT);
+ sin6->sin6_len = sizeof(*sin6);
_res.nscount = 1;
_res.ndots = 1;
_res.pfcode = 0;
@@ -300,16 +302,41 @@ res_init()
}
/* read nameservers to query */
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
- struct in_addr a;
+ char *q;
+ struct addrinfo hints, *res;
+ char pbuf[NI_MAXSERV];
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
- if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
- _res.nsaddr_list[nserv].sin_addr = a;
- _res.nsaddr_list[nserv].sin_family = AF_INET;
- _res.nsaddr_list[nserv].sin_port =
- htons(NAMESERVER_PORT);
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ for (q = cp; *q; q++) {
+ if (isspace(*q)) {
+ *q = '\0';
+ break;
+ }
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(pbuf, sizeof(pbuf), "%d", NAMESERVER_PORT);
+ if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
+ res->ai_next == NULL) {
+ if (res->ai_addrlen <= sizeof(_res_ext.nsaddr_list[nserv])) {
+ memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
+ res->ai_addrlen);
+ } else {
+ memset(&_res_ext.nsaddr_list[nserv], 0,
+ sizeof(_res_ext.nsaddr_list[nserv]));
+ }
+ if (res->ai_addrlen <= sizeof(_res.nsaddr_list[nserv])) {
+ memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
+ res->ai_addrlen);
+ } else {
+ memset(&_res.nsaddr_list[nserv], 0,
+ sizeof(_res.nsaddr_list[nserv]));
+ }
nserv++;
}
continue;
@@ -317,9 +344,9 @@ res_init()
#ifdef RESOLVSORT
if (MATCH(buf, "sortlist")) {
struct in_addr a;
-#ifdef INET6
struct in6_addr a6;
-#endif /* INET6 */
+ int m, i;
+ u_char *u;
cp = buf + sizeof("sortlist") - 1;
while (nsort < MAXRESOLVSORT) {
@@ -353,19 +380,14 @@ res_init()
_res.sort_list[nsort].mask =
net_mask(_res.sort_list[nsort].addr);
}
-#ifdef INET6
_res_ext.sort_list[nsort].af = AF_INET;
_res_ext.sort_list[nsort].addr.ina =
_res.sort_list[nsort].addr;
_res_ext.sort_list[nsort].mask.ina.s_addr =
_res.sort_list[nsort].mask;
-#endif /* INET6 */
nsort++;
}
-#ifdef INET6
else if (inet_pton(AF_INET6, net, &a6) == 1) {
- int m, i;
- u_char *u;
_res_ext.sort_list[nsort].af = AF_INET6;
_res_ext.sort_list[nsort].addr.in6a = a6;
@@ -407,7 +429,6 @@ res_init()
}
nsort++;
}
-#endif /* INET6 */
*cp = n;
}
continue;
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index 895db81..fade45e 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -109,8 +109,11 @@ static int use_poll = 1; /* adapt to poll() syscall availability */
static int s = -1; /* socket used for communications */
static int connected = 0; /* is the socket connected */
static int vc = 0; /* is the socket a virtual circuit? */
+static int af = 0; /* address family of socket */
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
+static char abuf[NI_MAXHOST];
+static char pbuf[32];
#define CAN_RECONNECT 1
@@ -131,16 +134,16 @@ static res_send_rhook Rhook = NULL;
FILE *file;
char *string;
int error;
- struct sockaddr_in address;
+ struct sockaddr *address;
{
int save = errno;
if (_res.options & RES_DEBUG) {
- fprintf(file, "res_send: %s ([%s].%u): %s\n",
- string,
- inet_ntoa(address.sin_addr),
- ntohs(address.sin_port),
- strerror(error));
+ getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
+ pbuf, sizeof(pbuf),
+ NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID);
+ fprintf(file, "res_send: %s ([%s].%s): %s\n",
+ string, abuf, pbuf, strerror(error));
}
errno = save;
}
@@ -189,21 +192,40 @@ int
res_isourserver(inp)
const struct sockaddr_in *inp;
{
- struct sockaddr_in ina;
+ struct sockaddr_in6 *in6p = (struct sockaddr_in6 *)inp;
+ const struct sockaddr_in6 *srv6;
+ const struct sockaddr_in *srv;
int ns, ret;
- ina = *inp;
ret = 0;
- for (ns = 0; ns < _res.nscount; ns++) {
- const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
-
- if (srv->sin_family == ina.sin_family &&
- srv->sin_port == ina.sin_port &&
- (srv->sin_addr.s_addr == INADDR_ANY ||
- srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
- ret++;
- break;
+ switch (inp->sin_family) {
+ case AF_INET6:
+ for (ns = 0; ns < _res.nscount; ns++) {
+ srv6 = (struct sockaddr_in6 *)&_res_ext.nsaddr_list[ns];
+ if (srv6->sin6_family == in6p->sin6_family &&
+ srv6->sin6_port == in6p->sin6_port &&
+ srv6->sin6_scope_id == in6p->sin6_scope_id &&
+ (memcmp(&srv6->sin6_addr, &in6addr_any,
+ sizeof(struct in6_addr)) == 0 ||
+ memcmp(&srv6->sin6_addr, &in6p->sin6_addr,
+ sizeof(struct in6_addr)) == 0)) {
+ ret++;
+ break;
+ }
+ }
+ break;
+ case AF_INET:
+ for (ns = 0; ns < _res.nscount; ns++) {
+ srv = (struct sockaddr_in *)&_res_ext.nsaddr_list[ns];
+ if (srv->sin_family == inp->sin_family &&
+ srv->sin_port == inp->sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
+ ret++;
+ break;
+ }
}
+ break;
}
return (ret);
}
@@ -332,7 +354,8 @@ res_send(buf, buflen, ans, anssiz)
*/
for (try = 0; try < _res.retry; try++) {
for (ns = 0; ns < _res.nscount; ns++) {
- struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ struct sockaddr *nsap = (struct sockaddr *)
+ &_res_ext.nsaddr_list[ns];
same_ns:
if (badns & (1 << ns)) {
res_close();
@@ -345,7 +368,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
- act = (*Qhook)(&nsap, &buf, &buflen,
+ act = (*Qhook)((struct sockaddr_in **)&nsap,
+ &buf, &buflen,
ans, anssiz, &resplen);
switch (act) {
case res_goahead:
@@ -369,9 +393,12 @@ res_send(buf, buflen, ans, anssiz)
} while (!done);
}
- Dprint(_res.options & RES_DEBUG,
+ Dprint((_res.options & RES_DEBUG) &&
+ getnameinfo(nsap, nsap->sa_len, abuf, sizeof(abuf),
+ NULL, 0,
+ NI_NUMERICHOST | NI_WITHSCOPEID) == 0,
(stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntoa(nsap->sin_addr)));
+ ns + 1, abuf));
if (v_circuit) {
int truncated;
@@ -385,11 +412,13 @@ res_send(buf, buflen, ans, anssiz)
*/
try = _res.retry;
truncated = 0;
- if (s < 0 || !vc || hp->opcode == ns_o_update) {
+ if (s < 0 || !vc || hp->opcode == ns_o_update ||
+ af != nsap->sa_family) {
if (s >= 0)
res_close();
- s = socket(PF_INET, SOCK_STREAM, 0);
+ af = nsap->sa_family;
+ s = socket(af, SOCK_STREAM, 0);
if (s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
@@ -397,10 +426,10 @@ res_send(buf, buflen, ans, anssiz)
}
errno = 0;
if (connect(s, (struct sockaddr *)nsap,
- sizeof *nsap) < 0) {
+ nsap->sa_len) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
- errno, *nsap);
+ errno, nsap);
badns |= (1 << ns);
res_close();
goto next_ns;
@@ -530,13 +559,14 @@ read_len:
struct timeval timeout;
fd_set dsmask, *dsmaskp;
int dsmasklen;
- struct sockaddr_in from;
+ struct sockaddr_storage from;
int fromlen;
- if ((s < 0) || vc) {
+ if (s < 0 || vc || af != nsap->sa_family) {
if (vc)
res_close();
- s = socket(PF_INET, SOCK_DGRAM, 0);
+ af = nsap->sa_family;
+ s = socket(af, SOCK_DGRAM, 0);
if (s < 0) {
#ifndef CAN_RECONNECT
bad_dg_sock:
@@ -570,11 +600,11 @@ read_len:
*/
if (!connected) {
if (connect(s, (struct sockaddr *)nsap,
- sizeof *nsap
+ nsap->sa_len
) < 0) {
Aerror(stderr,
"connect(dg)",
- errno, *nsap);
+ errno, nsap);
badns |= (1 << ns);
res_close();
goto next_ns;
@@ -594,6 +624,7 @@ read_len:
*/
if (connected) {
#ifdef CAN_RECONNECT
+ /* XXX: any errornous address */
struct sockaddr_in no_addr;
no_addr.sin_family = AF_INET;
@@ -604,7 +635,7 @@ read_len:
&no_addr,
sizeof no_addr);
#else
- int s1 = socket(PF_INET, SOCK_DGRAM,0);
+ int s1 = socket(af, SOCK_DGRAM,0);
if (s1 < 0)
goto bad_dg_sock;
(void)dup2(s1, s);
@@ -618,9 +649,9 @@ read_len:
#endif /* !CANNOT_CONNECT_DGRAM */
if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap,
- sizeof *nsap)
+ nsap->sa_len)
!= buflen) {
- Aerror(stderr, "sendto", errno, *nsap);
+ Aerror(stderr, "sendto", errno, nsap);
badns |= (1 << ns);
res_close();
goto next_ns;
@@ -749,7 +780,7 @@ read_len:
goto next_ns;
}
errno = 0;
- fromlen = sizeof(struct sockaddr_in);
+ fromlen = sizeof(from);
resplen = recvfrom(s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
@@ -784,7 +815,7 @@ read_len:
}
#ifdef CHECK_SRVR_ADDR
if (!(_res.options & RES_INSECURE1) &&
- !res_isourserver(&from)) {
+ !res_isourserver((struct sockaddr_in *)&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
@@ -861,7 +892,8 @@ read_len:
do {
res_sendhookact act;
- act = (*Rhook)(nsap, buf, buflen,
+ act = (*Rhook)((struct sockaddr_in *)nsap,
+ buf, buflen,
ans, anssiz, &resplen);
switch (act) {
case res_goahead:
@@ -914,6 +946,7 @@ res_close()
s = -1;
connected = 0;
vc = 0;
+ af = 0;
}
}
OpenPOWER on IntegriCloud