Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Correlate dial back responses with actual inbound dials #48

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

aarshkshah1992
Copy link
Collaborator

@aarshkshah1992 aarshkshah1992 commented Mar 2, 2020

@Stebalien @willscott

Please take a look.

For libp2p/go-libp2p#1480

@aarshkshah1992 aarshkshah1992 changed the title Correlate dial back responses with actual inbound dials [WIP] Correlate dial back responses with actual inbound dials Mar 2, 2020
@aarshkshah1992 aarshkshah1992 changed the title [WIP] Correlate dial back responses with actual inbound dials Correlate dial back responses with actual inbound dials Mar 2, 2020
func (d *dialBackTracker) ClosedStream(net network.Network, s network.Stream) {}

func (d *dialBackTracker) Connected(net network.Network, c network.Conn) {
dialer := c.RemotePeer()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien Since this & the dial back response happen on separate go-routines, we could see the dial back response before this code has had a chance to execute. However, the possibility of that seems low to me given the RTT times. Should we handle this race or just document it ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This'll be a problem for QUIC because the initiator will learn that the connection has finished before the receiver. That is, the initiator will receive the second message in the three-way handshake, send the final message, then start sending data.

Assuming the initiator (the AutoNAT server) acts fast enough, they can send the dial back response at pretty much the same time as the final handshake packet. At that point, it's a matter of scheduling and/or lost packets.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But let's not put too much work into this before we discuss it a bit.

Copy link
Contributor

@willscott willscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only design note is that the inboundDials cache could be specific to the in-flight autonat requests. It might be a bit more resilient to DoS requests if instead of recording all recent inbound dials in one cache structure, we only record the ones where we're expecting to see an inbound dial from an autonat service.

Comment on lines +58 to +59
msg := &pb.Message_DialerIdentityCertificate{}
msg.PublicKey = v.dialerPk
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
msg := &pb.Message_DialerIdentityCertificate{}
msg.PublicKey = v.dialerPk
msg := &pb.Message_DialerIdentityCertificate{PublicKey: v.dialerPk}

n := v.readNonce(s)

// dial
require.NoError(v.t, v.dialer.Connect(v.ctx, peer.AddrInfo{s.Conn().RemotePeer(), []ma.Multiaddr{s.Conn().RemoteMultiaddr()}}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it need to do this in the private case?

c := &client{
h: h,
getAddrs: getAddrs,
inboundDials: cache.New(10*time.Minute, 10*time.Minute),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the cache time to a const at the top of the file

@aarshkshah1992
Copy link
Collaborator Author

@willscott

Only design note is that the inboundDials cache could be specific to the in-flight autonat requests. It might be a bit more resilient to DoS requests if instead of recording all recent inbound dials in one cache structure, we only record the ones where we're expecting to see an inbound dial from an autonat service.

This is hard to do. Remember, there is no way for us to know which inbound dials we are expecting because we get the dialer peerID only when we get the dialback response.

One way to solve this would be to change the message flow as follows:

  1. Client sends a dial request.
  2. Server sends a Dialer Identity Certificate -> we record the dialer ID/start tracking it.
  3. Client asks the Server to go ahead.
  4. Server sends the dialback response.

But, this comes with additional costs.

willscott added a commit that referenced this pull request Mar 13, 2020
…ibp2p/go-libp2p-core-0.4.0

Bump github.com/libp2p/go-libp2p-core from 0.3.1 to 0.4.0
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants