cqueues icon indicating copy to clipboard operation
cqueues copied to clipboard

UDP server support

Open daurnimator opened this issue 11 years ago • 5 comments

There are a few of things missing before it's possible to write a UDP server with cqueues.

There is currently no binding to recvfrom(2) or recvmsg(2) to allow receiving messages from an un-connected peer. If you call udp_sock:recv() you don't know who the packet came from.

Also see:

  • [x] #20 (.listen() with type DGRAM returns not supported)
  • [x] #22 DTLS over UDP doesn't work

daurnimator avatar Dec 27 '14 06:12 daurnimator

Lacking a better API, it seems reasonable to add a receivefrom method with a similar signature to luasocket: http://w3.impa.br/~diego/software/luasocket/udp.html#receivefrom

Works exactly as the receive method, except it returns the IP address and port as extra return values (and is therefore slightly less efficient).

daurnimator avatar Dec 27 '14 06:12 daurnimator

Alternatively, you could keep the peer's sockaddr inside of the socket object, and update it on each receivefrom() call?

daurnimator avatar Dec 27 '14 06:12 daurnimator

Wanted this again today. I can't seem to find a scriptable DNS server.... so was going to make my own proof of concept.

daurnimator avatar Mar 29 '15 03:03 daurnimator

Alternatively, you could keep the peer's sockaddr inside of the socket object, and update it on each receivefrom() call?

This is what openssl's dgram BIOs do. I think this might be the best way forward.

daurnimator avatar Dec 15 '15 05:12 daurnimator

Hitting my nose today (as seen on IRC): In my case I have multiple udp sockets bound to multiple addresses and ports on v4 or v6 and I receive from multiple sources and I send to multiple destinations using those sockets. Yes, it's a mesh (router/proxy). This makes storing the address into the socket's peer data bad, unless you use the data as a key into a table of peers. In the case of table of peers, it sounds good, the gc will get rid of it when the data has been processed.

I used to do everything with lua-posix, so that was never an issue to me. But cqueues is definitely a higher level of programming. So what do I need:

..:sendto(addrspec,data)
data, addrspec = ..:recvfrom( )
s=socket:bind(addr,port)

In lua-posix I do a poll on the table with sockets and lookup the right things, so I can forward data. In lua-cqueus I want to do a blocking :recvfrom co-routine per socket I am waiting on. It's fine with me when addr is a userdata inet-addr struct or whatever it is called. Or maybe it is even preferred, as you don't have to transform lua strings into a binary struct on each send.

My biggest reason I want this in cqueues is cqueues ability to dns lookup all I need to know: for client server model it can determine v4 vs v6. (Which I still can of course)

Oh, while we are at it: multicast support: in this case we can speak of senders/casters and receivers. Receivers subscribe to the multicast address, I think senders do not really do special things except sending to the right address.

Edit: I do like the idea of doing socket:connect("someserverusingdns","someportusingresolver",DGRAM) for easy fast "client" coding.

ardje avatar Sep 14 '18 08:09 ardje