Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Some love for UDP and IPv6 #1205

Closed
4 tasks done
saghul opened this issue Mar 18, 2014 · 5 comments
Closed
4 tasks done

Some love for UDP and IPv6 #1205

saghul opened this issue Mar 18, 2014 · 5 comments

Comments

@saghul
Copy link
Contributor

saghul commented Mar 18, 2014

While working on adding IPv6 support to uv_udp_set_membership I noticed some inconsistencies / missing stuff in the UDP support which I plan to fix. Here is the list of things I'll be working on:

  • Extend uv_udp_bind to accept a UV_UDP_REUSEADDR flag and don't set SO_REUSEADDR by default.
  • Add IPv6 support to uv_udp_set_multicast_interface
  • Only do implicit binding on uv_udp_set_membership (binding to 'any' and setting UV_UDP_REUSEADDR, other uv_udp_set_* functions should probably return UV_EBADF. Currently Windows does implicit binding but Unix doesn't. I wonder if uv_udp_send and uv_recv_start shouldn't bind the socket either. Review where implicit binding happens and align Unxi and Windows.
  • Mark handles which were created with AF_INET6 with some flag, like Windows does.

Comments are welcome! /cc @indutny @bnoordhuis.

@bnoordhuis
Copy link
Contributor

I wonder if uv_udp_send and uv_recv_start shouldn't bind the socket either.

There is no real need for that, I think, you just need a valid socket file descriptor. UDP sockets on POSIX platforms are always implicitly bound to some address/port combo.

(I suppose that also applies to uv_udp_set_membership().)

@saghul
Copy link
Contributor Author

saghul commented Mar 18, 2014

There is no real need for that, I think, you just need a valid socket file descriptor. UDP sockets on POSIX platforms are always implicitly bound to some address/port combo.

(I suppose that also applies to uv_udp_set_membership().)

But until we bind to it the fd will be -1, won't it? We already to the implicit bind on uv_udp_send: https://github.com/joyent/libuv/blob/master/src/unix/udp.c#L405-L407 (also on `uv_udp_recv_start).

I was thinking about removing it, so the user is forced to bind it explicitly. That way, there would only be 2 ways to bind a socket: uv_udp_bind and uv_udp_set_membership, which would bind it to the 'any' address. What do you think?

@bnoordhuis
Copy link
Contributor

But until we bind to it the fd will be -1, won't it?

In the current implementation, yes. But you don't have to bind a socket in order for it to be usable: just socket(AF_INET, SOCK_DGRAM, 0) is enough to be able to call sendmsg() or whatever. You can bind it later if so desired.

I don't recall what the reason is for the current bind behavior. It was a long time ago and it's quite possible the choice for that approach was completely arbitrary but I imagine it has to do with the fact that getsockname() reports 0.0.0.0:0 until you start using the socket, either by sending data or by binding it. Libuv currently forces the issue with an implicit bind.

I was thinking about removing it, so the user is forced to bind it explicitly. That way, there would only be 2 ways to bind a socket: uv_udp_bind and uv_udp_set_membership, which would bind it to the 'any' address. What do you think?

That seems reasonable but as pointed out above, binding in uv_udp_set_membership() isn't really necessary, just creating the socket is enough.

@saghul
Copy link
Contributor Author

saghul commented Mar 18, 2014

In the current implementation, yes. But you don't have to bind a socket in order for it to be usable: just socket(AF_INET, SOCK_DGRAM, 0) is enough to be able to call sendmsg() or whatever. You can bind it later if so desired.

Indeed. We now seem to always create + bind the socket.

I don't recall what the reason is for the current bind behavior. It was a long time ago and it's quite possible the choice for that approach was completely arbitrary but I imagine it has to do with the fact that getsockname() reports 0.0.0.0:0 until you start using the socket, either by sending data or by binding it. Libuv currently forces the issue with an implicit bind.

Maybe it also had to do with the fact that if you create the socket early you'd need to get the family in uv_udp_init or something.

That seems reasonable but as pointed out above, binding in uv_udp_set_membership() isn't really necessary, just creating the socket is enough.

Not sure if it could be a problem, but my idea was to set SO_REUSEADDR if the socket wasn't already bound here. So, if a socket is implicitly bound by joining a multicast group it would always be bound to any address and use SO_REUSEADDR. If the user doesn't want this he could always bind first and join the group after.

I'll take a stab at the implementation and see how it feels like :-) Thanks for your comments Ben!

@saghul
Copy link
Contributor Author

saghul commented May 8, 2014

We are done here!

Note to self: fix #150.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants