From 6d1b80bdeb5e0df3dee6a8bc05d7e3f622371c1c Mon Sep 17 00:00:00 2001 From: JuanJo Ciarlante Date: Thu, 24 Sep 2009 20:09:55 +0200 Subject: [PATCH] * correctly setup hints.ai_socktype for getaddrinfo(), althought sorta hacky, see TODO.ipv6. --- README.ipv6.txt | 10 +--------- TODO.ipv6 | 11 +++++++++++ socket.c | 16 ++++++++++------ socket.h | 6 ++++++ 4 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 TODO.ipv6 diff --git a/README.ipv6.txt b/README.ipv6.txt index 3a894f02..f9b61713 100644 --- a/README.ipv6.txt +++ b/README.ipv6.txt @@ -60,15 +60,7 @@ Available under GPLv2 from addr_copy(), addr_zero(), ...etc proto_is_udp(), proto_is_dgram(), proto_is_net() -* TODO: - - Should not use random for listening in IPv6 "by name", as eg - ip6-localhost could return any ifindex, or "randomly" behave as - if it were IPV6_V6ONLY (caught this in my unittesting) - - win32: find out about mapped addresses, as I can't make it work - with bound at ::1 and connect to 127.0.0.1 - - Implement comparison for mapped addesses: server in dual stack - listening IPv6 must permit incoming streams from allowed IPv4 peer, - currently you need to pass eg: --remote ffff::1.2.3.4 +* TODO: See TODO.ipv6 -- JuanJo Ciarlante jjo () google () com diff --git a/TODO.ipv6 b/TODO.ipv6 new file mode 100644 index 00000000..c19e42cc --- /dev/null +++ b/TODO.ipv6 @@ -0,0 +1,11 @@ +* make possible to get AF from getaddrinfo() answer, ie allow openvpn to + use ipv4/6 if DNS returns A/AAAA without specifying protocol. + Hard: requires deep changes in initialization/calling logic +* the getaddr()/getaddr6() interface is not prepared for handling socktype + "tagging", currently I abuse the sockflags bits for getting the ai_socktype + downstream. +* win32: find out about mapped addresses, as I can't make it work + with bound at ::1 and connect to 127.0.0.1 +* implement comparison for mapped addesses: server in dual stack + listening IPv6 must permit incoming streams from allowed IPv4 peer, + currently you need to pass eg: --remote ffff::1.2.3.4 diff --git a/socket.c b/socket.c index 3024ea4e..96d26026 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, diff --git a/socket.h b/socket.h index 092d448f..f864ab19 100644 --- a/socket.h +++ b/socket.h @@ -210,6 +210,7 @@ struct link_socket # define SF_TCP_NODELAY (1<<1) # define SF_PORT_SHARE (1<<2) # define SF_HOST_RANDOMIZE (1<<3) +# define SF_GETADDRINFO_DGRAM (1<<4) unsigned int sockflags; /* for stream sockets */ @@ -474,6 +475,11 @@ struct resolve_list { #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8) #define GETADDR_RANDOMIZE (1<<9) +/* [ab]use flags bits to get socktype info downstream */ +/* TODO(jjo): resolve tradeoff between hackiness|args-overhead */ +#define GETADDR_DGRAM (1<<10) +#define dnsflags_to_socktype(flags) ((flags & GETADDR_DGRAM) ? SOCK_DGRAM : SOCK_STREAM) + in_addr_t getaddr (unsigned int flags, const char *hostname, int resolve_retry_seconds,