From 453317b28cf8286a6bb849ab425fcce74d4148f3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 24 Jan 2011 18:22:32 -0500 Subject: [PATCH 1/6] Fall back to sscanf if we have no other way to implement strtoll --- evutil.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/evutil.c b/evutil.c index 1d2c0fc9..227cc5b4 100644 --- a/evutil.c +++ b/evutil.c @@ -351,6 +351,8 @@ evutil_strtoll(const char *s, char **endptr, int base) r = (ev_int64_t) _atoi64(s); while (isspace(*s)) ++s; + if (*s == '-') + ++s; while (isdigit(*s)) ++s; if (endptr) @@ -358,6 +360,36 @@ evutil_strtoll(const char *s, char **endptr, int base) return r; #elif defined(WIN32) return (ev_int64_t) _strtoi64(s, endptr, base); +#elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8 + long long r; + int n; + if (base != 10 && base != 16) + return 0; + if (base == 10) { + n = sscanf(s, "%lld", &r); + } else { + unsigned long long ru=0; + n = sscanf(s, "%llx", &ru); + if (ru > EV_INT64_MAX) + return 0; + r = (long long) ru; + } + if (n != 1) + return 0; + while (EVUTIL_ISSPACE(*s)) + ++s; + if (*s == '-') + ++s; + if (base == 10) { + while (EVUTIL_ISDIGIT(*s)) + ++s; + } else { + while (EVUTIL_ISXDIGIT(*s)) + ++s; + } + if (endptr) + *endptr = (char*) s; + return r; #else #error "I don't know how to parse 64-bit integers." #endif From 9184563e49562f07efdfcb76618b74822f03e273 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 24 Jan 2011 18:29:20 -0500 Subject: [PATCH 2/6] Build correctly on platforms without sockaddr_storage --- configure.in | 2 +- util-internal.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 0b5cabc2..b14a420c 100644 --- a/configure.in +++ b/configure.in @@ -443,7 +443,7 @@ AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(void *) -AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo], , , +AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo, struct sockaddr_storage], , , [#define _GNU_SOURCE #include #ifdef HAVE_NETINET_IN_H diff --git a/util-internal.h b/util-internal.h index 5c153d30..4d8551d5 100644 --- a/util-internal.h +++ b/util-internal.h @@ -205,6 +205,23 @@ long _evutil_weakrand(void); #define EVUTIL_FAILURE_CHECK(cond) EVUTIL_UNLIKELY(cond) #endif +#ifndef _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE +/* Replacement for sockaddr storage that we can use internally on platforms + * that lack it. It is not space-efficient, but neither is sockaddr_storage. + */ +struct sockaddr_storage { + union { + struct sockaddr ss_sa; + struct sockaddr_in ss_sin; +#ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6 + struct sockaddr_in6 ss_sin6; +#endif + char ss_padding[128]; + } ss_union; +}; +#define ss_family ss_union.ss_sa.sa_family +#endif + /* Internal addrinfo error code. This one is returned from only from * evutil_getaddrinfo_common, when we are sure that we'll have to hit a DNS * server. */ From 713c254d21449e73b2877d6f69ee6c41aa56f182 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 24 Jan 2011 18:55:10 -0500 Subject: [PATCH 3/6] Try to build correctly on platforms with no IPv6 support --- ipv6-internal.h | 9 +++++++++ util-internal.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ipv6-internal.h b/ipv6-internal.h index 7d6fb736..1f272a0d 100644 --- a/ipv6-internal.h +++ b/ipv6-internal.h @@ -59,12 +59,21 @@ typedef int sa_family_t; #ifndef _EVENT_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 { + /* This will fail if we find a struct sockaddr that doesn't have + * sa_family as the first element. */ sa_family_t sin6_family; ev_uint16_t sin6_port; struct in6_addr sin6_addr; }; #endif +#ifndef AF_INET6 +#define AF_INET6 3333 +#endif +#ifndef PF_INET6 +#define PF_INET6 AF_INET6 +#endif + #ifdef __cplusplus } #endif diff --git a/util-internal.h b/util-internal.h index 4d8551d5..18d6ca75 100644 --- a/util-internal.h +++ b/util-internal.h @@ -38,6 +38,8 @@ #endif #include "event2/util.h" +#include "ipv6-internal.h" + #ifdef __cplusplus extern "C" { #endif @@ -213,9 +215,7 @@ struct sockaddr_storage { union { struct sockaddr ss_sa; struct sockaddr_in ss_sin; -#ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 ss_sin6; -#endif char ss_padding[128]; } ss_union; }; From cb921139790bed29427fdd5c07e804f26ea4c334 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 31 Jan 2011 16:32:05 -0500 Subject: [PATCH 4/6] Build on systems without AI_PASSIVE --- evutil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evutil.c b/evutil.c index 227cc5b4..8bab27bd 100644 --- a/evutil.c +++ b/evutil.c @@ -803,7 +803,7 @@ evutil_getaddrinfo_common(const char *nodename, const char *servname, memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(port); - if (hints->ai_flags & AI_PASSIVE) { + if (hints->ai_flags & EVUTIL_AI_PASSIVE) { /* Bind to :: */ } else { /* connect to ::1 */ @@ -820,7 +820,7 @@ evutil_getaddrinfo_common(const char *nodename, const char *servname, memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); - if (hints->ai_flags & AI_PASSIVE) { + if (hints->ai_flags & EVUTIL_AI_PASSIVE) { /* Bind to 0.0.0.0 */ } else { /* connect to 127.0.0.1 */ From 6092f1265f956f1968185bf669b8730edd7e3eaa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 31 Jan 2011 16:37:27 -0500 Subject: [PATCH 5/6] Fix http unit test on non-windows platforms without getaddrinfo --- test/regress_http.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index 99e9f938..4b894acc 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -56,6 +56,7 @@ #include "event2/http.h" #include "event2/buffer.h" #include "event2/bufferevent.h" +#include "event2/util.h" #include "log-internal.h" #include "util-internal.h" #include "http-internal.h" @@ -128,38 +129,23 @@ static evutil_socket_t http_connect(const char *address, u_short port) { /* Stupid code for connecting */ -#ifdef WIN32 - struct hostent *he; - struct sockaddr_in sin; -#else - struct addrinfo ai, *aitop; + struct evutil_addrinfo ai, *aitop; char strport[NI_MAXSERV]; -#endif + struct sockaddr *sa; int slen; evutil_socket_t fd; -#ifdef WIN32 - if (!(he = gethostbyname(address))) { - event_warn("gethostbyname"); - } - memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - slen = sizeof(struct sockaddr_in); - sa = (struct sockaddr*)&sin; -#else memset(&ai, 0, sizeof(ai)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_STREAM; evutil_snprintf(strport, sizeof(strport), "%d", port); - if (getaddrinfo(address, strport, &ai, &aitop) != 0) { + if (evutil_getaddrinfo(address, strport, &ai, &aitop) != 0) { event_warn("getaddrinfo"); return (-1); } sa = aitop->ai_addr; slen = aitop->ai_addrlen; -#endif fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) @@ -178,9 +164,7 @@ http_connect(const char *address, u_short port) #endif } -#ifndef WIN32 - freeaddrinfo(aitop); -#endif + evutil_freeaddrinfo(aitop); return (fd); } From 3c8f4e758e5a636e79f518b70319b115c39b1f23 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 31 Jan 2011 16:44:06 -0500 Subject: [PATCH 6/6] Add compile-time check for AF_UNSPEC==PF_UNSPEC --- evutil.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/evutil.c b/evutil.c index 8bab27bd..926ebc47 100644 --- a/evutil.c +++ b/evutil.c @@ -753,6 +753,10 @@ evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints) } } +#if AF_UNSPEC != PF_UNSPEC +#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC" +#endif + /** Implements the part of looking up hosts by name that's common to both * the blocking and nonblocking resolver: * - Adjust 'hints' to have a reasonable socktype and protocol.