diff --git a/src/http-header-glue.c b/src/http-header-glue.c index 3ad5ad2b..ce7a768d 100644 --- a/src/http-header-glue.c +++ b/src/http-header-glue.c @@ -19,70 +19,6 @@ #include "sys-strings.h" #include "sys-socket.h" #include -#ifndef _WIN32 -#include -#endif - -/* - * This was 'borrowed' from tcpdump. - * - * - * This is fun. - * - * In older BSD systems, socket addresses were fixed-length, and - * "sizeof (struct sockaddr)" gave the size of the structure. - * All addresses fit within a "struct sockaddr". - * - * In newer BSD systems, the socket address is variable-length, and - * there's an "sa_len" field giving the length of the structure; - * this allows socket addresses to be longer than 2 bytes of family - * and 14 bytes of data. - * - * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 - * variant of the old BSD scheme (with "struct sockaddr_storage" rather - * than "struct sockaddr"), and some use the new BSD scheme. - * - * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" - * macro that determines the size based on the address family. Other - * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 - * but not in the final version). On the latter systems, we explicitly - * check the AF_ type to determine the length; we assume that on - * all those systems we have "struct sockaddr_storage". - */ - -#ifdef HAVE_IPV6 -# ifndef SA_LEN -# ifdef HAVE_SOCKADDR_SA_LEN -# define SA_LEN(addr) ((addr)->sa_len) -# else /* HAVE_SOCKADDR_SA_LEN */ -# ifdef HAVE_STRUCT_SOCKADDR_STORAGE -static size_t get_sa_len(const struct sockaddr *addr) { - switch (addr->sa_family) { - -# ifdef AF_INET - case AF_INET: - return (sizeof (struct sockaddr_in)); -# endif - -# ifdef AF_INET6 - case AF_INET6: - return (sizeof (struct sockaddr_in6)); -# endif - - default: - return (sizeof (struct sockaddr)); - - } -} -# define SA_LEN(addr) (get_sa_len(addr)) -# else /* HAVE_SOCKADDR_STORAGE */ -# define SA_LEN(addr) (sizeof (struct sockaddr)) -# endif /* HAVE_SOCKADDR_STORAGE */ -# endif /* HAVE_SOCKADDR_SA_LEN */ -# endif /* SA_LEN */ -#endif - - int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { @@ -142,10 +78,6 @@ int http_response_redirect_to_directory(server *srv, connection *con) { buffer_append_string_buffer(o, con->uri.authority); } else { /* get the name of the currently connected socket */ - struct hostent *he; -#ifdef HAVE_IPV6 - char hbuf[256]; -#endif sock_addr our_addr; socklen_t our_addr_len; @@ -162,51 +94,12 @@ int http_response_redirect_to_directory(server *srv, connection *con) { return 0; } - /* Lookup name: secondly try to get hostname for bind address */ - switch(our_addr.plain.sa_family) { -#ifdef HAVE_IPV6 - case AF_INET6: - if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), - SA_LEN((const struct sockaddr *)&our_addr.ipv6), - hbuf, sizeof(hbuf), NULL, 0, 0)) { - - char dst[INET6_ADDRSTRLEN]; - - log_error_write(srv, __FILE__, __LINE__, - "SSS", "NOTICE: getnameinfo failed: ", - strerror(errno), ", using ip-address instead"); - - buffer_append_string_len(o, CONST_STR_LEN("[")); - buffer_append_string(o, - inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, - dst, sizeof(dst))); - buffer_append_string_len(o, CONST_STR_LEN("]")); - } else { - buffer_append_string(o, hbuf); - } - break; -#endif - case AF_INET: - if (NULL == (he = gethostbyaddr((char *)&our_addr.ipv4.sin_addr, sizeof(struct in_addr), AF_INET))) { - log_error_write(srv, __FILE__, __LINE__, - "SdS", "NOTICE: gethostbyaddr failed: ", - h_errno, ", using ip-address instead"); - - buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr)); - } else { - buffer_append_string(o, he->h_name); - } - break; - default: - log_error_write(srv, __FILE__, __LINE__, - "S", "ERROR: unsupported address-type"); - + if (0 != sock_addr_nameinfo_append_buffer(srv, o, &our_addr)) { + con->http_status = 500; buffer_free(o); return -1; - } - - { + } else { unsigned short default_port = 80; if (buffer_is_equal_caseless_string(con->uri.scheme, CONST_STR_LEN("https"))) { default_port = 443; diff --git a/src/inet_ntop_cache.c b/src/inet_ntop_cache.c index 28992c04..14e783ac 100644 --- a/src/inet_ntop_cache.c +++ b/src/inet_ntop_cache.c @@ -104,6 +104,52 @@ int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr) } +int sock_addr_nameinfo_append_buffer(server *srv, buffer *b, const sock_addr *addr) +{ + /*(this routine originates from + * http-header-glue.c:http_response_redirect_to_directory())*/ + /*(note: name resolution here is *blocking*)*/ + if (AF_INET == addr->plain.sa_family) { + struct hostent *he = gethostbyaddr((char *)&addr->ipv4.sin_addr, + sizeof(struct in_addr), AF_INET); + if (NULL == he) { + log_error_write(srv, __FILE__, __LINE__, + "SdS", "NOTICE: gethostbyaddr failed: ", + h_errno, ", using ip-address instead"); + + sock_addr_inet_ntop_append_buffer(b, addr); + } else { + buffer_append_string(b, he->h_name); + } + } + #ifdef HAVE_IPV6 + else if (AF_INET6 == addr->plain.sa_family) { + char hbuf[256]; + if (0 != getnameinfo((const struct sockaddr *)(&addr->ipv6), + sizeof(&addr->ipv6), + hbuf, sizeof(hbuf), NULL, 0, 0)) { + log_error_write(srv, __FILE__, __LINE__, + "SSS", "NOTICE: getnameinfo failed: ", + strerror(errno), ", using ip-address instead"); + + buffer_append_string_len(b, CONST_STR_LEN("[")); + sock_addr_inet_ntop_append_buffer(b, addr); + buffer_append_string_len(b, CONST_STR_LEN("]")); + } else { + buffer_append_string(b, hbuf); + } + } + #endif + else { + log_error_write(srv, __FILE__, __LINE__, + "S", "ERROR: unsupported address-type"); + return -1; + } + + return 0; +} + + int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const char *str, int family, unsigned short port) { /*(note: name resolution here is *blocking*)*/ diff --git a/src/inet_ntop_cache.h b/src/inet_ntop_cache.h index b1635267..9e7e98f0 100644 --- a/src/inet_ntop_cache.h +++ b/src/inet_ntop_cache.h @@ -18,6 +18,7 @@ int sock_addr_inet_pton(sock_addr *addr, const char *str, int family, unsigned s const char * sock_addr_inet_ntop(const sock_addr *addr, char *buf, socklen_t sz); int sock_addr_inet_ntop_copy_buffer(buffer *b, const sock_addr *addr); int sock_addr_inet_ntop_append_buffer(buffer *b, const sock_addr *addr); +int sock_addr_nameinfo_append_buffer(server *srv, buffer *b, const sock_addr *addr); int sock_addr_from_buffer_hints_numeric(server *srv, sock_addr *addr, socklen_t *len, const buffer *b, int family, unsigned short port); int sock_addr_from_str_hints(server *srv, sock_addr *addr, socklen_t *len, const char *str, int family, unsigned short port);