fips_core/endpoint/
builder.rs1use super::*;
2
3#[derive(Debug, Clone)]
5pub struct FipsEndpointBuilder {
6 config: Config,
7 identity_nsec: Option<String>,
8 discovery_scope: Option<String>,
9 local_ethernet_interfaces: Vec<String>,
10 disable_system_networking: bool,
11 packet_channel_capacity: usize,
12}
13
14const DEFAULT_ENDPOINT_PACKET_CHANNEL_CAPACITY: usize = 4096;
15
16impl Default for FipsEndpointBuilder {
17 fn default() -> Self {
18 Self {
19 config: Config::new(),
20 identity_nsec: None,
21 discovery_scope: None,
22 local_ethernet_interfaces: Vec::new(),
23 disable_system_networking: true,
24 packet_channel_capacity: DEFAULT_ENDPOINT_PACKET_CHANNEL_CAPACITY,
25 }
26 }
27}
28
29impl FipsEndpointBuilder {
30 pub fn config(mut self, config: Config) -> Self {
32 self.config = config;
33 self
34 }
35
36 pub fn identity_nsec(mut self, nsec: impl Into<String>) -> Self {
38 self.identity_nsec = Some(nsec.into());
39 self
40 }
41
42 pub fn discovery_scope(mut self, scope: impl Into<String>) -> Self {
50 self.discovery_scope = Some(scope.into());
51 self
52 }
53
54 pub fn local_ethernet(mut self, interface: impl Into<String>) -> Self {
61 self.local_ethernet_interfaces.push(interface.into());
62 self
63 }
64
65 pub fn without_system_tun(mut self) -> Self {
67 self.disable_system_networking = true;
68 self
69 }
70
71 pub fn packet_channel_capacity(mut self, capacity: usize) -> Self {
73 self.packet_channel_capacity = capacity.max(1);
74 self
75 }
76
77 pub(super) fn prepared_config(&self) -> Config {
78 let mut config = self.config.clone();
79 if let Some(nsec) = &self.identity_nsec {
80 config.node.identity = IdentityConfig {
81 nsec: Some(nsec.clone()),
82 persistent: false,
83 };
84 }
85 if self.disable_system_networking {
86 config.tun.enabled = false;
87 config.dns.enabled = false;
88 config.node.system_files_enabled = false;
89 }
90 if let Some(scope) = self.discovery_scope.as_deref() {
91 config.node.discovery.lan.scope = Some(scope.to_string());
92 config.node.discovery.local.enabled = true;
93 apply_default_scoped_discovery(&mut config, scope);
94 }
95 for interface in &self.local_ethernet_interfaces {
96 add_endpoint_ethernet_transport(
97 &mut config,
98 interface,
99 self.discovery_scope.as_deref(),
100 );
101 }
102 config
103 }
104
105 pub async fn bind(self) -> Result<FipsEndpoint, FipsEndpointError> {
107 endpoint_debug_log("FipsEndpointBuilder::bind begin");
108 let config = self.prepared_config();
109 endpoint_debug_log("FipsEndpointBuilder::bind config prepared");
110
111 let mut node = Node::new(config)?;
112 endpoint_debug_log("FipsEndpointBuilder::bind node created");
113 let identity = PeerIdentity::from_pubkey_full(node.identity().pubkey_full());
114 let npub = identity.npub();
115 let node_addr = *identity.node_addr();
116 let address = *identity.address();
117 let packet_io = node.attach_external_packet_io(self.packet_channel_capacity)?;
118 endpoint_debug_log("FipsEndpointBuilder::bind packet io attached");
119 let endpoint_data_io = node.attach_endpoint_data_io(self.packet_channel_capacity)?;
120 endpoint_debug_log("FipsEndpointBuilder::bind endpoint data io attached");
121 endpoint_debug_log("FipsEndpointBuilder::bind node.start begin");
122 node.start().await?;
123 endpoint_debug_log("FipsEndpointBuilder::bind node.start complete");
124
125 let (shutdown_tx, shutdown_rx) = oneshot::channel();
126 let task = spawn_node_task(node, shutdown_rx);
127 endpoint_debug_log("FipsEndpointBuilder::bind node task spawned");
128 let endpoint_priority_commands = endpoint_data_io.priority_command_tx;
129 let endpoint_commands = endpoint_data_io.command_tx;
130
131 Ok(FipsEndpoint {
132 identity,
133 npub,
134 node_addr,
135 address,
136 discovery_scope: self.discovery_scope,
137 outbound_packets: packet_io.outbound_tx,
138 delivered_packets: Arc::new(Mutex::new(packet_io.inbound_rx)),
139 endpoint_priority_commands,
140 endpoint_commands,
141 inbound_endpoint_tx: endpoint_data_io.event_tx,
142 inbound_endpoint_rx: Arc::new(Mutex::new(EndpointReceiveState::new(
143 endpoint_data_io.event_rx,
144 ))),
145 peer_identity_cache: std::sync::Mutex::new(std::collections::HashMap::new()),
146 shutdown_tx: Some(shutdown_tx),
147 task,
148 })
149 }
150}