[dns-operations] Using IP_RECVERR/IPV6_RECVERR on resolver client sockets
Paul Wouters
paul at nohats.ca
Wed Jan 9 00:04:16 UTC 2019
On Tue, 8 Jan 2019, Florian Weimer wrote:
> Subject: [dns-operations] Using IP_RECVERR/IPV6_RECVERR on resolver client
> sockets
>
> Someone noticed that the Linux kernel only puts some networking-related
> errors on the socket error queue for connected UDP sockets:
>
> <https://sourceware.org/bugzilla/show_bug.cgi?id=24047>
Here, let me show you my 20 year old scar:
https://github.com/libreswan/libreswan/blob/master/programs/pluto/server.c#L1120
/* Process any message on the MSG_ERRQUEUE
*
* This information is generated because of the IP_RECVERR socket option.
* The API is sparsely documented, and may be LINUX-only, and only on
* fairly recent versions at that (hence the conditional compilation).
*
* - ip(7) describes IP_RECVERR
* - recvmsg(2) describes MSG_ERRQUEUE
* - readv(2) describes iovec
* - cmsg(3) describes how to process auxiliary messages
*
* ??? we should link this message with one we've sent
* so that the diagnostic can refer to that negotiation.
*
* ??? how long can the messge be?
*
* ??? poll(2) has a very incomplete description of the POLL* events.
* We assume that POLLIN, POLLOUT, and POLLERR are all we need to deal with
* and that POLLERR will be on iff there is a MSG_ERRQUEUE message.
*
* We have to code around a couple of surprises:
*
* - Select can say that a socket is ready to read from, and
* yet a read will hang. It turns out that a message available on the
* MSG_ERRQUEUE will cause select to say something is pending, but
* a normal read will hang. poll(2) can tell when a MSG_ERRQUEUE
* message is pending.
*
* This is dealt with by calling check_msg_errqueue after select
* has indicated that there is something to read, but before the
* read is performed. check_msg_errqueue will return TRUE if there
* is something left to read.
* A write to a socket may fail because there is a pending MSG_ERRQUEUE
* message, without there being anything wrong with the write. This
* makes for confusing diagnostics.
*
* To avoid this, we call check_msg_errqueue before a write. True,
* there is a race condition (a MSG_ERRQUEUE message might arrive
* between the check and the write), but we should eliminate many
* of the problematic events. To narrow the window, the poll(2)
* will await until an event happens (in the case or a write,
* POLLOUT; this should be benign for POLLIN).
*/
Paul
More information about the dns-operations
mailing list