diff --git a/ChangeLog b/ChangeLog index 9a17b25ae..c2e6cadc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20091107 + - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to + set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify + setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() + report and fix from jan.kratochvil AT redhat.com + 20091107 - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private keys when built with OpenSSL versions that don't do AES. diff --git a/channels.c b/channels.c index e8b8aa07e..22e7f628b 100644 --- a/channels.c +++ b/channels.c @@ -2577,6 +2577,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, } channel_set_reuseaddr(sock); + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); debug("Local forwarding listening on %s port %s.", ntop, strport); @@ -3108,13 +3110,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, continue; } } -#ifdef IPV6_V6ONLY - if (ai->ai_family == AF_INET6) { - int on = 1; - if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) - error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); - } -#endif + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); if (x11_use_localhost) channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { diff --git a/misc.c b/misc.c index 143dbf0e2..4dc152310 100644 --- a/misc.c +++ b/misc.c @@ -849,3 +849,14 @@ ms_to_timeval(struct timeval *tv, int ms) tv->tv_usec = (ms % 1000) * 1000; } +void +sock_set_v6only(int s) +{ +#ifdef IPV6_V6ONLY + int on = 1; + + debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) + error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); +#endif +} diff --git a/misc.h b/misc.h index 5da170d2f..e26b0aaff 100644 --- a/misc.h +++ b/misc.h @@ -35,6 +35,7 @@ char *tohex(const void *, size_t); void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); +void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); const char *ssh_gai_strerror(int); diff --git a/sshd.c b/sshd.c index 13a455d1f..04d8f9fa0 100644 --- a/sshd.c +++ b/sshd.c @@ -979,15 +979,9 @@ server_listen(void) &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); -#ifdef IPV6_V6ONLY /* Only communicate in IPv6 over AF_INET6 sockets. */ - if (ai->ai_family == AF_INET6) { - if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, - &on, sizeof(on)) == -1) - error("setsockopt IPV6_V6ONLY: %s", - strerror(errno)); - } -#endif + if (ai->ai_family == AF_INET6) + sock_set_v6only(listen_sock); debug("Bind to port %s on %s.", strport, ntop);