mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-10 08:37:02 +00:00
feat(node): app-owned TUN seam — embedder owns the fd, FIPS uses channels
Node::enable_app_owned_tun() lets an embedder that owns the TUN fd (e.g. an Android VpnService) exchange IPv6 packet bytes with FIPS over channels instead of FIPS creating a system TUN device. It returns (app_outbound_tx, app_inbound_rx): the embedder pushes packets read from its fd into the outbound sender (app -> mesh) and pulls packets destined for its fd from the inbound receiver (mesh -> app). Called after Node::new and before start(), mirroring control_read_handle(). start() now gates TunDevice::create on tun_tx being unset, so when the app-owned channels are pre-installed it skips system-TUN creation and does no system-TUN ops. The inbound IPv6-shim delivery already writes to tun_tx, and run_rx_loop already drains tun_outbound_rx into handle_tun_outbound, so both directions reuse the existing wiring. Packets entering via app_outbound_tx bypass the system-TUN reader's handle_tun_packet, so the embedder must push only fd::/8-destined packets (FIPS no longer filters the destination) and clamp TCP MSS on outbound SYNs; the rustdoc and the IPv6-adapter design doc spell this out. Tests: app_owned_tun_seam_wires_channels covers the channel round-trip and the Active state; start_skips_system_tun_when_app_owned runs start() and asserts no named system device is created (tun_name stays unset).
This commit is contained in:
+32
-1
@@ -65,7 +65,7 @@ use crate::transport::{
|
||||
use crate::tree::TreeState;
|
||||
use crate::upper::hosts::HostMap;
|
||||
use crate::upper::icmp_rate_limit::IcmpRateLimiter;
|
||||
use crate::upper::tun::{TunError, TunOutboundRx, TunState, TunTx};
|
||||
use crate::upper::tun::{TunError, TunOutboundRx, TunOutboundTx, TunState, TunTx};
|
||||
use crate::utils::index::IndexAllocator;
|
||||
use crate::{Config, ConfigError, Identity, IdentityError, NodeAddr, PeerIdentity};
|
||||
use rand::Rng;
|
||||
@@ -2856,6 +2856,37 @@ impl Node {
|
||||
self.tun_tx.as_ref()
|
||||
}
|
||||
|
||||
/// Set up an **app-owned TUN**: rather than FIPS creating a system TUN
|
||||
/// device, the embedder (e.g. an Android `VpnService`) owns the fd and
|
||||
/// exchanges IPv6 packet bytes with FIPS over the returned channels. Call
|
||||
/// this after [`Node::new`] and **before** [`Self::start`] — and before
|
||||
/// moving the node into a background task — exactly like
|
||||
/// [`Self::control_read_handle`].
|
||||
///
|
||||
/// Returns `(app_outbound_tx, app_inbound_rx)`:
|
||||
/// - push IPv6 packets read from the app's TUN fd into `app_outbound_tx`
|
||||
/// (app → mesh); FIPS routes them to the destination node.
|
||||
/// - pull IPv6 packets destined for the app's TUN fd from `app_inbound_rx`
|
||||
/// (mesh → app) and write them to the fd (`recv_timeout` for clean stop).
|
||||
///
|
||||
/// With this set, [`Self::start`] skips system-TUN creation (it gates on
|
||||
/// `tun_tx` being unset). Packets pushed into `app_outbound_tx` bypass the
|
||||
/// system-TUN reader's `handle_tun_packet`, so the embedder must do what that
|
||||
/// path otherwise would: push only `fd::/8`-destined IPv6 packets — FIPS no
|
||||
/// longer filters the destination or emits ICMPv6 unreachable for off-mesh
|
||||
/// dests — and clamp TCP MSS on outbound SYNs.
|
||||
pub fn enable_app_owned_tun(&mut self) -> (TunOutboundTx, std::sync::mpsc::Receiver<Vec<u8>>) {
|
||||
let tun_channel_size = self.config().node.buffers.tun_channel;
|
||||
// app → mesh: the app pushes; `run_rx_loop` drains `tun_outbound_rx`.
|
||||
let (outbound_tx, outbound_rx) = tokio::sync::mpsc::channel(tun_channel_size);
|
||||
// mesh → app: the node writes inbound packets to `tun_tx`; the app pulls.
|
||||
let (tun_tx, tun_rx) = std::sync::mpsc::channel();
|
||||
self.tun_tx = Some(tun_tx);
|
||||
self.tun_outbound_rx = Some(outbound_rx);
|
||||
self.tun_state = TunState::Active;
|
||||
(outbound_tx, tun_rx)
|
||||
}
|
||||
|
||||
// === Sending ===
|
||||
|
||||
/// Encrypt and send a link-layer message to an authenticated peer.
|
||||
|
||||
Reference in New Issue
Block a user