go-libp2p icon indicating copy to clipboard operation
go-libp2p copied to clipboard

quic: require address validation when under load

Open fulviodenza opened this issue 2 years ago • 13 comments

This PR adds the address validation when under load, referred to the issue #1535

fulviodenza avatar Jun 17 '22 11:06 fulviodenza

I recommend reviewers to squash the commits

ErikPelli avatar Jun 17 '22 15:06 ErikPelli

It's probably easier if you use a slice of bufferEntrys. That slice could then start at length 1, and we'd append every minute, until we reach the maximum length (5). As we append to that slice once per minute, so there's no need to worried about the cost of allocations.

When you finish the minutes what do you do? Overwrite starting from the first value? Anyway i don't think that append is necessary, as you can simply do a make([]bufferEntry, minutes) in the constructor, because the allocated space is very small

ErikPelli avatar Jun 17 '22 17:06 ErikPelli

It's probably easier if you use a slice of bufferEntrys. That slice could then start at length 1, and we'd append every minute, until we reach the maximum length (5). As we append to that slice once per minute, so there's no need to worried about the cost of allocations.

When you finish the minutes what do you do? Overwrite starting from the first value? Anyway i don't think that append is necessary, as you can simply do a make([]bufferEntry, minutes) in the constructor, because the allocated space is very small

Yes exactly, you add a new bufferEntry at the end. And if you reach a length of 5, you drop the first entry. This way you avoid the index calculations that you need when using a ring buffer, and you avoid special cases when you don't have 5 entries yet because you just booted the node.

marten-seemann avatar Jun 17 '22 21:06 marten-seemann

5 is fixed or is the number of minutes chosen by the user?

ErikPelli avatar Jun 17 '22 21:06 ErikPelli

I think it can be a constant, the user chooses the duration (and that duration could, in principle, even be less than a minute).

marten-seemann avatar Jun 17 '22 21:06 marten-seemann

In the fraction, what represents token.IsRetryToken == false? From the name I think that it's a boolean that says if the user sent the correct retry token, but in that case go-quic doesn't even call the function I think.

With duration what do you mean? The time to go to next buffer item (so instead of 1 minute this value is changeable)?

ErikPelli avatar Jun 17 '22 21:06 ErikPelli

In the fraction, what represents token.IsRetryToken == false? From the name I think that it's a boolean that says if the user sent the correct retry token, but in that case go-quic doesn't even call the function I think.

There are two types of tokens, both used in the same header field of the Initial packet. Retry tokens, as the name says, are tokens that are echoed from a Retry packet. There's also tokens generated on previous connections (see https://datatracker.ietf.org/doc/html/rfc9000#section-8.1.3). You don't need to worry about them too much.

marten-seemann avatar Jun 17 '22 21:06 marten-seemann

Hi @marten-seemann, we finished the implementation and were working on testing the new feature. We are a bit confused about the testing part, mainly on these points:

  1. Should we mock the two peers? We found createPeer function to instantiate the peers that need to connect with each other but we're not sure about the correctness of this approach.
  2. Should we create a mock for some component with the clock like in this function? https://github.com/libp2p/go-libp2p/blob/bedce2290de15f7f6150ea1740a59d07b78a34f4/p2p/discovery/mocks/mocks.go#L28-L33 If yes what component should we add the clock to?
  3. How do we interrupt handshakes after the accept function and before the conclusion?

fulviodenza avatar Jun 19 '22 22:06 fulviodenza

Hi @marten-seemann, we finished the implementation and were working on testing the new feature. We are a bit confused about the testing part, mainly on these points:

1. Should we mock the two peers? We found `createPeer` function to instantiate the peers that need to connect with each other but we're not sure about the correctness of this approach.

2. Should we create a mock for some component with the clock like in this function? https://github.com/libp2p/go-libp2p/blob/bedce2290de15f7f6150ea1740a59d07b78a34f4/p2p/discovery/mocks/mocks.go#L28-L33
    If yes what component should we add the clock to?

3. How do we interrupt handshakes after the accept function and before the conclusion?

Any news about that? There hasn't been an answer yet.

ErikPelli avatar Jun 28 '22 18:06 ErikPelli

  1. Should we mock the two peers? We found createPeer function to instantiate the peers that need to connect with each other but we're not sure about the correctness of this approach.

Yes, that sounds reasonable.

  1. Should we create a mock for some component with the clock like in this function? https://github.com/libp2p/go-libp2p/blob/bedce2290de15f7f6150ea1740a59d07b78a34f4/p2p/discovery/mocks/mocks.go#L28-L33

Yes. Having a WithClock Option is probably the best way to go.

  1. How do we interrupt handshakes after the accept function and before the conclusion?

Probably the easiest way will be to give the client an invalid certificate, like we do in the TLS tests: https://github.com/libp2p/go-libp2p/blob/master/p2p/security/tls/transport_test.go#L281. That will then lead to a failure of the QUIC handshake.

marten-seemann avatar Jul 07 '22 22:07 marten-seemann

Hi @marten-seemann, I think we finished the feature itself but we can't get out of the test question. We struggled on tests but cannot figure out how to write them. Would you be available to give us a help/hint to implement them? Thank you

fulviodenza avatar Jul 18 '22 20:07 fulviodenza

2022-08-26 conversation: @marten-seemann has done some work to cleanup the quic-go API. @marten-seemann needs to release this and then will circle back here to explain the changes so the PR can be updated.

BigLep avatar Aug 26 '22 16:08 BigLep

Status: blocked until the quic-go issue is addressed: https://github.com/lucas-clemente/quic-go/issues/3549

BigLep avatar Sep 16 '22 16:09 BigLep