Peter Rabbitson wrote: > Peter Rabbitson wrote: >> Samuli Seppänen wrote: >>> Hi, >>> >>> Is someone successfully using the --multihome option on latest OpenVPN >>> release? Or is this bug report still valid: >>> >>> <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=562099> >>> >> I am sorry I dropped the ball on testing that one. Will test the coming >> night EST, and update. >> > > Looking more at the *debian* changelog, I see that there was a 3rd party > ipv6 patch, which *could* have caused these problems. However it is not > very easy for me to compile a "clean" openvpn on the multihomed server. > Please let me know if this can be diagnosed in any other way, if not - > I will find a way to test with vanilla openvpn. >
And unfortunately I was right (proven with the help of [1]) :( openvpn_2.1~rc20-1_i386.deb works openvpn_2.1~rc20-2_i386.deb does not The only code-change between the two is: * patches/jjo-ipv6-support.patch: Added ipv6 support. (Closes: #307846) Patch from JuanJo Ciarlante. So this got to be the culprit. Attaching a -U10 diff between the sources of both debian packages (not too long): [1] http://snapshot.debian.org/package/openvpn/ diff -U10 -r openvpn-2.1_rc21-1/mroute.c openvpn-2.1_rc21-2/mroute.c --- openvpn-2.1_rc21-1/mroute.c 2010-05-01 21:33:38.520080366 +0200 +++ openvpn-2.1_rc21-2/mroute.c 2010-05-01 21:33:51.746080500 +0200 @@ -358,21 +358,21 @@ } } break; case MR_ADDR_IPV6: #ifdef USE_PF_INET6 { struct buffer buf; struct sockaddr_in6 sin6; int port; char buf6[INET6_ADDRSTRLEN] = ""; - memset(&sin6, 0, sizeof sin6); + CLEAR(sin6); sin6.sin6_family = AF_INET6; buf_set_read (&buf, maddr.addr, maddr.len); if (buf_read(&buf, &sin6.sin6_addr, sizeof (sin6.sin6_addr))) { if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), buf6, sizeof (buf6), NULL, 0, NI_NUMERICHOST) != 0) { buf_printf (&out, "MR_ADDR_IPV6 getnameinfo() err"); break; } diff -U10 -r openvpn-2.1_rc21-1/options.c openvpn-2.1_rc21-2/options.c --- openvpn-2.1_rc21-1/options.c 2010-05-01 21:33:38.529079829 +0200 +++ openvpn-2.1_rc21-2/options.c 2010-05-01 21:33:51.792080328 +0200 @@ -1,19 +1,22 @@ /* * OpenVPN -- An application to securely tunnel IP networks * over a single UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sa...@openvpn.net> * + * Additions for eurephia plugin done by: + * David Sommerseth <d...@users.sourceforge.net> Copyright (C) 2009 + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -72,20 +75,21 @@ #endif #ifdef ENABLE_PKCS11 " [PKCS11]" #endif #ifdef ENABLE_IP_PKTINFO " [MH]" #endif #ifdef USE_PF_INET6 " [PF_INET6]" #endif + " [eurephia]" " built on " __DATE__ ; #ifndef ENABLE_SMALL static const char usage_message[] = "%s\n" "\n" "General Options:\n" "--config file : Read configuration options from file.\n" @@ -1545,28 +1549,36 @@ /* * Sanity check on TCP mode options */ if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT #ifdef USE_PF_INET6 && ce->proto != PROTO_TCPv6_CLIENT #endif ) - msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client"); + msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client" +#ifdef USE_PF_INET6 + " or tcp6-client" +#endif + ); if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT #ifdef USE_PF_INET6 && ce->proto != PROTO_TCPv6_CLIENT #endif ) - msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client"); + msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client" +#ifdef USE_PF_INET6 + " or tcp6-client" +#endif + ); /* * Sanity check on MTU parameters */ if (options->tun_mtu_defined && options->link_mtu_defined) msg (M_USAGE, "only one of --tun-mtu or --link-mtu may be defined (note that --ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT); #ifdef ENABLE_OCC if (!proto_is_udp(ce->proto) && options->mtu_test) msg (M_USAGE, "--mtu-test only makes sense with --proto udp"); @@ -1695,29 +1707,37 @@ { if (!(dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP)) msg (M_USAGE, "--mode server only works with --dev tun or --dev tap"); if (options->pull) msg (M_USAGE, "--pull cannot be used with --mode server"); if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCPv4_SERVER #ifdef USE_PF_INET6 || ce->proto == PROTO_TCPv6_SERVER #endif )) - msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); + msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server" +#ifdef USE_PF_INET6 + " or proto tcp6-server" +#endif + ); #if PORT_SHARE if ((options->port_share_host || options->port_share_port) && (ce->proto != PROTO_TCPv4_SERVER #ifdef USE_PF_INET6 && ce->proto != PROTO_TCPv6_SERVER #endif )) - msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server)"); + msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server" +#ifdef USE_PF_INET6 + " or tcp6-server" +#endif + ")"); #endif if (!options->tls_server) msg (M_USAGE, "--mode server requires --tls-server"); if (ce->remote) msg (M_USAGE, "--remote cannot be used with --mode server"); if (!ce->bind_local) msg (M_USAGE, "--nobind cannot be used with --mode server"); #ifdef ENABLE_HTTP_PROXY if (ce->http_proxy_options) msg (M_USAGE, "--http-proxy cannot be used with --mode server"); @@ -1736,21 +1756,25 @@ msg (M_USAGE, "--shaper cannot be used with --mode server"); if (options->inetd) msg (M_USAGE, "--inetd cannot be used with --mode server"); if (options->ipchange) msg (M_USAGE, "--ipchange cannot be used with --mode server (use --client-connect instead)"); if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCPv4_SERVER #ifdef USE_PF_INET6 || ce->proto == PROTO_TCPv6_SERVER #endif )) - msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); + msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server" +#ifdef USE_PF_INET6 + " or --proto tcp6-server" +#endif + ); if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per)) msg (M_USAGE, "--connect-freq only works with --mode server --proto udp. Try --max-clients instead."); if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask) msg (M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode"); #ifdef ENABLE_OCC if (options->explicit_exit_notification) msg (M_USAGE, "--explicit-exit-notify cannot be used with --mode server"); #endif if (options->routes && (options->routes->flags & RG_ENABLE)) msg (M_USAGE, "--redirect-gateway cannot be used with --mode server (however --push \"redirect-gateway\" is fine)"); diff -U10 -r openvpn-2.1_rc21-1/route.c openvpn-2.1_rc21-2/route.c --- openvpn-2.1_rc21-1/route.c 2009-10-01 20:02:18.000000000 +0200 +++ openvpn-2.1_rc21-2/route.c 2010-05-01 21:33:51.760080170 +0200 @@ -565,27 +565,37 @@ } else if (tla == TLA_LOCAL) { dmsg (D_ROUTE, "ROUTE remote_host is LOCAL"); local = true; } } if (!local) { /* route remote host to original default gateway */ - add_route3 (rl->spec.remote_host, - ~0, - rl->spec.net_gateway, - tt, - flags, - es); - rl->did_local = true; +#ifdef USE_PF_INET6 + /* if remote_host is not ipv4 (ie: ipv6), just skip + * adding this special /32 route */ + if (rl->spec.remote_host != IPV4_INVALID_ADDR) { +#endif + add_route3 (rl->spec.remote_host, + ~0, + rl->spec.net_gateway, + tt, + flags, + es); + rl->did_local = true; +#ifdef USE_PF_INET6 + } else { + dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled"); + } +#endif } /* route DHCP/DNS server traffic through original default gateway */ add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); if (rl->flags & RG_REROUTE_GW) { if (rl->flags & RG_DEF1) { /* add new default route (1st component) */ diff -U10 -r openvpn-2.1_rc21-1/socket.c openvpn-2.1_rc21-2/socket.c --- openvpn-2.1_rc21-1/socket.c 2010-05-01 21:33:38.541079913 +0200 +++ openvpn-2.1_rc21-2/socket.c 2010-05-01 21:33:51.763079902 +0200 @@ -2109,24 +2109,24 @@ /* * This logic supports "redirect-gateway" semantic, which * makes sense only for PF_INET routes over PF_INET endpoints * * Maybe in the future consider PF_INET6 endpoints also ... * by now just ignore it * */ #ifdef USE_PF_INET6 - if(lsa->actual.dest.addr.sa.sa_family != AF_INET) - return 0; + if (lsa->actual.dest.addr.sa.sa_family != AF_INET) + return IPV4_INVALID_ADDR; #else - ASSERT(lsa->actual.dest.addr.sa.sa_family == AF_INET); + ASSERT (lsa->actual.dest.addr.sa.sa_family == AF_INET); #endif if (link_socket_actual_defined (&lsa->actual)) return ntohl (lsa->actual.dest.addr.in4.sin_addr.s_addr); else if (addr_defined (&lsa->remote)) return ntohl (lsa->remote.addr.in4.sin_addr.s_addr); else return 0; } @@ -2438,21 +2438,21 @@ CLEAR (sa); sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); } #ifdef USE_PF_INET6 break; case AF_INET6: { struct sockaddr_in6 sin6; char buf[INET6_ADDRSTRLEN] = "[undef]"; - memset(&sin6, 0, sizeof sin6); + CLEAR(sin6); sin6.sin6_family = AF_INET6; sin6.sin6_addr = act->pi.in6.ipi6_addr; { if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) == 0) buf_printf (&out, " (via %s)", buf); else buf_printf (&out, " (via [getnameinfo() err])"); } } @@ -2664,22 +2664,22 @@ #endif if (proto) { return proto_sa_family(proto); /* already stamped */ } #ifdef USE_PF_INET6 else { struct addrinfo hints , *ai; int err; - memset(&hints, 0, sizeof hints); - hints.ai_flags=AI_NUMERICHOST; + CLEAR(hints); + hints.ai_flags = AI_NUMERICHOST; err = getaddrinfo(name, NULL, &hints, &ai); if ( 0 == err ) { ret=ai->ai_family; freeaddrinfo(ai); return ret; } } #endif return AF_INET; /* default */ @@ -2966,82 +2966,65 @@ int socket_recv_queue (struct link_socket *sock, int maxsize) { if (sock->reads.iostate == IOSTATE_INITIAL) { WSABUF wsabuf[1]; int status; /* reset buf to its initial state */ - if (sock->info.proto == PROTO_UDPv4 -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_UDPv6 -#endif - ) + if (proto_is_udp(sock->info.proto)) { sock->reads.buf = sock->reads.buf_init; } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER -#endif - ) + else if (proto_is_tcp(sock->info.proto)) { stream_buf_get_next (&sock->stream_buf, &sock->reads.buf); } else { ASSERT (0); } /* Win32 docs say it's okay to allocate the wsabuf on the stack */ wsabuf[0].buf = BPTR (&sock->reads.buf); wsabuf[0].len = maxsize ? maxsize : BLEN (&sock->reads.buf); /* check for buffer overflow */ ASSERT (wsabuf[0].len <= BLEN (&sock->reads.buf)); /* the overlapped read will signal this event on I/O completion */ ASSERT (ResetEvent (sock->reads.overlapped.hEvent)); sock->reads.flags = 0; - if (sock->info.proto == PROTO_UDPv4 -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_UDPv6 -#endif - ) + if (proto_is_udp(sock->info.proto)) { sock->reads.addr_defined = true; #ifdef USE_PF_INET6 if (sock->info.proto == PROTO_UDPv6) sock->reads.addrlen = sizeof (sock->reads.addr6); else #endif sock->reads.addrlen = sizeof (sock->reads.addr); status = WSARecvFrom( sock->sd, wsabuf, 1, &sock->reads.size, &sock->reads.flags, (struct sockaddr *) &sock->reads.addr, &sock->reads.addrlen, &sock->reads.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER -#endif - ) - + else if (proto_is_tcp(sock->info.proto)) { sock->reads.addr_defined = false; status = WSARecv( sock->sd, wsabuf, 1, &sock->reads.size, &sock->reads.flags, &sock->reads.overlapped, NULL); @@ -3113,25 +3096,21 @@ ASSERT (buf_copy (&sock->writes.buf, buf)); /* Win32 docs say it's okay to allocate the wsabuf on the stack */ wsabuf[0].buf = BPTR (&sock->writes.buf); wsabuf[0].len = BLEN (&sock->writes.buf); /* the overlapped write will signal this event on I/O completion */ ASSERT (ResetEvent (sock->writes.overlapped.hEvent)); sock->writes.flags = 0; - if (sock->info.proto == PROTO_UDPv4 -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_UDPv6 -#endif - ) + if (proto_is_udp(sock->info.proto)) { /* set destination address for UDP writes */ sock->writes.addr_defined = true; #ifdef USE_PF_INET6 if (sock->info.proto == PROTO_UDPv6) { sock->writes.addr6 = to->dest.addr.in6; sock->writes.addrlen = sizeof (sock->writes.addr6); } else @@ -3145,25 +3124,21 @@ sock->sd, wsabuf, 1, &sock->writes.size, sock->writes.flags, (struct sockaddr *) &sock->writes.addr, sock->writes.addrlen, &sock->writes.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER -#ifdef USE_PF_INET6 - || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER -#endif - ) + else if (proto_is_tcp(sock->info.proto)) { /* destination address for TCP writes was established on connection initiation */ sock->writes.addr_defined = false; status = WSASend( sock->sd, wsabuf, 1, &sock->writes.size, sock->writes.flags, diff -U10 -r openvpn-2.1_rc21-1/socket.h openvpn-2.1_rc21-2/socket.h --- openvpn-2.1_rc21-1/socket.h 2010-05-01 21:33:38.542079929 +0200 +++ openvpn-2.1_rc21-2/socket.h 2010-05-01 21:33:51.772080120 +0200 @@ -376,20 +376,26 @@ in_addr_t addr, const bool flags); void setenv_link_socket_actual (struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, const bool flags); void bad_address_length (int actual, int expected); +#ifdef USE_PF_INET6 +/* IPV4_INVALID_ADDR: returned by link_socket_current_remote() + * to ease redirect-gateway logic for ipv4 tunnels on ipv6 endpoints + */ +#define IPV4_INVALID_ADDR 0xffffffff +#endif in_addr_t link_socket_current_remote (const struct link_socket_info *info); void link_socket_connection_initiated (const struct buffer *buf, struct link_socket_info *info, const struct link_socket_actual *addr, const char *common_name, struct env_set *es); void link_socket_bad_incoming_addr (struct buffer *buf, const struct link_socket_info *info, diff -U10 -r openvpn-2.1_rc21-1/ssl.c openvpn-2.1_rc21-2/ssl.c --- openvpn-2.1_rc21-1/ssl.c 2009-10-25 16:28:02.000000000 +0100 +++ openvpn-2.1_rc21-2/ssl.c 2010-05-01 21:33:51.795080798 +0200 @@ -1,19 +1,23 @@ /* * OpenVPN -- An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sa...@openvpn.net> * + * Additions for eurephia plugin done by: + * David Sommerseth <d...@users.sourceforge.net> Copyright (C) 2008-2009 + * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -770,20 +774,28 @@ /* save common name in session object */ if (ctx->error_depth == 0) set_common_name (session, common_name); /* export subject name string as environmental variable */ session->verify_maxlevel = max_int (session->verify_maxlevel, ctx->error_depth); openvpn_snprintf (envname, sizeof(envname), "tls_id_%d", ctx->error_depth); setenv_str (opt->es, envname, subject); + /* export X509 cert SHA1 fingerprint */ + { + struct gc_arena gc = gc_new (); + openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", ctx->error_depth); + setenv_str (opt->es, envname, + format_hex_ex(ctx->current_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc)); + gc_free(&gc); + } #if 0 /* export common name string as environmental variable */ openvpn_snprintf (envname, sizeof(envname), "tls_common_name_%d", ctx->error_depth); setenv_str (opt->es, envname, common_name); #endif /* export serial number as environmental variable */ { const int serial = (int) ASN1_INTEGER_get (X509_get_serialNumber (ctx->current_cert)); openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", ctx->error_depth); diff -U10 -r openvpn-2.1_rc21-1/tun.c openvpn-2.1_rc21-2/tun.c --- openvpn-2.1_rc21-1/tun.c 2009-10-01 20:02:18.000000000 +0200 +++ openvpn-2.1_rc21-2/tun.c 2010-05-01 21:33:51.788080607 +0200 @@ -1598,21 +1598,23 @@ /* Enable multicast on the interface */ if (tt->fd >= 0) { struct tuninfo info; if (ioctl (tt->fd, TUNGIFINFO, &info) < 0) { msg (M_WARN | M_ERRNO, "Can't get interface info: %s", strerror(errno)); } +#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */ info.flags |= IFF_MULTICAST; +#endif if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) { msg (M_WARN | M_ERRNO, "Can't set interface info: %s", strerror(errno)); } } } void close_tun (struct tuntap* tt) -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org