summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/host.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils/host.c')
-rw-r--r--src/libstrongswan/utils/host.c139
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();