From dc2a4fe4e949c250ca25708aa5a6dd575878fd7e Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 14 Dec 2013 19:38:50 -0500 Subject: [PATCH] vos: GetServer search for non-loopback address GetServer() is used to obtain an IP address for the 'aname' parameter. 'aname' can be either a dotted address or a host name. If it is a dotted address, it is returned immediately. If it is a host name, then gethostbyname() is used to obtain an IP address. The prior version of this function had two failings: 1. It assumed that a struct hostent only contained a single address. It used the former h_addr field. For all platforms supported by OpenAFS h_addr is a macro referencing the first address in the h_addr_list array. If h_addr was a loopback address, it would ignore any additional addresses that might be in the list. 2. It assumed that if gethostbyname(aname) returned a loopback address as h_addr that 'aname' must be referring to the machine that the vos command is being executed on. It therefore used gethostname() to obtain an alternate name to use for a gethostbyname() query. The results of this query were not checked to be a loopback. As a result, a loopback address could be returned to the caller which in turn could be set into the VLDB. Change-Id: Ib8d513be9daf650045e9c40718b0187f6b9770a2 Reviewed-on: http://gerrit.openafs.org/10585 Reviewed-by: D Brashear Reviewed-by: Benjamin Kaduk Reviewed-by: Harald Barth Tested-by: BuildBot --- src/volser/vos.c | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/volser/vos.c b/src/volser/vos.c index b6cb029..95df17b 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -208,7 +208,7 @@ GetServerNoresolve(char *aname) return 0; } /* - * Parse a server name/address and return the address in network byte order + * Parse a server name/address and return a non-loopback address in network byte order */ afs_uint32 GetServer(char *aname) @@ -217,25 +217,50 @@ GetServer(char *aname) afs_uint32 addr; /* in network byte order */ afs_int32 code; char hostname[MAXHOSTCHARS]; + int i; - if ((addr = GetServerNoresolve(aname)) == 0) { - th = gethostbyname(aname); - if (!th) + addr = GetServerNoresolve(aname); + if (addr != 0) { + if (!rx_IsLoopbackAddr(ntohl(addr))) + return addr; + else return 0; - memcpy(&addr, th->h_addr, sizeof(addr)); } - if (rx_IsLoopbackAddr(ntohl(addr))) { /* local host */ + th = gethostbyname(aname); + if (th != NULL) { + for (i=0; i < th->h_length; i++) { + if (!rx_IsLoopbackAddr(ntohl(*(afs_uint32 *)th->h_addr_list[i]))) { + memcpy(&addr, th->h_addr_list[i], sizeof(addr)); + return addr; + } + } + + /* + * If we reach this point all of the addresses returned by + * gethostbyname() are loopback addresses. We assume that means + * that the name is supposed to describe the machine this code + * is executing on. Try gethostname() to and check to see if + * that name can provide us a non-loopback address. + */ code = gethostname(hostname, MAXHOSTCHARS); - if (code) - return 0; - th = gethostbyname(hostname); - if (!th) - return 0; - memcpy(&addr, th->h_addr, sizeof(addr)); + if (code == 0) { + th = gethostbyname(hostname); + if (th != NULL) { + for (i=0; i < th->h_length; i++) { + if (!rx_IsLoopbackAddr(ntohl(*(afs_uint32 *)th->h_addr_list[i]))) { + memcpy(&addr, th->h_addr_list[i], sizeof(addr)); + return addr; + } + } + } + } } - return (addr); + /* + * No non-loopback address could be obtained for 'aname'. + */ + return 0; } afs_int32 -- 1.9.4