Skip to content

ts_tunnel: fix the triggers for session rotation#286

Open
danderson wants to merge 1 commit into
mainfrom
push-vklkwnswztqz
Open

ts_tunnel: fix the triggers for session rotation#286
danderson wants to merge 1 commit into
mainfrom
push-vklkwnswztqz

Conversation

@danderson

Copy link
Copy Markdown
Member

Previously, session rotation triggered only on sending by either peer. This does not conform to the spec (section 6.2): only the initiator should trigger session rotation, and it should do so on both send and receive.

Fixes #283

Change-Id: I4fef3c7306905957932220aca8bcab1f6a6a6964


This change is a bit larger than the minimum surgical change: now that the final consumer of an established session needs to know whether or not it's the initiator (previously it just needed to know what its send/recv keys were), I adjusted the ts_noise APIs to return the session keys in a role-agnostic way (named initiator_to_responder rather than send or recv) along with the local endpoint's role, and let the caller decide how to use each key based on that.

For the control protocol this is trivial since the client is always the initiator, but for ts_tunnel BidiSession's constructor is now where the keys are assigned their send/recv purpose, depending on the local role. I found that this ended up being easier to follow through the layers of handshakes and helpers, because it means you don't have to look around at the local context to figure out which traffic direction keys.send is supposed to be.

This PR has no regression tests for this issue, because as I implemented those I got side-tracked into refactoring the tests to be more readable. That is #284 (currently draft), which I'll polish up and send out as a followup to this PR. The draft PR does include tests for key rotation, both from the initiator and responder's perspective, and they confirm that with this change, rotation triggers at the right time and place.

@npry npry left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

only blocking question is the polarity on codec, otherwise lgtm

Comment thread ts_noise/src/core.rs Outdated
Comment thread ts_control_noise/src/codec.rs Outdated
Comment on lines +60 to +61
tx: Codec::<Tx>::from(session.initiator_to_responder),
rx: Codec::<Rx>::from(session.responder_to_initiator),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this check the session polarity to resolve which one is send vs receive from our perspective?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, fair enough. I skipped it because in our current code we're always the initiator, but that's not necessarily true in future and could result in catastrophic key reuse in that case. Fixed.

Comment thread ts_tunnel/src/session.rs
@danderson
danderson force-pushed the push-vklkwnswztqz branch 2 times, most recently from 3b9569b to a4de20c Compare July 22, 2026 18:42
@danderson
danderson force-pushed the push-vklkwnswztqz branch 2 times, most recently from 30a457e to ce31ede Compare July 24, 2026 19:45
Previously, session rotation triggered only on sending by either
peer. This does not conform to the spec (section 6.2): only the
initiator should trigger session rotation, and it should do so on
both send and receive.

Fixes #283

Signed-off-by: David Anderson <danderson@tailscale.com>
Change-Id: I4fef3c7306905957932220aca8bcab1f6a6a6964
@danderson
danderson force-pushed the push-vklkwnswztqz branch from ce31ede to a120aab Compare July 24, 2026 19:53
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

Successfully merging this pull request may close these issues.

ts_tunnel: session rotation trigger doesn't match spec

2 participants