Let socket_create take struct addrinfo as argument and use the entries of
addrinfo to create the socket.
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1395407925-25518-11-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/8370
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -1568,7 +1568,7 @@ man_listen (struct management *man) |
1568 | 1568 |
else |
1569 | 1569 |
#endif |
1570 | 1570 |
{ |
1571 |
- man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family); |
|
1571 |
+ man->connection.sd_top = create_socket_tcp (man->settings.local); |
|
1572 | 1572 |
socket_bind (man->connection.sd_top, man->settings.local, |
1573 | 1573 |
man->settings.local->ai_family, "MANAGEMENT", false); |
1574 | 1574 |
} |
... | ... |
@@ -1635,7 +1635,7 @@ man_connect (struct management *man) |
1635 | 1635 |
else |
1636 | 1636 |
#endif |
1637 | 1637 |
{ |
1638 |
- man->connection.sd_cli = create_socket_tcp (AF_INET); |
|
1638 |
+ man->connection.sd_cli = create_socket_tcp (man->settings.local); |
|
1639 | 1639 |
status = openvpn_connect (man->connection.sd_cli, |
1640 | 1640 |
man->settings.local->ai_addr, |
1641 | 1641 |
5, |
... | ... |
@@ -769,11 +769,15 @@ link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf) |
769 | 769 |
*/ |
770 | 770 |
|
771 | 771 |
socket_descriptor_t |
772 |
-create_socket_tcp (int af) |
|
772 |
+create_socket_tcp (struct addrinfo* addrinfo) |
|
773 | 773 |
{ |
774 | 774 |
socket_descriptor_t sd; |
775 | 775 |
|
776 |
- if ((sd = socket (af, SOCK_STREAM, IPPROTO_TCP)) < 0) |
|
776 |
+ ASSERT (addrinfo); |
|
777 |
+ ASSERT (addrinfo->ai_socktype == SOCK_STREAM); |
|
778 |
+ ASSERT (addrinfo->ai_protocol == IPPROTO_TCP); |
|
779 |
+ |
|
780 |
+ if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0) |
|
777 | 781 |
msg (M_ERR, "Cannot create TCP socket"); |
778 | 782 |
|
779 | 783 |
#ifndef WIN32 /* using SO_REUSEADDR on Windows will cause bind to succeed on port conflicts! */ |
... | ... |
@@ -790,17 +794,21 @@ create_socket_tcp (int af) |
790 | 790 |
} |
791 | 791 |
|
792 | 792 |
static socket_descriptor_t |
793 |
-create_socket_udp (const int af, const unsigned int flags) |
|
793 |
+create_socket_udp (struct addrinfo* addrinfo, const unsigned int flags) |
|
794 | 794 |
{ |
795 | 795 |
socket_descriptor_t sd; |
796 | 796 |
|
797 |
- if ((sd = socket (af, SOCK_DGRAM, IPPROTO_UDP)) < 0) |
|
797 |
+ ASSERT (addrinfo); |
|
798 |
+ ASSERT (addrinfo->ai_socktype == SOCK_DGRAM); |
|
799 |
+ ASSERT (addrinfo->ai_protocol == IPPROTO_UDP); |
|
800 |
+ |
|
801 |
+ if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0) |
|
798 | 802 |
msg (M_ERR, "UDP: Cannot create UDP/UDP6 socket"); |
799 | 803 |
#if ENABLE_IP_PKTINFO |
800 | 804 |
else if (flags & SF_USE_IP_PKTINFO) |
801 | 805 |
{ |
802 | 806 |
int pad = 1; |
803 |
- if(af == AF_INET) |
|
807 |
+ if(addrinfo->ai_family == AF_INET) |
|
804 | 808 |
{ |
805 | 809 |
#ifdef IP_PKTINFO |
806 | 810 |
if (setsockopt (sd, SOL_IP, IP_PKTINFO, |
... | ... |
@@ -814,7 +822,7 @@ create_socket_udp (const int af, const unsigned int flags) |
814 | 814 |
#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) |
815 | 815 |
#endif |
816 | 816 |
} |
817 |
- else if (af == AF_INET6 ) |
|
817 |
+ else if (addrinfo->ai_family == AF_INET6 ) |
|
818 | 818 |
{ |
819 | 819 |
#ifndef IPV6_RECVPKTINFO /* Some older Darwin platforms require this */ |
820 | 820 |
if (setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO, |
... | ... |
@@ -830,28 +838,49 @@ create_socket_udp (const int af, const unsigned int flags) |
830 | 830 |
return sd; |
831 | 831 |
} |
832 | 832 |
|
833 |
-static void |
|
834 |
-create_socket (struct link_socket *sock) |
|
833 |
+static void bind_local (struct link_socket *sock, const sa_family_t ai_family) |
|
835 | 834 |
{ |
836 |
- /* create socket, use information carried over from getaddrinfo */ |
|
837 |
- const int ai_proto = sock->info.lsa->actual.ai_protocol; |
|
838 |
- int ai_family = sock->info.lsa->actual.ai_family; |
|
839 |
- |
|
840 |
- ASSERT (sock->info.af == AF_UNSPEC || sock->info.af == ai_family); |
|
835 |
+ /* bind to local address/port */ |
|
836 |
+ if (sock->bind_local) |
|
837 |
+ { |
|
838 |
+#ifdef ENABLE_SOCKS |
|
839 |
+ if (sock->socks_proxy && sock->info.proto == PROTO_UDP) |
|
840 |
+ socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local, |
|
841 |
+ ai_family, "SOCKS", false); |
|
842 |
+ else |
|
843 |
+#endif |
|
844 |
+ socket_bind (sock->sd, sock->info.lsa->bind_local, |
|
845 |
+ ai_family, |
|
846 |
+ "TCP/UDP", sock->info.bind_ipv6_only); |
|
847 |
+ } |
|
848 |
+} |
|
841 | 849 |
|
842 |
- if (ai_proto == IPPROTO_UDP) |
|
850 |
+static void |
|
851 |
+create_socket (struct link_socket* sock, struct addrinfo* addr) |
|
852 |
+{ |
|
853 |
+ if (addr->ai_protocol == IPPROTO_UDP) |
|
843 | 854 |
{ |
844 |
- sock->sd = create_socket_udp (ai_family, sock->sockflags); |
|
855 |
+ sock->sd = create_socket_udp (addr, sock->sockflags); |
|
845 | 856 |
sock->sockflags |= SF_GETADDRINFO_DGRAM; |
846 | 857 |
|
847 | 858 |
#ifdef ENABLE_SOCKS |
859 |
+ /* Assume that control socket and data socket to the socks proxy |
|
860 |
+ * are using the same IP family */ |
|
848 | 861 |
if (sock->socks_proxy) |
849 |
- sock->ctrl_sd = create_socket_tcp (ai_family); |
|
862 |
+ { |
|
863 |
+ /* Construct a temporary addrinfo to create the socket, |
|
864 |
+ * currently resolve two remote addresses is not supported, |
|
865 |
+ * TODO: Rewrite the whole resolve_remote */ |
|
866 |
+ struct addrinfo addrinfo_tmp = *addr; |
|
867 |
+ addrinfo_tmp.ai_socktype = SOCK_STREAM; |
|
868 |
+ addrinfo_tmp.ai_protocol = IPPROTO_TCP; |
|
869 |
+ sock->ctrl_sd = create_socket_tcp (&addrinfo_tmp); |
|
870 |
+ } |
|
850 | 871 |
#endif |
851 | 872 |
} |
852 |
- else if (ai_proto == IPPROTO_TCP) |
|
873 |
+ else if (addr->ai_protocol == IPPROTO_TCP) |
|
853 | 874 |
{ |
854 |
- sock->sd = create_socket_tcp (ai_family); |
|
875 |
+ sock->sd = create_socket_tcp (addr); |
|
855 | 876 |
} |
856 | 877 |
else |
857 | 878 |
{ |
... | ... |
@@ -862,6 +891,8 @@ create_socket (struct link_socket *sock) |
862 | 862 |
|
863 | 863 |
/* set socket to --mark packets with given value */ |
864 | 864 |
socket_set_mark (sock->sd, sock->mark); |
865 |
+ |
|
866 |
+ bind_local (sock, addr->ai_family); |
|
865 | 867 |
} |
866 | 868 |
|
867 | 869 |
#ifdef TARGET_ANDROID |
... | ... |
@@ -1207,21 +1238,15 @@ void set_actual_address (struct link_socket_actual* actual, struct addrinfo* ai) |
1207 | 1207 |
else |
1208 | 1208 |
ASSERT(0); |
1209 | 1209 |
|
1210 |
- /* Copy addrinfo sock parameters for socket creating */ |
|
1211 |
- actual->ai_family = ai->ai_family; |
|
1212 |
- actual->ai_protocol = ai->ai_protocol; |
|
1213 |
- actual->ai_socktype = ai->ai_socktype; |
|
1214 | 1210 |
} |
1215 | 1211 |
|
1216 | 1212 |
void |
1217 |
-socket_connect (socket_descriptor_t *sd, |
|
1218 |
- struct link_socket_addr *lsa, |
|
1213 |
+socket_connect (socket_descriptor_t* sd, |
|
1214 |
+ const struct sockaddr* dest, |
|
1219 | 1215 |
const int connect_timeout, |
1220 | 1216 |
struct signal_info* sig_info) |
1221 | 1217 |
{ |
1222 | 1218 |
struct gc_arena gc = gc_new (); |
1223 |
- const struct sockaddr *dest = &lsa->actual.dest.addr.sa; |
|
1224 |
- |
|
1225 | 1219 |
int status; |
1226 | 1220 |
|
1227 | 1221 |
#ifdef CONNECT_NONBLOCK |
... | ... |
@@ -1349,23 +1374,6 @@ resolve_bind_local (struct link_socket *sock, const sa_family_t af) |
1349 | 1349 |
gc_free (&gc); |
1350 | 1350 |
} |
1351 | 1351 |
|
1352 |
-static void bind_local (struct link_socket *sock) |
|
1353 |
-{ |
|
1354 |
- /* bind to local address/port */ |
|
1355 |
- if (sock->bind_local) |
|
1356 |
- { |
|
1357 |
-#ifdef ENABLE_SOCKS |
|
1358 |
- if (sock->socks_proxy && sock->info.proto == PROTO_UDP) |
|
1359 |
- socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local, |
|
1360 |
- sock->info.lsa->actual.ai_family, "SOCKS", false); |
|
1361 |
- else |
|
1362 |
-#endif |
|
1363 |
- socket_bind (sock->sd, sock->info.lsa->bind_local, |
|
1364 |
- sock->info.lsa->actual.ai_family, |
|
1365 |
- "TCP/UDP", sock->info.bind_ipv6_only); |
|
1366 |
- } |
|
1367 |
-} |
|
1368 |
- |
|
1369 | 1352 |
static void |
1370 | 1353 |
resolve_remote (struct link_socket *sock, |
1371 | 1354 |
int phase, |
... | ... |
@@ -1494,30 +1502,6 @@ link_socket_new (void) |
1494 | 1494 |
} |
1495 | 1495 |
|
1496 | 1496 |
void |
1497 |
-create_new_socket (struct link_socket* sock) |
|
1498 |
-{ |
|
1499 |
- if (sock->bind_local) { |
|
1500 |
- resolve_bind_local (sock, sock->info.af); |
|
1501 |
- } |
|
1502 |
- resolve_remote (sock, 1, NULL, NULL); |
|
1503 |
- |
|
1504 |
- /* |
|
1505 |
- * In P2P or server mode we must create the socket even when resolving |
|
1506 |
- * the remote site fails/is not specified. */ |
|
1507 |
- |
|
1508 |
- if (sock->info.lsa->actual.ai_family==0 && sock->bind_local) |
|
1509 |
- { |
|
1510 |
- /* Copy sock parameters from bind addr */ |
|
1511 |
- set_actual_address (&sock->info.lsa->actual, sock->info.lsa->bind_local); |
|
1512 |
- /* clear destination set by set_actual_address */ |
|
1513 |
- CLEAR(sock->info.lsa->actual.dest); |
|
1514 |
- } |
|
1515 |
-} |
|
1516 |
- |
|
1517 |
- |
|
1518 |
- |
|
1519 |
-/* bind socket if necessary */ |
|
1520 |
-void |
|
1521 | 1497 |
link_socket_init_phase1 (struct link_socket *sock, |
1522 | 1498 |
const char *local_host, |
1523 | 1499 |
const char *local_port, |
... | ... |
@@ -1658,7 +1642,10 @@ link_socket_init_phase1 (struct link_socket *sock, |
1658 | 1658 |
} |
1659 | 1659 |
else if (mode != LS_MODE_TCP_ACCEPT_FROM) |
1660 | 1660 |
{ |
1661 |
- create_new_socket (sock); |
|
1661 |
+ if (sock->bind_local) { |
|
1662 |
+ resolve_bind_local (sock, sock->info.af); |
|
1663 |
+ } |
|
1664 |
+ resolve_remote (sock, 1, NULL, NULL); |
|
1662 | 1665 |
} |
1663 | 1666 |
} |
1664 | 1667 |
|
... | ... |
@@ -1742,11 +1729,14 @@ linksock_print_addr (struct link_socket *sock) |
1742 | 1742 |
msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true)); |
1743 | 1743 |
else if (sock->bind_local) |
1744 | 1744 |
{ |
1745 |
- /* Socket is always bound on the first matching address */ |
|
1745 |
+ sa_family_t ai_family = sock->info.lsa->actual.dest.addr.sa.sa_family; |
|
1746 |
+ /* Socket is always bound on the first matching address, |
|
1747 |
+ * For bound sockets with no remote addr this is the element of |
|
1748 |
+ * the list */ |
|
1746 | 1749 |
struct addrinfo *cur; |
1747 | 1750 |
for (cur = sock->info.lsa->bind_local; cur; cur=cur->ai_next) |
1748 | 1751 |
{ |
1749 |
- if(cur->ai_family == sock->info.lsa->actual.ai_family) |
|
1752 |
+ if(!ai_family || ai_family == cur->ai_family) |
|
1750 | 1753 |
break; |
1751 | 1754 |
} |
1752 | 1755 |
ASSERT (cur); |
... | ... |
@@ -1815,8 +1805,9 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info) |
1815 | 1815 |
const bool proxy_retry = false; |
1816 | 1816 |
#endif |
1817 | 1817 |
do { |
1818 |
+ ASSERT (sock->info.lsa->current_remote->ai_protocol == IPPROTO_TCP); |
|
1818 | 1819 |
socket_connect (&sock->sd, |
1819 |
- sock->info.lsa, |
|
1820 |
+ sock->info.lsa->current_remote->ai_addr, |
|
1820 | 1821 |
sock->connect_timeout, |
1821 | 1822 |
sig_info); |
1822 | 1823 |
|
... | ... |
@@ -1848,10 +1839,8 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info) |
1848 | 1848 |
#endif |
1849 | 1849 |
if (proxy_retry) |
1850 | 1850 |
{ |
1851 |
- /* TODO (schwabe): This code assumes AF_INET for the proxy socket |
|
1852 |
- * when retrying a connection */ |
|
1853 | 1851 |
openvpn_close_socket (sock->sd); |
1854 |
- sock->sd = create_socket_tcp (AF_INET); |
|
1852 |
+ sock->sd = create_socket_tcp (sock->info.lsa->current_remote); |
|
1855 | 1853 |
} |
1856 | 1854 |
|
1857 | 1855 |
} while (proxy_retry); |
... | ... |
@@ -1863,7 +1852,7 @@ static void |
1863 | 1863 |
phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info) |
1864 | 1864 |
{ |
1865 | 1865 |
socket_connect (&sock->ctrl_sd, |
1866 |
- sock->info.lsa, |
|
1866 |
+ sock->info.lsa->current_remote->ai_addr, |
|
1867 | 1867 |
sock->connect_timeout, |
1868 | 1868 |
sig_info); |
1869 | 1869 |
|
... | ... |
@@ -1935,33 +1924,34 @@ link_socket_init_phase2 (struct link_socket *sock, |
1935 | 1935 |
/* Second chance to resolv/create socket */ |
1936 | 1936 |
resolve_remote (sock, 2, &remote_dynamic, &sig_info->signal_received); |
1937 | 1937 |
|
1938 |
+ /* If a valid remote has been found, create the socket with its addrinfo */ |
|
1939 |
+ if (sock->info.lsa->current_remote) |
|
1940 |
+ create_socket (sock, sock->info.lsa->current_remote); |
|
1941 |
+ |
|
1938 | 1942 |
/* If socket has not already been created create it now */ |
1939 | 1943 |
if (sock->sd == SOCKET_UNDEFINED) |
1940 | 1944 |
{ |
1941 |
- /* If we have no --remote and have still not figured out the |
|
1942 |
- * protocol family to use we will use the first of the bind */ |
|
1943 |
- if (sock->bind_local && sock->info.lsa->bind_local |
|
1944 |
- && !sock->info.lsa->actual.ai_family && !sock->remote_host) |
|
1945 |
- { |
|
1946 |
- msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s", |
|
1947 |
- addr_family_name(sock->info.lsa->bind_local->ai_family)); |
|
1948 |
- set_actual_address(&sock->info.lsa->actual, sock->info.lsa->bind_local); |
|
1949 |
- |
|
1950 |
- } |
|
1945 |
+ /* If we have no --remote and have still not figured out the |
|
1946 |
+ * protocol family to use we will use the first of the bind */ |
|
1951 | 1947 |
|
1952 |
- if (sock->info.lsa->actual.ai_family) |
|
1953 |
- { |
|
1954 |
- create_socket (sock); |
|
1955 |
- } |
|
1956 |
- else |
|
1948 |
+ if (sock->bind_local && !sock->remote_host && sock->info.lsa->bind_local) |
|
1957 | 1949 |
{ |
1958 |
- msg (M_WARN, "Could not determine IPv4/IPv6 protocol"); |
|
1959 |
- sig_info->signal_received = SIGUSR1; |
|
1960 |
- goto done; |
|
1950 |
+ /* Warn if this is because neither v4 or v6 was specified |
|
1951 |
+ * and we should not connect a remote */ |
|
1952 |
+ if (sock->info.af == AF_UNSPEC) |
|
1953 |
+ msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s", |
|
1954 |
+ addr_family_name(sock->info.lsa->bind_local->ai_family)); |
|
1955 |
+ |
|
1956 |
+ create_socket (sock, sock->info.lsa->bind_local); |
|
1961 | 1957 |
} |
1958 |
+ } |
|
1962 | 1959 |
|
1963 |
- if (sock->bind_local) |
|
1964 |
- bind_local(sock); |
|
1960 |
+ /* Socket still undefined, give a warning and abort connection */ |
|
1961 |
+ if (sock->sd == SOCKET_UNDEFINED) |
|
1962 |
+ { |
|
1963 |
+ msg (M_WARN, "Could not determine IPv4/IPv6 protocol"); |
|
1964 |
+ sig_info->signal_received = SIGUSR1; |
|
1965 |
+ goto done; |
|
1965 | 1966 |
} |
1966 | 1967 |
|
1967 | 1968 |
if (sig_info && sig_info->signal_received) |
... | ... |
@@ -2801,6 +2791,7 @@ proto_remote (int proto, bool remote) |
2801 | 2801 |
return "TCPv4_CLIENT"; |
2802 | 2802 |
|
2803 | 2803 |
ASSERT (0); |
2804 |
+ return ""; /* Make the compiler happy */ |
|
2804 | 2805 |
} |
2805 | 2806 |
|
2806 | 2807 |
/* |
... | ... |
@@ -2936,7 +2927,12 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock, |
2936 | 2936 |
from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex; |
2937 | 2937 |
from->pi.in6.ipi6_addr = pkti6->ipi6_addr; |
2938 | 2938 |
} |
2939 |
+ else if (cmsg != NULL) |
|
2940 |
+ { |
|
2941 |
+ msg(M_WARN, "CMSG received that cannot be parsed (cmsg_level=%d, cmsg_type=%d, cmsg=len=%d)", (int)cmsg->cmsg_level, (int)cmsg->cmsg_type, (int)cmsg->cmsg_len ); |
|
2942 |
+ } |
|
2939 | 2943 |
} |
2944 |
+ |
|
2940 | 2945 |
return fromlen; |
2941 | 2946 |
} |
2942 | 2947 |
#endif |
... | ... |
@@ -3003,7 +2999,7 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, |
3003 | 3003 |
iov.iov_len = BLEN (buf); |
3004 | 3004 |
mesg.msg_iov = &iov; |
3005 | 3005 |
mesg.msg_iovlen = 1; |
3006 |
- switch (to->ai_family) |
|
3006 |
+ switch (to->dest.addr.sa.sa_family) |
|
3007 | 3007 |
{ |
3008 | 3008 |
case AF_INET: |
3009 | 3009 |
{ |
... | ... |
@@ -91,10 +91,6 @@ struct cached_dns_entry { |
91 | 91 |
struct link_socket_actual |
92 | 92 |
{ |
93 | 93 |
/*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */ |
94 |
- int ai_family; /* PF_xxx */ |
|
95 |
- int ai_socktype; /* SOCK_xxx */ |
|
96 |
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ |
|
97 |
- |
|
98 | 94 |
|
99 | 95 |
struct openvpn_sockaddr dest; |
100 | 96 |
#if ENABLE_IP_PKTINFO |
... | ... |
@@ -473,7 +469,7 @@ bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn); |
473 | 473 |
bool mac_addr_safe (const char *mac_addr); |
474 | 474 |
bool ipv6_addr_safe (const char *ipv6_text_addr); |
475 | 475 |
|
476 |
-socket_descriptor_t create_socket_tcp (int af); |
|
476 |
+socket_descriptor_t create_socket_tcp (struct addrinfo*); |
|
477 | 477 |
|
478 | 478 |
socket_descriptor_t socket_do_accept (socket_descriptor_t sd, |
479 | 479 |
struct link_socket_actual *act, |