* 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
This commit is contained in:
JuanJo Ciarlante 2011-03-22 21:59:23 +01:00
parent c47fd4b35c
commit d3774cdf1e
3 changed files with 57 additions and 3 deletions

View file

@ -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

View file

@ -86,7 +86,12 @@ struct link_socket_actual
struct openvpn_sockaddr dest;
#if ENABLE_IP_PKTINFO
union {
#ifdef HAVE_IN_PKTINFO
struct in_pktinfo in4;
#endif
#ifdef IP_RECVDSTADDR
struct in_addr in4;
#endif
#ifdef USE_PF_INET6
struct in6_pktinfo in6;
#endif
@ -594,7 +599,12 @@ addr_defined_ipi (const struct link_socket_actual *lsa)
#if ENABLE_IP_PKTINFO
if (!lsa) return 0;
switch (lsa->dest.addr.sa.sa_family) {
#ifdef HAVE_IN_PKTINFO
case AF_INET: return lsa->pi.in4.ipi_spec_dst.s_addr != 0;
#endif
#ifdef IP_RECVDSTADDR
case AF_INET: return lsa->pi.in4.s_addr != 0;
#endif
#ifdef USE_PF_INET6
case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&lsa->pi.in6.ipi6_addr);
#endif

View file

@ -390,9 +390,10 @@
#endif
/*
* Does this platform support linux-style IP_PKTINFO?
* Does this platform support linux-style IP_PKTINFO
* or bsd-style IP_RECVDSTADDR ?
*/
#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
#if defined(ENABLE_MULTIHOME) && ((defined(HAVE_IN_PKTINFO)&&defined(IP_PKTINFO)) || defined(IP_RECVDSTADDR)) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
#define ENABLE_IP_PKTINFO 1
#else
#define ENABLE_IP_PKTINFO 0