-
Notifications
You must be signed in to change notification settings - Fork 43
Dial from a port we're listening on #8
Comments
I’m not exactly sure how the reuseport-transport works, but I think there’s an even better solution with QUIC. Since QUIC connections are identified by a connection ID, we can use a single port for all outgoing connections. I’ve been working on a set of changes to make this possible in quic-go (quic-go/quic-go#1324), and I’m expecting to merge these next week or so. |
Nice! So, my point about reuseport-transport is that it can handle the case where we're listening on multiple ports. That is, users may listen on |
Ok, that makes sense. |
Thinking through this a bit, the approach we're currently using in go-reuseport-transport won't work. If a libp2p node is configured to listen on some unicast IP X and then tries to dial a unicast IP Y, that may fail with both #34 and #44 as there may be no route from X to Y. go-reuseport-transport works around this by:
The trick is dialing from 0.0.0.0 instead of X. Unfortunately, we can't reuse this same trick for QUIC because we don't want to open a new file descriptor bound to 0.0.0.0. The only solution I can think of is to do this the right way and use netlink. See: libp2p/go-reuseport-transport#2 A partial solution would be to reuse the source port if and only if we're listening on 0.0.0.0. |
It may also be possible to use On windows, we'll have to use the |
Could you elaborate it a bit? In my knowledge the routing table is system-wide despite network namespace, I don't understand why there's no route from X to Y when a route between 0.0.0.0 and Y exists. |
IP address X is actually bound to a specific interface. There may be no route through that interface to IP address Y. For example, X could be 10.1.2.3 bound to some VPN interface depending on the VPN's configuration, traffic entering that VPN may not be able to exit it. |
Related: quic-go/quic-go#1736 |
@marten-seemann is that actually an issue? That is, does QUIC care about the source IP address? |
It might cause some problems during the handshake, since migration is only allowed after the handshake. After the handshake, this would just lead to a migration to the new IP address, so as long as the host is also reachable under the new address, things should be fine. All of this requires the mapping to be stable though, if the kernel keeps choosing source IPs by random, things would get very messy. |
I see. Unfortunately, the only clean solution I can think of is:
|
so would you consider the proposed solution by @ironsteel with IP_PKTINFO ? |
That looks like it should work but it also looks harder to implement given the current functions exposed by the standard library. |
How would you like it to be implemented? We can make a pull request with the actual implementation. |
is there any update on this issue? |
@hackman sorry, missed the notification. Looking at @ironsteel's proposal, that actually looks correct. I just didn't think that would be possible without dropping down to manual syscalls (which don't play well with golang's networking stack). @lnykww Status is in quic-go/quic-go#1736. |
@Stebalien And Can we use the logic of go-reuseport-transport to solve this problem? |
@lnykww you're right. Sorry, I haden't fully paged this issue back in. The best solution I can think of for this issue is the netlink approach. And no, there haven't been any updates. |
@Stebalien @marten-seemann |
Without reuseport, we wouldn't even be able to bind to 4.4.4.4. With reuseport, well, I'm not sure. Really, that shouldn't be an issue here. Here, we can:
|
QUIC should try to pick a port we're listening on when dialing instead of opening a new one. We may want to extract some of the logic in https://github.com/libp2p/go-reuseport-transport.
The text was updated successfully, but these errors were encountered: