Comments (20)
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.
from go-libp2p-quic-transport.
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 localhost:123
and my_public_addr:345
. We'd want to use port 345 when dialing out. reuseport-transport has a bunch of logic for picking a reasonable source port based on the destination address.
from go-libp2p-quic-transport.
Ok, that makes sense.
We should use that logic once quic-go supports running a listener and a dialer on the same packet conn (quic-go/quic-go#561). It's a kind of complicated issue, so I don't expect to fix it within the next few weeks.
from go-libp2p-quic-transport.
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:
- Picking the best port it can by looking at address types.
- Binding to
0.0.0.0:PORT
instead ofX:PORT
. - Dialing.
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.
from go-libp2p-quic-transport.
It may also be possible to use /proc/net/route
along with the list of interfaces. Unfortunately, netlink
will only work on Linux.
On windows, we'll have to use the GetBestInterface
function (from the windows API), lookup that interface with go, and then figure out if we're listening on any of those interface's addresses.
from go-libp2p-quic-transport.
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.
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.
from go-libp2p-quic-transport.
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.
from go-libp2p-quic-transport.
Related: quic-go/quic-go#1736
from go-libp2p-quic-transport.
@marten-seemann is that actually an issue? That is, does QUIC care about the source IP address?
from go-libp2p-quic-transport.
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.
from go-libp2p-quic-transport.
I see. Unfortunately, the only clean solution I can think of is:
- Always use reuseport when listening on 0.0.0.0.
- When responding to a packet received on IP X, open a socket with a source port X (if not already open) and use that instead of 0.0.0.0.
from go-libp2p-quic-transport.
so would you consider the proposed solution by @ironsteel with IP_PKTINFO ?
from go-libp2p-quic-transport.
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.
from go-libp2p-quic-transport.
How would you like it to be implemented? We can make a pull request with the actual implementation.
from go-libp2p-quic-transport.
is there any update on this issue?
from go-libp2p-quic-transport.
@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.
from go-libp2p-quic-transport.
@Stebalien
The Issue(quic-go/quic-go#1736) is to resolve the source address selection for response. but our problem is the source address selection for dial. Can the issue really resolve our problem?
And Can we use the logic of go-reuseport-transport to solve this problem?
from go-libp2p-quic-transport.
@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.
from go-libp2p-quic-transport.
@Stebalien @marten-seemann
Does QUIC can work If accept new connection via Dial socket?
For Example:
If we have a machine with ips 4.4.4.4 and 192.168.1.2. And has quic-transport listen on socket1 with address (0.0.0.0:3344).
We want dial 5.5.5.5:3344,then we use netlink to choose the source address and we get source address (4.4.4.4). then we listen on socket2 with address (4.4.4.4:3344) and send data via socket2. This is no problem.
But For kernel, if packet send to 4.4.4.4:3344, this packet will deliver to socket2 rather than socket1. For example, 6.6.6.6:3344 send packet to 4.4.4.4:3344 for a new QUIC connection, this packet will deliver to socket2. But QUIC listen on socket1 rather than socket2. I am not sure if QUIC will work properly under such circumstances.
from go-libp2p-quic-transport.
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:
- Check the expected source address using netlink.
- If we're listening on that address, use that socket.
- If we're not, check to see if we have any open 0.0.0.0 listeners. If we do, use one of them.
- Otherwise, open (or use an existing) a "dial only" socket on a random port.
from go-libp2p-quic-transport.
Related Issues (20)
- Unreliable QUIC Go HOT 1
- implement transport.Close() HOT 3
- make sure the packet conn exposes UDPConn functions HOT 1
- go get github.com/libp2p/go-libp2p-quic-transport 包的错误 HOT 1
- flaky interop test HOT 1
- hanging multi-transfer interop test HOT 2
- zstd memory consumption kills nodes
- qlog compression is a memory hog
- flaky unit test HOT 2
- failing hole punching test HOT 4
- Dangling sockets HOT 2
- cmd examples do not work
- failing dial test
- Update go-libp2p-tls to 0.2.0
- tracing of version negotiation failures is wasteful
- Reduce netroute syscalls HOT 3
- flaky TestHolePunching test HOT 1
- Race condition in allowWindowIncrease HOT 1
- quic.Session is no longer defined HOT 1
- n00b question HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-libp2p-quic-transport.