The code in link_socket_write_udp_posix_sendmsg() for the IP_RECVDESTADDR
case was sending a too-large control message (sizeof openvpn_pktinfo,
which is a union for IPv4+IPv6) instead of just openvpn_in4_pktinfo,
leading to sendmsg() refusing to send the packet.
Use RFC 2292 macros for alignment + size calculation.
Fix trac#327
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Lazy-Ack-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1390164697-1590-1-git-send-email-gert@greenie.muc.de>
URL: http://article.gmane.org/gmane.network.openvpn.devel/8250
(cherry picked from commit 661d914c8732a208580b1eab167255c85da162c9)
... | ... |
@@ -2801,11 +2801,11 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, |
2801 | 2801 |
mesg.msg_name = &to->dest.addr.sa; |
2802 | 2802 |
mesg.msg_namelen = sizeof (struct sockaddr_in); |
2803 | 2803 |
mesg.msg_control = &opi; |
2804 |
- mesg.msg_controllen = sizeof (struct openvpn_in4_pktinfo); |
|
2805 | 2804 |
mesg.msg_flags = 0; |
2805 |
+#ifdef HAVE_IN_PKTINFO |
|
2806 |
+ mesg.msg_controllen = sizeof (struct openvpn_in4_pktinfo); |
|
2806 | 2807 |
cmsg = CMSG_FIRSTHDR (&mesg); |
2807 | 2808 |
cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); |
2808 |
-#ifdef HAVE_IN_PKTINFO |
|
2809 | 2809 |
cmsg->cmsg_level = SOL_IP; |
2810 | 2810 |
cmsg->cmsg_type = IP_PKTINFO; |
2811 | 2811 |
{ |
... | ... |
@@ -2816,6 +2816,10 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, |
2816 | 2816 |
pkti->ipi_addr.s_addr = 0; |
2817 | 2817 |
} |
2818 | 2818 |
#elif defined(IP_RECVDSTADDR) |
2819 |
+ ASSERT( CMSG_SPACE(sizeof (struct in_addr)) <= sizeof(opi) ); |
|
2820 |
+ mesg.msg_controllen = CMSG_SPACE(sizeof (struct in_addr)); |
|
2821 |
+ cmsg = CMSG_FIRSTHDR (&mesg); |
|
2822 |
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); |
|
2819 | 2823 |
cmsg->cmsg_level = IPPROTO_IP; |
2820 | 2824 |
cmsg->cmsg_type = IP_RECVDSTADDR; |
2821 | 2825 |
*(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4; |