-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
noise: make it possible for the server to send early data #1750
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Marten, Thanks for making this API available!
p2p/security/noise/handshake.go
Outdated
return err | ||
} | ||
if s.earlyDataHandler != nil { | ||
if err := s.earlyDataHandler.Received(ctx, s.insecureConn, rcvdEd); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The early data handler may need to know the handshake state to drive its internal state machine, for example if this is the server or client side, at which stage is the early data received. Do you think we should pass the handshake state info to the earlyDataHandler too? or maybe that is available in other ways already and I missed it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For both client and server, the data is sent with their respective first flights.
I think the nicest way to resolve this is to pass separate client and server EarlyDataHandlers
to the EarlyData
option. I applied that change in 0b36832. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks great, thanks for the changes which make the Noise based muxer selection and other early data utilization smoother.
p2p/security/noise/handshake.go
Outdated
@@ -82,7 +77,7 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { | |||
// will be the size of the maximum handshake message for the Noise XX pattern. | |||
// Also, since we prefix every noise handshake message with its length, we need to account for | |||
// it when we fetch the buffer from the pool | |||
maxMsgSize := 2*noise.DH25519.DHLen() + len(payload) + 2*chacha20poly1305.Overhead | |||
maxMsgSize := 2*noise.DH25519.DHLen() + 2*chacha20poly1305.Overhead + 1024 /* payload */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering if there is a more efficient way of setting length rather than a hard limit here, I don't have a better way readily available, just want to throw some thoughts here to explore the options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to a fixed value of 2048 in 24459c5.
It's not even a hard limit, it's just the size we use to get a buffer from the buffer pool. If we get a buffer that's too small, the worst thing that happens is that append
would allocate a larger buffer.
We can just use a large enough buffer here. What exactly "large enough" means depends on the amount of early data we send, but 2048 should be enough for practically all use cases. And if not, we can live with that one allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification, that makes sense. Sorry I was not aware that we can do extra allocation if the limit is exceeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
24459c5
to
4f8a466
Compare
@MarcoPolo Good catch, this will make the code easier to understand. I updated the variable names to match the spec. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with the comments I added to EarlyDataHandler. Feel free to tweak, but the gist should be the same (a user should understand the caveats around this and what "early data" means in go-libp2p since this isn't a standard).
I updated the PR, such that early data is sent with the 2nd and 3rd handshake message. This means that early data is always sent encrypted. The slight annoyance here is that if the |
78ede96
to
e6c29ed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One fix for the comment, but otherwise looks good. Feel free to ping when the change is in and I’ll approve
// EarlyDataHandler allows attaching an (unencrypted) application payload to the first handshake message. | ||
// While unencrypted, the integrity of this early data is retroactively authenticated on completion of the handshake. | ||
// EarlyDataHandler defines what the application payload is for either the second | ||
// (if initiator) or third (if responder) handshake message, and defines the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// (if initiator) or third (if responder) handshake message, and defines the | |
// (if responder) or third (if initiator) handshake message, and defines the |
Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m going to commit this and approve.
So far, only the client could send early data in its first handshake message, which the server would then receive.
This PR extends the logic, such that the server can now also send early data in its first handshake message.
Needed for libp2p/specs#404 (comment). Also needed for libp2p/specs#446, if I understand correctly.