diff options
author | Geoff Garside <geoff@geoffgarside.co.uk> | 2011-06-17 01:49:21 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2013-07-08 15:49:22 +0200 |
commit | e0cb24351cb2ebbfdda5d1b4bdc2e83ca14c09a2 (patch) | |
tree | 5e13ca93937335390ee0396df210e4af8a5b4b82 | |
parent | 0e01ce1b13c4e0a974dc4009dc78811a234f0244 (diff) | |
download | redis-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.c | 40 |
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; } |