Opened 11 years ago

Closed 10 years ago

#327 closed Bug / Defect (fixed)

[PATCH] multihome mode doesn't work on FreeBSD

Reported by: Dan Nelson Owned by: Gert Döring
Priority: minor Milestone: release 2.3.4
Component: Networking Version: OpenVPN 2.3.2 (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords:
Cc: plaisthos

Description

Socket.c has some #ifdefs to cover both the Linux and BSD extensions for setting both the source and destination IP address when sending UDP packets. The link_socket_write_udp_posix_sendmsg() function uses the wrong length values in the BSD cased, though, which causes sendmsg() to fail with the EINVAL error. The fix is to move the setting of mesg.msg_controllen and cmsg->cmsg_len into the #ifdef blocks.

Attachments (2)

patch-dn-socket.diff (1.1 KB) - added by Dan Nelson 11 years ago.
use the correct length values for BSD's sendmsg()
0001-Repair-multihome-on-FreeBSD-for-IPv4-sockets.patch (1.9 KB) - added by Gert Döring 10 years ago.

Download all attachments as: .zip

Change History (9)

Changed 11 years ago by Dan Nelson

Attachment: patch-dn-socket.diff added

use the correct length values for BSD's sendmsg()

comment:1 Changed 11 years ago by Gert Döring

Owner: set to Gert Döring
Status: newassigned

At first glance, this looks reasonable. Can you point me at the relevant FreeBSD manpage to read up how the arguments should be?

Integrating this patch is going to be a bit more time consuming, as I'll need to figure out which platforms are using this particular code section (NetBSD, OpenBSD?, ...) and test --multihome on each.

comment:2 Changed 11 years ago by Dan Nelson

The FreeBSD manpage describing IP_RECVDSTADDR is readable here: http://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4

The CMSG_SPACE macro that I used doesn't seem to have any official FreeBSD documentation, but there's an OpenBSD manpage with some examples: http://www.openbsd.org/cgi-bin/man.cgi?query=CMSG_SPACE

All of the BSDs, plus OS X would be using this bit of code I think.

comment:3 Changed 10 years ago by plaisthos

Cc: plaisthos added

comment:4 Changed 10 years ago by Gert Döring

Milestone: release 2.3.3

there's also #306 and #348, but *this* is, as far as I can see, purely IPv4 and only on BSDs. The fix looks easy enough, I "just" need to set a test environment to run server tests on BSD before/after applying this.

comment:5 Changed 10 years ago by Gert Döring

Hi,

so I spent some time today with testing this, and with the patch applied, all I get is a core dump :-o - because with the patch, when "cmsg = CMSG_FIRSTHDR (&mesg);" runs, it returns NULL - seems to dislike a not-yet-set controllen.

Moving cmsg = CMSG_FIRSTHDR (&mesg); into the respective #ifdef clause, after setting mesg.msg_controllen, makes it work nicely for me on FreeBSD 9.1 (didn't test any other BSD yet).

Also, I've added an ASSERT() to ensure that CMSG_SPACE() actually fits into the structure we're using. It should be safe enough (given that that one is a union that can also hold an IPv6 address) but I don't really feel save enough here.

(JFTR, the CMSG_SPACE and CMSG_LEN macros are actually introduced by the socket API extentions in RFC 2292 - the FreeBSD headers point there, and it's good reading :-) )

Modified patch appended for review...

comment:6 Changed 10 years ago by Gert Döring

Milestone: release 2.3.3release 2.3.4

I'm not sure if anyone ever got the mail from trac about the patch, but as it "worksforme" and looks "obviously correct", and nobody complained about on the openvpn-devel list, I've just committed and pushed it.

Will be in the upcoming 2.3.4 release, and in 2.4

commit 661d914c8732a208580b1eab167255c85da162c9 (master)
commit fc759c2eb4fbf0792d0052966fcf36efebc5bf5d (release/2.3)

I'll leave this ticket open a few more days so you can yell at me if it's not working - will close next friday.

comment:7 Changed 10 years ago by Gert Döring

Resolution: fixed
Status: assignedclosed

2.3.4 will be released today (git has been tagged on wednesday already). I think it's solved, closing the ticket.

Re-open if you disagree :-)

Note: See TracTickets for help on using tickets.