Author baikie
Recipients baikie, exarkun, giampaolo.rodola, jackdied, synapse, therve, wiml
Date 2010-05-28.19:09:47
SpamBayes Score 0.0623035
Marked as misclassified No
Message-id <1275073806.38.0.770578164309.issue6560@psf.upfronthosting.co.za>
In-reply-to
Content
Here is a new version of the patch; I've added some tests which
use the RFC 3542 interface (IPv6 advanced API) and am now quite
happy with it generally.

As well as Linux, I've tested it on an old (unsupported) FreeBSD
5.3 installation, which required a few changes in the tests and
the code, but is probably representative of many socket
implementations.  Testing on other systems would be appreciated!

The main issue was that when truncating ancillary data, FreeBSD
seemed to just copy as much into the buffer as would fit and did
not adjust the last item's cmsg_len member to reflect the amount
of data that was actually present, so the item would appear to
extend past the end of the buffer.  The last version of the patch
detected this and raised RuntimeError, which prevented any
truncated receives from succeeding.  The new version instead
issues a warning and returns as much of the last item as is in
the buffer.

The warning could perhaps be disabled for systems like this,
given that it happens every time ancillary data is truncated, but
truncation generally shouldn't happen in a program's normal
operation, and on other platforms a bad cmsg_len value might
indicate that the returned data is actually incorrect in some
way.


After some investigation, I've stuck with using CMSG_FIRSTHDR()
and CMSG_NXTHDR() to step through the headers when assembling the
ancillary data in sendmsg().

The KAME IPv6 userspace utilities at [1] include several programs
which send multiple control messages at once, and these always
use CMSG_NXTHDR() to advance to the next uninitialized header,
while some (but not all) of them zero-fill the buffer beforehand,
suggesting they ran into the issue with glibc's macros returning
NULL (KAME developed the BSD IPv6 stack, and the zero-filling
isn't necessary with the BSD macros).

The alternative would be to add CMSG_SPACE(size) to the pointer
to get to the next header.  Going by the diagram in RFC 3542,
that should be equivalent, but if some system defined
CMSG_SPACE(len) as, say, CMSG_LEN(len) + 3, instead of
(CMSG_LEN(len) + 3) & ~3, it would probably go unnoticed until
someone tried to use CMSG_SPACE() that way.  So given the KAME
example, I think using CMSG_NXTHDR() with a zero-filled buffer is
the way to go.


[1] http://www.kame.net/dev/cvsweb2.cgi/kame/kame/kame/
History
Date User Action Args
2010-05-28 19:10:07baikiesetrecipients: + baikie, exarkun, therve, jackdied, giampaolo.rodola, synapse, wiml
2010-05-28 19:10:06baikiesetmessageid: <1275073806.38.0.770578164309.issue6560@psf.upfronthosting.co.za>
2010-05-28 19:10:05baikielinkissue6560 messages
2010-05-28 19:10:04baikiecreate