* Get host reordering working
@ 1999-09-16 6:40 Andreas Jaeger
0 siblings, 0 replies; only message in thread
From: Andreas Jaeger @ 1999-09-16 6:40 UTC (permalink / raw)
To: libc-hacker
I've seen a few of complaints that 'reorder on' in /etc/host.conf
doesn't work at all. The code was proteced by an #ifdef but since the
needed define was never included the code was not compiled into glibc
- and it couldn't have worked at all since it didn't even compile.:-(
I've gone over the code and enabled the reordering also for
gethstbyname2.
Please note that the code works only for IPv4.
Andreas
1999-09-16 Andreas Jaeger <aj@suse.de>
* inet/gethstbynm2_r.c: Reorder addresses.
* resolv/res_hconf.c: Add missing includes to get all prototypes.
(_res_hconf_reorder_addrs): Rewrite. This never worked before.
Reported by John DiMarco <jdd@cs.toronto.edu>.
(_res_hconf_reorder_addrs): Made thread safe.
(free_mem): New function, needed for malloc debugging.
--- resolv/res_hconf.c.~1~ Thu Apr 29 20:59:23 1999
+++ resolv/res_hconf.c Wed Sep 15 12:45:01 1999
@@ -17,9 +17,9 @@
Boston, MA 02111-1307, USA. */
/* This file provides a Linux /etc/host.conf compatible front end to
-the various name resolvers (/etc/hosts, named, NIS server, etc.).
-Though mostly compatibly, the following differences exist compared
-to the original implementation:
+ the various name resolvers (/etc/hosts, named, NIS server, etc.).
+ Though mostly compatibly, the following differences exist compared
+ to the original implementation:
- new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK
environment variable (i.e., `off', `nowarn', or `warn').
@@ -27,12 +27,18 @@
- line comments can appear anywhere (not just at the beginning of
a line)
*/
+
+#include <errno.h>
#include <ctype.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <bits/libc-lock.h>
#include "res_hconf.h"
@@ -374,30 +380,44 @@
}
+/* List of known interfaces. */
+static struct netaddr
+{
+ int addrtype;
+ union
+ {
+ struct
+ {
+ u_int32_t addr;
+ u_int32_t mask;
+ } ipv4;
+ } 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. */
+ Otherwise, nothing is changed.
+
+ Note that this function currently only handles IPv4 addresses. */
void
_res_hconf_reorder_addrs (struct hostent *hp)
{
#if defined SIOCGIFCONF && defined SIOCGIFNETMASK
- static int num_ifs = -1; /* number of interfaces */
- static struct netaddr
- {
- int addrtype;
- union
- {
- struct
- {
- u_int32_t addr;
- u_int32_t mask;
- } ipv4
- } u;
- } *ifaddrs;
+ int i, j;
+ /* Number of interfaces. */
+ static int num_ifs = -1;
+ /* Only reorder if we're supposed to. */
+ if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
+ return;
+
+ /* Can't deal with anything but IPv4 for now... */
if (hp->h_addrtype != AF_INET)
- return; /* can't deal with anything but IPv4 for now... */
+ return;
if (num_ifs <= 0)
{
@@ -405,8 +425,10 @@
struct ifreq *ifr;
size_t size, num;
int sd;
-
- /* initialize interface table: */
+ /* Save errno. */
+ int save = errno;
+
+ /* Initialize interface table. */
num_ifs = 0;
@@ -414,73 +436,83 @@
if (sd < 0)
return;
- /* Now get list of interfaces. Since we don't know how many
+ /* Get lock. */
+ __libc_lock_lock (lock);
+
+ /* Now get a list of interfaces. Since we don't know how many
interfaces there are, we keep increasing the buffer size
until we have at least sizeof(struct ifreq) too many bytes.
- That implies that the ioctl() return because it ran out of
- interfaces, not memory */
+ That implies that the ioctl() returns because it ran out of
+ interfaces, not memory. */
size = 0;
- ifs.ifc_buf = 0;
+ ifs.ifc_buf = NULL;
do
{
size += 4 * sizeof (struct ifreq);
- ifs.ifc_buf = realloc (ifs.ifs_buf, size);
+ ifs.ifc_buf = realloc (ifs.ifc_buf, size);
if (ifs.ifc_buf == NULL)
- {
- close (sd);
- return;
- }
+ goto cleanup1;
+
ifs.ifc_len = size;
if (__ioctl (sd, SIOCGIFCONF, &ifs) < 0)
goto cleanup;
}
- while (size - ifs.ifc_len < sizeof (struct ifreq));
+ while (size < sizeof (struct ifreq) + ifs.ifc_len);
+ /* Number of interfaces. */
num = ifs.ifc_len / sizeof (struct ifreq);
ifaddrs = malloc (num * sizeof (ifaddrs[0]));
if (!ifaddrs)
goto cleanup;
+ /* Copy usable interfaces in ifaddrs structure. */
ifr = ifs.ifc_req;
- for (i = 0; i < num; ++i)
+ for (i = 0; i < num; ++i, ifr++)
{
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
+
ifaddrs[num_ifs].addrtype = AF_INET;
+ ifaddrs[num_ifs].u.ipv4.addr =
+ ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
- memcpy (&ifaddrs[num_ifs].u.ipv4.addr,
- &((struct sockaddr_in *)ifr->ifr_addr)->sin_addr, 4);
-
- if (__ioctl (sd, SIOCGIFNETMASK, if) < 0)
+ if (__ioctl (sd, SIOCGIFNETMASK, ifr) < 0)
continue;
- memcpy (&ifaddrs[num_ifs].u.ipv4.mask,
- ((struct sockaddr_in *)ifr->ifr_mask)->sin_addr, 4);
- ++num_ifs; /* now we're committed to this entry */
+ ifaddrs[num_ifs].u.ipv4.mask =
+ ((struct sockaddr_in *) &ifr->ifr_netmask)->sin_addr.s_addr;
+
+ /* Now we're committed to this entry. */
+ ++num_ifs;
}
- /* just keep enough memory to hold all the interfaces we want: */
+ /* Just keep enough memory to hold all the interfaces we want. */
ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
cleanup:
- close (sd);
free (ifs.ifc_buf);
+
+ cleanup1:
+ /* Release lock, preserve error value, and close socket. */
+ save = errno;
+ __libc_lock_unlock (lock);
+ close (sd);
}
if (num_ifs == 0)
return;
- /* find an address for which we have a direct connection: */
+ /* Find an address for which we have a direct connection. */
for (i = 0; hp->h_addr_list[i]; ++i)
{
- h_addr = (struct in_addr *) hp->h_addr_list[i];
+ struct in_addr *haddr = (struct in_addr *) hp->h_addr_list[i];
for (j = 0; j < num_ifs; ++j)
{
- if_addr = ifaddrs[j].u.ipv4.addr;
- if_netmask = ifaddrs[j].u.ipv4.mask;
+ u_int32_t if_addr = ifaddrs[j].u.ipv4.addr;
+ u_int32_t if_netmask = ifaddrs[j].u.ipv4.mask;
- if (((h_addr->s_addr ^ if_addr) & if_netmask) == 0)
+ if (((haddr->s_addr ^ if_addr) & if_netmask) == 0)
{
void *tmp;
@@ -537,3 +569,14 @@
for (i = 0; hp->h_aliases[i]; ++i)
_res_hconf_trim_domain (hp->h_aliases[i]);
}
+
+
+/* Free all resources if necessary. */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ if (ifaddrs != NULL)
+ free (ifaddrs);
+}
+
+text_set_element (__libc_subfreeres, free_mem);
--- inet/gethstbynm2_r.c~ Sat Jan 17 10:57:09 1998
+++ inet/gethstbynm2_r.c Thu Sep 16 15:06:27 1999
@@ -31,6 +31,10 @@
#define ADD_PARAMS const char *name, int af
#define ADD_VARIABLES name, af
#define NEED_H_ERRNO 1
+#define NEED__RES_HCONF 1
+#define POSTPROCESS \
+ if (status == NSS_STATUS_SUCCESS) \
+ _res_hconf_reorder_addrs (resbuf);
#define HANDLE_DIGITS_DOTS 1
#define HAVE_LOOKUP_BUFFER 1
--
Andreas Jaeger aj@arthur.rhein-neckar.de aj@suse.de
for pgp-key finger ajaeger@aixd1.rhrk.uni-kl.de
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~1999-09-16 6:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-09-16 6:40 Get host reordering working Andreas Jaeger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).