Skip to content

dataplane, transport: node keys -> peer ids#173

Open
npry wants to merge 4 commits into
mainfrom
npry/peer_ids
Open

dataplane, transport: node keys -> peer ids#173
npry wants to merge 4 commits into
mainfrom
npry/peer_ids

Conversation

@npry
Copy link
Copy Markdown
Collaborator

@npry npry commented May 7, 2026

Begin using ts_transport::PeerId (a locally-assigned peer index allocated by ts_runtime::PeerTracker) to uniquely identify peers. This lets us stop referring to NodePublicKey for peer identification from everywhere except ts_tunnel and derp (which need it to function). ts_tunnel now is no longer responsible for allocating peer ids, and instead is informed what peer id to use for what node key. (That happens in DataplaneActor as part of the peer update received from PeerTracker.)

This change revolves around PeerDb, which is HashMap<PeerId, Node> augmented by a number of secondary indices on nodekey, name, stable id, id, tailnet ips, accepted routes, and disco key (if known).

Implements an in-place update of the node key in wireguard for a given PeerId if the nodekey changes.

Closes #167 -- the PeerDb's name, ip, and route indexes address this

underlay transport

The last two commits refactor ts_transport::UnderlayTransport and derp's implementation of it. First, I wrote a helper trait that captures the packet batch iterator idea (this is basically what we had discussed @dylan-tailscale, I found a way to represent it that I think is actually easier to read, and also we need it on the recv side now too, so it got repetitive).

But the bigger change is that UnderlayTransport now takes a PeerKey associated type, which is PeerId inside ts_runtime, but NodePublicKey inside derp. I also provide a with_lookup combinator that allows mapping the key type for a transport using a PeerLookup trait, which the runtime implements by referencing the PeerDb. This lets derp and any other underlay transport not care about the peer id mapping, since the runtime handles the translation to/from the transport-specific peer identifier.

This is what that looks like in ts_runtime::Multiderp:

struct PeerDbLookup<'a>(&'a RwLock<Option<Arc<PeerDb>>>);
impl ts_transport::PeerLookup<PeerId, NodePublicKey> for PeerDbLookup<'_> {
fn lookup_key(&self, id: PeerId) -> Option<NodePublicKey> {
let db = self.0.read().unwrap();
let db = db.as_ref()?;
let (_, node) = db.get(&id)?;
Some(node.node_key)
}
}
impl ts_transport::PeerLookup<NodePublicKey, PeerId> for PeerDbLookup<'_> {
fn lookup_key(&self, key: NodePublicKey) -> Option<PeerId> {
let db = self.0.read().unwrap();
let db = db.as_ref()?;
let (id, _) = db.get(&key)?;
Some(id)
}
}

let client = ts_derp::DefaultClient::connect(&region.servers, &keys).await?;
let transport = client.with_key_lookup(PeerDbLookup(peer_db));

client above implements UnderlayTransport<Key = NodePublicKey>, and transport wraps it using the PeerDbLookup to provide UnderlayTransport<Key = PeerId>

review notes

Review commits one at a time — the second commit is a pure rename

@npry npry force-pushed the npry/peer_ids branch 2 times, most recently from 9bd650d to d290ae3 Compare May 7, 2026 12:30
Base automatically changed from npry/keys.randomize-disco to main May 7, 2026 20:03
@npry npry force-pushed the npry/peer_ids branch 14 times, most recently from 259d51d to e7dc788 Compare May 15, 2026 21:28
@npry npry marked this pull request as ready for review May 15, 2026 21:46
@npry npry force-pushed the npry/peer_ids branch from e7dc788 to 73d6b9d Compare May 19, 2026 20:45
npry added 4 commits May 20, 2026 05:35
Signed-off-by: Nathan Perry <nathan@tailscale.com>
Change-Id: I4bf750ea2de19b720cd9525852a5268f6a6a6964
The transport implementation is secondary, now in an especially
meaningful sense given that transports communicate over PeerIds, while
derp uses NodePublicKeys. This rename aligns with separation of the
client into the core non-transport functionality, and a transport
wrapper that handles translating to and from PeerId (forthcoming in a
future commit).

Signed-off-by: Nathan Perry <nathan@tailscale.com>
Change-Id: If5dd9a39d4e1299fe999f8457e38e94a6a6a6964
Make `ts_transport::UnderlayTransport` parametric over the peer key
type and provide a combinator that allows mapping a transport to a
different key type using a lookup trait. This lets the runtime operate
on `PeerId` everywhere while supplying the lookup functionality (e.g.
to/from `NodePublicKey` for derp), so the peer db doesn't have to
infiltrate all the transports.

The derp transport implementation is refactored to make use of this in a
future commit.

Signed-off-by: Nathan Perry <nathan@tailscale.com>
Change-Id: Ib965f787e92880ac3d74c364760acc546a6a6964
The baseline derp client doesn't need to know about translating nodekeys
to transport `PeerId`s, that's a higher level concern now provided by
`ts_transport::UnderlayTransportExt::with_lookup`, which the runtime
provides.

Signed-off-by: Nathan Perry <nathan@tailscale.com>
Change-Id: Ib965f787e92880ac3d74c364760acc546a6a6964
@npry npry force-pushed the npry/peer_ids branch from 73d6b9d to 70a3688 Compare May 20, 2026 09:35
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.

runtime: accelerate peer ip queries

1 participant