From e0cb24351cb2ebbfdda5d1b4bdc2e83ca14c09a2 Mon Sep 17 00:00:00 2001 From: Geoff Garside Date: Fri, 17 Jun 2011 01:49:21 +0100 Subject: [PATCH] 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. --- src/anet.c | 40 +++++++++++++++++++++++++++------------- 1 file 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; }