Commit e50f2c93 authored by Geoff Garside's avatar Geoff Garside Committed by antirez
Browse files

Use getaddrinfo(3) in anetTcpGenericConnect.

Change anetTcpGenericConnect() function to use getaddrinfo(3) to
perform address resolution, socket creation and connection. Resolved
addresses are limited to those reachable by the AF_INET family.
parent d36dc1fc
...@@ -217,38 +217,52 @@ static int anetCreateSocket(char *err, int domain) { ...@@ -217,38 +217,52 @@ static int anetCreateSocket(char *err, int domain) {
#define ANET_CONNECT_NONBLOCK 1 #define ANET_CONNECT_NONBLOCK 1
static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
{ {
int s; int s, rv;
struct sockaddr_in sa; char _port[6]; /* strlen("65535"); */
struct addrinfo hints, *servinfo, *p;
if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
return ANET_ERR;
sa.sin_family = AF_INET; snprintf(_port,6,"%d",port);
sa.sin_port = htons(port); memset(&hints,0,sizeof(hints));
if (inet_aton(addr, &sa.sin_addr) == 0) { hints.ai_family = AF_INET;
struct hostent *he; hints.ai_socktype = SOCK_STREAM;
he = gethostbyname(addr); if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
if (he == NULL) { anetSetError(err, "%s", gai_strerror(rv));
anetSetError(err, "can't resolve: %s", addr);
close(s);
return ANET_ERR; return ANET_ERR;
} }
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); for (p = servinfo; p != NULL; p = p->ai_next) {
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
continue;
/* if we set err then goto cleanup, otherwise next */
if (anetSetReuseAddr(err,s) == ANET_ERR) {
goto error;
} }
if (flags & ANET_CONNECT_NONBLOCK) { if (flags & ANET_CONNECT_NONBLOCK) {
if (anetNonBlock(err,s) != ANET_OK) if (anetNonBlock(err,s) != ANET_OK)
return ANET_ERR; goto error;
} }
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
if (errno == EINPROGRESS && if (errno == EINPROGRESS &&
flags & ANET_CONNECT_NONBLOCK) flags & ANET_CONNECT_NONBLOCK)
return s; goto end;
anetSetError(err, "connect: %s", strerror(errno));
close(s); close(s);
return ANET_ERR; continue;
}
/* break with the socket */
goto end;
} }
if (p == NULL) {
anetSetError(err, "creating socket: %s", strerror(errno));
goto error;
}
error:
s = ANET_ERR;
end:
freeaddrinfo(servinfo);
return s; return s;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment