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

[circuit-relay] Circuit features/functionality discussion #425

Closed
dryajov opened this issue Mar 17, 2017 · 14 comments
Closed

[circuit-relay] Circuit features/functionality discussion #425

dryajov opened this issue Mar 17, 2017 · 14 comments

Comments

@dryajov
Copy link
Member

dryajov commented Mar 17, 2017

Here are some notes after my conversation with @diasdavid.

  1. We need a way to ask the relay for all its relayed peer connections (@diasdavid, I forgot why we needed this, can you please explain? Would this be related to point 2 in this list?)
    • After thinking about this a bit, I think what we discussed is:
      • When a peer connects to me, get its connected peers, and have it relay connection to those peers. That way we'll quickly form a mesh of peers over the same muxed channel.
      • One obvious use case I can see, for example, in orbit chat, getting peers that are trying to connect to the same channel to quickly interconnected over the already muxed channel. That should make accessing the same resource a lot quicker and reduce the number of physical connections.
  2. Enable/disable ls for available connections on relay nodes (see above ^^ @diasdavid)
  3. All peers are relays, but they can function in two modes:
    • active/proactive relays that dial into other nodes
      • this are explicitly enabled by config options
    • passive relays, which only relay over known connections, no explicit dialing. If no connection exists for the requested peer, the relay is refused.
  4. A peer can say that it's only available over a particular relay (can it be multiple relays?), by adding it to its swarm config - /p2p-circuit/< ma >
    • Useful in case of peers located in a private/slow network
    • What are the other use cases for this?
  5. Relays only relay connections from Peer A to Peer B, if there are more than one hop in the multiaddr (chaining/nesting), then its the dialer that initiates the connection to the next relay pair in the chain. This is needed so that we disclose the least possible amount of information to the network.

Here is an example of a possible circuit/relay config:

Swarm: {
  Addresses: [
    '/p2p-circuit/<multiaddr of the Relay>'
  ]
}
Relay: {
  Circuit: {
    Enabled: false,
    list-peers: false
    Proactive: false
  }
}

@lgierth @diasdavid @dignifiedquire

I'm going to start implementing some of this, in particular points 3, 4, 5, point 1 and 2 might need some discussion/clarification.

Also, lets use this issue for further discussion. :)

@daviddias
Copy link
Member

@dryajov going to expand rewrite your notes in my own words to help our brain sync :)

Modes of operation

A peer can:

  • Accept relayed connections (through swarm.handle(circuit protocol))
  • Listen on a relayed address. This translates to:
    • Proactively checking if the relay is available to him
    • Announce its relayed address to the other peers
  • Be a relay of other peers.
  • Act as a routing service by answering queries asking which peers it is connected to (the ls option)

By default, a peer:

  • Accept relayed connections
  • Won't listen on relay addresses
  • Won't be a relay of other peers
  • Won't act as a routing service

Relay protocol

The relay protocol must consist of a message with two options:

  • Relay this conn to another peer
  • Tell me which peers you are connected (ls)

Other notes

  • There is no limit in the number of relays one peer can have
  • Every relayed connection is end-to-end encrypted

@dryajov
Copy link
Member Author

dryajov commented Mar 24, 2017

Thanks @diasdavid!

A few more questions around dialing/connecting over a relay.

From my notes above:

  • A relay has two modes of operation:
    • Actively dial on behalf of another peer
    • Passively relay connections only to peers its already connected to

Are this correct assumptions?

@daviddias
Copy link
Member

@dryajov correct 👍

@dryajov
Copy link
Member Author

dryajov commented Mar 24, 2017

@diasdavid @lgierth

A few more clarifications:

  • Listen on a relayed address. This translates to:
    • Proactively checking if the relay is available to him
    • Announce its relayed address to the other peers

The above, as I understand it means, putting the relay address in the peers swarm config and being reachable only over that relay.

A few questions around that:

  • In the general case, a peer is accessible over any available relay. Correct?
  • When a peer listens on an explicit relay address, does that mean that its only reachable over that relay?
    • Also, can it listen on multiple relay addresses?
  • Does the above also effectively disables the relay from being reachable over any other relay?

Edit: moving flow into it's own comment.

@daviddias
Copy link
Member

In the general case, a relay is accessible over any available relay. Correct?

A peer that mounts the relay protocol is accessible through any relay node.

When a peer listens on an explicit relay address, does that mean that its only reachable over that relay?

No, listening on a relay address means that the peer will try to dial to that relay on the start of the node. This is like hole punching out, so that future connections can come in.

Also, can it listen on multiple relay addresses?

Yes

Does the above also effectively disables the relay from being reachable over any other relay?

I don't see anything that would cause this.

@dryajov
Copy link
Member Author

dryajov commented Mar 24, 2017

@diasdavid

more questions:

Be a relay of other peers.

How do you know if a peer is able to relay connections as opposed to simply accepting them? The spec is pretty vague on it as it is:

After getting a stream to the relay node from its libp2p swarm, the dialing transport writes the header to the stream. The relaying node reads the header, gets a stream to the destination node, then writes the header to the destination stream and shortcircuits the two streams.

Sinse a peer can both relay connections and listen for relayed connections and both use the same multistream proto header, it makes it a bit cumbersome to figure out if the peer is a relay or simply listening for relayed connections.

It would be nice to be able to query the node for its capabilities, specially since we now also have an additional command ls that could be either enabled or disabled on the relay peer.

@daviddias
Copy link
Member

How do you know if a peer is able to relay connections

Once you establish a stream-muxer (see inside swarm) you attempt to dial on the relay protocol, if it succeeds, then it supports relay, if not, no biggie :).

Opening muxed streams is very cheap.

@dryajov
Copy link
Member Author

dryajov commented Mar 24, 2017

Yeah that makes sense. Still I think its valuable to be able to ask the relay what can you do?, and it will respond with its capabilities?

i.e.

/ipfs/relay/circuit/1.0.0
capabilities
/ipfs/relay/circuit/1.0.0
ls
dial
...

I think this is useful for passive relay discovery. For example, you can listen for the peer-mux-established swarm even't and interrogate the incoming peer for its capabilities, if it's a relay you can add it to your known relays, if not you don't have to try dialing on it? We could enable/disable this behavior in config.

@dryajov
Copy link
Member Author

dryajov commented Mar 25, 2017

@diasdavid @lgierth @dignifiedquire

Documenting flow/requirements. Feedback/corrections/questions appreciated 😄

https://hackmd.io/EYQw7ALMCmDMDGBaAnAM1bREAmAmXiwAHBEVhKvDrhttiEA=?view

@daviddias
Copy link
Member

@dryajov as we chatted through IRC, please open a PR with it, giving reviews and feedback without version control and threads is a nightmare. That being said, let me know if you have any question, the document looks like it translates all our notes and discussions, good work :)

@dryajov
Copy link
Member Author

dryajov commented Mar 25, 2017

@diasdavid

here it is - libp2p/js-libp2p-circuit#5

I think this can be merged so that we can keep creating PR's against it?

@dryajov
Copy link
Member Author

dryajov commented Mar 25, 2017

Merged the doc to master.

@dryajov
Copy link
Member Author

dryajov commented Mar 26, 2017

@diasdavid

  • Accept relayed connections
  • Won't listen on relay addresses
  • Won't be a relay of other peers
  • Won't act as a routing service

With this point Won't listen on relay addresses, you mean that we won't have any relay addresses in the swarm config, but not that we wont be accepting relayed connections - because it would contradict 1) 😃 ?

(requirements are hard™)

Edit: rephrasing

Whats the reason you think we shouldn't listen on relay addresses by default? Or, does that basically means that by default, we wont have relay addresses in the swarm config?

Basically, are you implying that we can explicitly enable/disable this through a specific config value, or is this implicit - if no relay address is in the swarm config then it Won't listen on relay addresses?

@daviddias daviddias changed the title Circuit features/functionality discussion [circuit-relay] Circuit features/functionality discussion Aug 22, 2019
@daviddias daviddias transferred this issue from libp2p/js-libp2p-circuit Aug 22, 2019
@mpetrunic
Copy link
Member

Closing as stale, circuit relay has been implemented and we have version 2 on the wall #1029

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

No branches or pull requests

3 participants