1use std::net::{IpAddr, SocketAddr, SocketAddrV4};
2use std::sync::mpsc::{channel, Receiver, Sender};
3use std::time;
4
5use log::*;
6
7use crate::arch_def::Architecture;
8use crate::configuration::*;
9use crate::crypt_udp::CryptUdp;
10use crate::crypt_udp::UdpPacket;
11use crate::error::*;
12use crate::event::Event;
13use crate::manager::*;
14use crate::tui_display::TuiApp;
15use crate::wg_dev::*;
16use crate::Arch;
17
18pub fn run(
19 static_config: &StaticConfiguration,
20 mut wg_dev: Box<dyn WireguardDevice>,
21) -> BoxResult<()> {
22 let (tx, rx) = channel();
23
24 Arch::arch_specific_init(tx.clone());
25
26 let tx_handler = tx.clone();
27 ctrlc::set_handler(move || {
28 warn!("CTRL-C");
29 tx_handler
30 .send(Event::CtrlC)
31 .expect("Could not send signal on channel.")
32 })
33 .expect("Error setting Ctrl-C handler");
34
35 let port = static_config.my_admin_port();
36
37 let (v4_socket_first, need_v4_socket, need_v6_socket) = Arch::ipv4v6_socket_setup();
38
39 let mut opt_crypt_socket_v6 = None;
40 let mut opt_crypt_socket_v4 = None;
41
42 if need_v4_socket && v4_socket_first {
43 debug!("bind to 0.0.0.0:{}", port);
44 opt_crypt_socket_v4 = Some(
45 CryptUdp::bind(IpAddr::V4("0.0.0.0".parse().unwrap()), port)?
46 .key(&static_config.shared_key)?,
47 );
48 }
49 if need_v6_socket {
50 debug!("bind to :::{}", port);
51 opt_crypt_socket_v6 = Some(
52 CryptUdp::bind(IpAddr::V6("::".parse().unwrap()), port)?
53 .key(&static_config.shared_key)?,
54 );
55 }
56 if need_v4_socket && !v4_socket_first {
57 debug!("bind to 0.0.0.0:{}", port);
58 opt_crypt_socket_v4 = Some(
59 CryptUdp::bind(IpAddr::V4("0.0.0.0".parse().unwrap()), port)?
60 .key(&static_config.shared_key)?,
61 );
62 }
63
64 if opt_crypt_socket_v4.is_none() {
65 opt_crypt_socket_v4 = opt_crypt_socket_v6.as_ref().map(|s| s.try_clone().unwrap());
66 }
67 if opt_crypt_socket_v6.is_none() {
68 opt_crypt_socket_v6 = opt_crypt_socket_v4.as_ref().map(|s| s.try_clone().unwrap());
69 }
70
71 let crypt_socket_v4 = opt_crypt_socket_v4.unwrap();
72 let crypt_socket_v6 = opt_crypt_socket_v6.unwrap();
73
74 if need_v4_socket {
76 let tx_clone = tx.clone();
77 let crypt_socket_v4_clone = crypt_socket_v4
78 .try_clone()
79 .expect("couldn't clone the crypt_socket");
80 std::thread::spawn(move || loop {
81 let mut buf = [0; 2000];
82 match crypt_socket_v4_clone.recv_from(&mut buf) {
83 Ok((received, src_addr)) => {
84 info!("received {} bytes from {:?}", received, src_addr);
85 match bincode::deserialize::<UdpPacket>(&buf[..received]) {
86 Ok(udp_packet) => {
87 tx_clone.send(Event::Udp(udp_packet, src_addr)).unwrap();
88 }
89 Err(e) => {
90 error!("Error in decode: {:?}", e);
91 }
92 }
93 }
94 Err(e) => {
95 error!("{:?}", e);
96 }
97 }
98 });
99 }
100
101 if need_v6_socket {
103 let tx_clone = tx.clone();
104 let crypt_socket_v6_clone = crypt_socket_v6
105 .try_clone()
106 .expect("couldn't clone the crypt_socket");
107 std::thread::spawn(move || loop {
108 let mut buf = [0; 2000];
109 match crypt_socket_v6_clone.recv_from(&mut buf) {
110 Ok((received, src_addr)) => {
111 info!("received {} bytes from {:?}", received, src_addr);
112 match bincode::deserialize::<UdpPacket>(&buf[..received]) {
113 Ok(udp_packet) => {
114 tx_clone.send(Event::Udp(udp_packet, src_addr)).unwrap();
115 }
116 Err(e) => {
117 error!("Error in decode: {:?}", e);
118 }
119 }
120 }
121 Err(e) => {
122 error!("{:?}", e);
123 }
124 }
125 });
126 }
127
128 let tx_clone = tx.clone();
130 std::thread::spawn(move || {
131 let interval_1s = time::Duration::from_millis(1000);
132 loop {
133 tx_clone.send(Event::TimerTick1s).unwrap();
134 std::thread::sleep(interval_1s);
135 }
136 });
137
138 if !static_config.use_existing_interface {
140 wg_dev.take_down_device().ok();
141
142 wg_dev.create_device()?;
143 } else {
144 wg_dev.flush_all()?;
145 }
146
147 wg_dev.set_ip(&static_config.wg_ip, &static_config.subnet)?;
148
149 let mut tui_app = if static_config.use_tui {
150 TuiApp::init(tx.clone())?
151 } else {
152 TuiApp::off()
153 };
154
155 let rc = main_loop(
156 static_config,
157 &*wg_dev,
158 crypt_socket_v4,
159 crypt_socket_v6,
160 tx,
161 rx,
162 &mut tui_app,
163 );
164
165 if !static_config.use_existing_interface {
166 wg_dev.take_down_device().ok();
167 }
168
169 tui_app.deinit()?;
170
171 rc
172}
173
174fn main_loop(
175 static_config: &StaticConfiguration,
176 wg_dev: &dyn WireguardDevice,
177 mut crypt_socket_v4: CryptUdp,
178 mut crypt_socket_v6: CryptUdp,
179 tx: Sender<Event>,
180 rx: Receiver<Event>,
181 tui_app: &mut TuiApp,
182) -> BoxResult<()> {
183 let mut network_manager = NetworkManager::new(static_config);
184
185 tx.send(Event::UpdateWireguardConfiguration).unwrap();
187
188 let mut tick_cnt = 0;
189 loop {
190 let evt = rx.recv();
191 match evt {
193 Err(e) => {
194 error!("Receive error: {:?}", e);
195 break;
196 }
197 Ok(Event::CtrlC) => {
198 break;
199 }
200 Ok(Event::TimerTick1s) => {
201 tui_app.draw()?;
202
203 if tick_cnt % 30 == 2 {
204 network_manager.stats();
206 }
207
208 let now = crate::util::now();
209 let events = network_manager.process_all_nodes_every_second(now, static_config);
210 for evt in events.into_iter() {
211 tx.send(evt).unwrap();
212 }
213
214 tick_cnt += 1;
215 }
216 Ok(Event::Udp(udp_packet, src_addr)) => {
217 let src_addr = match src_addr {
218 SocketAddr::V4(_) => src_addr,
219 SocketAddr::V6(sa) => {
220 if let Some(ipv4) = sa.ip().to_ipv4() {
221 SocketAddr::V4(SocketAddrV4::new(ipv4, sa.port()))
222 } else {
223 src_addr
224 }
225 }
226 };
227
228 use UdpPacket::*;
229 let events: Vec<Event>;
230 match udp_packet {
231 Advertisement(ad) => {
232 debug!(target: &ad.wg_ip.to_string(), "Received advertisement from {:?}", src_addr);
233 let now = crate::util::now();
234 events =
235 network_manager.analyze_advertisement(now, static_config, ad, src_addr);
236 }
237 RouteDatabaseRequest => match src_addr {
238 SocketAddr::V4(destination) => {
239 info!(target: "routing", "RouteDatabaseRequest from {:?}", src_addr);
240 debug!(target: &destination.ip().to_string(), "Received database request");
241 events = vec![Event::SendRouteDatabase { to: destination }];
242 }
243 SocketAddr::V6(source) => {
244 error!(target: "routing", "Expected IPV4 and not IPV6 address {:?}", source);
245 events = vec![];
246 }
247 },
248 RouteDatabase(db) => {
249 info!(target: "routing", "RouteDatabase from {}", src_addr);
250 debug!(target: &src_addr.ip().to_string(), "Received route database, version = {}", db.routedb_version);
251 events = network_manager
252 .process_route_database(db)
253 .unwrap_or_default();
254 }
255 LocalContactRequest => match src_addr {
256 SocketAddr::V4(destination) => {
257 info!(target: "probing", "LocalContactRequest from {:?}", src_addr);
258 debug!(target: &destination.ip().to_string(), "Received local contact request");
259 events = vec![Event::SendLocalContact { to: destination }];
260 }
261 SocketAddr::V6(source) => {
262 error!(target: "probing", "Expected IPV4 and not IPV6 address {:?}", source);
263 events = vec![];
264 }
265 },
266 LocalContact(contact) => {
267 debug!(target: "probing", "Received contact info: {:#?}", contact);
268 debug!(target: &contact.wg_ip.to_string(), "Received local contacts");
269 network_manager.process_local_contact(contact);
270 events = vec![];
271 }
272 }
273 for evt in events {
274 tx.send(evt).unwrap();
275 }
276 }
277 Ok(Event::SendAdvertisement {
278 addressed_to,
279 to: destination,
280 wg_ip,
281 }) => {
282 debug!(target: &wg_ip.to_string(),"Send advertisement to {:?}", destination);
283 let routedb_version = network_manager.db_version();
284 let my_visible_wg_endpoint =
285 network_manager.my_visible_wg_endpoint.as_ref().copied();
286 let my_local_wg_port = network_manager.my_local_wg_port;
287 let opt_node = network_manager.node_for(&wg_ip);
288 let advertisement = UdpPacket::advertisement_from_config(
289 static_config,
290 routedb_version,
291 addressed_to,
292 opt_node,
293 my_local_wg_port,
294 my_visible_wg_endpoint,
295 );
296 let buf = bincode::serialize(&advertisement).unwrap();
297 info!(target: "advertisement", "Send advertisement to {}", destination);
298 if destination.is_ipv4() {
299 crypt_socket_v4.send_to(&buf, destination).ok();
300 } else {
301 crypt_socket_v6.send_to(&buf, destination).ok();
302 }
303 }
304 Ok(Event::SendRouteDatabaseRequest { to: destination }) => {
305 debug!(target: &destination.ip().to_string(), "Send route database request to {:?}", destination);
306 let request = UdpPacket::route_database_request();
307 let buf = bincode::serialize(&request).unwrap();
308 info!(target: "routing", "Send RouteDatabaseRequest to {}", destination);
309 crypt_socket_v4
310 .send_to(&buf, SocketAddr::V4(destination))
311 .ok();
312 }
313 Ok(Event::SendRouteDatabase { to: destination }) => {
314 debug!(target: &destination.ip().to_string(), "Send route database to {:?}", destination);
315 let packages = network_manager.provide_route_database();
316 for p in packages {
317 let buf = bincode::serialize(&p).unwrap();
318 info!(target: "routing", "Send RouteDatabase to {}", destination);
319 crypt_socket_v4
320 .send_to(&buf, SocketAddr::V4(destination))
321 .ok();
322 }
323 }
324 Ok(Event::SendLocalContactRequest { to: destination }) => {
325 debug!(target: &destination.ip().to_string(), "Send local contact request to {:?}", destination);
326 let request = UdpPacket::local_contact_request();
327 let buf = bincode::serialize(&request).unwrap();
328 info!(target: "probing", "Send LocalContactRequest to {}", destination);
329 crypt_socket_v4
330 .send_to(&buf, SocketAddr::V4(destination))
331 .ok();
332 }
333 Ok(Event::SendLocalContact { to: destination }) => {
334 debug!(target: &destination.ip().to_string(), "Send local contacts to {:?}", destination);
335 let local_contact = UdpPacket::local_contact_from_config(
336 static_config,
337 network_manager.my_local_wg_port,
338 network_manager.my_visible_wg_endpoint,
339 );
340 trace!(target: "probing", "local contact to {:#?}", local_contact);
341 let buf = bincode::serialize(&local_contact).unwrap();
342 info!(target: "probing", "Send local contact to {}", destination);
343 crypt_socket_v4
344 .send_to(&buf, SocketAddr::V4(destination))
345 .ok();
346 }
347 Ok(Event::WireguardPortHop) => {
348 let mut new_port = network_manager.my_local_wg_port;
349 new_port = (new_port - 10000 + 1) % (65535 - 10000) + 10000;
350 trace!(target: "hopping", "Perform wireguard port hop to {}", new_port);
351 network_manager.my_local_wg_port = new_port;
352 }
353 Ok(Event::UpdateWireguardConfiguration) => {
354 info!("Update peers");
355 let conf = static_config.to_wg_configuration(&network_manager);
356 info!(target: "wireguard", "Configuration as peer\n{}\n", conf);
357 wg_dev.sync_conf(&conf)?;
358 }
359 Ok(Event::ReadWireguardConfiguration) => {
360 let pubkey_to_endpoint = wg_dev.retrieve_conf()?;
361 network_manager.current_wireguard_configuration(pubkey_to_endpoint);
362 }
363 Ok(Event::UpdateRoutes) => {
364 let changes = network_manager.get_route_changes();
365 for rc in changes {
366 use RouteChange::*;
367 debug!("{:?}", rc);
368 match rc {
369 AddRoute { to, gateway } => {
370 debug!(target: &to.to_string(), "add route with gateway {:?}", gateway);
371 wg_dev.add_route(to, gateway)?;
372 }
373 ReplaceRoute { to, gateway } => {
374 debug!(target: &to.to_string(), "replace route with gateway {:?}", gateway);
375 wg_dev.replace_route(to, gateway)?;
376 }
377 DelRoute { to, gateway } => {
378 debug!(target: &to.to_string(), "del route with gateway {:?}", gateway);
379 wg_dev.del_route(to, gateway)?;
380 }
381 }
382 }
383 tx.send(Event::UpdateWireguardConfiguration).unwrap();
384 }
385 Ok(Event::TuiApp(evt)) => {
386 tui_app.process_event(evt);
387 tui_app.draw()?;
388 }
389 }
390 }
391 Ok(())
392}