diff options
Diffstat (limited to 'src/libstrongswan/utils/host.c')
-rw-r--r-- | src/libstrongswan/utils/host.c | 139 |
1 files changed, 53 insertions, 86 deletions
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index 484de5e54..661bec315 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -17,6 +17,7 @@ */ #define _GNU_SOURCE +#include <sys/socket.h> #include <netdb.h> #include <string.h> @@ -433,16 +434,40 @@ host_t *host_create_from_string(char *string, u_int16_t port) /* * Described in header. */ +host_t *host_create_from_sockaddr(sockaddr_t *sockaddr) +{ + private_host_t *this = host_create_empty(); + + switch (sockaddr->sa_family) + { + case AF_INET: + { + memcpy(&this->address4, sockaddr, sizeof(struct sockaddr_in)); + this->socklen = sizeof(struct sockaddr_in); + return &this->public; + } + case AF_INET6: + { + memcpy(&this->address6, sockaddr, sizeof(struct sockaddr_in6)); + this->socklen = sizeof(struct sockaddr_in6); + return &this->public; + } + default: + break; + } + free(this); + return NULL; +} + +/* + * Described in header. + */ host_t *host_create_from_dns(char *string, int af, u_int16_t port) { private_host_t *this; - struct hostent *ptr; - int ret = 0, err; -#ifdef HAVE_GETHOSTBYNAME_R - struct hostent host; - char buf[512]; -#endif - + struct addrinfo hints, *result; + int error; + if (streq(string, "%any")) { return host_create_any_port(af ? af : AF_INET, port); @@ -451,62 +476,32 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port) { return host_create_any_port(af ? af : AF_INET6, port); } - else if (strchr(string, ':')) - { - /* gethostbyname does not like IPv6 addresses - fallback */ - return host_create_from_string(string, port); - } - -#ifdef HAVE_GETHOSTBYNAME_R - if (af) - { - ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err); - } - else - { - ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err); - } -#else - /* Some systems (e.g. Mac OS X) do not support gethostbyname_r */ - if (af) - { - ptr = gethostbyname2(string, af); - } - else - { - ptr = gethostbyname(string); - } - if (ptr == NULL) - { - err = h_errno; - } -#endif - if (ret != 0 || ptr == NULL) + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + error = getaddrinfo(string, NULL, &hints, &result); + if (error != 0) { - DBG1("resolving '%s' failed: %s", string, hstrerror(err)); + DBG1("resolving '%s' failed: %s", string, gai_strerror(error)); return NULL; } - this = host_create_empty(); - this->address.sa_family = ptr->h_addrtype; - switch (this->address.sa_family) + /* result is a linked list, but we use only the first address */ + this = (private_host_t*)host_create_from_sockaddr(result->ai_addr); + freeaddrinfo(result); + if (this) { - case AF_INET: - memcpy(&this->address4.sin_addr.s_addr, - ptr->h_addr_list[0], ptr->h_length); - this->address4.sin_port = htons(port); - this->socklen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - memcpy(&this->address6.sin6_addr.s6_addr, - ptr->h_addr_list[0], ptr->h_length); - this->address6.sin6_port = htons(port); - this->socklen = sizeof(struct sockaddr_in6); - break; - default: - free(this); - return NULL; + switch (this->address.sa_family) + { + case AF_INET: + this->address4.sin_port = htons(port); + break; + case AF_INET6: + this->address6.sin6_port = htons(port); + break; + } + return &this->public; } - return &this->public; + return NULL; } /* @@ -569,34 +564,6 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) /* * Described in header. */ -host_t *host_create_from_sockaddr(sockaddr_t *sockaddr) -{ - private_host_t *this = host_create_empty(); - - switch (sockaddr->sa_family) - { - case AF_INET: - { - memcpy(&this->address4, sockaddr, sizeof(struct sockaddr_in)); - this->socklen = sizeof(struct sockaddr_in); - return &this->public; - } - case AF_INET6: - { - memcpy(&this->address6, sockaddr, sizeof(struct sockaddr_in6)); - this->socklen = sizeof(struct sockaddr_in6); - return &this->public; - } - default: - break; - } - free(this); - return NULL; -} - -/* - * Described in header. - */ host_t *host_create_any(int family) { private_host_t *this = host_create_empty(); |