From 397048716a40fb34611c41e6a0f5a1f25949974d Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Mon, 17 Dec 2012 22:34:44 +0100 Subject: More Dual Stack patch fixes --- openvpn/config.h | 2 +- openvpn/src/openvpn/options.c | 22 +++++++++++- openvpn/src/openvpn/socket.c | 83 ++++++++++++++++++++++++++++++++----------- openvpn/src/openvpn/socket.h | 15 +------- 4 files changed, 86 insertions(+), 36 deletions(-) (limited to 'openvpn') diff --git a/openvpn/config.h b/openvpn/config.h index 510db135..be6733fb 100644 --- a/openvpn/config.h +++ b/openvpn/config.h @@ -450,7 +450,7 @@ #define PACKAGE_NAME "OpenVPN" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "OpenVPN 2.3_rc1+dspatch1" +#define PACKAGE_STRING "OpenVPN 2.3_rc1+dspatch2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "openvpn" diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c index 6a618212..64c81cf2 100644 --- a/openvpn/src/openvpn/options.c +++ b/openvpn/src/openvpn/options.c @@ -2488,6 +2488,13 @@ options_postprocess_mutate (struct options *o) *ace = ce; } } + else if(!o->remote_list && !o->connection_list) + { + struct connection_entry *ace; + ace = alloc_connection_entry (o, M_USAGE); + ASSERT (ace); + *ace = o->ce; + } ASSERT (o->connection_list); int i; @@ -2885,7 +2892,11 @@ options_string (const struct options *o, buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame)); buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame)); buf_printf (&out, ",proto %s", proto_remote (o->ce.proto, remote)); - if (o->tun_ipv6) + + /* send tun_ipv6 only in peer2peer mode - in client/server mode, it + * is usually pushed by the server, triggering a non-helpful warning + */ + if (o->tun_ipv6 && o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o)) buf_printf (&out, ",tun-ipv6"); /* @@ -3065,6 +3076,15 @@ options_warning_safe_scan2 (const int msglevel, const char *b1_name, const char *b2_name) { + /* we will stop sending 'proto xxx' in OCC in a future version + * (because it's not useful), and to reduce questions when + * interoperating, we start not-printing a warning about it today + */ + if (strncmp(p1, "proto ", 6) == 0 ) + { + return; + } + if (strlen (p1) > 0) { struct gc_arena gc = gc_new (); diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index 04a21357..29a15a63 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -234,18 +234,20 @@ openvpn_getaddrinfo (unsigned int flags, get_signal (signal_received); if (*signal_received) /* were we interrupted by a signal? */ { - if (0 == status) { - ASSERT(res); - freeaddrinfo(*res); - res = NULL; - } if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ { msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); *signal_received = 0; } else - goto done; + { + if (0 == status) { + ASSERT(res); + freeaddrinfo(*res); + res = NULL; + } + goto done; + } } } @@ -674,7 +676,7 @@ create_socket (struct link_socket *sock) #ifdef ENABLE_SOCKS if (sock->socks_proxy) - sock->ctrl_sd = create_socket_tcp (AF_INET); + sock->ctrl_sd = create_socket_tcp (ai_family); #endif } else if (ai_proto == IPPROTO_TCP) @@ -685,6 +687,12 @@ create_socket (struct link_socket *sock) { ASSERT (0); } + /* set socket buffers based on --sndbuf and --rcvbuf options */ + socket_set_buffers (sock->sd, &sock->socket_buffer_sizes); + + /* set socket to --mark packets with given value */ + socket_set_mark (sock->sd, sock->mark); + #ifdef TARGET_ANDROID struct user_pass up; strcpy(up.username ,__func__); @@ -895,7 +903,8 @@ socket_bind (socket_descriptor_t sd, break; } if (!cur) - msg (M_FATAL, "%s: Socket bind failed: No addr to bind has no v4/v6 record", prefix); + msg (M_FATAL, "%s: Socket bind failed: Addr to bind has no %s record", + prefix, addr_family_name(ai_family)); if (bind (sd, cur->ai_addr, cur->ai_addrlen)) { @@ -1143,7 +1152,7 @@ static void bind_local (struct link_socket *sock) if (sock->bind_local) { #ifdef ENABLE_SOCKS - if (sock->socks_proxy && sock->info.proto == PROTO_UDP && sock->info.af == AF_INET) + if (sock->socks_proxy && sock->info.proto == PROTO_UDP) socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local, sock->info.lsa->actual.ai_family, "SOCKS"); else @@ -1280,23 +1289,34 @@ link_socket_new (void) } void -create_new_socket (struct link_socket* sock, int mark) +create_new_socket (struct link_socket* sock) { if (sock->bind_local) { resolve_bind_local (sock, sock->info.af); } resolve_remote (sock, 1, NULL, NULL); - create_socket (sock); - - /* set socket buffers based on --sndbuf and --rcvbuf options */ - socket_set_buffers (sock->sd, &sock->socket_buffer_sizes); + /* + * In P2P or server mode we must create the socket even when resolving + * the remote site fails/is not specified. */ - /* set socket to --mark packets with given value */ - socket_set_mark (sock->sd, mark); - - if (sock->bind_local) - bind_local(sock); + if (sock->info.af && sock->info.lsa->actual.ai_family==0 && sock->bind_local) + { + /* Copy sock parameters from bind addr */ + set_actual_address (&sock->info.lsa->actual, sock->info.lsa->bind_local); + /* clear destination set by set_actual_address */ + CLEAR(sock->info.lsa->actual.dest); + } + /* + * Create the socket early if socket should be bound + */ + if (sock->bind_local && sock->info.lsa->actual.ai_family) + { + create_socket (sock); + + if (sock->bind_local) + bind_local(sock); + } } @@ -1363,6 +1383,7 @@ link_socket_init_phase1 (struct link_socket *sock, sock->socket_buffer_sizes.sndbuf = sndbuf; sock->sockflags = sockflags; + sock->mark = mark; sock->info.proto = proto; sock->info.af = af; @@ -1438,7 +1459,7 @@ link_socket_init_phase1 (struct link_socket *sock, } else if (mode != LS_MODE_TCP_ACCEPT_FROM) { - create_new_socket (sock, mark); + create_new_socket (sock); } } @@ -1712,8 +1733,28 @@ link_socket_init_phase2 (struct link_socket *sock, } else { + /* Second chance to resolv/create socket */ resolve_remote (sock, 2, &remote_dynamic, &sig_info->signal_received); + + /* If socket has not already been created create it now */ + if (sock->sd == SOCKET_UNDEFINED) + { + if (sock->info.lsa->actual.ai_family) + { + create_socket (sock); + } + else + { + msg (M_WARN, "Could not determine IPv4/IPv6 protocol"); + sig_info->signal_received = SIGUSR1; + goto done; + } + + if (sock->bind_local) + bind_local(sock); + } + if (sig_info && sig_info->signal_received) goto done; @@ -2167,6 +2208,8 @@ print_sockaddr_ex (const struct sockaddr *sa, salen = sizeof (struct sockaddr_in6); addr_is_defined = !IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*) sa)->sin6_addr); break; + case AF_UNSPEC: + return "[AF_UNSPEC]"; default: ASSERT(0); } diff --git a/openvpn/src/openvpn/socket.h b/openvpn/src/openvpn/socket.h index 33a59f0f..b30a1bc7 100644 --- a/openvpn/src/openvpn/socket.h +++ b/openvpn/src/openvpn/socket.h @@ -215,6 +215,7 @@ struct link_socket # define SF_HOST_RANDOMIZE (1<<3) # define SF_GETADDRINFO_DGRAM (1<<4) unsigned int sockflags; + int mark; /* for stream sockets */ struct stream_buf stream_buf; @@ -651,20 +652,6 @@ addrlist_match (const struct openvpn_sockaddr *a1, const struct addrinfo *addrli return false; } -static inline in_addr_t -addr_host (const struct openvpn_sockaddr *addr) -{ - /* - * "public" addr returned is checked against ifconfig for - * possible clash: non sense for now given - * that we do ifconfig only IPv4 - */ - if(addr->addr.sa.sa_family != AF_INET) - return 0; - return ntohl (addr->addr.in4.sin_addr.s_addr); -} - - static inline bool addrlist_port_match (const struct openvpn_sockaddr *a1, const struct addrinfo *a2) { -- cgit v1.2.3