From: Nick Mathewson Date: Wed, 3 Oct 2007 17:19:22 +0000 (+0000) Subject: r15517@catbus: nickm | 2007-10-03 13:14:05 -0400 X-Git-Tag: release-2.0.1-alpha~548 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49ede3be00c7461d54fa289005db8ef6e8e76225;p=libevent r15517@catbus: nickm | 2007-10-03 13:14:05 -0400 Correct the pointer manipulation in fake_getaddrinfo(), and do the right thing for fake_getaddrinfo(NULL,&ai). Based on a patch by Lubmir Marinov, hacked until the unit tests passed on Linux with #undef HAVE_GETADDRINFO. svn:r459 --- diff --git a/ChangeLog b/ChangeLog index c36ce72c..6dd6b354 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,3 +27,4 @@ Changes in current version: o Make the test.sh script run unit tests for the evpoll method. o Make the entire evdns.h header enclosed in "extern C" as appropriate. o Fix implementation of strsep on platforms that lack it + o Fix implementation of getaddrinfo on platforms that lack it; mainly, this will make Windows http.c work better. Original patch by Lubomir Marinov. \ No newline at end of file diff --git a/http.c b/http.c index d0e458e4..447d7647 100644 --- a/http.c +++ b/http.c @@ -90,17 +90,28 @@ struct addrinfo { static int fake_getaddrinfo(const char *hostname, struct addrinfo *ai) { - struct hostent *he; - he = gethostbyname(hostname); - if (!he) - return (-1); - ai->ai_family = he->h_addrtype; + struct hostent *he = NULL; + struct sockaddr_in *sa; + if (hostname) { + he = gethostbyname(hostname); + if (!he) + return (-1); + } + ai->ai_family = he ? he->h_addrtype : AF_INET; ai->ai_socktype = SOCK_STREAM; ai->ai_protocol = 0; - ai->ai_addrlen = he->h_length; + ai->ai_addrlen = sizeof(struct sockaddr_in); if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen))) return (-1); - memcpy(ai->ai_addr, &he->h_addr_list[0], ai->ai_addrlen); + sa = (struct sockaddr_in*)ai->ai_addr; + memset(sa, 0, ai->ai_addrlen); + if (he) { + sa->sin_family = he->h_addrtype; + memcpy(&sa->sin_addr, he->h_addr_list[0], he->h_length); + } else { + sa->sin_family = AF_INET; + sa->sin_addr.s_addr = INADDR_ANY; + } ai->ai_next = NULL; return (0); } @@ -144,7 +155,7 @@ static char * strsep(char **s, const char *del) { char *d, *tok; - assert(strlen(del) == 1); + assert(strlen(del) == 1); if (!s || !*s) return NULL; tok = *s; @@ -349,7 +360,7 @@ evhttp_make_header_response(struct evhttp_connection *evcon, cur_p = gmtime(&t); #else gmtime_r(&t, &cur); - cur_p = &cur; + cur_p = &cur; #endif if (strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) { @@ -1939,8 +1950,8 @@ accept_socket(int fd, short what, void *arg) event_warn("%s: bad accept", __func__); return; } - if (evutil_make_socket_nonblocking(nfd) < 0) - return; + if (evutil_make_socket_nonblocking(nfd) < 0) + return; evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen); } @@ -2277,7 +2288,7 @@ addr_from_name(char *address) struct addrinfo ai, *aitop; int ai_result; - memset(&ai, 0, sizeof (ai)); + memset(&ai, 0, sizeof(ai)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_RAW; ai.ai_flags = 0; @@ -2369,18 +2380,19 @@ bind_socket_ai(struct addrinfo *ai) static struct addrinfo * make_addrinfo(const char *address, u_short port) { - struct addrinfo ai[2], *aitop = NULL; + struct addrinfo *aitop = NULL; #ifdef HAVE_GETADDRINFO + struct addrinfo ai; char strport[NI_MAXSERV]; int ai_result; - memset(&ai[0], 0, sizeof (ai[0])); - ai[0].ai_family = AF_INET; - ai[0].ai_socktype = SOCK_STREAM; - ai[0].ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */ - snprintf(strport, sizeof (strport), "%d", port); - if ((ai_result = getaddrinfo(address, strport, &ai[0], &aitop)) != 0) { + memset(&ai, 0, sizeof(ai)); + ai.ai_family = AF_INET; + ai.ai_socktype = SOCK_STREAM; + ai.ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */ + snprintf(strport, sizeof(strport), "%d", port); + if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) { if ( ai_result == EAI_SYSTEM ) event_warn("getaddrinfo"); else @@ -2389,6 +2401,7 @@ make_addrinfo(const char *address, u_short port) } #else static int cur; + static struct addrinfo ai[2]; /* We will be returning the address of some of this memory so it has to last even after this call. */ if (++cur == 2) cur = 0; /* allow calling this function twice */ if (fake_getaddrinfo(address, &ai[cur]) < 0) { @@ -2396,6 +2409,7 @@ make_addrinfo(const char *address, u_short port) return (NULL); } aitop = &ai[cur]; + ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port); #endif return (aitop); @@ -2405,7 +2419,7 @@ static int bind_socket(const char *address, u_short port) { int fd; - struct addrinfo *aitop = make_addrinfo(address, port); + struct addrinfo *aitop = make_addrinfo(address, port); if (aitop == NULL) return (-1);