2002-05-21  Jakub Jelinek  <jakub@redhat.com>

	* resolv/resolv.h (struct __res_state): Remove unused nstimes.
	Add nsmap.
	* resolv/res_init.c (__res_vinit): Initialize nsmap array.
	Remove nstimes setting.
	(res_nclose): Check all MAXNS nameservers with non-NULL nsaddrs.
	* resolv/res_send.c (res_nsend): Don't close unconditionally if
	there is mix of IPv6 and IPv4 nameservers.
	Use nsmap array to find free slots and preserve nameserver ordering.
	Fix RES_ROTATE.
This commit is contained in:
Ulrich Drepper 2002-05-31 07:54:02 +00:00
parent 2afdb78308
commit b64e156626
4 changed files with 81 additions and 48 deletions

View File

@ -1,3 +1,15 @@
2002-05-21 Jakub Jelinek <jakub@redhat.com>
* resolv/resolv.h (struct __res_state): Remove unused nstimes.
Add nsmap.
* resolv/res_init.c (__res_vinit): Initialize nsmap array.
Remove nstimes setting.
(res_nclose): Check all MAXNS nameservers with non-NULL nsaddrs.
* resolv/res_send.c (res_nsend): Don't close unconditionally if
there is mix of IPv6 and IPv4 nameservers.
Use nsmap array to find free slots and preserve nameserver ordering.
Fix RES_ROTATE.
2002-05-30 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/sys/sendfile.h: It is now possible to

View File

@ -182,8 +182,10 @@ __res_vinit(res_state statp, int preinit) {
statp->_u._ext.nscount = 0;
#ifdef _LIBC
statp->_u._ext.nscount6 = 0;
for (n = 0; n < MAXNS; n++)
statp->_u._ext.nsaddrs[n] = NULL;
for (n = 0; n < MAXNS; n++) {
statp->_u._ext.nsaddrs[n] = NULL;
statp->_u._ext.nsmap[n] = MAXNS;
}
#endif
/* Allow user to override the local domain definition */
@ -323,8 +325,8 @@ __res_vinit(res_state statp, int preinit) {
sa6->sin6_family = AF_INET6;
sa6->sin6_port = htons(NAMESERVER_PORT);
statp->_u._ext.nsaddrs[nservall] = sa6;
statp->_u._ext.nstimes[nservall] = RES_MAXTIME;
statp->_u._ext.nssocks[nservall] = -1;
statp->_u._ext.nsmap[nservall] = MAXNS + 1;
nservall++;
}
}
@ -537,16 +539,14 @@ res_nclose(res_state statp) {
statp->_flags &= ~(RES_F_VC | RES_F_CONN);
}
#ifdef _LIBC
for (ns = 0; ns < statp->_u._ext.nscount + statp->_u._ext.nscount6;
ns++)
for (ns = 0; ns < MAXNS; ns++)
#else
for (ns = 0; ns < statp->_u._ext.nscount; ns++)
#endif
{
if (statp->_u._ext.nssocks[ns] != -1) {
if (statp->_u._ext.nsaddrs[ns]
&& statp->_u._ext.nssocks[ns] != -1) {
(void) __close(statp->_u._ext.nssocks[ns]);
statp->_u._ext.nssocks[ns] = -1;
}
}
statp->_u._ext.nsinit = 0;
}

View File

