Skip to content

Commit 6088ba1

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 96f1f03 commit 6088ba1

5 files changed

Lines changed: 59 additions & 64 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ts_dataplane/src/async_tokio.rs

Lines changed: 45 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 {
@@ -89,13 +102,12 @@ impl DataPlane {
89102
}
90103

91104
/// Allocate a new underlay transport.
105+
///
106+
/// The channels handed back are for an underlay to receive messages from the dataplane
107+
/// (`ToUnderlay`) and send messages to the dataplane (`FromUnderlay`).
92108
pub async fn new_underlay_transport(
93109
&self,
94-
) -> (
95-
UnderlayTransportId,
96-
DataplaneFromUnderlay,
97-
DataplaneToUnderlay,
98-
) {
110+
) -> (UnderlayTransportId, Rx<ToUnderlay>, Tx<FromUnderlay>) {
99111
let id = self
100112
.next_underlay_transport
101113
.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
@@ -114,9 +126,12 @@ impl DataPlane {
114126
}
115127

116128
/// Allocate a new overlay transport.
129+
///
130+
/// The channels handed back are for an overlay to send messages to the dataplane
131+
/// (`FromOverlay`) and receive messages from the dataplane (`ToOverlay`).
117132
pub async fn new_overlay_transport(
118133
&self,
119-
) -> (OverlayTransportId, DataplaneToOverlay, DataplaneFromOverlay) {
134+
) -> (OverlayTransportId, Tx<FromOverlay>, Rx<ToOverlay>) {
120135
let id = self
121136
.next_overlay_transport
122137
.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
@@ -146,7 +161,7 @@ impl DataPlane {
146161
pub async fn step(&self) {
147162
enum SelectResult {
148163
OverlayDown(Vec<PacketMut>),
149-
UnderlayUp(PeerId, Vec<PacketMut>),
164+
UnderlayUp(Vec<PacketMut>),
150165
TransportsChanged,
151166
Event,
152167
}
@@ -185,10 +200,10 @@ impl DataPlane {
185200
}
186201

187202
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());
203+
let underlay_pkts = underlay_pkts.unwrap();
204+
tracing::trace!(n_underlay_pkts = underlay_pkts.len());
190205

191-
SelectResult::UnderlayUp(peer_id, underlay_pkts)
206+
SelectResult::UnderlayUp(underlay_pkts)
192207
}
193208

194209
_ = self.transports_changed.notified() => {
@@ -214,7 +229,7 @@ impl DataPlane {
214229

215230
(Some(to_peers), Some(loopback))
216231
}
217-
SelectResult::UnderlayUp(_peer_id, underlay_up) => {
232+
SelectResult::UnderlayUp(underlay_up) => {
218233
let InboundResult { to_local, to_peers } = core.sync.process_inbound(underlay_up);
219234

220235
(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, Spawn},
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, Task,
@@ -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
}
@@ -38,18 +25,14 @@ impl DataplaneActor {
3825
#[message]
3926
pub async fn new_overlay_transport(
4027
&self,
41-
) -> (OverlayTransportId, OverlayToDataplane, OverlayFromDataplane) {
28+
) -> (OverlayTransportId, Tx<FromOverlay>, Rx<ToOverlay>) {
4229
self.dataplane.new_overlay_transport().await
4330
}
4431

4532
#[message]
4633
pub async fn new_underlay_transport(
4734
&self,
48-
) -> (
49-
UnderlayTransportId,
50-
UnderlayFromDataplane,
51-
UnderlayToDataplane,
52-
) {
35+
) -> (UnderlayTransportId, Rx<ToUnderlay>, Tx<FromUnderlay>) {
5336
self.dataplane.new_underlay_transport().await
5437
}
5538
}

ts_runtime/src/multiderp/uniderp.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use kameo::{
1212
use smol_str::SmolStr;
1313
use tokio::sync::{Mutex, watch};
1414
use ts_control::DerpRegion;
15+
use ts_dataplane::async_tokio::{FromUnderlay, Rx, ToUnderlay, Tx};
1516
use ts_derp::RegionId;
1617
use ts_keys::{NodeKeyPair, NodePublicKey};
1718
use ts_packet::PacketMut;
@@ -21,7 +22,7 @@ use ts_transport::{
2122

2223
use crate::{
2324
Task,
24-
dataplane::{DataplaneActor, NewUnderlayTransport, UnderlayFromDataplane, UnderlayToDataplane},
25+
dataplane::{DataplaneActor, NewUnderlayTransport},
2526
derp_latency::DerpLatencyMeasurement,
2627
env::Env,
2728
multiderp::{Multiderp, SetRegionTransportId},
@@ -221,8 +222,8 @@ struct Runner {
221222
region_id: RegionId,
222223
region: DerpRegion,
223224
home_derp_rx: watch::Receiver<bool>,
224-
to_dataplane: UnderlayToDataplane,
225-
from_dataplane: Arc<Mutex<UnderlayFromDataplane>>,
225+
to_dataplane: Tx<FromUnderlay>,
226+
from_dataplane: Arc<Mutex<Rx<ToUnderlay>>>,
226227
peer_db: Arc<RwLock<Option<Arc<PeerDb>>>>,
227228
keys: NodeKeyPair,
228229
}
@@ -306,7 +307,7 @@ impl Runner {
306307

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

309-
let Ok(()) = self.to_dataplane.send((peer_id, pkts)) else {
310+
let Ok(()) = self.to_dataplane.send(pkts) else {
310311
tracing::error!(parent: &span, "underlay receive channel closed");
311312
break;
312313
};

ts_runtime/src/netstack_actor.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ use netstack::{
99
netcore::{Channel, NetstackControl},
1010
};
1111
use tokio::sync::Mutex;
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-
task::Task,
19-
};
15+
use crate::{Error, env::Env, task::Task};
2016

2117
pub struct NetstackActor {
2218
channel: Channel,
@@ -26,8 +22,8 @@ impl kameo::Actor for NetstackActor {
2622
type Args = (
2723
Env,
2824
netstack::netcore::Config,
29-
OverlayToDataplane,
30-
Arc<Mutex<OverlayFromDataplane>>,
25+
Tx<FromOverlay>,
26+
Arc<Mutex<Rx<ToOverlay>>>,
3127
);
3228
type Error = Error;
3329

0 commit comments

Comments
 (0)