Skip to content

Commit 9ba42f0

Browse files
committed
dataplane: don't require peer id from underlay
The peer id isn't actually known a priori from the underlay, even if some transports can give an indication of what they think it is (such as derp reporting the nodekey). Ultimately the only way the peer identity can be trusted is if it's cryptographically authenticated by data within the packet, which WireGuard derives from the ongoing session (identified by the session id field), and disco gets from the disco pubkey field in its header. STUN packets are unverified but don't require any association to the peer's id. Removing this requirement will simplify the architecture for the UDP direct transport in future commits. Signed-off-by: Nathan Perry <nathan@tailscale.com> Change-Id: Ib3fe81d7f41fbd6e3b637f282b51f4f96a6a6964
1 parent dcb473a commit 9ba42f0

4 files changed

Lines changed: 52 additions & 62 deletions

File tree

ts_dataplane/src/async_tokio.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,30 @@ use ts_tunnel::NodeKeyPair;
99

1010
use crate::{EventResult, InboundResult, OutboundResult};
1111

12-
/// Queue for packets leaving the data plane "up" into an overlay transport.
13-
pub type DataplaneToOverlay = mpsc::UnboundedSender<Vec<PacketMut>>;
14-
15-
/// Queue for packets entering the data plane "down" from an overlay transport.
16-
pub type DataplaneFromOverlay = mpsc::UnboundedReceiver<Vec<PacketMut>>;
17-
18-
/// Queue for packets leaving the data plane "down" into an underlay transport.
19-
pub type DataplaneToUnderlay = mpsc::UnboundedSender<(PeerId, Vec<PacketMut>)>;
20-
21-
/// Queue for packets entering the data plane "up" from an underlay transport.
22-
pub type DataplaneFromUnderlay = mpsc::UnboundedReceiver<(PeerId, Vec<PacketMut>)>;
23-
24-
// TODO: wire in overlay/underlay transport traits
12+
// NOTE(npry): this used to have unique types for each queue, but the names got confusing due to
13+
// having to think about the cartesian product of PacketType x QueueDirection x Network
14+
// (this is a "sender handle for receive packets on the overlay", vs. "receive handle for sender
15+
// packets on the overlay", etc.). It wasn't always clear to distinguish what referred to the
16+
// channel direction (sender/receiver) and what referred to the actual traffic kind (packets
17+
// received _from_ the underlay are different from packets sent _to_ the underlay). So now we name
18+
// the packet type here (to/from overlay/underlay) and use separate helper types to make the channel
19+
// directions easier to name.
20+
21+
/// Packet batches sent to an overlay.
22+
pub type ToOverlay = Vec<PacketMut>;
23+
/// Packet batches received from an overlay.
24+
pub type FromOverlay = Vec<PacketMut>;
25+
26+
/// Packet batches sent to an underlay.
27+
pub type ToUnderlay = (PeerId, Vec<PacketMut>);
28+
/// Packet batches received from an underlay.
29+
pub type FromUnderlay = Vec<PacketMut>;
30+
31+
/// Shorthand for a sender channel.
32+
pub type Tx<T> = mpsc::UnboundedSender<T>;
33+
34+
/// Shorthand for a receiver channel.
35+
pub type Rx<T> = mpsc::UnboundedReceiver<T>;
2536

