summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoff Garside <geoff@geoffgarside.co.uk>2011-06-17 01:49:21 +0100
committerantirez <antirez@gmail.com>2013-07-08 15:49:22 +0200
commite0cb24351cb2ebbfdda5d1b4bdc2e83ca14c09a2 (patch)
tree5e13ca93937335390ee0396df210e4af8a5b4b82
parent0e01ce1b13c4e0a974dc4009dc78811a234f0244 (diff)
downloadredis-e0cb24351cb2ebbfdda5d1b4bdc2e83ca14c09a2.tar.gz
Use getaddrinfo(3) in a anetTcpServer.
Change anetTcpServer() function to use getaddrinfo(3) to perform address resolution, socket creation and binding. Resolved addresses are limited to those reachable by the AF_INET address family.
-rw-r--r--src/anet.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/anet.c b/src/anet.c
index bbff3e3e9..0c33fbf45 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -362,23 +362,37 @@ static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len) {
int anetTcpServer(char *err, int port, char *bindaddr)
{
- int s;
- struct sockaddr_in sa;
+ int s, rv;
+ char _port[6]; /* strlen("65535") */
+ struct addrinfo hints, *servinfo, *p;
- if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
- return ANET_ERR;
+ snprintf(_port,6,"%d",port);
+ memset(&hints,0,sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE; /* No effect if bindaddr != NULL */
- memset(&sa,0,sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
- sa.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bindaddr && inet_aton(bindaddr, &sa.sin_addr) == 0) {
- anetSetError(err, "invalid bind address");
- close(s);
+ if ((rv = getaddrinfo(bindaddr,_port,&hints,&servinfo)) != 0) {
+ anetSetError(err, "%s", gai_strerror(rv));
return ANET_ERR;
}
- if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa)) == 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;
+
+ if (anetListen(err,s,p->ai_addr,p->ai_addrlen) == ANET_ERR)
+ goto error; /* could continue here? */
+ goto end;
+ }
+ if (p == NULL) {
+ anetSetError(err, "unable to bind socket");
+ goto error;
+ }
+
+error:
+ s = ANET_ERR;
+end:
+ freeaddrinfo(servinfo);
return s;
}