Replacing gethostbyname, gethostbyname2 and their _r variants with getaddrinfo to increase portability.

This commit is contained in:
Tobias Brunner
2009-08-14 16:14:32 +02:00
parent 26965b4ef3
commit f1777dff59
6 changed files with 128 additions and 130 deletions
+4 -6
View File
@@ -54,7 +54,7 @@ on a big-endian host and
.B 4.3.2.1
on a little-endian host),
a DNS name to be looked up via
.IR gethostbyname (3),
.IR getaddrinfo (3),
or an old-style network name to be looked up via
.IR getnetbyname (3).
.PP
@@ -91,10 +91,8 @@ DNS names may be complete (optionally terminated with a ``.'')
or incomplete, and are looked up as specified by local system configuration
(see
.IR resolver (5)).
The
.I h_addr
value returned by
.IR gethostbyname (3)
The first value returned by
.IR getaddrinfo (3)
is used,
so with current DNS implementations,
the result when the name corresponds to more than one address is
@@ -102,7 +100,7 @@ difficult to predict.
Name lookup resorts to
.IR getnetbyname (3)
only if
.IR gethostbyname (3)
.IR getaddrinfo (3)
fails.
.PP
A subnet specification is of the form \fInetwork\fB/\fImask\fR.
+29 -11
View File
@@ -12,6 +12,8 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
*/
#include <sys/socket.h>
#include "internal.h"
#include "freeswan.h"
@@ -41,7 +43,7 @@ const char *src;
size_t srclen; /* 0 means "apply strlen" */
struct in_addr *addrp;
{
struct hostent *h;
struct addrinfo hints, *res;
struct netent *ne = NULL;
const char *oops;
# define HEXLEN 10 /* strlen("0x11223344") */
@@ -51,6 +53,7 @@ struct in_addr *addrp;
char namebuf[ATOADDRBUF];
char *p = namebuf;
char *q;
int error;
if (srclen == 0)
srclen = strlen(src);
@@ -87,18 +90,33 @@ struct in_addr *addrp;
return "illegal (non-DNS-name) character in name";
/* try as host name, failing that as /etc/networks network name */
h = gethostbyname(p);
if (h == NULL)
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
error = getaddrinfo(p, NULL, &hints, &res);
if (error != 0)
{
ne = getnetbyname(p);
if (p != namebuf)
FREE(p);
if (h == NULL && ne == NULL)
return "name lookup failed";
if (h != NULL)
memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr));
else
if (ne == NULL)
{
if (p != namebuf)
{
FREE(p);
}
return "name lookup failed";
}
addrp->s_addr = htonl(ne->n_net);
}
else
{
memcpy(&addrp->s_addr, res->ai_addr->sa_data, sizeof(addrp->s_addr));
freeaddrinfo(res);
}
if (p != namebuf)
{
FREE(p);
}
return NULL;
}
+5 -7
View File
@@ -59,7 +59,7 @@ on a big-endian host and
.B 4.3.2.1
on a little-endian host),
a DNS name to be looked up via
.IR gethostbyname (3),
.IR getaddrinfo (3),
or an old-style network name to be looked up via
.IR getnetbyname (3).
.PP
@@ -100,7 +100,7 @@ abbreviating at most one subsequence of multiple zeros (e.g.
which is synonymous with
.BR 99:ab:0:0:0:0:54:68 ),
or a DNS name to be looked up via
.IR gethostbyname (3).
.IR getaddrinfo (3).
The result of applying
.I addrtot
to an IPv6 address will use
@@ -115,10 +115,8 @@ DNS names may be complete (optionally terminated with a ``.'')
or incomplete, and are looked up as specified by local system configuration
(see
.IR resolver (5)).
The
.I h_addr
value returned by
.IR gethostbyname2 (3)
The first value returned by
.IR getaddrinfo (3)
is used,
so with current DNS implementations,
the result when the name corresponds to more than one address is
@@ -126,7 +124,7 @@ difficult to predict.
IPv4 name lookup resorts to
.IR getnetbyname (3)
only if
.IR gethostbyname2 (3)
.IR getaddrinfo (3)
fails.
.PP
A subnet specification is of the form \fInetwork\fB/\fImask\fR.
+37 -19
View File
@@ -157,12 +157,15 @@ int nultermd; /* is it known to be NUL-terminated? */
int af;
ip_address *dst;
{
struct hostent *h;
struct addrinfo hints, *res;
struct netent *ne = NULL;
char namebuf[100]; /* enough for most DNS names */
const char *cp;
char *p = namebuf;
unsigned char *addr = NULL;
size_t n;
int error;
err_t err = NULL;
for (cp = src, n = srclen; n > 0; cp++, n--)
if (ISASCII(*cp) && strchr(namechars, *cp) == NULL)
@@ -181,25 +184,40 @@ ip_address *dst;
cp = (const char *)p;
}
h = gethostbyname2(cp, af);
if (h == NULL && af == AF_INET)
ne = getnetbyname(cp);
if (p != namebuf)
FREE(p);
if (h == NULL && ne == NULL)
return "does not look numeric and name lookup failed";
if (h != NULL) {
if (h->h_addrtype != af)
return "address-type mismatch from gethostbyname2!!!";
return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst);
} else {
if (ne->n_addrtype != af)
return "address-type mismatch from getnetbyname!!!";
ne->n_net = htonl(ne->n_net);
return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net),
af, dst);
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
error = getaddrinfo(cp, NULL, &hints, &res);
if (error != 0)
{ /* getaddrinfo failed, try getnetbyname */
if (af == AF_INET)
{
ne = getnetbyname(cp);
if (ne != NULL)
{
ne->n_net = htonl(ne->n_net);
addr = (unsigned char*)&ne->n_net;
err = initaddr(addr, sizeof(ne->n_net), af, dst);
}
}
}
else
{
addr = res->ai_addr->sa_data;
err = initaddr(addr, res->ai_addrlen, af, dst);
freeaddrinfo(res);
}
if (p != namebuf)
{
FREE(p);
}
if (addr == NULL)
{
return "does not look numeric and name lookup failed";
}
return err;
}
/*