From 360230e08f1c17a573b7042ab83fc71e108c9edc Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 10 Nov 2020 23:31:51 +0100 Subject: WIP: BindIPv6Mapped --- src/conf-tokens.c | 1 + src/conf-tokens.h | 1 + src/conf.c | 8 ++++++++ src/conf.h | 1 + src/conns.c | 6 +++--- src/conns.h | 6 +++--- src/reqs.c | 18 +++++++++++++----- src/sock.c | 16 +++++++++++++++- 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;iuser); 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) { /* diff --git a/src/conf.h b/src/conf.h index a7c5a0c..572aeb1 100644 --- a/src/conf.h +++ b/src/conf.h @@ -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 diff --git a/src/reqs.c b/src/reqs.c index f5c804a..da23405 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1530,7 +1530,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)); @@ -1538,8 +1538,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]" : @@ -1548,7 +1556,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; } @@ -1689,7 +1697,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", diff --git a/src/sock.c b/src/sock.c index f9d6a89..b11babb 100644 --- a/src/sock.c +++ b/src/sock.c @@ -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; } diff --git a/src/sock.h b/src/sock.h index 15ab4df..170dc3c 100644 --- a/src/sock.h +++ b/src/sock.h @@ -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 -- cgit v1.2.3