From: James Yonan <james@openvpn.net>
To: netdev@vger.kernel.org
Subject: UDP "accept" proposed
Date: Tue, 18 Jun 2013 02:48:26 -0600 [thread overview]
Message-ID: <51C01EDA.30705@openvpn.net> (raw)
One of the frustrations of creating UDP servers using BSD sockets is
that there isn't an easy way for a server to pass off a socket for a
particular client instance to a handler thread or process.
By contrast, with TCP you can "accept" an incoming connection, and pass
the socket representing that connection off to any arbitrary handler.
But UDP servers that want to play well with stateful firewalls and NAT
are forced to aggregate their entire connection pool onto a single
socket, since BSD sockets don't have the equivalent of an "accept"
mechanism to provide a connection-specific socket.
This is a disaster from a performance perspective because you can't take
a UDP server that binds to a single port and efficiently scale it up
across multiple threads or processors because you must operate off a
single socket.
So why can't I "accept" a UDP socket? The conventional response would
be that UDP is connectionless and that "accept" is meaningless outside
the context of a connection. UDP may be connectionless, but it's not
stateless. The tuple of (local address/port, remote address/port)
concisely defines the state of a UDP session between a client and
server. Netfilter connection tracking recognizes this statefulness, but
unfortunately BSD sockets do not.
I would like to propose that Linux adds a userspace API method to allow
UDP sockets to be "accepted":
int accept_udp(int sockfd, const struct sockaddr *addr, socklen_t
*addrlen, int flags)
accept_udp will return a new UDP socket which is bound to the original
local address/port of sockfd but which is additionally bound to the
source address/port denoted by addr. This socket will only receive
datagrams having a source address of addr, and when used with send(),
will transmit datagrams to addr.
This socket, while open, will have priority in the sense of receiving
any datagrams having a source address of addr that would normally have
been received by sockfd. When closed, datagrams from addr will revert
to being received by sockfd.
This abstraction allows UDP servers to follow the same scalable event
loop as TCP servers, i.e. bind to local socket, then:
1. recvfrom to read a packet
2. call accept_udp on socket, passing the source address of packet read
in (1)
3. pass the return socket of accept_udp to a handler thread
4. repeat
This would require the UDP implementation in the kernel to understand
how to dispatch incoming UDP datagrams to sockets based on the tuple of
(source addr, local addr) rather than just local addr as is currently
the case.
But this would be a huge performance win for UDP servers (I'm thinking
about OpenVPN in particular) because making the kernel smarter about
dispatching UDP datagrams would make it much easier to develop scalable
UDP servers on Linux.
James
next reply other threads:[~2013-06-18 9:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-18 8:48 James Yonan [this message]
2013-06-18 9:52 ` UDP "accept" proposed Daniel Borkmann
2013-06-18 10:17 ` Eric Dumazet
2013-06-18 10:41 ` Daniel Borkmann
2013-06-18 9:54 ` David Laight
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51C01EDA.30705@openvpn.net \
--to=james@openvpn.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).