Sending packets to a connected peer with rust-libp2p

I’m learning about libp2p and trying to re-implement a VPN similar to hyprspace in rust. However I’m realizing that the go lib and the rust lib have dissimilar APIs.

The gist of the application is:

  1. Provide a mapping from Iv4Addr to PeerId
  2. select! between receiving a fixed-size packet ([u8;1500]) from the TUN device and a SwarmEvent
  3. When a connection is established with a known peer id, open a stream (maybe async_std::channel::Sender/Receiver<[u8;1500]>?) to the peer and associate the given Ipv4Addr with the stream using a HashMap.
  4. When a packet is received from the TUN device, parse its destination address and send the packet to the associated stream in the HashMap.

Step 3 is what’s confusing me. I assumed Swarm::dial() would result in a SwarmEvent::ConnectionEstablished containing a Sender and Receiver for that peer, but it does not.

My questions are:

  1. How do I create a channel from a connected peer?
  2. Do I need to define any custom NetworkBehaviour for the Swarm or is the Kademlia behaviour for peer discovery + routing enough?

In case anyone bumps into this while researching a similar question, I’ve found my answer in the file-sharing example. Implementing the RequestResponseCodec provides the async_std::io I didn’t know I was looking for. Thanks to dvc94ch for pointing me in the right direction.

I need to dig a little deeper into how the RequestResponse protocol works for my specific needs (no need for a response because the transport should handle resending dropped packets if I’m understanding correctly).

1 Like

I need to dig a little deeper into how the RequestResponse protocol works for my specific needs (no need for a response because the transport should handle resending dropped packets if I’m understanding correctly).

@benlittle no need to send a reply. libp2p-request-response supports just sending a request.

1 Like

To clarify, do you mean using RequestResponseEvent<Packet, ()>? The implementation of RequestResponse seems to use a queue of requests and ensures that the most recent sent request gets a response before trying to send the next.

That is not the case. libp2p-request-response does not guarantee ordering across requests. In other words a later request might get an earlier response.