-
Notifications
You must be signed in to change notification settings - Fork 106
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: PatternXX
and testing with go
#406
Conversation
Though there are things to be added and confirmed, I think this should be ready for review. We can talk with go implementation through |
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.
great! i think we are fine to just focus on the XX
pattern for now. i like how you refactored the packet reading/writing so that we don't duplicate all of that across the various security transports.
excited for the interop tests!
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.
Some idle comments. This is large enough and I know little enough about the noise protocol that I was only able to provide superficial review.
return int.from_bytes(length_bytes, byteorder=BYTE_ORDER) | ||
|
||
|
||
def encode_msg_with_length(msg_bytes: bytes) -> bytes: | ||
len_prefix = len(msg_bytes).to_bytes(SIZE_LEN_BYTES, "big") | ||
def encode_msg_with_length(msg_bytes: bytes, size_len_bytes: int) -> bytes: |
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.
Why is the size passed in here instead of measuring it from len(msg_bytes)
?
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.
size_len_bytes
means the size of the length field in the message. In noise, it's 2 bytes. len(msg_bytes)
is encoded and put in this length field, and therefore len(msg_bytes)
should be < 2**(8*2) = 65536
.
read_closer: ReadCloser | ||
next_length: Optional[int] | ||
@abstractmethod | ||
def encode_msg(self, msg: bytes) -> bytes: |
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.
should this be public? Is it used as an external API or only called internally?
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.
It's only called internally, but I expect subclasses to implement it to make write_msg
work. So as next_msg_len
, which is used internally but needs to be implemented by the subclasses to make read_msg
work.
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 a lot for the review!
read_closer: ReadCloser | ||
next_length: Optional[int] | ||
@abstractmethod | ||
def encode_msg(self, msg: bytes) -> bytes: |
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.
It's only called internally, but I expect subclasses to implement it to make write_msg
work. So as next_msg_len
, which is used internally but needs to be implemented by the subclasses to make read_msg
work.
return int.from_bytes(length_bytes, byteorder=BYTE_ORDER) | ||
|
||
|
||
def encode_msg_with_length(msg_bytes: bytes) -> bytes: | ||
len_prefix = len(msg_bytes).to_bytes(SIZE_LEN_BYTES, "big") | ||
def encode_msg_with_length(msg_bytes: bytes, size_len_bytes: int) -> bytes: |
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.
size_len_bytes
means the size of the length field in the message. In noise, it's 2 bytes. len(msg_bytes)
is encoded and put in this length field, and therefore len(msg_bytes)
should be < 2**(8*2) = 65536
.
TODO - Figure out why `state.rs` is erased at some moment(even handshake is not done). - Refactor - Add tests
TODO: Add a buffer to read only `n` bytes in `read(n)`
- Abstract it as `MsgReadWriter` - `MsgIOReadWriter` as a subclass of `MsgReadWriter`
Make security sessions(secio, noise) share the same implementation `BaseSession` to avoid duplicate implementation of buffered read.
`connection.py` is removed.
- Change `BaseMsgReadWriter` to encode/decode messages with abstract method, which can be implemented by the subclasses. This allows us to create subclasses `FixedSizeLenMsgReadWriter` and `VarIntLenMsgReadWriter`.
f90fc46
to
ec8c109
Compare
I'm merging this PR since it gets too large and it already works fine with the go implementation. Will open a new one if everything gets updated. |
What was wrong?
#375
How was it fixed?
Based on #405
Pattern XX
SecureSession
(a buffered stream reader originally used in secio) is refactored and used by bothNoise
andSecio
now.MsgReadWriter
FixedSizeLenMsgReadWriter
NoiseReadWriter
VarIntLengthMsgReadWriter
PlaintextHandshakeReadWriter
VarIntLengthMsgReadWriter
overFixedSizeLenMsgReadWriter
. Ref: use varints for delimiting plaintext 2.0 msgs go-libp2p-core#74go-libp2p-daemon
against different security protocol.go-libp2p-noise
32
bytes for now. Will investigate what is wrong later.noise.proto
plaintext.proto
TODO
Reference
Cute Animal Picture