From 8335caf929f21b317a0243a12285e1f04361db25 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Sun, 13 Sep 2009 13:43:04 +0200 Subject: * rebased openvpn-2.1_rc1b.jjo.20061206.d.patch * passes {udp,tcp}x{v4,v6} loopback tests * passes {udp,tcp}x{v6} remote tests --- socket.c | 593 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 490 insertions(+), 103 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index a49940d..67bd2eb 100644 --- a/socket.c +++ b/socket.c @@ -36,10 +36,16 @@ #include "memdbg.h" const int proto_overhead[] = { /* indexed by PROTO_x */ - IPv4_UDP_HEADER_SIZE, + 0, + IPv4_UDP_HEADER_SIZE, /* IPv4 */ IPv4_TCP_HEADER_SIZE, IPv4_TCP_HEADER_SIZE, - IPv4_TCP_HEADER_SIZE +#ifdef USE_PF_INET6 + IPv6_UDP_HEADER_SIZE, /* IPv6 */ + IPv6_TCP_HEADER_SIZE, + IPv6_TCP_HEADER_SIZE, + IPv6_TCP_HEADER_SIZE, +#endif }; /* @@ -410,6 +416,8 @@ update_remote (const char* host, bool *changed, const unsigned int sockflags) { + switch(addr->addr.sa.sa_family) { + case AF_INET: if (host && addr) { const in_addr_t new_addr = getaddr ( @@ -418,12 +426,39 @@ update_remote (const char* host, 1, NULL, NULL); - if (new_addr && addr->sa.sin_addr.s_addr != new_addr) + if (new_addr && addr->addr.in4.sin_addr.s_addr != new_addr) { - addr->sa.sin_addr.s_addr = new_addr; + addr->addr.in4.sin_addr.s_addr = new_addr; *changed = true; } } + break; +#ifdef USE_PF_INET6 + case AF_INET6: /* TODO(jjo): should adapt getaddr() + sf2gaf() for AF_INET6 */ + if (host && addr) + { + struct addrinfo hints , *ai; + int err; + memset(&hints, 0, sizeof hints); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_INET6; + if ((err=getaddrinfo(host, NULL, &hints, &ai))==0) + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; + if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &addr->addr.in6.sin6_addr)) + { + int port = addr->addr.in6.sin6_port; /* backup current port for easier copy, restore later */ + addr->addr.in6 = *sin6; /* ipv6 requires also eg. sin6_scope_id => easy to full copy*/ + addr->addr.in6.sin6_port = port; + } + freeaddrinfo(ai); + } + } + break; +#endif + default: + ASSERT(0); + } } static int @@ -616,6 +651,44 @@ create_socket_udp (const unsigned int flags) return sd; } +#ifdef USE_PF_INET6 +static socket_descriptor_t +create_socket_udp6 (const unsigned int flags) +{ + socket_descriptor_t sd; + + if ((sd = socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) + msg (M_SOCKERR, "UDP: Cannot create UDP6 socket"); +#if ENABLE_IP_PKTINFO + else if (flags & SF_USE_IP_PKTINFO) + { + int pad = 1; + setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO, (void*)&pad, sizeof(pad)); + } +#endif + return sd; +} + +static socket_descriptor_t +create_socket_tcp6 (void) +{ + socket_descriptor_t sd; + + if ((sd = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) + msg (M_SOCKERR, "Cannot create TCP6 socket"); + + /* set SO_REUSEADDR on socket */ + { + int on = 1; + if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, + (void *) &on, sizeof (on)) < 0) + msg (M_SOCKERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP6 socket"); + } + + return sd; +} + +#endif static void create_socket (struct link_socket *sock) { @@ -634,6 +707,17 @@ create_socket (struct link_socket *sock) { sock->sd = create_socket_tcp (); } +#ifdef USE_PF_INET6 + else if (sock->info.proto == PROTO_TCPv6_SERVER + || sock->info.proto == PROTO_TCPv6_CLIENT) + { + sock->sd = create_socket_tcp6 (); + } + else if (sock->info.proto == PROTO_UDPv6) + { + sock->sd = create_socket_udp6 (sock->sockflags); + } +#endif else { ASSERT (0); @@ -671,7 +755,12 @@ socket_do_accept (socket_descriptor_t sd, struct link_socket_actual *act, const bool nowait) { - socklen_t remote_len = sizeof (act->dest.sa); + /* af_addr_size WILL return 0 in this case if AFs other than AF_INET + * are compiled because act is empty here. + * could use getsockname() to support later remote_len check + */ + socklen_t remote_len_af = af_addr_size(act->dest.addr.sa.sa_family); + socklen_t remote_len = sizeof(act->dest.addr); socket_descriptor_t new_sd = SOCKET_UNDEFINED; CLEAR (*act); @@ -679,7 +768,7 @@ socket_do_accept (socket_descriptor_t sd, #ifdef HAVE_GETPEERNAME if (nowait) { - new_sd = getpeername (sd, (struct sockaddr *) &act->dest.sa, &remote_len); + new_sd = getpeername (sd, &act->dest.addr.sa, &remote_len); if (!socket_defined (new_sd)) msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: getpeername() failed"); @@ -692,7 +781,7 @@ socket_do_accept (socket_descriptor_t sd, #endif else { - new_sd = accept (sd, (struct sockaddr *) &act->dest.sa, &remote_len); + new_sd = accept (sd, &act->dest.addr.sa, &remote_len); } #if 0 /* For debugging only, test the effect of accept() failures */ @@ -708,7 +797,8 @@ socket_do_accept (socket_descriptor_t sd, { msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: accept(%d) failed", sd); } - else if (remote_len != sizeof (act->dest.sa)) + /* only valid if we have remote_len_af!=0 */ + else if (remote_len_af && remote_len != remote_len_af) { msg (D_LINK_ERRORS, "TCP: Received strange incoming connection with unknown address length=%d", remote_len); openvpn_close_socket (new_sd); @@ -809,7 +899,7 @@ socket_bind (socket_descriptor_t sd, { struct gc_arena gc = gc_new (); - if (bind (sd, (struct sockaddr *) &local->sa, sizeof (local->sa))) + if (bind (sd, &local->addr.sa, af_addr_size(local->addr.sa.sa_family))) { const int errnum = openvpn_errno_socket (); msg (M_FATAL, "%s: Socket bind failed on local address %s: %s", @@ -830,7 +920,7 @@ openvpn_connect (socket_descriptor_t sd, #ifdef CONNECT_NONBLOCK set_nonblock (sd); - status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); + status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); if (status) status = openvpn_errno_socket (); if (status == EINPROGRESS) @@ -1030,17 +1120,44 @@ resolve_bind_local (struct link_socket *sock) /* resolve local address if undefined */ if (!addr_defined (&sock->info.lsa->local)) - { - sock->info.lsa->local.sa.sin_family = AF_INET; - sock->info.lsa->local.sa.sin_addr.s_addr = - (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, - sock->local_host, - 0, - NULL, - NULL) - : htonl (INADDR_ANY)); - sock->info.lsa->local.sa.sin_port = htons (sock->local_port); + { + /* may return AF_{INET|INET6} guessed from local_host */ + switch(addr_guess_family(sock->info.proto, sock->local_host)) { + case AF_INET: + sock->info.lsa->local.addr.in4.sin_family = AF_INET; + sock->info.lsa->local.addr.in4.sin_addr.s_addr = + (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, + sock->local_host, + 0, + NULL, + NULL) + : htonl (INADDR_ANY)); + sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port); + break; +#ifdef USE_PF_INET6 + case AF_INET6: + { + struct addrinfo hints , *ai; + int err; + memset(&hints, 0, sizeof hints); + hints.ai_flags=AI_PASSIVE; + hints.ai_family=AF_INET6; + /* if no local_host provided, ask for IN6ADDR_ANY ... */ + if ((err=getaddrinfo(sock->local_host? sock->local_host : "::", + NULL, &hints, &ai))==0) { + sock->info.lsa->local.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); + freeaddrinfo(ai); + } else { + msg (M_FATAL, "getaddrinfo() failed for local \"%s\": %s", + sock->local_host, + gai_strerror(err)); + } + sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); + } + break; +#endif } + } /* bind to local address/port */ if (sock->bind_local) @@ -1068,8 +1185,11 @@ resolve_remote (struct link_socket *sock, /* resolve remote address if undefined */ if (!addr_defined (&sock->info.lsa->remote)) { - sock->info.lsa->remote.sa.sin_family = AF_INET; - sock->info.lsa->remote.sa.sin_addr.s_addr = 0; + switch(addr_guess_family(sock->info.proto, sock->remote_host)) + { + case AF_INET: + sock->info.lsa->remote.addr.in4.sin_family = AF_INET; + sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; if (sock->remote_host) { @@ -1112,7 +1232,7 @@ resolve_remote (struct link_socket *sock, ASSERT (0); } - sock->info.lsa->remote.sa.sin_addr.s_addr = getaddr ( + sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( flags, sock->remote_host, retry, @@ -1139,7 +1259,29 @@ resolve_remote (struct link_socket *sock, } } - sock->info.lsa->remote.sa.sin_port = htons (sock->remote_port); + sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port); + break; +#ifdef USE_PF_INET6 + case AF_INET6: /* TODO(jjo): ipv6 signal logic */ + { + struct addrinfo hints , *ai; + int err; + memset(&hints, 0, sizeof hints); + hints.ai_flags=0; + hints.ai_family=AF_INET6; + if ((err=getaddrinfo(sock->remote_host? sock->remote_host : "::" , NULL, &hints, &ai))==0) { + sock->info.lsa->remote.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); + freeaddrinfo(ai); + } else { + msg (M_FATAL, "getaddrinfo() failed for remote \"%s\": %s", + sock->remote_host, + gai_strerror(err)); + } + sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); + } + break; +#endif + } } /* should we re-use previous active remote address? */ @@ -1384,7 +1526,11 @@ link_socket_init_phase2 (struct link_socket *sock, goto done; /* TCP client/server */ - if (sock->info.proto == PROTO_TCPv4_SERVER) + if (sock->info.proto == PROTO_TCPv4_SERVER +#ifdef USE_PF_INET6 + ||sock->info.proto == PROTO_TCPv6_SERVER +#endif + ) { switch (sock->mode) { @@ -1419,7 +1565,11 @@ link_socket_init_phase2 (struct link_socket *sock, ASSERT (0); } } - else if (sock->info.proto == PROTO_TCPv4_CLIENT) + else if (sock->info.proto == PROTO_TCPv4_CLIENT +#ifdef USE_PF_INET6 + ||sock->info.proto == PROTO_TCPv6_CLIENT +#endif + ) { #ifdef GENERAL_PROXY_SUPPORT @@ -1506,8 +1656,8 @@ link_socket_init_phase2 (struct link_socket *sock, sock->remote_port = sock->proxy_dest_port; sock->did_resolve_remote = false; - sock->info.lsa->actual.dest.sa.sin_addr.s_addr = 0; - sock->info.lsa->remote.sa.sin_addr.s_addr = 0; + addr_zero_host(&sock->info.lsa->actual.dest); + addr_zero_host(&sock->info.lsa->remote); resolve_remote (sock, 1, NULL, signal_received); @@ -1522,7 +1672,7 @@ link_socket_init_phase2 (struct link_socket *sock, if (remote_changed) { msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment"); - sock->info.lsa->remote.sa.sin_addr.s_addr = sock->info.lsa->actual.dest.sa.sin_addr.s_addr; + addr_copy_host(&sock->info.lsa->remote, &sock->info.lsa->actual.dest); } } @@ -1708,13 +1858,20 @@ link_socket_bad_incoming_addr (struct buffer *buf, { struct gc_arena gc = gc_new (); - msg (D_LINK_ERRORS, - "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", - print_link_socket_actual (from_addr, &gc), - (int)from_addr->dest.sa.sin_family, - print_sockaddr (&info->lsa->remote, &gc)); + switch(from_addr->dest.addr.sa.sa_family) + { + case AF_INET: +#ifdef USE_PF_INET6 + case AF_INET6: +#endif + msg (D_LINK_ERRORS, + "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", + print_link_socket_actual (from_addr, &gc), + (int)from_addr->dest.addr.sa.sa_family, + print_sockaddr (&info->lsa->remote, &gc)); + break; + } buf->len = 0; - gc_free (&gc); } @@ -1729,10 +1886,25 @@ link_socket_current_remote (const struct link_socket_info *info) { const struct link_socket_addr *lsa = info->lsa; +/* + * 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 + * + */ +#if defined ( USE_PF_INET6 ) + if(lsa->actual.dest.addr.sa.sa_family != AF_INET) + return 0; +#else + ASSERT(lsa->actual.dest.addr.sa.sa_family == AF_INET); +#endif + if (link_socket_actual_defined (&lsa->actual)) - return ntohl (lsa->actual.dest.sa.sin_addr.s_addr); + return ntohl (lsa->actual.dest.addr.in4.sin_addr.s_addr); else if (addr_defined (&lsa->remote)) - return ntohl (lsa->remote.sa.sin_addr.s_addr); + return ntohl (lsa->remote.addr.in4.sin_addr.s_addr); else return 0; } @@ -1959,26 +2131,58 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, const unsigned int flags, struct gc_arena *gc) { - if (addr) - { - struct buffer out = alloc_buf_gc (64, gc); - const int port = ntohs (addr->sa.sin_port); - - if (!(flags & PS_DONT_SHOW_ADDR)) - buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sa.sin_addr) : "[undef]")); - - if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED))) - && port) + struct buffer out; + bool addr_is_defined; + if (!addr) { + return "[NULL]"; + } + addr_is_defined = addr_defined (addr); + switch(addr->addr.sa.sa_family) { + case AF_INET: + { + const int port= ntohs (addr->addr.in4.sin_port); + out = alloc_buf_gc (128, gc); + buf_puts (&out, "[AF_INET]"); + mutex_lock_static (L_INET_NTOA); + buf_puts (&out, (addr_is_defined ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); + mutex_unlock_static (L_INET_NTOA); + + if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) + && port) { if (separator) buf_printf (&out, "%s", separator); buf_printf (&out, "%d", port); } - return BSTR (&out); - } - else - return "[NULL]"; + } + break; +#ifdef USE_PF_INET6 + case AF_INET6: + { + const int port= ntohs (addr->addr.in6.sin6_port); + char buf[INET6_ADDRSTRLEN] = "[undef]"; + out = alloc_buf_gc (128, gc); + buf_puts (&out, "[AF_INET6]"); + if (addr_is_defined) + { + getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), + buf, sizeof (buf), NULL, 0, NI_NUMERICHOST); + buf_puts (&out, buf); + } + if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) + && port) + { + if (separator) + buf_puts (&out, separator); + + buf_printf (&out, "%d", port); + } + } + break; +#endif + } + return BSTR (&out); } const char * @@ -1998,12 +2202,38 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, struct buffer out = alloc_buf_gc (128, gc); buf_printf (&out, "%s", print_sockaddr_ex (&act->dest, separator, flags, gc)); #if ENABLE_IP_PKTINFO - if ((flags & PS_SHOW_PKTINFO) && act->pi.ipi_spec_dst.s_addr) + if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act)) { + switch(act->dest.addr.sa.sa_family) + { + case AF_INET: + { struct openvpn_sockaddr sa; CLEAR (sa); - sa.sa.sin_addr = act->pi.ipi_spec_dst; + sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); + } + break; +#ifdef USE_PF_INET6 + case AF_INET6: + { + struct sockaddr_in6 sin6; + char buf[INET6_ADDRSTRLEN] = "[undef]"; + memset(&sin6, 0, sizeof 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])"); + } + } + break; +#endif + } + } #endif return BSTR (&out); @@ -2037,19 +2267,37 @@ void setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags) { char name_buf[256]; + char buf[128]; - if (flags & SA_IP_PORT) - openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); - else - openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); + switch(addr->addr.sa.sa_family) { + case AF_INET: + if (flags & SA_IP_PORT) + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); + else + openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); - setenv_str (es, name_buf, inet_ntoa (addr->sa.sin_addr)); + mutex_lock_static (L_INET_NTOA); + setenv_str (es, name_buf, inet_ntoa (addr->addr.in4.sin_addr)); + mutex_unlock_static (L_INET_NTOA); + + if ((flags & SA_IP_PORT) && addr->addr.in4.sin_port) + { + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); + setenv_int (es, name_buf, ntohs (addr->addr.in4.sin_port)); + } + break; +#ifdef USE_PF_INET6 + case AF_INET6: + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip6", name_prefix); + getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); + setenv_str (es, name_buf, buf); - if ((flags & SA_IP_PORT) && addr->sa.sin_port) - { openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); - setenv_int (es, name_buf, ntohs (addr->sa.sin_port)); - } + setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); + break; +#endif + } } void @@ -2059,7 +2307,8 @@ setenv_in_addr_t (struct env_set *es, const char *name_prefix, in_addr_t addr, c { struct openvpn_sockaddr si; CLEAR (si); - si.sa.sin_addr.s_addr = htonl (addr); + si.addr.in4.sin_family = AF_INET; + si.addr.in4.sin_addr.s_addr = htonl (addr); setenv_sockaddr (es, name_prefix, &si, flags); } } @@ -2080,16 +2329,63 @@ setenv_link_socket_actual (struct env_set *es, struct proto_names { const char *short_form; const char *display_form; + bool is_dgram; + bool is_net; + sa_family_t proto_af; }; /* Indexed by PROTO_x */ -static const struct proto_names proto_names[] = { - {"udp", "UDPv4"}, - {"tcp-server", "TCPv4_SERVER"}, - {"tcp-client", "TCPv4_CLIENT"}, - {"tcp", "TCPv4"} +static const struct proto_names proto_names[PROTO_N] = { + {"proto-uninitialized", "proto-NONE",0,0, AF_UNSPEC}, + {"udp", "UDPv4",1,1, AF_INET}, + {"tcp-server", "TCPv4_SERVER",0,1, AF_INET}, + {"tcp-client", "TCPv4_CLIENT",0,1, AF_INET}, + {"tcp", "TCPv4",0,1, AF_INET}, +#ifdef USE_PF_INET6 + {"udp6" ,"UDPv6",1,1, AF_INET6}, + {"tcp6-server","TCPv6_SERVER",0,1, AF_INET6}, + {"tcp6-client","TCPv6_CLIENT",0,1, AF_INET6}, + {"tcp6" ,"TCPv6",0,1, AF_INET6}, +#endif }; +bool +proto_is_net(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].is_net; +} +bool +proto_is_dgram(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].is_dgram; +} +bool +proto_is_udp(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].is_dgram&&proto_names[proto].is_net; +} +bool +proto_is_tcp(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return (!proto_names[proto].is_dgram)&&proto_names[proto].is_net; +} + +sa_family_t +proto_sa_family(int proto) +{ + if (proto < 0 || proto >= PROTO_N) + ASSERT(0); + return proto_names[proto].proto_af; +} + int ascii2proto (const char* proto_name) { @@ -2129,6 +2425,38 @@ proto2ascii_all (struct gc_arena *gc) return BSTR (&out); } +int +addr_guess_family(int proto, const char *name) +{ + sa_family_t ret; + 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; + if ((err=getaddrinfo(name, NULL, &hints, &ai))==0) { + ret=ai->ai_family; + freeaddrinfo(ai); + return ret; + } + } +#endif + return AF_INET; /* default */ +} +const char * +addr_family_name (int af) +{ + switch (af) { + case AF_INET: return "AF_INET"; + case AF_INET6: return "AF_INET6"; + } + return "AF_UNSPEC"; +} + /* * Given a local proto, return local proto * if !remote, or compatible remote proto @@ -2143,10 +2471,15 @@ proto_remote (int proto, bool remote) ASSERT (proto >= 0 && proto < PROTO_N); if (remote) { - if (proto == PROTO_TCPv4_SERVER) - return PROTO_TCPv4_CLIENT; - if (proto == PROTO_TCPv4_CLIENT) - return PROTO_TCPv4_SERVER; + switch (proto) + { + case PROTO_TCPv4_SERVER: return PROTO_TCPv4_CLIENT; + case PROTO_TCPv4_CLIENT: return PROTO_TCPv4_SERVER; +#ifdef USE_PF_INET6 + case PROTO_TCPv6_SERVER: return PROTO_TCPv6_CLIENT; + case PROTO_TCPv6_CLIENT: return PROTO_TCPv6_SERVER; +#endif + } } return proto; } @@ -2205,10 +2538,24 @@ link_socket_read_tcp (struct link_socket *sock, #if ENABLE_IP_PKTINFO #pragma pack(1) /* needed to keep structure size consistent for 32 vs. 64-bit architectures */ -struct openvpn_pktinfo +struct openvpn_in4_pktinfo { struct cmsghdr cmsghdr; - struct in_pktinfo in_pktinfo; + struct in_pktinfo pi; +}; +#ifdef USE_PF_INET6 +struct openvpn_in6_pktinfo +{ + struct cmsghdr cmsghdr; + struct in6_pktinfo pi6; +}; +#endif + +union openvpn_pktinfo { + struct openvpn_in4_pktinfo cmsgpi; +#ifdef USE_PF_INET6 + struct openvpn_in6_pktinfo cmsgpi6; +#endif }; #pragma pack() @@ -2219,15 +2566,15 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, struct link_socket_actual *from) { struct iovec iov; - struct openvpn_pktinfo opi; + union openvpn_pktinfo opi; struct msghdr mesg; - socklen_t fromlen = sizeof (from->dest.sa); + socklen_t fromlen = sizeof (from->dest.addr); iov.iov_base = BPTR (buf); iov.iov_len = maxsize; mesg.msg_iov = &iov; mesg.msg_iovlen = 1; - mesg.msg_name = &from->dest.sa; + mesg.msg_name = &from->dest.addr; mesg.msg_namelen = fromlen; mesg.msg_control = &opi; mesg.msg_controllen = sizeof (opi); @@ -2244,9 +2591,21 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, && cmsg->cmsg_len >= sizeof (opi)) { struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); - from->pi.ipi_ifindex = pkti->ipi_ifindex; - from->pi.ipi_spec_dst = pkti->ipi_spec_dst; + from->pi.in4.ipi_ifindex = pkti->ipi_ifindex; + from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst; } +#ifdef USE_PF_INET6 + else if (cmsg != NULL + && CMSG_NXTHDR (&mesg, cmsg) == NULL + && cmsg->cmsg_level == IPPROTO_IPV6 + && cmsg->cmsg_type == IPV6_PKTINFO + && cmsg->cmsg_len >= sizeof (struct openvpn_in6_pktinfo)) + { + struct in6_pktinfo *pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); + from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex; + from->pi.in6.ipi6_addr = pkti6->ipi6_addr; + } +#endif } return fromlen; } @@ -2258,18 +2617,20 @@ link_socket_read_udp_posix (struct link_socket *sock, int maxsize, struct link_socket_actual *from) { - socklen_t fromlen = sizeof (from->dest.sa); - from->dest.sa.sin_addr.s_addr = 0; + socklen_t fromlen = sizeof (from->dest.addr); + socklen_t expectedlen = af_addr_size(proto_sa_family(sock->info.proto)); + addr_zero_host(&from->dest); ASSERT (buf_safe (buf, maxsize)); #if ENABLE_IP_PKTINFO - if (sock->sockflags & SF_USE_IP_PKTINFO) + /* Both PROTO_UDPv4 and PROTO_UDPv6 */ + if (proto_is_udp(sock->info.proto) && sock->sockflags & SF_USE_IP_PKTINFO) fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, maxsize, from); else #endif buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0, - (struct sockaddr *) &from->dest.sa, &fromlen); - if (fromlen != sizeof (from->dest.sa)) - bad_address_length (fromlen, sizeof (from->dest.sa)); + &from->dest.addr.sa, &fromlen); + if (buf->len >= 0 && expectedlen && fromlen != expectedlen) + bad_address_length (fromlen, expectedlen); return buf->len; } @@ -2306,26 +2667,52 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, struct iovec iov; struct msghdr mesg; struct cmsghdr *cmsg; - struct in_pktinfo *pkti; - struct openvpn_pktinfo opi; iov.iov_base = BPTR (buf); iov.iov_len = BLEN (buf); mesg.msg_iov = &iov; mesg.msg_iovlen = 1; - mesg.msg_name = &to->dest.sa; - mesg.msg_namelen = sizeof (to->dest.sa); - mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); - mesg.msg_flags = 0; - cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi); - cmsg->cmsg_level = SOL_IP; - cmsg->cmsg_type = IP_PKTINFO; - pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); - pkti->ipi_ifindex = to->pi.ipi_ifindex; - pkti->ipi_spec_dst = to->pi.ipi_spec_dst; - pkti->ipi_addr.s_addr = 0; + switch (sock->info.lsa->remote.addr.sa.sa_family) + { + case AF_INET: { + struct openvpn_in4_pktinfo opi; + struct in_pktinfo *pkti; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in); + mesg.msg_control = &opi; + mesg.msg_controllen = sizeof (opi); + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (opi); + cmsg->cmsg_level = SOL_IP; + cmsg->cmsg_type = IP_PKTINFO; + pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); + pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; + pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; + pkti->ipi_addr.s_addr = 0; + break; + } +#ifdef USE_PF_INET6 + case AF_INET6: { + struct openvpn_in6_pktinfo opi6; + struct in6_pktinfo *pkti6; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in6); + mesg.msg_control = &opi6; + mesg.msg_controllen = sizeof (opi6); + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (opi6); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); + pkti6->ipi6_ifindex = to->pi.in6.ipi6_ifindex; + pkti6->ipi6_addr = to->pi.in6.ipi6_addr; + break; + } +#endif + default: ASSERT(0); + } return sendmsg (sock->sd, &mesg, 0); } @@ -2469,7 +2856,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li { /* set destination address for UDP writes */ sock->writes.addr_defined = true; - sock->writes.addr = to->dest.sa; + sock->writes.addr = to->dest.addr.in4; sock->writes.addrlen = sizeof (sock->writes.addr); status = WSASendTo( @@ -2625,10 +3012,10 @@ socket_finalize (SOCKET s, { if (io->addrlen != sizeof (io->addr)) bad_address_length (io->addrlen, sizeof (io->addr)); - from->dest.sa = io->addr; + from->dest.addr.sa = io->addr; } else - CLEAR (from->dest.sa); + CLEAR (from->dest.addr.sa); } if (buf) -- cgit From ea93a078053e2911b30a80685d82897159aee488 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Mon, 14 Sep 2009 18:31:42 +0200 Subject: * created getaddr6(), use it from resolve_remote() next: merge ipv{4,6} signal logic into one inside resolve_remote() * passes {loopback,remote}{udp,tcp}{4,6} tests --- socket.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 265 insertions(+), 15 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 67bd2eb..a632f84 100644 --- a/socket.c +++ b/socket.c @@ -282,6 +282,188 @@ getaddr_multi (unsigned int flags, return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; } +#ifdef USE_PF_INET6 +/* + * Translate IPv6 addr or hostname into struct addrinfo + * If resolve error, try again for + * resolve_retry_seconds seconds. + */ +bool +getaddr6 (unsigned int flags, + const char *hostname, + int resolve_retry_seconds, + volatile int *signal_received, + struct sockaddr_in6 *in6) +{ + bool success; + struct addrinfo hints, *ai; + int status; + int sigrec = 0; + int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; + struct gc_arena gc = gc_new (); + + ASSERT(in6); + + if (flags & GETADDR_RANDOMIZE) + hostname = hostname_randomize(hostname, &gc); + + if (flags & GETADDR_MSG_VIRT_OUT) + msglevel |= M_MSG_VIRT_OUT; + + CLEAR (ai); + success = false; + + if ((flags & (GETADDR_FATAL_ON_SIGNAL|GETADDR_WARN_ON_SIGNAL)) + && !signal_received) + signal_received = &sigrec; + + /* try numeric ipv6 addr first */ + CLEAR(hints); + hints.ai_family = AF_INET6; + hints.ai_flags = AI_NUMERICHOST; + if ((status = getaddrinfo(hostname, NULL, &hints, &ai))==0) { + *in6 = *((struct sockaddr_in6 *)(ai->ai_addr)); + freeaddrinfo(ai); + ai = NULL; + } + + if (status != 0) /* parse as IPv6 address failed? */ + { + const int fail_wait_interval = 5; /* seconds */ + int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : (resolve_retry_seconds / fail_wait_interval); + const char *fmt; + int level = 0; + int err; + + ai = NULL; + + fmt = "RESOLVE: Cannot resolve host address: %s: %s"; + if ((flags & GETADDR_MENTION_RESOLVE_RETRY) + && !resolve_retry_seconds) + fmt = "RESOLVE: Cannot resolve host address: %s: %s (I would have retried this name query if you had specified the --resolv-retry option.)"; + + if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL) + { + msg (msglevel, "RESOLVE: Cannot parse IPv6 address: %s", hostname); + goto done; + } + +#ifdef ENABLE_MANAGEMENT + if (flags & GETADDR_UPDATE_MANAGEMENT_STATE) + { + if (management) + management_set_state (management, + OPENVPN_STATE_RESOLVE, + NULL, + (in_addr_t)0, + (in_addr_t)0); + } +#endif + + /* + * Resolve hostname + */ + while (true) + { + /* try hostname lookup */ + hints.ai_flags = 0; + err = getaddrinfo(hostname, NULL, &hints, &ai); + + if (signal_received) + { + get_signal (signal_received); + if (*signal_received) /* were we interrupted by a signal? */ + { + if (0 == err) { + ASSERT(ai); + freeaddrinfo(ai); + ai = NULL; + } + if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ + { + msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); + *signal_received = 0; + } + else + goto done; + } + } + + /* success? */ + if (0 == err) + break; + + /* resolve lookup failed, should we + continue or fail? */ + + level = msglevel; + if (resolve_retries > 0) + level = D_RESOLVE_ERRORS; + + msg (level, + fmt, + hostname, + gai_strerror(err)); + + if (--resolve_retries <= 0) + goto done; + + openvpn_sleep (fail_wait_interval); + } + + ASSERT(ai); + + if (!ai->ai_next) + *in6 = *((struct sockaddr_in6*)(ai->ai_addr)); + else + /* more than one address returned */ + { + struct addrinfo *ai_cursor; + int n = 0; + /* count address list */ + for (ai_cursor = ai; ai_cursor; ai_cursor = ai_cursor->ai_next) n++; + ASSERT (n >= 2); + + msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d ipv6 addresses, choosing one by random", + hostname, + n); + + /* choose address randomly, for basic load-balancing capability */ + n--; + n %= get_random(); + for (ai_cursor = ai; n; ai_cursor = ai_cursor->ai_next) n--; + *in6 = *((struct sockaddr_in6*)(ai_cursor->ai_addr)); + } + + freeaddrinfo(ai); + ai = NULL; + + /* hostname resolve succeeded */ + success = true; + } + else + { + /* IP address parse succeeded */ + success = true; + } + + done: + if (signal_received && *signal_received) + { + int level = 0; + if (flags & GETADDR_FATAL_ON_SIGNAL) + level = M_FATAL; + else if (flags & GETADDR_WARN_ON_SIGNAL) + level = M_WARN; + msg (level, "RESOLVE: signal received during DNS resolution attempt"); + } + + gc_free (&gc); + //return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; + return success; +} +#endif /* USE_PF_INET6 */ + /* * We do our own inet_aton because the glibc function * isn't very good about error checking. @@ -445,10 +627,11 @@ update_remote (const char* host, if ((err=getaddrinfo(host, NULL, &hints, &ai))==0) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; - if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &addr->addr.in6.sin6_addr)) + if (!IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &addr->addr.in6.sin6_addr)) { - int port = addr->addr.in6.sin6_port; /* backup current port for easier copy, restore later */ - addr->addr.in6 = *sin6; /* ipv6 requires also eg. sin6_scope_id => easy to full copy*/ + int port = addr->addr.in6.sin6_port; + /* ipv6 requires also eg. sin6_scope_id => easier to fully copy and override port */ + addr->addr.in6 = *sin6; addr->addr.in6.sin6_port = port; } freeaddrinfo(ai); @@ -1147,6 +1330,7 @@ resolve_bind_local (struct link_socket *sock) NULL, &hints, &ai))==0) { sock->info.lsa->local.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); freeaddrinfo(ai); + ai = NULL; } else { msg (M_FATAL, "getaddrinfo() failed for local \"%s\": %s", sock->local_host, @@ -1264,19 +1448,85 @@ resolve_remote (struct link_socket *sock, #ifdef USE_PF_INET6 case AF_INET6: /* TODO(jjo): ipv6 signal logic */ { - struct addrinfo hints , *ai; - int err; - memset(&hints, 0, sizeof hints); - hints.ai_flags=0; - hints.ai_family=AF_INET6; - if ((err=getaddrinfo(sock->remote_host? sock->remote_host : "::" , NULL, &hints, &ai))==0) { - sock->info.lsa->remote.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); - freeaddrinfo(ai); - } else { - msg (M_FATAL, "getaddrinfo() failed for remote \"%s\": %s", - sock->remote_host, - gai_strerror(err)); + if (sock->remote_host) + { + unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); + int retry = 0; + bool status = false; + + if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) + { + if (phase == 2) + flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL); + retry = 0; + } + else if (phase == 1) + { + if (sock->resolve_retry_seconds) + { + retry = 0; + } + else + { + flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY); + retry = 0; + } + } + else if (phase == 2) + { + if (sock->resolve_retry_seconds) + { + flags |= GETADDR_FATAL; + retry = sock->resolve_retry_seconds; + } + else + { + ASSERT (0); + } + } + else + { + ASSERT (0); + } + + status = getaddr6 ( + flags, + sock->remote_host, + retry, + signal_received, + &sock->info.lsa->remote.addr.in6); + + dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", + flags, + phase, + retry, + signal_received ? *signal_received : -1, + status); + + if (signal_received) + { + if (*signal_received) + goto done; + } + if (!status) + { + if (signal_received) + *signal_received = SIGUSR1; + goto done; + } } + else + { + /* + * no ipv6 hostname given: + * shortcut instead of calling getaddrinfo("::", ...) + */ + + CLEAR(sock->info.lsa->remote.addr.in6); + sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; + sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; + } + sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); } break; -- cgit From 97ba084bc8b8cc5cc817c14c6032a313a493fa87 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Mon, 14 Sep 2009 21:51:54 +0200 Subject: * migrated all getaddrinfo() to getaddr6 * tests Ok: {loopback,remote}{udp,tcp}{4,6} --- socket.c | 234 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 101 insertions(+), 133 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index a632f84..229c0b0 100644 --- a/socket.c +++ b/socket.c @@ -293,6 +293,7 @@ getaddr6 (unsigned int flags, const char *hostname, int resolve_retry_seconds, volatile int *signal_received, + int *gai_err, struct sockaddr_in6 *in6) { bool success; @@ -304,6 +305,9 @@ getaddr6 (unsigned int flags, ASSERT(in6); + if (!hostname) + hostname = "::"; + if (flags & GETADDR_RANDOMIZE) hostname = hostname_randomize(hostname, &gc); @@ -321,11 +325,15 @@ getaddr6 (unsigned int flags, CLEAR(hints); hints.ai_family = AF_INET6; hints.ai_flags = AI_NUMERICHOST; - if ((status = getaddrinfo(hostname, NULL, &hints, &ai))==0) { - *in6 = *((struct sockaddr_in6 *)(ai->ai_addr)); - freeaddrinfo(ai); - ai = NULL; - } + if ((status = getaddrinfo(hostname, NULL, &hints, &ai))==0) + { + *in6 = *((struct sockaddr_in6 *)(ai->ai_addr)); + freeaddrinfo(ai); + ai = NULL; + } + if (gai_err) + *gai_err = status; + if (status != 0) /* parse as IPv6 address failed? */ { @@ -368,6 +376,8 @@ getaddr6 (unsigned int flags, /* try hostname lookup */ hints.ai_flags = 0; err = getaddrinfo(hostname, NULL, &hints, &ai); + if (gai_err) + *gai_err = err; if (signal_received) { @@ -459,7 +469,6 @@ getaddr6 (unsigned int flags, } gc_free (&gc); - //return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; return success; } #endif /* USE_PF_INET6 */ @@ -616,27 +625,29 @@ update_remote (const char* host, } break; #ifdef USE_PF_INET6 - case AF_INET6: /* TODO(jjo): should adapt getaddr() + sf2gaf() for AF_INET6 */ + case AF_INET6: if (host && addr) - { - struct addrinfo hints , *ai; - int err; - memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = AF_INET6; - if ((err=getaddrinfo(host, NULL, &hints, &ai))==0) - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; - if (!IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &addr->addr.in6.sin6_addr)) - { - int port = addr->addr.in6.sin6_port; - /* ipv6 requires also eg. sin6_scope_id => easier to fully copy and override port */ - addr->addr.in6 = *sin6; - addr->addr.in6.sin6_port = port; - } - freeaddrinfo(ai); - } - } + { + struct sockaddr_in6 sin6; + CLEAR(sin6); + int success = getaddr6 ( + sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), + host, + 1, + NULL, + NULL, + &sin6); + if ( success ) + { + if (!IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, &addr->addr.in6.sin6_addr)) + { + int port = addr->addr.in6.sin6_port; + /* ipv6 requires also eg. sin6_scope_id => easier to fully copy and override port */ + addr->addr.in6 = sin6; + addr->addr.in6.sin6_port = port; + } + } + } break; #endif default: @@ -1320,22 +1331,30 @@ resolve_bind_local (struct link_socket *sock) #ifdef USE_PF_INET6 case AF_INET6: { - struct addrinfo hints , *ai; - int err; - memset(&hints, 0, sizeof hints); - hints.ai_flags=AI_PASSIVE; - hints.ai_family=AF_INET6; - /* if no local_host provided, ask for IN6ADDR_ANY ... */ - if ((err=getaddrinfo(sock->local_host? sock->local_host : "::", - NULL, &hints, &ai))==0) { - sock->info.lsa->local.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); - freeaddrinfo(ai); - ai = NULL; - } else { - msg (M_FATAL, "getaddrinfo() failed for local \"%s\": %s", - sock->local_host, - gai_strerror(err)); - } + int success; + int err; + CLEAR(sock->info.lsa->local.addr.in6); + if (sock->local_host) + { + success = getaddr6(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, + sock->local_host, + 0, + NULL, + &err, + &sock->info.lsa->local.addr.in6); + } + else + { + sock->info.lsa->local.addr.in6.sin6_family = AF_INET6; + sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any; + success = true; + } + if (!success) + { + msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", + sock->local_host, + gai_strerror(err)); + } sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); } break; @@ -1363,17 +1382,27 @@ resolve_remote (struct link_socket *sock, volatile int *signal_received) { struct gc_arena gc = gc_new (); + int af; if (!sock->did_resolve_remote) { /* resolve remote address if undefined */ if (!addr_defined (&sock->info.lsa->remote)) { - switch(addr_guess_family(sock->info.proto, sock->remote_host)) - { - case AF_INET: - sock->info.lsa->remote.addr.in4.sin_family = AF_INET; - sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; + af = addr_guess_family(sock->info.proto, sock->remote_host); + switch(af) { + case AF_INET: + sock->info.lsa->remote.addr.in4.sin_family = AF_INET; + sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; + break; +#ifdef USE_PF_INET6 + case AF_INET6: + CLEAR(sock->info.lsa->remote.addr.in6); + sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; + sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; + break; +#endif + } if (sock->remote_host) { @@ -1416,85 +1445,28 @@ resolve_remote (struct link_socket *sock, ASSERT (0); } + switch(af) { + case AF_INET: sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( flags, sock->remote_host, retry, &status, signal_received); - - dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", - flags, - phase, - retry, - signal_received ? *signal_received : -1, - status); - - if (signal_received) - { - if (*signal_received) - goto done; - } - if (!status) - { - if (signal_received) - *signal_received = SIGUSR1; - goto done; - } - } - - sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port); - break; + break; #ifdef USE_PF_INET6 - case AF_INET6: /* TODO(jjo): ipv6 signal logic */ - { - if (sock->remote_host) - { - unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); - int retry = 0; - bool status = false; - - if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) - { - if (phase == 2) - flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL); - retry = 0; - } - else if (phase == 1) - { - if (sock->resolve_retry_seconds) - { - retry = 0; - } - else - { - flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY); - retry = 0; - } - } - else if (phase == 2) - { - if (sock->resolve_retry_seconds) - { - flags |= GETADDR_FATAL; - retry = sock->resolve_retry_seconds; - } - else - { - ASSERT (0); - } - } - else - { - ASSERT (0); - } - + case AF_INET6: status = getaddr6 ( flags, sock->remote_host, retry, signal_received, + NULL, &sock->info.lsa->remote.addr.in6); + break; +#endif + } + dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", flags, @@ -1515,23 +1487,17 @@ resolve_remote (struct link_socket *sock, goto done; } } - else + switch(af) { - /* - * no ipv6 hostname given: - * shortcut instead of calling getaddrinfo("::", ...) - */ - - CLEAR(sock->info.lsa->remote.addr.in6); - sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; - sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; - } - - sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); - } - break; + case AF_INET: + sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port); + break; +#ifdef USE_PF_INET6 + case AF_INET6: + sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); + break; #endif - } + } } /* should we re-use previous active remote address? */ @@ -2688,11 +2654,13 @@ addr_guess_family(int proto, const char *name) int err; memset(&hints, 0, sizeof hints); hints.ai_flags=AI_NUMERICHOST; - if ((err=getaddrinfo(name, NULL, &hints, &ai))==0) { - ret=ai->ai_family; - freeaddrinfo(ai); - return ret; - } + err = getaddrinfo(name, NULL, &hints, &ai); + if ( 0 == err ) + { + ret=ai->ai_family; + freeaddrinfo(ai); + return ret; + } } #endif return AF_INET; /* default */ -- cgit From d9c04efcdffc610163dcca988578cfe677c3af15 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 15 Sep 2009 09:22:46 +0200 Subject: * socket.c: use USE_PF_INET6 in switch constructs to actually toss them out, GNU indentation for my deltas --- socket.c | 432 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 226 insertions(+), 206 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 229c0b0..f3a893d 100644 --- a/socket.c +++ b/socket.c @@ -607,23 +607,24 @@ update_remote (const char* host, bool *changed, const unsigned int sockflags) { - switch(addr->addr.sa.sa_family) { - case AF_INET: - if (host && addr) - { - const in_addr_t new_addr = getaddr ( - sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), - host, - 1, - NULL, - NULL); - if (new_addr && addr->addr.in4.sin_addr.s_addr != new_addr) + switch(addr->addr.sa.sa_family) + { + case AF_INET: + if (host && addr) { - addr->addr.in4.sin_addr.s_addr = new_addr; - *changed = true; + const in_addr_t new_addr = getaddr ( + sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), + host, + 1, + NULL, + NULL); + if (new_addr && addr->addr.in4.sin_addr.s_addr != new_addr) + { + addr->addr.in4.sin_addr.s_addr = new_addr; + *changed = true; + } } - } - break; + break; #ifdef USE_PF_INET6 case AF_INET6: if (host && addr) @@ -651,7 +652,7 @@ update_remote (const char* host, break; #endif default: - ASSERT(0); + ASSERT(0); } } @@ -1314,53 +1315,54 @@ resolve_bind_local (struct link_socket *sock) /* resolve local address if undefined */ if (!addr_defined (&sock->info.lsa->local)) - { - /* may return AF_{INET|INET6} guessed from local_host */ - switch(addr_guess_family(sock->info.proto, sock->local_host)) { - case AF_INET: - sock->info.lsa->local.addr.in4.sin_family = AF_INET; - sock->info.lsa->local.addr.in4.sin_addr.s_addr = - (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, - sock->local_host, - 0, - NULL, - NULL) - : htonl (INADDR_ANY)); - sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port); - break; -#ifdef USE_PF_INET6 - case AF_INET6: + { + /* may return AF_{INET|INET6} guessed from local_host */ + switch(addr_guess_family(sock->info.proto, sock->local_host)) { - int success; - int err; - CLEAR(sock->info.lsa->local.addr.in6); - if (sock->local_host) - { - success = getaddr6(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, - sock->local_host, - 0, - NULL, - &err, - &sock->info.lsa->local.addr.in6); - } - else - { - sock->info.lsa->local.addr.in6.sin6_family = AF_INET6; - sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any; - success = true; - } - if (!success) - { - msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", - sock->local_host, - gai_strerror(err)); - } - sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); - } - break; + case AF_INET: + sock->info.lsa->local.addr.in4.sin_family = AF_INET; + sock->info.lsa->local.addr.in4.sin_addr.s_addr = + (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, + sock->local_host, + 0, + NULL, + NULL) + : htonl (INADDR_ANY)); + sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port); + break; +#ifdef USE_PF_INET6 + case AF_INET6: + { + int success; + int err; + CLEAR(sock->info.lsa->local.addr.in6); + if (sock->local_host) + { + success = getaddr6(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, + sock->local_host, + 0, + NULL, + &err, + &sock->info.lsa->local.addr.in6); + } + else + { + sock->info.lsa->local.addr.in6.sin6_family = AF_INET6; + sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any; + success = true; + } + if (!success) + { + msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", + sock->local_host, + gai_strerror(err)); + } + sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); + } + break; #endif + } } - } /* bind to local address/port */ if (sock->bind_local) @@ -1382,27 +1384,32 @@ resolve_remote (struct link_socket *sock, volatile int *signal_received) { struct gc_arena gc = gc_new (); +#ifdef USE_PF_INET6 int af; +#endif if (!sock->did_resolve_remote) { /* resolve remote address if undefined */ if (!addr_defined (&sock->info.lsa->remote)) { +#ifdef USE_PF_INET6 af = addr_guess_family(sock->info.proto, sock->remote_host); - switch(af) { - case AF_INET: - sock->info.lsa->remote.addr.in4.sin_family = AF_INET; - sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; - break; + switch(af) + { + case AF_INET: +#endif + sock->info.lsa->remote.addr.in4.sin_family = AF_INET; + sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; #ifdef USE_PF_INET6 - case AF_INET6: - CLEAR(sock->info.lsa->remote.addr.in6); - sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; - sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; - break; + break; + case AF_INET6: + CLEAR(sock->info.lsa->remote.addr.in6); + sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; + sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; + break; + } #endif - } if (sock->remote_host) { @@ -1445,27 +1452,30 @@ resolve_remote (struct link_socket *sock, ASSERT (0); } - switch(af) { - case AF_INET: - sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( - flags, - sock->remote_host, - retry, - &status, - signal_received); - break; #ifdef USE_PF_INET6 - case AF_INET6: - status = getaddr6 ( - flags, - sock->remote_host, - retry, - signal_received, - NULL, - &sock->info.lsa->remote.addr.in6); - break; + switch(af) + { + case AF_INET: +#endif + sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( + flags, + sock->remote_host, + retry, + &status, + signal_received); +#ifdef USE_PF_INET6 + break; + case AF_INET6: + status = getaddr6 ( + flags, + sock->remote_host, + retry, + signal_received, + NULL, + &sock->info.lsa->remote.addr.in6); + break; + } #endif - } dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", @@ -1487,17 +1497,19 @@ resolve_remote (struct link_socket *sock, goto done; } } +#ifdef USE_PF_INET6 switch(af) { case AF_INET: +#endif sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port); - break; #ifdef USE_PF_INET6 + break; case AF_INET6: sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); break; -#endif } +#endif } /* should we re-use previous active remote address? */ @@ -1783,9 +1795,9 @@ link_socket_init_phase2 (struct link_socket *sock, } else if (sock->info.proto == PROTO_TCPv4_CLIENT #ifdef USE_PF_INET6 - ||sock->info.proto == PROTO_TCPv6_CLIENT + ||sock->info.proto == PROTO_TCPv6_CLIENT #endif - ) + ) { #ifdef GENERAL_PROXY_SUPPORT @@ -2075,18 +2087,18 @@ link_socket_bad_incoming_addr (struct buffer *buf, struct gc_arena gc = gc_new (); switch(from_addr->dest.addr.sa.sa_family) - { + { case AF_INET: #ifdef USE_PF_INET6 case AF_INET6: #endif msg (D_LINK_ERRORS, - "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", - print_link_socket_actual (from_addr, &gc), - (int)from_addr->dest.addr.sa.sa_family, - print_sockaddr (&info->lsa->remote, &gc)); + "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", + print_link_socket_actual (from_addr, &gc), + (int)from_addr->dest.addr.sa.sa_family, + print_sockaddr (&info->lsa->remote, &gc)); break; - } + } buf->len = 0; gc_free (&gc); } @@ -2112,7 +2124,7 @@ link_socket_current_remote (const struct link_socket_info *info) */ #if defined ( USE_PF_INET6 ) if(lsa->actual.dest.addr.sa.sa_family != AF_INET) - return 0; + return 0; #else ASSERT(lsa->actual.dest.addr.sa.sa_family == AF_INET); #endif @@ -2353,51 +2365,54 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, return "[NULL]"; } addr_is_defined = addr_defined (addr); - switch(addr->addr.sa.sa_family) { +#ifdef USE_PF_INET6 + switch(addr->addr.sa.sa_family) + { case AF_INET: - { - const int port= ntohs (addr->addr.in4.sin_port); - out = alloc_buf_gc (128, gc); - buf_puts (&out, "[AF_INET]"); - mutex_lock_static (L_INET_NTOA); - buf_puts (&out, (addr_is_defined ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); - mutex_unlock_static (L_INET_NTOA); - - if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) - && port) +#endif { - if (separator) - buf_printf (&out, "%s", separator); + const int port= ntohs (addr->addr.in4.sin_port); + out = alloc_buf_gc (128, gc); + buf_puts (&out, "[AF_INET]"); + mutex_lock_static (L_INET_NTOA); + buf_puts (&out, (addr_is_defined ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); + mutex_unlock_static (L_INET_NTOA); + + if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) + && port) + { + if (separator) + buf_printf (&out, "%s", separator); - buf_printf (&out, "%d", port); + buf_printf (&out, "%d", port); + } } - } - break; #ifdef USE_PF_INET6 + break; case AF_INET6: - { - const int port= ntohs (addr->addr.in6.sin6_port); - char buf[INET6_ADDRSTRLEN] = "[undef]"; - out = alloc_buf_gc (128, gc); - buf_puts (&out, "[AF_INET6]"); - if (addr_is_defined) - { - getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), - buf, sizeof (buf), NULL, 0, NI_NUMERICHOST); - buf_puts (&out, buf); - } - if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) - && port) { - if (separator) - buf_puts (&out, separator); + const int port= ntohs (addr->addr.in6.sin6_port); + char buf[INET6_ADDRSTRLEN] = "[undef]"; + out = alloc_buf_gc (128, gc); + buf_puts (&out, "[AF_INET6]"); + if (addr_is_defined) + { + getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), + buf, sizeof (buf), NULL, 0, NI_NUMERICHOST); + buf_puts (&out, buf); + } + if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) + && port) + { + if (separator) + buf_puts (&out, separator); - buf_printf (&out, "%d", port); + buf_printf (&out, "%d", port); + } } - } break; + } #endif - } return BSTR (&out); } @@ -2421,34 +2436,34 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act)) { switch(act->dest.addr.sa.sa_family) - { - case AF_INET: - { - struct openvpn_sockaddr sa; - 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)); - } - break; -#ifdef USE_PF_INET6 - case AF_INET6: - { - struct sockaddr_in6 sin6; - char buf[INET6_ADDRSTRLEN] = "[undef]"; - memset(&sin6, 0, sizeof 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])"); - } - } - break; + case AF_INET: + { + struct openvpn_sockaddr sa; + 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)); + } + break; +#ifdef USE_PF_INET6 + case AF_INET6: + { + struct sockaddr_in6 sin6; + char buf[INET6_ADDRSTRLEN] = "[undef]"; + memset(&sin6, 0, sizeof 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])"); + } + } + break; #endif - } + } } #endif @@ -2485,8 +2500,11 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openv char name_buf[256]; char buf[128]; - switch(addr->addr.sa.sa_family) { +#ifdef USE_PF_INET6 + switch(addr->addr.sa.sa_family) + { case AF_INET: +#endif if (flags & SA_IP_PORT) openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); else @@ -2497,23 +2515,23 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openv mutex_unlock_static (L_INET_NTOA); if ((flags & SA_IP_PORT) && addr->addr.in4.sin_port) - { - openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); - setenv_int (es, name_buf, ntohs (addr->addr.in4.sin_port)); - } - break; + { + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); + setenv_int (es, name_buf, ntohs (addr->addr.in4.sin_port)); + } #ifdef USE_PF_INET6 + break; case AF_INET6: openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip6", name_prefix); getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), - buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); setenv_str (es, name_buf, buf); openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); break; + } #endif - } } void @@ -2891,46 +2909,48 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, mesg.msg_iov = &iov; mesg.msg_iovlen = 1; switch (sock->info.lsa->remote.addr.sa.sa_family) - { - case AF_INET: { - struct openvpn_in4_pktinfo opi; - struct in_pktinfo *pkti; - mesg.msg_name = &to->dest.addr.sa; - mesg.msg_namelen = sizeof (struct sockaddr_in); - mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); - mesg.msg_flags = 0; - cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi); - cmsg->cmsg_level = SOL_IP; - cmsg->cmsg_type = IP_PKTINFO; - pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); - pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; - pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; - pkti->ipi_addr.s_addr = 0; - break; - } + { + case AF_INET: + { + struct openvpn_in4_pktinfo opi; + struct in_pktinfo *pkti; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in); + mesg.msg_control = &opi; + mesg.msg_controllen = sizeof (opi); + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (opi); + cmsg->cmsg_level = SOL_IP; + cmsg->cmsg_type = IP_PKTINFO; + pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); + pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; + pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; + pkti->ipi_addr.s_addr = 0; + break; + } #ifdef USE_PF_INET6 - case AF_INET6: { - struct openvpn_in6_pktinfo opi6; - struct in6_pktinfo *pkti6; - mesg.msg_name = &to->dest.addr.sa; - mesg.msg_namelen = sizeof (struct sockaddr_in6); - mesg.msg_control = &opi6; - mesg.msg_controllen = sizeof (opi6); - mesg.msg_flags = 0; - cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi6); - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); - pkti6->ipi6_ifindex = to->pi.in6.ipi6_ifindex; - pkti6->ipi6_addr = to->pi.in6.ipi6_addr; - break; - } + case AF_INET6: + { + struct openvpn_in6_pktinfo opi6; + struct in6_pktinfo *pkti6; + mesg.msg_name = &to->dest.addr.sa; + mesg.msg_namelen = sizeof (struct sockaddr_in6); + mesg.msg_control = &opi6; + mesg.msg_controllen = sizeof (opi6); + mesg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = sizeof (opi6); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); + pkti6->ipi6_ifindex = to->pi.in6.ipi6_ifindex; + pkti6->ipi6_addr = to->pi.in6.ipi6_addr; + break; + } #endif default: ASSERT(0); - } + } return sendmsg (sock->sd, &mesg, 0); } -- cgit From 51afc8b8865fe09f76b81ae341e693a5b16199f2 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 15 Sep 2009 16:48:46 +0200 Subject: * support --disable-ipv6 build properly: - tests now are pass (and fail) properly for ipv6/4 builds * more GNU indenting --- socket.c | 59 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index f3a893d..01c18e9 100644 --- a/socket.c +++ b/socket.c @@ -1316,10 +1316,12 @@ resolve_bind_local (struct link_socket *sock) /* resolve local address if undefined */ if (!addr_defined (&sock->info.lsa->local)) { +#ifdef USE_PF_INET6 /* may return AF_{INET|INET6} guessed from local_host */ switch(addr_guess_family(sock->info.proto, sock->local_host)) { case AF_INET: +#endif sock->info.lsa->local.addr.in4.sin_family = AF_INET; sock->info.lsa->local.addr.in4.sin_addr.s_addr = (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, @@ -1329,8 +1331,8 @@ resolve_bind_local (struct link_socket *sock) NULL) : htonl (INADDR_ANY)); sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port); - break; #ifdef USE_PF_INET6 + break; case AF_INET6: { int success; @@ -1360,8 +1362,8 @@ resolve_bind_local (struct link_socket *sock) sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); } break; -#endif } +#endif /* USE_PF_INET6 */ } /* bind to local address/port */ @@ -1756,7 +1758,7 @@ link_socket_init_phase2 (struct link_socket *sock, /* TCP client/server */ if (sock->info.proto == PROTO_TCPv4_SERVER #ifdef USE_PF_INET6 - ||sock->info.proto == PROTO_TCPv6_SERVER + ||sock->info.proto == PROTO_TCPv6_SERVER #endif ) { @@ -1795,7 +1797,7 @@ link_socket_init_phase2 (struct link_socket *sock, } else if (sock->info.proto == PROTO_TCPv4_CLIENT #ifdef USE_PF_INET6 - ||sock->info.proto == PROTO_TCPv6_CLIENT + ||sock->info.proto == PROTO_TCPv6_CLIENT #endif ) { @@ -2122,7 +2124,7 @@ link_socket_current_remote (const struct link_socket_info *info) * by now just ignore it * */ -#if defined ( USE_PF_INET6 ) +#ifdef USE_PF_INET6 if(lsa->actual.dest.addr.sa.sa_family != AF_INET) return 0; #else @@ -2435,17 +2437,19 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, #if ENABLE_IP_PKTINFO if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act)) { +#ifdef USE_PF_INET6 switch(act->dest.addr.sa.sa_family) { case AF_INET: +#endif { struct openvpn_sockaddr sa; 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)); } - break; #ifdef USE_PF_INET6 + break; case AF_INET6: { struct sockaddr_in6 sin6; @@ -2462,8 +2466,8 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, } } break; -#endif } +#endif /* USE_PF_INET6 */ } #endif @@ -2663,33 +2667,36 @@ int addr_guess_family(int proto, const char *name) { sa_family_t ret; - if (proto) { - return proto_sa_family(proto); /* already stamped */ - } + 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; - err = getaddrinfo(name, NULL, &hints, &ai); - if ( 0 == err ) - { - ret=ai->ai_family; - freeaddrinfo(ai); - return ret; - } - } + else + { + struct addrinfo hints , *ai; + int err; + memset(&hints, 0, sizeof 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 */ } const char * addr_family_name (int af) { - switch (af) { - case AF_INET: return "AF_INET"; + switch (af) + { + case AF_INET: return "AF_INET"; case AF_INET6: return "AF_INET6"; - } + } return "AF_UNSPEC"; } -- cgit From 97549c67678bb9b5196d4a87971e9fde6147cce0 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 15 Sep 2009 22:42:46 +0200 Subject: * important fix for tcp6 reconnection was incorrectly creating a PF_INET socket --- socket.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 01c18e9..344c0dd 100644 --- a/socket.c +++ b/socket.c @@ -1251,7 +1251,20 @@ socket_connect (socket_descriptor_t *sd, if (*signal_received) goto done; - *sd = create_socket_tcp (); +#ifdef USE_PF_INET6 + switch(local->addr.sa.sa_family) + { + case PF_INET6: + *sd = create_socket_tcp6 (); + break; + case PF_INET: +#endif + *sd = create_socket_tcp (); +#ifdef USE_PF_INET6 + break; + } +#endif + if (bind_local) socket_bind (*sd, local, "TCP Client"); update_remote (remote_dynamic, remote, remote_changed, sockflags); -- cgit From 4d3df224e1210f732b84cf4273fb57993361d4ba Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Sat, 19 Sep 2009 18:33:40 +0200 Subject: * fixed win32 non-ipv6 build --- socket.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 344c0dd..3340314 100644 --- a/socket.c +++ b/socket.c @@ -1173,7 +1173,7 @@ openvpn_connect (socket_descriptor_t sd, } } #else - status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); + status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); if (status) status = openvpn_errno_socket (); #endif @@ -2515,9 +2515,9 @@ void setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags) { char name_buf[256]; - char buf[128]; #ifdef USE_PF_INET6 + char buf[128]; switch(addr->addr.sa.sa_family) { case AF_INET: @@ -2582,7 +2582,7 @@ struct proto_names { const char *display_form; bool is_dgram; bool is_net; - sa_family_t proto_af; + unsigned short proto_af; }; /* Indexed by PROTO_x */ @@ -2629,7 +2629,7 @@ proto_is_tcp(int proto) return (!proto_names[proto].is_dgram)&&proto_names[proto].is_net; } -sa_family_t +unsigned short proto_sa_family(int proto) { if (proto < 0 || proto >= PROTO_N) @@ -2679,7 +2679,9 @@ proto2ascii_all (struct gc_arena *gc) int addr_guess_family(int proto, const char *name) { - sa_family_t ret; +#ifdef USE_PF_INET6 + unsigned short ret; +#endif if (proto) { return proto_sa_family(proto); /* already stamped */ @@ -3270,10 +3272,10 @@ socket_finalize (SOCKET s, { if (io->addrlen != sizeof (io->addr)) bad_address_length (io->addrlen, sizeof (io->addr)); - from->dest.addr.sa = io->addr; + from->dest.addr.in4 = io->addr; } else - CLEAR (from->dest.addr.sa); + CLEAR (from->dest.addr); } if (buf) -- cgit From b7f203c8cfd2c0e412afd6f5ca0aa4eb62a031d2 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Sat, 19 Sep 2009 21:36:46 +0200 Subject: * ipv6 on win32 "milestone": 1st snapshot that passes all unittests --- socket.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 9 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 3340314..3024ea4 100644 --- a/socket.c +++ b/socket.c @@ -2993,11 +2993,19 @@ socket_recv_queue (struct link_socket *sock, int maxsize) int status; /* reset buf to its initial state */ - if (sock->info.proto == PROTO_UDPv4) + if (sock->info.proto == PROTO_UDPv4 +#ifdef USE_PF_INET6 + || sock->info.proto == PROTO_UDPv6 +#endif + ) { sock->reads.buf = sock->reads.buf_init; } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + 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 + ) { stream_buf_get_next (&sock->stream_buf, &sock->reads.buf); } @@ -3017,10 +3025,19 @@ socket_recv_queue (struct link_socket *sock, int maxsize) ASSERT (ResetEvent (sock->reads.overlapped.hEvent)); sock->reads.flags = 0; - if (sock->info.proto == PROTO_UDPv4) + if (sock->info.proto == PROTO_UDPv4 +#ifdef USE_PF_INET6 + || sock->info.proto == PROTO_UDPv6 +#endif + ) { sock->reads.addr_defined = true; - sock->reads.addrlen = sizeof (sock->reads.addr); +#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, @@ -3032,7 +3049,12 @@ socket_recv_queue (struct link_socket *sock, int maxsize) &sock->reads.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + 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 + ) + { sock->reads.addr_defined = false; status = WSARecv( @@ -3052,8 +3074,14 @@ socket_recv_queue (struct link_socket *sock, int maxsize) if (!status) /* operation completed immediately? */ { +#ifdef USE_PF_INET6 + int addrlen = af_addr_size(sock->info.lsa->local.addr.sa.sa_family); + if (sock->reads.addr_defined && sock->reads.addrlen != addrlen) + bad_address_length (sock->reads.addrlen, addrlen); +#else if (sock->reads.addr_defined && sock->reads.addrlen != sizeof (sock->reads.addr)) bad_address_length (sock->reads.addrlen, sizeof (sock->reads.addr)); +#endif sock->reads.iostate = IOSTATE_IMMEDIATE_RETURN; @@ -3112,12 +3140,26 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li ASSERT (ResetEvent (sock->writes.overlapped.hEvent)); sock->writes.flags = 0; - if (sock->info.proto == PROTO_UDPv4) + if (sock->info.proto == PROTO_UDPv4 +#ifdef USE_PF_INET6 + || sock->info.proto == PROTO_UDPv6 +#endif + ) { /* set destination address for UDP writes */ sock->writes.addr_defined = true; - sock->writes.addr = to->dest.addr.in4; - sock->writes.addrlen = sizeof (sock->writes.addr); +#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 +#endif + { + sock->writes.addr = to->dest.addr.in4; + sock->writes.addrlen = sizeof (sock->writes.addr); + } status = WSASendTo( sock->sd, @@ -3130,7 +3172,11 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li &sock->writes.overlapped, NULL); } - else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) + 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 + ) { /* destination address for TCP writes was established on connection initiation */ sock->writes.addr_defined = false; @@ -3269,11 +3315,42 @@ socket_finalize (SOCKET s, if (from) { if (ret >= 0 && io->addr_defined) +#ifdef USE_PF_INET6 + { + /* TODO(jjo): streamline this mess */ + /* in this func we dont have relevant info about the PF_ of this + * endpoint, as link_socket_actual will be zero for the 1st received packet + * + * Test for inets PF_ possible sizes + */ + switch (io->addrlen) + { + case sizeof(struct sockaddr_in): + case sizeof(struct sockaddr_in6): + /* TODO(jjo): for some reason (?) I'm getting 24,28 for AF_INET6 */ + case sizeof(struct sockaddr_in6)-4: + break; + default: + bad_address_length (io->addrlen, af_addr_size(io->addr.sin_family)); + } + + switch (io->addr.sin_family) + { + case AF_INET: + from->dest.addr.in4 = io->addr; + break; + case AF_INET6: + from->dest.addr.in6 = io->addr6; + break; + } + } +#else { if (io->addrlen != sizeof (io->addr)) bad_address_length (io->addrlen, sizeof (io->addr)); from->dest.addr.in4 = io->addr; } +#endif else CLEAR (from->dest.addr); } -- cgit From 6d1b80bdeb5e0df3dee6a8bc05d7e3f622371c1c Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Thu, 24 Sep 2009 20:09:55 +0200 Subject: * correctly setup hints.ai_socktype for getaddrinfo(), althought sorta hacky, see TODO.ipv6. --- socket.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 3024ea4..96d2602 100644 --- a/socket.c +++ b/socket.c @@ -52,13 +52,12 @@ const int proto_overhead[] = { /* indexed by PROTO_x */ * Convert sockflags/getaddr_flags into getaddr_flags */ static unsigned int -sf2gaf(const unsigned int getaddr_flags, +sf2gaf(unsigned int getaddr_flags, const unsigned int sockflags) { - if (sockflags & SF_HOST_RANDOMIZE) - return getaddr_flags | GETADDR_RANDOMIZE; - else - return getaddr_flags; + getaddr_flags |= (sockflags & SF_GETADDRINFO_DGRAM) ? GETADDR_DGRAM : 0; + getaddr_flags |= (sockflags & SF_HOST_RANDOMIZE) ? GETADDR_RANDOMIZE : 0; + return getaddr_flags; } /* @@ -375,7 +374,11 @@ getaddr6 (unsigned int flags, { /* try hostname lookup */ hints.ai_flags = 0; + hints.ai_socktype = dnsflags_to_socktype(flags); + dmsg (D_SOCKET_DEBUG, "GETADDR6 flags=0x%04x ai_family=%d ai_socktype=%d", + flags, hints.ai_family, hints.ai_socktype); err = getaddrinfo(hostname, NULL, &hints, &ai); + if (gai_err) *gai_err = err; @@ -891,6 +894,7 @@ create_socket (struct link_socket *sock) if (sock->info.proto == PROTO_UDPv4) { sock->sd = create_socket_udp (sock->sockflags); + sock->sockflags |= SF_GETADDRINFO_DGRAM; #ifdef ENABLE_SOCKS if (sock->socks_proxy) @@ -911,6 +915,7 @@ create_socket (struct link_socket *sock) else if (sock->info.proto == PROTO_UDPv6) { sock->sd = create_socket_udp6 (sock->sockflags); + sock->sockflags |= SF_GETADDRINFO_DGRAM; } #endif else @@ -1492,7 +1497,6 @@ resolve_remote (struct link_socket *sock, } #endif - dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", flags, phase, -- cgit From aa8e9576bbd2ecd094276521ad9cf88227a119c9 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Thu, 1 Oct 2009 00:15:12 +0200 Subject: * fix multi-tcp crash (corrected assertion) --- socket.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 96d2602..2bb7141 100644 --- a/socket.c +++ b/socket.c @@ -1645,7 +1645,11 @@ link_socket_init_phase1 (struct link_socket *sock, if (mode == LS_MODE_TCP_ACCEPT_FROM) { ASSERT (accept_from); - ASSERT (sock->info.proto == PROTO_TCPv4_SERVER); + ASSERT (sock->info.proto == PROTO_TCPv4_SERVER +#ifdef USE_PF_INET6 + || sock->info.proto == PROTO_TCPv6_SERVER +#endif + ); ASSERT (!sock->inetd); sock->sd = accept_from->sd; } -- cgit From fc9a44e24299386b26f610a204656e30885c1ab5 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Mon, 5 Oct 2009 12:24:20 +0200 Subject: * socket.c: better buf logic in print_sockaddr_ex --- socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 2bb7141..943cb58 100644 --- a/socket.c +++ b/socket.c @@ -2382,7 +2382,7 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, const unsigned int flags, struct gc_arena *gc) { - struct buffer out; + struct buffer out = alloc_buf_gc (128, gc); bool addr_is_defined; if (!addr) { return "[NULL]"; @@ -2395,7 +2395,6 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, #endif { const int port= ntohs (addr->addr.in4.sin_port); - out = alloc_buf_gc (128, gc); buf_puts (&out, "[AF_INET]"); mutex_lock_static (L_INET_NTOA); buf_puts (&out, (addr_is_defined ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); @@ -2416,7 +2415,6 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, { const int port= ntohs (addr->addr.in6.sin6_port); char buf[INET6_ADDRSTRLEN] = "[undef]"; - out = alloc_buf_gc (128, gc); buf_puts (&out, "[AF_INET6]"); if (addr_is_defined) { @@ -2434,6 +2432,8 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, } } break; + default: + ASSERT(0); } #endif return BSTR (&out); -- cgit From 4af2d42d85e619e508645682bef3904f5d6e39af Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Mon, 5 Oct 2009 14:44:20 +0200 Subject: * fixed segfault for undef address family in print_sockaddr_ex (thanks Marcel!) --- socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 943cb58..52b7b68 100644 --- a/socket.c +++ b/socket.c @@ -2384,10 +2384,10 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, { struct buffer out = alloc_buf_gc (128, gc); bool addr_is_defined; - if (!addr) { - return "[NULL]"; + addr_is_defined = addr_defined (addr); + if (!addr_is_defined) { + return "[undef]"; } - addr_is_defined = addr_defined (addr); #ifdef USE_PF_INET6 switch(addr->addr.sa.sa_family) { @@ -2414,7 +2414,7 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, case AF_INET6: { const int port= ntohs (addr->addr.in6.sin6_port); - char buf[INET6_ADDRSTRLEN] = "[undef]"; + char buf[INET6_ADDRSTRLEN] = ""; buf_puts (&out, "[AF_INET6]"); if (addr_is_defined) { -- cgit From 1ad6fc2976c6e5eedb248769e4b1f48e33c75346 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 20 Oct 2009 22:38:50 +0200 Subject: * no new funcionality, just small cleanups: - cmdline options help: add tcp6/udp6 missing messages - win32: expand usage of proto_is_udp(), proto_is_tcp() - replace some memset(&obj, 0, sizeof obj) by openvpn's CLEAR(obj) --- socket.c | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 52b7b68..bade47e 100644 --- a/socket.c +++ b/socket.c @@ -2146,10 +2146,10 @@ link_socket_current_remote (const struct link_socket_info *info) * */ #ifdef USE_PF_INET6 - if(lsa->actual.dest.addr.sa.sa_family != AF_INET) + if (lsa->actual.dest.addr.sa.sa_family != AF_INET) return 0; #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)) @@ -2475,7 +2475,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, { 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; { @@ -2699,8 +2699,8 @@ addr_guess_family(int proto, const char *name) { 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 ) { @@ -3001,19 +3001,11 @@ socket_recv_queue (struct link_socket *sock, int maxsize) 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); } @@ -3033,11 +3025,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize) 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 @@ -3057,12 +3045,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize) &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( @@ -3148,11 +3131,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li 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; @@ -3180,11 +3159,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li &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; -- cgit From efa85c8b086121dc5df0e07b110751077e3d1ec4 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 10 Nov 2009 23:46:46 +0100 Subject: * (prototype) fix for supporting "redirect-gateway" for tunneled ipv4 over ipv6 endpoints --- socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index bade47e..2d46d3f 100644 --- a/socket.c +++ b/socket.c @@ -2147,7 +2147,7 @@ link_socket_current_remote (const struct link_socket_info *info) */ #ifdef USE_PF_INET6 if (lsa->actual.dest.addr.sa.sa_family != AF_INET) - return 0; + return 0xffffffff; #else ASSERT (lsa->actual.dest.addr.sa.sa_family == AF_INET); #endif -- cgit From 9d4c64b584173789780431e5fd5acf977cf72e9d Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Wed, 11 Nov 2009 15:35:31 +0100 Subject: * polished redirect-gateway (ipv4 on ipv6 endpoints) support --- socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 2d46d3f..72da792 100644 --- a/socket.c +++ b/socket.c @@ -2147,7 +2147,7 @@ link_socket_current_remote (const struct link_socket_info *info) */ #ifdef USE_PF_INET6 if (lsa->actual.dest.addr.sa.sa_family != AF_INET) - return 0xffffffff; + return IPV4_INVALID_ADDR; #else ASSERT (lsa->actual.dest.addr.sa.sa_family == AF_INET); #endif -- cgit From 830038fce4a30f317eb265079f91d9555981ad76 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Thu, 23 Sep 2010 01:15:35 +0200 Subject: * fix --multihome for ipv4: cmsg_len must compare against in_pktinfo size, not the full 4+6 union, also use saner variable names. --- socket.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 72da792..577ef93 100644 --- a/socket.c +++ b/socket.c @@ -2466,6 +2466,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, { struct openvpn_sockaddr sa; CLEAR (sa); + sa.addr.in4.sin_family = AF_INET; sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); } @@ -2807,7 +2808,7 @@ link_socket_read_tcp (struct link_socket *sock, struct openvpn_in4_pktinfo { struct cmsghdr cmsghdr; - struct in_pktinfo pi; + struct in_pktinfo pi4; }; #ifdef USE_PF_INET6 struct openvpn_in6_pktinfo @@ -2818,9 +2819,9 @@ struct openvpn_in6_pktinfo #endif union openvpn_pktinfo { - struct openvpn_in4_pktinfo cmsgpi; + struct openvpn_in4_pktinfo msgpi4; #ifdef USE_PF_INET6 - struct openvpn_in6_pktinfo cmsgpi6; + struct openvpn_in6_pktinfo msgpi6; #endif }; #pragma pack() @@ -2843,7 +2844,7 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, mesg.msg_name = &from->dest.addr; mesg.msg_namelen = fromlen; mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); + mesg.msg_controllen = sizeof opi; buf->len = recvmsg (sock->sd, &mesg, 0); if (buf->len >= 0) { @@ -2854,7 +2855,7 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, && CMSG_NXTHDR (&mesg, cmsg) == NULL && cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO - && cmsg->cmsg_len >= sizeof (opi)) + && cmsg->cmsg_len >= sizeof (struct openvpn_in4_pktinfo)) { struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); from->pi.in4.ipi_ifindex = pkti->ipi_ifindex; @@ -2942,15 +2943,15 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, { case AF_INET: { - struct openvpn_in4_pktinfo opi; + struct openvpn_in4_pktinfo msgpi4; struct in_pktinfo *pkti; mesg.msg_name = &to->dest.addr.sa; mesg.msg_namelen = sizeof (struct sockaddr_in); - mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (opi); + mesg.msg_control = &msgpi4; + mesg.msg_controllen = sizeof msgpi4; mesg.msg_flags = 0; cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi); + cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); cmsg->cmsg_level = SOL_IP; cmsg->cmsg_type = IP_PKTINFO; pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); @@ -2962,15 +2963,15 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, #ifdef USE_PF_INET6 case AF_INET6: { - struct openvpn_in6_pktinfo opi6; + struct openvpn_in6_pktinfo msgpi6; struct in6_pktinfo *pkti6; mesg.msg_name = &to->dest.addr.sa; mesg.msg_namelen = sizeof (struct sockaddr_in6); - mesg.msg_control = &opi6; - mesg.msg_controllen = sizeof (opi6); + mesg.msg_control = &msgpi6; + mesg.msg_controllen = sizeof msgpi6; mesg.msg_flags = 0; cmsg = CMSG_FIRSTHDR (&mesg); - cmsg->cmsg_len = sizeof (opi6); + cmsg->cmsg_len = sizeof (struct openvpn_in6_pktinfo); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); -- cgit From 5d6dbb03776de4d38f45e429ef674313a2bda8cc Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Sun, 6 Feb 2011 09:52:46 +0100 Subject: * fix --multihome for ipv6: IPV6_RECVPKTINFO - setsockopt IPV6_RECVPKTINFO (not IPV6_PKTINFO!) - do check for setsockopt() failures - append % in INFO msg --- socket.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 577ef93..cfec757 100644 --- a/socket.c +++ b/socket.c @@ -843,7 +843,9 @@ create_socket_udp (const unsigned int flags) else if (flags & SF_USE_IP_PKTINFO) { int pad = 1; - setsockopt (sd, SOL_IP, IP_PKTINFO, (void*)&pad, sizeof(pad)); + if (setsockopt (sd, SOL_IP, IP_PKTINFO, + (void*)&pad, sizeof(pad)) < 0) + msg(M_SOCKERR, "UDP: failed setsockopt for IP_PKTINFO"); } #endif return sd; @@ -861,7 +863,9 @@ create_socket_udp6 (const unsigned int flags) else if (flags & SF_USE_IP_PKTINFO) { int pad = 1; - setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO, (void*)&pad, sizeof(pad)); + if (setsockopt (sd, IPPROTO_IPV6, IPV6_RECVPKTINFO, + (void*)&pad, sizeof(pad)) < 0) + msg(M_SOCKERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO"); } #endif return sd; @@ -2453,6 +2457,7 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, { if (act) { + char ifname[IF_NAMESIZE] = "[undef]"; struct buffer out = alloc_buf_gc (128, gc); buf_printf (&out, "%s", print_sockaddr_ex (&act->dest, separator, flags, gc)); #if ENABLE_IP_PKTINFO @@ -2468,7 +2473,10 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, CLEAR (sa); sa.addr.in4.sin_family = AF_INET; sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; - buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); + if_indextoname(act->pi.in4.ipi_ifindex, ifname); + buf_printf (&out, " (via %s%%%s)", + print_sockaddr_ex (&sa, separator, 0, gc), + ifname); } #ifdef USE_PF_INET6 break; @@ -2479,13 +2487,12 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, 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])"); - } + if_indextoname(act->pi.in6.ipi6_ifindex, ifname); + if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), + buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) == 0) + buf_printf (&out, " (via %s%%%s)", buf, ifname); + else + buf_printf (&out, " (via [getnameinfo() err]%%%s)", ifname); } break; } -- cgit From c47fd4b35cc99130c4177fd6b19ed2e0b4776756 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Mon, 21 Mar 2011 09:21:39 +0100 Subject: * ipv6-0.4.14: fix xinetd usage: - closes http://bugs.debian.org/574164 - also needed for --disable-ipv6 builds - supports IPv6 from xinetd --- socket.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index cfec757..7de56ab 100644 --- a/socket.c +++ b/socket.c @@ -1710,7 +1710,11 @@ link_socket_init_phase1 (struct link_socket *sock, /* were we started by inetd or xinetd? */ if (sock->inetd) { - ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT); + ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT +#ifdef USE_PF_INET6 + && sock->info.proto != PROTO_TCPv6_CLIENT +#endif + ); ASSERT (socket_defined (inetd_socket_descriptor)); sock->sd = inetd_socket_descriptor; } @@ -1759,7 +1763,34 @@ link_socket_init_phase2 (struct link_socket *sock, /* were we started by inetd or xinetd? */ if (sock->inetd) { - if (sock->info.proto == PROTO_TCPv4_SERVER) + if (sock->info.proto == PROTO_TCPv4_SERVER +#ifdef USE_PF_INET6 + || sock->info.proto == PROTO_TCPv6_SERVER +#endif + ) { + /* AF_INET as default (and fallback) for inetd */ + sock->info.lsa->actual.dest.addr.sa.sa_family = AF_INET; +#ifdef USE_PF_INET6 +#ifdef HAVE_GETSOCKNAME + { + /* inetd: hint family type for dest = local's */ + struct openvpn_sockaddr local_addr; + socklen_t addrlen = sizeof(local_addr); + if (getsockname (sock->sd, (struct sockaddr *)&local_addr, &addrlen) == 0) { + sock->info.lsa->actual.dest.addr.sa.sa_family = local_addr.addr.sa.sa_family; + dmsg (D_SOCKET_DEBUG, "inetd(%s): using sa_family=%d from getsockname(%d)", + proto2ascii(sock->info.proto, false), local_addr.addr.sa.sa_family, + sock->sd); + } else + msg (M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET", + proto2ascii(sock->info.proto, false), sock->sd); + } +#else + msg (M_WARN, "inetd(%s): this OS does not provide the getsockname() " + "function, using AF_INET", + proto2ascii(sock->info.proto, false)); +#endif +#endif sock->sd = socket_listen_accept (sock->sd, &sock->info.lsa->actual, @@ -1769,6 +1800,7 @@ link_socket_init_phase2 (struct link_socket *sock, false, sock->inetd == INETD_NOWAIT, signal_received); + } ASSERT (!remote_changed); if (*signal_received) goto done; -- cgit From d3774cdf1e3c2f4e86fac52a723a3869b75b5b4e Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Tue, 22 Mar 2011 21:59:23 +0100 Subject: * ipv6-0.4.15: add --multihome support to xBSD - _both_ for IPv4 (which was missing) and for IPv6 - tested on OpenBSD 4.7, FreeBSD 8.1 --- socket.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 7de56ab..7efdf3a 100644 --- a/socket.c +++ b/socket.c @@ -843,9 +843,17 @@ create_socket_udp (const unsigned int flags) else if (flags & SF_USE_IP_PKTINFO) { int pad = 1; +#ifdef IP_PKTINFO if (setsockopt (sd, SOL_IP, IP_PKTINFO, (void*)&pad, sizeof(pad)) < 0) msg(M_SOCKERR, "UDP: failed setsockopt for IP_PKTINFO"); +#elif defined(IP_RECVDSTADDR) + if (setsockopt (sd, IPPROTO_IP, IP_RECVDSTADDR, + (void*)&pad, sizeof(pad)) < 0) + msg(M_SOCKERR, "UDP: failed setsockopt for IP_RECVDSTADDR"); +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif } #endif return sd; @@ -2504,8 +2512,15 @@ print_link_socket_actual_ex (const struct link_socket_actual *act, struct openvpn_sockaddr sa; CLEAR (sa); sa.addr.in4.sin_family = AF_INET; +#ifdef IP_PKTINFO sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; if_indextoname(act->pi.in4.ipi_ifindex, ifname); +#elif defined(IP_RECVDSTADDR) + sa.addr.in4.sin_addr = act->pi.in4; + ifname[0]=0; +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif buf_printf (&out, " (via %s%%%s)", print_sockaddr_ex (&sa, separator, 0, gc), ifname); @@ -2847,7 +2862,12 @@ link_socket_read_tcp (struct link_socket *sock, struct openvpn_in4_pktinfo { struct cmsghdr cmsghdr; +#ifdef HAVE_IN_PKTINFO struct in_pktinfo pi4; +#endif +#ifdef IP_RECVDSTADDR + struct in_addr pi4; +#endif }; #ifdef USE_PF_INET6 struct openvpn_in6_pktinfo @@ -2892,13 +2912,26 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, cmsg = CMSG_FIRSTHDR (&mesg); if (cmsg != NULL && CMSG_NXTHDR (&mesg, cmsg) == NULL +#ifdef IP_PKTINFO && cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO +#elif defined(IP_RECVDSTADDR) + && cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_RECVDSTADDR +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif && cmsg->cmsg_len >= sizeof (struct openvpn_in4_pktinfo)) { +#ifdef IP_PKTINFO struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); from->pi.in4.ipi_ifindex = pkti->ipi_ifindex; from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst; +#elif defined(IP_RECVDSTADDR) + from->pi.in4 = *(struct in_addr*) CMSG_DATA (cmsg); +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif } #ifdef USE_PF_INET6 else if (cmsg != NULL @@ -2983,7 +3016,6 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, case AF_INET: { struct openvpn_in4_pktinfo msgpi4; - struct in_pktinfo *pkti; mesg.msg_name = &to->dest.addr.sa; mesg.msg_namelen = sizeof (struct sockaddr_in); mesg.msg_control = &msgpi4; @@ -2991,12 +3023,23 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, mesg.msg_flags = 0; cmsg = CMSG_FIRSTHDR (&mesg); cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); +#ifdef HAVE_IN_PKTINFO cmsg->cmsg_level = SOL_IP; cmsg->cmsg_type = IP_PKTINFO; + { + struct in_pktinfo *pkti; pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; pkti->ipi_addr.s_addr = 0; + } +#elif defined(IP_RECVDSTADDR) + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_RECVDSTADDR; + *(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4; +#else +#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) +#endif break; } #ifdef USE_PF_INET6 -- cgit From 86093c1cb434f448253cc8c7da4481dca320cafc Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Fri, 25 Mar 2011 14:51:33 +0100 Subject: * ipv6-0.4.15b: rebase over openvpn-testing-master --- socket.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 7efdf3a..7cd6276 100644 --- a/socket.c +++ b/socket.c @@ -52,12 +52,13 @@ const int proto_overhead[] = { /* indexed by PROTO_x */ * Convert sockflags/getaddr_flags into getaddr_flags */ static unsigned int -sf2gaf(unsigned int getaddr_flags, +sf2gaf(const unsigned int getaddr_flags, const unsigned int sockflags) { - getaddr_flags |= (sockflags & SF_GETADDRINFO_DGRAM) ? GETADDR_DGRAM : 0; - getaddr_flags |= (sockflags & SF_HOST_RANDOMIZE) ? GETADDR_RANDOMIZE : 0; - return getaddr_flags; + if (sockflags & SF_HOST_RANDOMIZE) + return getaddr_flags | GETADDR_RANDOMIZE; + else + return getaddr_flags; } /* @@ -2440,11 +2441,11 @@ print_sockaddr_ex (const struct openvpn_sockaddr *addr, { const int port= ntohs (addr->addr.in4.sin_port); buf_puts (&out, "[AF_INET]"); - mutex_lock_static (L_INET_NTOA); - buf_puts (&out, (addr_is_defined ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); - mutex_unlock_static (L_INET_NTOA); - if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) + if (!(flags & PS_DONT_SHOW_ADDR)) + buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); + + if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED))) && port) { if (separator) @@ -2590,9 +2591,7 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openv else openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); - mutex_lock_static (L_INET_NTOA); setenv_str (es, name_buf, inet_ntoa (addr->addr.in4.sin_addr)); - mutex_unlock_static (L_INET_NTOA); if ((flags & SA_IP_PORT) && addr->addr.in4.sin_port) { @@ -2607,8 +2606,11 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openv buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); setenv_str (es, name_buf, buf); - openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); - setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); + if ((flags & SA_IP_PORT) && addr->addr.in6.sin6_port) + { + openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); + setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); + } break; } #endif -- cgit From 6dbf82a96253add5ed5f6c923080f4de4366c874 Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Sun, 27 Mar 2011 23:41:22 +0200 Subject: * ipv6-0.4.16: fix mingw32 build --- socket.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'socket.c') diff --git a/socket.c b/socket.c index 7cd6276..1059d3a 100644 --- a/socket.c +++ b/socket.c @@ -2490,6 +2490,10 @@ print_link_socket_actual (const struct link_socket_actual *act, struct gc_arena return print_link_socket_actual_ex (act, ":", PS_SHOW_PORT|PS_SHOW_PKTINFO, gc); } +#ifndef IF_NAMESIZE +#define IF_NAMESIZE 16 +#endif + const char * print_link_socket_actual_ex (const struct link_socket_actual *act, const char *separator, -- cgit