@ -400,12 +400,15 @@ res_nsend(res_state statp,
if (EXT(statp).nscount != statp->nscount)
needclose++;
else
for (ns = 0; ns < statp->nscount; ns++)
#ifdef _LIBC
if (!sock_eq((struct sockaddr_in6 *)
&statp->nsaddr_list[ns],
EXT(statp).nsaddrs[ns]))
for (ns = 0; ns < MAXNS; ns++) {
unsigned int map = EXT(statp).nsmap[ns];
if (map < MAXNS
&& !sock_eq((struct sockaddr_in6 *)
&statp->nsaddr_list[map],
EXT(statp).nsaddrs[ns]))
#else
for (ns = 0; ns < statp->nscount; ns++) {
if (!sock_eq(&statp->nsaddr_list[ns],
&EXT(statp).nsaddrs[ns]))
#endif
@ -413,6 +416,7 @@ res_nsend(res_state statp,
needclose++;
break;
}
}
if (needclose)
res_nclose(statp);
}
@ -422,20 +426,34 @@ res_nsend(res_state statp,
*/
if (EXT(statp).nsinit == 0) {
#ifdef _LIBC
n = 0;
#endif
for (ns = 0; ns < statp->nscount; ns++) {
#ifdef _LIBC
/* find a hole */
while ((n < MAXNS) &&
(EXT(statp).nsaddrs[n] != NULL) &&
(EXT(statp).nsaddrs[n]->sin6_family == AF_INET6) &&
!IN6_IS_ADDR_V4MAPPED(
&EXT(statp).nsaddrs[n]->sin6_addr))
n++;
if (n == MAXNS)
break;
unsigned char map[MAXNS];
memset (map, MAXNS, sizeof (map));
for (n = 0; n < MAXNS; n++) {
ns = EXT(statp).nsmap[n];
if (ns < statp->nscount)
map[ns] = n;
else if (ns < MAXNS) {
free(EXT(statp).nsaddrs[n]);
EXT(statp).nsaddrs[n] = NULL;
EXT(statp).nsmap[n] = MAXNS;
}
}
n = statp->nscount;
if (statp->nscount > EXT(statp).nscount)
for (n = EXT(statp).nscount, ns = 0;
n < statp->nscount; n++) {
while (ns < MAXNS
&& EXT(statp).nsmap[ns] != MAXNS)
ns++;
if (ns == MAXNS)
break;
EXT(statp).nsmap[ns] = n;
map[n] = ns++;
}
EXT(statp).nscount = n;
for (ns = 0; ns < EXT(statp).nscount; ns++) {
n = map[ns];
if (EXT(statp).nsaddrs[n] == NULL)
EXT(statp).nsaddrs[n] =
malloc(sizeof (struct sockaddr_in6));
@ -443,31 +461,18 @@ res_nsend(res_state statp,
memcpy(EXT(statp).nsaddrs[n],
&statp->nsaddr_list[ns],
sizeof (struct sockaddr_in));
EXT(statp).nstimes[n] = RES_MAXTIME;
EXT(statp).nssocks[n] = -1;
n++;
}
}
#else
for (ns = 0; ns < statp->nscount; ns++) {
EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns];
EXT(statp).nstimes[ns] = RES_MAXTIME;
EXT(statp).nssocks[ns] = -1;
#endif
}
EXT(statp).nscount = statp->nscount;
EXT(statp).nscount = ns;
#endif
EXT(statp).nsinit = 1;
#ifdef _LIBC
/* If holes left, free memory and set to NULL */
while (n < MAXNS) {
if ((EXT(statp).nsaddrs[n] != NULL) &&
((EXT(statp).nsaddrs[n]->sin6_family != AF_INET6)
|| IN6_IS_ADDR_V4MAPPED(
&EXT(statp).nsaddrs[n]->sin6_addr))) {
free(EXT(statp).nsaddrs[n]);
EXT(statp).nsaddrs[n] = NULL;
}
n++;
}
#endif
}
/*
@ -478,12 +483,28 @@ res_nsend(res_state statp,
(statp->options & RES_BLAST) == 0) {
#ifdef _LIBC
struct sockaddr_in6 *ina;
int lastns = statp->nscount + EXT(statp).nscount6 - 1;
unsigned int map;
ina = EXT(statp).nsaddrs[0];
for (ns = 0; ns < lastns; ns++)
EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
EXT(statp).nsaddrs[lastns] = ina;
n = 0;
while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
n++;
if (n < MAXNS) {
ina = EXT(statp).nsaddrs[n];
map = EXT(statp).nsmap[n];
for (;;) {
ns = n + 1;
while (ns < MAXNS
&& EXT(statp).nsmap[ns] == MAXNS)
ns++;
if (ns == MAXNS)
break;
EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns];
EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
n = ns;
}
EXT(statp).nsaddrs[n] = ina;
EXT(statp).nsmap[n] = map;
}
#else
struct sockaddr_in ina;
int lastns = statp->nscount - 1;

View File

@ -130,7 +130,7 @@ struct __res_state {
char pad[52]; /* On an i386 this means 512b total. */
struct {
u_int16_t nscount;
u_int16_t nstimes[MAXNS]; /* ms. */
u_int16_t nsmap[MAXNS];
int nssocks[MAXNS];
u_int16_t nscount6;
u_int16_t nsinit;