Commit 0e01ce1b 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 580b7dce
...@@ -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) snprintf(_port,6,"%d",port);
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
anetSetError(err, "%s", gai_strerror(rv));
return ANET_ERR; return ANET_ERR;
}
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
continue;
sa.sin_family = AF_INET; /* if we set err then goto cleanup, otherwise next */
sa.sin_port = htons(port); if (anetSetReuseAddr(err,s) == ANET_ERR) {
if (inet_aton(addr, &sa.sin_addr) == 0) { goto error;
struct hostent *he; }
if (flags & ANET_CONNECT_NONBLOCK) {
if (anetNonBlock(err,s) != ANET_OK)
goto error;
}
if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
if (errno == EINPROGRESS &&
flags & ANET_CONNECT_NONBLOCK)
goto end;
he = gethostbyname(addr);
if (he == NULL) {
anetSetError(err, "can't resolve: %s", addr);
close(s); close(s);
return ANET_ERR; continue;
} }
memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
/* break with the socket */
goto end;
} }
if (flags & ANET_CONNECT_NONBLOCK) { if (p == NULL) {
if (anetNonBlock(err,s) != ANET_OK) anetSetError(err, "creating socket: %s", strerror(errno));
return ANET_ERR; goto error;
} }
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
if (errno == EINPROGRESS &&
flags & ANET_CONNECT_NONBLOCK)
return s;
anetSetError(err, "connect: %s", strerror(errno)); error:
close(s); s = ANET_ERR;
return 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