diff options
-rw-r--r-- | src/conf-tokens.c | 1 | ||||
-rw-r--r-- | src/conf-tokens.h | 1 | ||||
-rw-r--r-- | src/conf.c | 8 | ||||
-rw-r--r-- | src/conf.h | 1 | ||||
-rw-r--r-- | src/conns.c | 6 | ||||
-rw-r--r-- | src/conns.h | 6 | ||||
-rw-r--r-- | src/reqs.c | 18 | ||||
-rw-r--r-- | src/sock.c | 16 | ||||
-rw-r--r-- | src/sock.h | 3 |
9 files changed, 47 insertions, 13 deletions
diff --git a/src/conf-tokens.c b/src/conf-tokens.c index 4ca38e3..edfcedf 100644 --- a/src/conf-tokens.c +++ b/src/conf-tokens.c @@ -59,6 +59,7 @@ config_directive_find (register const char *str, register size_t len) {"addheader", CD_addheader}, {"maxrequestsperchild", CD_maxrequestsperchild}, {"bindipv4mapped", CD_bindipv4mapped}, + {"bindipv6mapped", CD_bindipv6mapped}, }; for(i=0;i<sizeof(wordlist)/sizeof(wordlist[0]);++i) { diff --git a/src/conf-tokens.h b/src/conf-tokens.h index 7188dbf..e99f0de 100644 --- a/src/conf-tokens.h +++ b/src/conf-tokens.h @@ -43,6 +43,7 @@ CD_reversepath, CD_upstream, CD_loglevel, CD_bindipv4mapped, +CD_bindipv6mapped, }; struct config_directive_entry { const char* name; enum config_directive value; }; @@ -118,6 +118,7 @@ static HANDLE_FUNC (handle_basicauth); static HANDLE_FUNC (handle_anonymous); static HANDLE_FUNC (handle_bind); static HANDLE_FUNC (handle_bindipv4mapped); +static HANDLE_FUNC (handle_bindipv6mapped); static HANDLE_FUNC (handle_bindsame); static HANDLE_FUNC (handle_connectport); static HANDLE_FUNC (handle_defaulterrorfile); @@ -218,6 +219,7 @@ struct { handle_deny), STDCONF (bind, "(" IP "|" IPV6 ")", handle_bind), STDCONF (bindipv4mapped, "(" IPV6 ")", handle_bindipv4mapped), + STDCONF (bindipv6mapped, "(" IP ")", handle_bindipv6mapped), /* other */ STDCONF (basicauth, ALNUM WS ALNUM, handle_basicauth), STDCONF (errorfile, INT WS STR, handle_errorfile), @@ -292,6 +294,7 @@ void free_config (struct config_s *conf) safefree (conf->user); safefree (conf->group); safefree (conf->bind_ipv4mapped); + safefree (conf->bind_ipv6mapped); stringlist_free(conf->basicauth_list); stringlist_free(conf->listen_addrs); stringlist_free(conf->bind_addrs); @@ -853,6 +856,11 @@ static HANDLE_FUNC (handle_bindipv4mapped) return set_string_arg(&conf->bind_ipv4mapped, line, &match[2]); } +static HANDLE_FUNC (handle_bindipv6mapped) +{ + return set_string_arg(&conf->bind_ipv6mapped, line, &match[2]); +} + static HANDLE_FUNC (handle_errorfile) { /* @@ -71,6 +71,7 @@ struct config_s { sblist *bind_addrs; unsigned int bindsame; char *bind_ipv4mapped; + char *bind_ipv6mapped; /* * The configured name to use in the HTTP "Via" header field. diff --git a/src/conns.c b/src/conns.c index 921cdf6..feac522 100644 --- a/src/conns.c +++ b/src/conns.c @@ -40,7 +40,7 @@ void conn_struct_init(struct conn_s *connptr) { int conn_init_contents (struct conn_s *connptr, const char *ipaddr, const char *sock_ipaddr, - const char *sock_ipaddr_mapped) + const char *sock_ipaddr_alt) { struct buffer_s *cbuffer, *sbuffer; @@ -60,8 +60,8 @@ int conn_init_contents (struct conn_s *connptr, const char *ipaddr, connptr->server_ip_addr = (sock_ipaddr ? safestrdup (sock_ipaddr) : NULL); - connptr->server_ip_addr_mapped = (sock_ipaddr_mapped ? - safestrdup (sock_ipaddr_mapped) : NULL); + connptr->server_ip_addr_alt = (sock_ipaddr_alt ? + safestrdup (sock_ipaddr_alt) : NULL); connptr->client_ip_addr = safestrdup (ipaddr); update_stats (STAT_OPEN); diff --git a/src/conns.h b/src/conns.h index c702fed..36082f2 100644 --- a/src/conns.h +++ b/src/conns.h @@ -62,9 +62,9 @@ struct conn_s { char *server_ip_addr; /* - * Store the server's mapped IP (for BindSame) + * Store the server's alternative IP (for BindIPv4/6Mapped) */ - char *server_ip_addr_mapped; + char *server_ip_addr_alt; /* * Store the client's IP information @@ -99,7 +99,7 @@ extern void conn_struct_init(struct conn_s *connptr); /* second stage initializiation, sets up buffers and connection details */ extern int conn_init_contents (struct conn_s *connptr, const char *ipaddr, const char *sock_ipaddr, - const char *sock_ipaddr_mapped); + const char *sock_ipaddr_alt); extern void conn_destroy_contents (struct conn_s *connptr); #endif @@ -1517,7 +1517,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) orderedmap hashofheaders = NULL; char sock_ipaddr[IP_LENGTH]; - char sock_ipaddr_mapped[IP_LENGTH]; + char sock_ipaddr_alt[IP_LENGTH]=""; char peer_ipaddr[IP_LENGTH]; getpeer_information (addr, peer_ipaddr, sizeof(peer_ipaddr)); @@ -1525,8 +1525,16 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) if (config->bindsame) getsock_ip (fd, sock_ipaddr); - if (config->bind_ipv4mapped) - getmapped_ip (config->bind_ipv4mapped, sock_ipaddr, sock_ipaddr_mapped); + switch (SOCKADDR_UNION_AF(addr)) { + case AF_INET: + if (config->bind_ipv4mapped) + getmapped_ipv6 (config->bind_ipv4mapped, sock_ipaddr, sock_ipaddr_alt); + break; + case AF_INET6: + if (config->bind_ipv6mapped) + getmapped_ipv4 (config->bind_ipv6mapped, sock_ipaddr, sock_ipaddr_alt); + break; + } log_message (LOG_CONN, config->bindsame ? "Connect (file descriptor %d): %s at [%s]" : @@ -1535,7 +1543,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) if(!conn_init_contents (connptr, peer_ipaddr, config->bindsame ? sock_ipaddr : NULL, - config->bind_ipv4mapped ? sock_ipaddr_mapped : NULL)) { + sock_ipconfig_alt[0] ? sock_ipaddr_alt : NULL)) { close (fd); return; } @@ -1676,7 +1684,7 @@ e401: } else { connptr->server_fd = opensock (request->host, request->port, connptr->server_ip_addr, - connptr->server_ip_addr_mapped); + connptr->server_ip_addr_alt); if (connptr->server_fd < 0) { indicate_http_error (connptr, 500, "Unable to connect", "detail", @@ -385,11 +385,25 @@ int getsock_ip (int fd, char *ipaddr) return 0; } -int getmapped_ip (const char *ipv4mapped_conf, const char *ipaddr, char *ipaddr_mapped) +int getmapped_ipv4 (const char *ipv6mapped_conf, const char *ipaddr, char *ipaddr_mapped) +{ + struct in6_addr addr6; + struct in_addr addr; + + memset(&addr6, 0, sizeof(addr6)); + if ( inet_pton(AF_INET6, ipaddr, &addr6) < 0 ) + return -1; + + memcpy(&addr, addr6.s6_addr + 12, sizeof(&addr)); + return inet_ntop(AF_INET, &addr, ipaddr_mapped, IP_LENGTH) == NULL ? -1 : 0; +} + +int getmapped_ipv6 (const char *ipv4mapped_conf, const char *ipaddr, char *ipaddr_mapped) { memset(ipaddr_mapped, 0, IP_LENGTH); strncpy(ipaddr_mapped, ipv4mapped_conf, IP_LENGTH-1); strncat(ipaddr_mapped, ipaddr, IP_LENGTH-1-strlen(ipaddr_mapped)); + return 0; } @@ -57,7 +57,8 @@ extern int socket_nonblocking (int sock); extern int socket_blocking (int sock); extern int getsock_ip (int fd, char *ipaddr); -extern int getmapped_ip (const char *ipv4mapped_conf, const char *ipaddr, char *ipaddr_mapped); +extern int getmapped_ipv6 (const char *ipv4mapped_conf, const char *ipaddr, char *ipaddr_mapped); +extern int getmapped_ipv4 (const char *ipv6mapped_conf, const char *ipaddr, char *ipaddr_mapped); extern void getpeer_information (union sockaddr_union *addr, char *ipaddr, size_t ipaddr_len); #endif |