summaryrefslogtreecommitdiff
path: root/resolv
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-12-12 18:13:35 +0000
committerJakub Jelinek <jakub@redhat.com>2007-12-12 18:13:35 +0000
commit574e283890a6ca92325a06dafa76ff307a8019a2 (patch)
tree055e44e24a55fb4863e5d9cdc04e320cde52ffe9 /resolv
parenta162e5955f7e324be82d9318bbcbe869c66ffb86 (diff)
Updated to fedora-glibc-20071212T1051
Diffstat (limited to 'resolv')
-rw-r--r--resolv/Versions1
-rw-r--r--resolv/nss_dns/dns-host.c27
-rw-r--r--resolv/res_hconf.c80
3 files changed, 68 insertions, 40 deletions
diff --git a/resolv/Versions b/resolv/Versions
index 5a350cae36..fc2111a1cb 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -88,6 +88,7 @@ libnss_dns {
_nss_dns_gethostbyname3_r;
_nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r;
_nss_dns_getnetbyname_r; _nss_dns_getcanonname_r;
+ _nss_dns_gethostbyaddr2_r;
}
}
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 0e25564670..def44e9dbf 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -255,10 +255,18 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
}
+extern enum nss_status _nss_dns_gethostbyaddr2_r (const void *addr,
+ socklen_t len, int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp);
+hidden_proto (_nss_dns_gethostbyaddr2_r)
+
enum nss_status
-_nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
- struct hostent *result, char *buffer, size_t buflen,
- int *errnop, int *h_errnop)
+_nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
+ struct hostent *result, char *buffer, size_t buflen,
+ int *errnop, int *h_errnop, int32_t *ttlp)
{
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
@@ -374,7 +382,7 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
got_it_already:
status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
- errnop, h_errnop, 0 /* XXX */, NULL, NULL);
+ errnop, h_errnop, 0 /* XXX */, ttlp, NULL);
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
if (status != NSS_STATUS_SUCCESS)
@@ -408,6 +416,17 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
+hidden_def (_nss_dns_gethostbyaddr2_r)
+
+
+enum nss_status
+_nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
+ struct hostent *result, char *buffer, size_t buflen,
+ int *errnop, int *h_errnop)
+{
+ return _nss_dns_gethostbyaddr2_r (addr, len, af, result, buffer, buflen,
+ errnop, h_errnop, NULL);
+}
#ifdef RESOLVSORT
static void addrsort (char **ap, int num);
diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c
index c53b809ef7..25f7397927 100644
--- a/resolv/res_hconf.c
+++ b/resolv/res_hconf.c
@@ -377,9 +377,6 @@ static struct netaddr
} u;
} *ifaddrs);
-/* We need to protect the dynamic buffer handling. */
-__libc_lock_define_initialized (static, lock);
-
/* Reorder addresses returned in a hostent such that the first address
is an address on the local subnet, if there is such an address.
Otherwise, nothing is changed.
@@ -393,6 +390,8 @@ _res_hconf_reorder_addrs (struct hostent *hp)
int i, j;
/* Number of interfaces. */
static int num_ifs = -1;
+ /* We need to protect the dynamic buffer handling. */
+ __libc_lock_define_initialized (static, lock);
/* Only reorder if we're supposed to. */
if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
@@ -411,8 +410,6 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Initialize interface table. */
- num_ifs = 0;
-
/* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket. */
sd = __socket (AF_INET, SOCK_DGRAM, 0);
if (sd < 0)
@@ -421,45 +418,56 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Get lock. */
__libc_lock_lock (lock);
- /* Get a list of interfaces. */
- __ifreq (&ifr, &num, sd);
- if (!ifr)
- goto cleanup;
+ /* Recheck, somebody else might have done the work by done. */
+ if (num_ifs <= 0)
+ {
+ int new_num_ifs = 0;
- ifaddrs = malloc (num * sizeof (ifaddrs[0]));
- if (!ifaddrs)
- goto cleanup1;
+ /* Get a list of interfaces. */
+ __ifreq (&ifr, &num, sd);
+ if (!ifr)
+ goto cleanup;
- /* Copy usable interfaces in ifaddrs structure. */
- for (cur_ifr = ifr, i = 0; i < num; cur_ifr = __if_nextreq (cur_ifr), ++i)
- {
- if (cur_ifr->ifr_addr.sa_family != AF_INET)
- continue;
+ ifaddrs = malloc (num * sizeof (ifaddrs[0]));
+ if (!ifaddrs)
+ goto cleanup1;
- ifaddrs[num_ifs].addrtype = AF_INET;
- ifaddrs[num_ifs].u.ipv4.addr =
- ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
+ /* Copy usable interfaces in ifaddrs structure. */
+ for (cur_ifr = ifr, i = 0; i < num;
+ cur_ifr = __if_nextreq (cur_ifr), ++i)
+ {
+ if (cur_ifr->ifr_addr.sa_family != AF_INET)
+ continue;
- if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
- continue;
+ ifaddrs[new_num_ifs].addrtype = AF_INET;
+ ifaddrs[new_num_ifs].u.ipv4.addr =
+ ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
- ifaddrs[num_ifs].u.ipv4.mask =
- ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
+ if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
+ continue;
- /* Now we're committed to this entry. */
- ++num_ifs;
- }
- /* Just keep enough memory to hold all the interfaces we want. */
- ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
- assert (ifaddrs != NULL);
+ ifaddrs[new_num_ifs].u.ipv4.mask =
+ ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
- cleanup1:
- __if_freereq (ifr, num);
+ /* Now we're committed to this entry. */
+ ++new_num_ifs;
+ }
+ /* Just keep enough memory to hold all the interfaces we want. */
+ ifaddrs = realloc (ifaddrs, new_num_ifs * sizeof (ifaddrs[0]));
+ assert (ifaddrs != NULL);
+
+ cleanup1:
+ __if_freereq (ifr, num);
+
+ cleanup:
+ /* Release lock, preserve error value, and close socket. */
+ save = errno;
+
+ num_ifs = new_num_ifs;
+
+ __libc_lock_unlock (lock);
+ }
- cleanup:
- /* Release lock, preserve error value, and close socket. */
- save = errno;
- __libc_lock_unlock (lock);
__close (sd);
}