- struct hostent *phe;
- struct servent *pse;
- struct protoent *ppe;
- struct sockaddr_in sin;
- struct sockaddr_in egress_sin;
- int s, type;
-
- if ((host == NULL) || IsEmptyStr(host))
- return(-1);
- if ((service == NULL) || IsEmptyStr(service))
- return(-1);
- if ((protocol == NULL) || IsEmptyStr(protocol))
- return(-1);
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
-
- pse = getservbyname(service, protocol);
- if (pse) {
- sin.sin_port = pse->s_port;
- } else if ((sin.sin_port = htons((u_short) atoi(service))) == 0) {
- CtdlLogPrintf(CTDL_CRIT, "Can't get %s service entry: %s\n",
- service, strerror(errno));
- return(-1);
- }
- phe = gethostbyname(host);
- if (phe) {
- memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
- } else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
- CtdlLogPrintf(CTDL_ERR, "Can't get %s host entry: %s\n",
- host, strerror(errno));
- return(-1);
- }
- if ((ppe = getprotobyname(protocol)) == 0) {
- CtdlLogPrintf(CTDL_CRIT, "Can't get %s protocol entry: %s\n",
- protocol, strerror(errno));
- return(-1);
- }
- if (!strcmp(protocol, "udp")) {
- type = SOCK_DGRAM;
+ struct in6_addr serveraddr;
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
+ struct addrinfo *ai = NULL;
+ int rc = (-1);
+ int sock = (-1);
+
+ if ((host == NULL) || IsEmptyStr(host))
+ return (-1);
+ if ((service == NULL) || IsEmptyStr(service))
+ return (-1);
+
+ memset(&hints, 0x00, sizeof(hints));
+ hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ /*
+ * Handle numeric IPv4 and IPv6 addresses
+ */
+ rc = inet_pton(AF_INET, host, &serveraddr);
+ if (rc == 1) { /* dotted quad */
+ hints.ai_family = AF_INET;
+ hints.ai_flags |= AI_NUMERICHOST;