2637
/// Transforms packets to make tailscale happen.
2738
pub struct DataPlane {
@@ -30,8 +41,10 @@ pub struct DataPlane {
3041

3142
transports_changed: tokio::sync::Notify,
3243

33-
underlay_down: DataplaneToUnderlay,
34-
overlay_up: DataplaneToOverlay,
44+
// These are the senders handed out in new_*_transport, just held here so we can clone them, we
45+
// never send to them.
46+
underlay_down: Tx<FromUnderlay>,
47+
overlay_up: Tx<FromOverlay>,
3548

3649
next_underlay_transport: AtomicU32,
3750
next_overlay_transport: AtomicU32,
@@ -42,17 +55,17 @@ struct CoreState {
4255
sync: crate::DataPlane,
4356

4457
/// Queues to write packets to overlay transports.
45-
overlay_transports: HashMap<OverlayTransportId, DataplaneToOverlay>,
58+
overlay_transports: HashMap<OverlayTransportId, Tx<ToOverlay>>,
4659
/// Queues to write packets to underlay transports.
47-
underlay_transports: HashMap<UnderlayTransportId, DataplaneToUnderlay>,
60+
underlay_transports: HashMap<UnderlayTransportId, Tx<ToUnderlay>>,
4861
}
4962

5063
/// State that must be held during async polling.
5164
struct PollState {
5265
/// Queue for packets entering the data plane ("coming down") from overlay transports.
53-
from_overlay: DataplaneFromOverlay,
66+
from_overlay: Rx<FromOverlay>,
5467
/// Queue for packets entering the data plane ("coming up") from underlay transports.
55-
from_underlay: DataplaneFromUnderlay,
68+
from_underlay: Rx<FromUnderlay>,
5669
}
5770

5871
impl DataPlane {
@@ -91,11 +104,7 @@ impl DataPlane {
91104
/// Allocate a new underlay transport.
92105
pub async fn new_underlay_transport(
93106
&self,
94-
) -> (
95-
UnderlayTransportId,
96-
DataplaneFromUnderlay,
97-
DataplaneToUnderlay,
98-
) {
107+
) -> (UnderlayTransportId, Rx<ToUnderlay>, Tx<FromUnderlay>) {
99108
let id = self
100109
.next_underlay_transport
101110
.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
@@ -116,7 +125,7 @@ impl DataPlane {
116125
/// Allocate a new overlay transport.
117126
pub async fn new_overlay_transport(
118127
&self,
119-
) -> (OverlayTransportId, DataplaneToOverlay, DataplaneFromOverlay) {
128+
) -> (OverlayTransportId, Tx<FromOverlay>, Rx<ToOverlay>) {
120129
let id = self
121130
.next_overlay_transport
122131
.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
@@ -146,7 +155,7 @@ impl DataPlane {
146155
pub async fn step(&self) {
147156
enum SelectResult {
148157
OverlayDown(Vec<PacketMut>),
149-
UnderlayUp(PeerId, Vec<PacketMut>),
158+
UnderlayUp(Vec<PacketMut>),
150159
TransportsChanged,
151160
Event,
152161
}
@@ -185,10 +194,10 @@ impl DataPlane {
185194
}
186195

187196
underlay_pkts = underlay_up.recv() => {
188-
let (peer_id, underlay_pkts) = underlay_pkts.unwrap();
189-
tracing::trace!(%peer_id, n_underlay_pkts = underlay_pkts.len());
197+
let underlay_pkts = underlay_pkts.unwrap();
198+
tracing::trace!(n_underlay_pkts = underlay_pkts.len());
190199

191-
SelectResult::UnderlayUp(peer_id, underlay_pkts)
200+
SelectResult::UnderlayUp(underlay_pkts)
192201
}
193202

194203
_ = self.transports_changed.notified() => {
@@ -214,7 +223,7 @@ impl DataPlane {
214223

215224
(Some(to_peers), Some(loopback))
216225
}
217-
SelectResult::UnderlayUp(_peer_id, underlay_up) => {
226+
SelectResult::UnderlayUp(underlay_up) => {
218227
let InboundResult { to_local, to_peers } = core.sync.process_inbound(underlay_up);
219228

220229
(Some(to_peers), Some(to_local))

ts_runtime/src/dataplane.rs

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use kameo::{
44
actor::ActorRef,
55
message::{Context, Message},
66
};
7-
use tokio::sync::mpsc;
8-
use ts_packet::PacketMut;
9-
use ts_transport::{OverlayTransportId, PeerId, UnderlayTransportId};
7+
use ts_dataplane::async_tokio::{FromOverlay, FromUnderlay, Rx, ToOverlay, ToUnderlay, Tx};
8+
use ts_transport::{OverlayTransportId, UnderlayTransportId};
109

1110
use crate::{
1211
Error,
@@ -17,18 +16,6 @@ use crate::{
1716
src_filter::SourceFilterState,
1817
};
1918

20-
/// Queue for packets sent from the overlay to the dataplane.
21-
pub type OverlayToDataplane = mpsc::UnboundedSender<Vec<PacketMut>>;
22-
23-
/// Queue for packets entering the overlay from the dataplane.
24-
pub type OverlayFromDataplane = mpsc::UnboundedReceiver<Vec<PacketMut>>;
25-
26-
/// Queue for packets leaving the underlay to the dataplane.
27-
pub type UnderlayToDataplane = mpsc::UnboundedSender<(PeerId, Vec<PacketMut>)>;
28-
29-
/// Queue for packets entering an underlay from the dataplane.
30-
pub type UnderlayFromDataplane = mpsc::UnboundedReceiver<(PeerId, Vec<PacketMut>)>;
31-
3219
pub struct DataplaneActor {
3320
dataplane: Arc<ts_dataplane::async_tokio::DataPlane>,
3421
task: tokio::task::JoinHandle<()>,
@@ -45,18 +32,14 @@ impl DataplaneActor {
4532
#[message]
4633
pub async fn new_overlay_transport(
4734
&self,
48-
) -> (OverlayTransportId, OverlayToDataplane, OverlayFromDataplane) {
35+
) -> (OverlayTransportId, Tx<FromOverlay>, Rx<ToOverlay>) {
4936
self.dataplane.new_overlay_transport().await
5037
}
5138

5239
#[message]
5340
pub async fn new_underlay_transport(
5441
&self,
55-
) -> (
56-
UnderlayTransportId,
57-
UnderlayFromDataplane,
58-
UnderlayToDataplane,
59-
) {
42+
) -> (UnderlayTransportId, Rx<ToUnderlay>, Tx<FromUnderlay>) {
6043
self.dataplane.new_underlay_transport().await
6144
}
6245
}

ts_runtime/src/multiderp.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use kameo::{
1111
};
1212
use tokio::{sync::watch, task::JoinSet};
1313
use ts_control::DerpRegion;
14+
use ts_dataplane::async_tokio::{FromUnderlay, Rx, ToUnderlay, Tx};
1415
use ts_derp::RegionId;
1516
use ts_keys::{NodeKeyPair, NodePublicKey};
1617
use ts_transport::{
@@ -19,7 +20,7 @@ use ts_transport::{
1920

2021
use crate::{
2122
Env, Error,
22-
dataplane::{DataplaneActor, NewUnderlayTransport, UnderlayFromDataplane, UnderlayToDataplane},
23+
dataplane::{DataplaneActor, NewUnderlayTransport},
2324
derp_latency::DerpLatencyMeasurement,
2425
peer_tracker::{PeerDb, PeerState},
2526
};
@@ -161,8 +162,8 @@ async fn run_derp_once(
161162
id: RegionId,
162163
region: &DerpRegion,
163164
keys: NodeKeyPair,
164-
to_dataplane: &UnderlayToDataplane,
165-
from_dataplane: &mut UnderlayFromDataplane,
165+
to_dataplane: &Tx<FromUnderlay>,
166+
from_dataplane: &mut Rx<ToUnderlay>,
166167
home_derp_rx: &mut watch::Receiver<bool>,
167168
peer_db: &RwLock<Option<Arc<PeerDb>>>,
168169
) -> Result<(), ts_derp::Error> {
@@ -215,7 +216,7 @@ async fn run_derp_once(
215216

216217
tracing::trace!(parent: &span, %peer_id, len = pkts.len(), "packet from derp server");
217218

218-
let Ok(()) = to_dataplane.send((peer_id, pkts)) else {
219+
let Ok(()) = to_dataplane.send(pkts) else {
219220
tracing::error!(parent: &span, "underlay receive channel closed");
220221
break;
221222
};

ts_runtime/src/netstack_actor.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@ use netstack::{
99
netcore::{Channel, NetstackControl},
1010
};
1111
use tokio::task::JoinSet;
12+
use ts_dataplane::async_tokio::{FromOverlay, Rx, ToOverlay, Tx};
1213
use ts_packet::PacketMut;
1314

14-
use crate::{
15-
Error,
16-
dataplane::{OverlayFromDataplane, OverlayToDataplane},
17-
env::Env,
18-
};
15+
use crate::{Error, env::Env};
1916

2017
pub struct NetstackActor {
2118
_joinset: JoinSet<()>,
@@ -26,8 +23,8 @@ impl kameo::Actor for NetstackActor {
2623
type Args = (
2724
Env,
2825
netstack::netcore::Config,
29-
OverlayToDataplane,
30-
OverlayFromDataplane,
26+
Tx<FromOverlay>,
27+
Rx<ToOverlay>,
3128
);
3229
type Error = Error;
3330

0 commit comments

Comments
 (0)