Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use udp instead of tcp in multiaddress #353

Closed
jimmy9065 opened this issue Jun 11, 2018 · 14 comments
Closed

How to use udp instead of tcp in multiaddress #353

jimmy9065 opened this issue Jun 11, 2018 · 14 comments

Comments

@jimmy9065
Copy link

I'm studying this example and try to make it fit my own project.
In my project, there are several NAT devices between the proxy server and the proxy client. So I need to do a NAT traverse to make them connected.
I choose to use the UDP punching hole to do the NAT traverse. Thus I need to set udp instead tcp in the multiaddress like this:
Changed:

libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", port)))

To:

libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/udp/%d", port)))

However, After I run the program, I get error like this:

failed to listen on any addresses: [no transport for protocol]

So I just want to if I did something wrong here or udp is just not supported by the library right now for transport protocol?

Thank you. Hope I make myself clear on this.

@Stebalien
Copy link
Member

We do not currently have any UDP based transports. We are working on adding QUIC support but QUIC multiaddrs will have the form /ip4/127.0.0.1/udp/PORT/quic.

FYI, we do have several NAT traversal mechanisms and are working on more.

  1. To work around full-cone NATs, we reuse the source port for all TCP connections and, when we establish a connection to some endpoint, we ask the endpoint for the ip/port they observe us using. We then tell the network to connect to us at this address.
  2. For NATs that support UPnP or NATPMP, we have a go-libp2p-nat package that handles port mapping.
  3. We have a relay transport (go-libp2p-circuit). However, while you can always manually dial through a relay to another node, we don't currently have any support for automatically picking a good relay (so we won't do this automatically).

@bkolad
Copy link

bkolad commented Nov 15, 2018

Any plans to start supporting UDP?

@raulk
Copy link
Member

raulk commented Nov 15, 2018

I'm lacking the history context here, but adding raw UDP support (no QUIC) would involve creating a "glue" UDPTransport similar to go-tcp-transport that bridges the Transport interface with go-multiaddr-net?

@Stebalien – would love your 2 cents here.

@Stebalien
Copy link
Member

So, there are two parts to this:

  1. Packet protocols. We currently don't have any packet protocol support but we'd like them. To do that, we'd need some way to define packet transports. IIRC, @lgierth was working on this for a bit but he's taking the quarter off.
  2. Streaming over UDP. That is, we'd start with a UDP connection, and then keep upgrading (using multistream) until we get a fully featured connection.

However, we still have to think carefully about the abstractions involved.

@raulk
Copy link
Member

raulk commented Nov 20, 2018

@Stebalien thanks for the clarification! 👍

Regarding (1), I found the multigram proposal which is intended as the multistream counterpart for datagram sockets.

About (2), I'm not sure I follow. Wouldn't multistream negotiations and SecIO behave well on top of a message-oriented transport? After all they use varint-delimited writes. If the application guarantees that all its messages are below ~64kb in length (after encapsulating in multiplexer, etc... length for UDP datagrams), wouldn't we be able to use datagrams straightaway? (leaving aside the fact that the stream nomenclature might be a misnomer)

^^ that is assuming that UDPConn.Write() ends up creating a message and calling sendmsg() for us.

@raulk
Copy link
Member

raulk commented Nov 20, 2018

Actually, I’m thinking that application would need a way to declare to libp2p that it can live without a reliable transport, which would unlock the usage of UDP if we had no other transports for the peer. Not sure how worthwhile an investment this would be in the advent of QUIC, though.

@bkolad – would you guys like to serve as an early adopter of QUIC? It’s in experimental stages.

@bkolad
Copy link

bkolad commented Nov 20, 2018

@raulk - yes we can check out QUIC, thx for the suggestion.

@Stebalien
Copy link
Member

About (2), I'm not sure I follow.

Sort of. The minimum MTU is actually quite a bit smaller than 64Kib (really, you can only expect ~1KiB`). However, SECIO itself expects a stream transport. That is, it won't work properly unless the underlying transport delivers packets in-order.

Basically, (2) is:

  1. Negotiate a in-order stream transport over the packet-based UDP transport.
  2. Negotiate secio, etc...

Also note: Multistream won't work by itself as we'll get out-of-order and duplicate messages.

can live without a reliable transport, which would unlock the usage of UDP if we had no other transports for the peer

IMO, this is quite useful. For example, many DHT operations don't really care about trying again. However, yes, we'd need to expose this to the application. My thinking is that the user would call SendMessage and SendMessageUnreliable functions to indicate if they care about reliability. The main benefits over QUIC are:

  1. We can fire and forget (no state).
  2. We don't have to establish a session first.

However, the second is mitigated by QUIC's session resumption. The current plan is to (eventually) store these session tickets in the peerstore. As long as we don't get too much DHT churn, DHT requests should usually take one RTT.

@marten-seemann
Copy link
Contributor

The minimum MTU is actually quite a bit smaller than 64Kib (really, you can only expect ~1KiB`).

Google performed some measurements for this, and they concluded that 1370 bytes is safe for IPv4 UDP packets (which is the value Chrome now uses for QUIC packets).

The main benefits over QUIC are:

  1. We can fire and forget (no state).
  2. We don't have to establish a session first.

There's currently a QUIC extension being defined that allows unreliable messages. We'd still have to do the handshake (we need that if we want to encrypt stuff anyway, unless we want to do some asymmetric crypto).

@bkolad
Copy link

bkolad commented Nov 23, 2018

@raulk & @Stebalien
tried to use quic but now experiencing
libp2p/go-libp2p-quic-transport#33

we are using "go get", any plans to fix go-libp2p-quic-transport with go-get?

@marten-seemann
Copy link
Contributor

This is unfortunately due to the fact that the QUIC protocol is not stable yet, and quic-go therefore doesn’t expose any stable QUIC version numbers. Please see https://github.com/lucas-clemente/quic-go for more details.
Every now and then, we publish a new release of quic-go, with a dedicated version number. However, this version number is only supported by this one release commit.

Once the QUIC protocol (and the implementation) become stable, it will be possible to install and use via go get.

@Stebalien
Copy link
Member

There's currently a QUIC extension being defined that allows unreliable messages.

This would be so awesome...

This is unfortunately due to the fact that the QUIC protocol is not stable yet, and quic-go therefore doesn’t expose any stable QUIC version numbers.

What if we used a fork of quic-go for now, or something like that. It would be really nice to be able to use the QUIC transport without gx.

@marten-seemann
Copy link
Contributor

This is unfortunately due to the fact that the QUIC protocol is not stable yet, and quic-go therefore doesn’t expose any stable QUIC version numbers.

What if we used a fork of quic-go for now, or something like that. It would be really nice to be able to use the QUIC transport without gx.

We can use plain old dependency vendoring here. I opened libp2p/go-libp2p-quic-transport#41.

@Stebalien
Copy link
Member

(closing because this is more of a discussion and isn't worth tracking)

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

No branches or pull requests

5 participants