1use crate::{P2PError, Result};
26use async_trait::async_trait;
27use serde::{Deserialize, Serialize};
28use std::net::{Ipv4Addr, Ipv6Addr};
29use std::time::{Duration, Instant};
30use tokio::sync::RwLock;
31use tracing::{debug, info, warn};
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35pub enum TunnelProtocol {
36 SixToFour,
38 Teredo,
40 SixInFour,
42 DsLite,
44 Isatap,
46 MapE,
48 MapT,
50}
51
52#[derive(Debug, Clone)]
54pub struct TunnelConfig {
55 pub protocol: TunnelProtocol,
57 pub local_ipv4: Option<Ipv4Addr>,
59 pub remote_ipv4: Option<Ipv4Addr>,
61 pub ipv6_prefix: Option<Ipv6Addr>,
63 pub aftr_ipv6: Option<Ipv6Addr>,
65 pub aftr_name: Option<String>,
67 pub mtu: u16,
69 pub keepalive_interval: Duration,
71 pub establishment_timeout: Duration,
73}
74
75#[derive(Debug, Clone)]
77pub struct TunnelMetrics {
78 pub bytes_sent: u64,
80 pub bytes_received: u64,
82 pub packets_sent: u64,
84 pub packets_received: u64,
86 pub packets_dropped: u64,
88 pub rtt: Option<Duration>,
90 pub establishment_time: Duration,
92 pub last_activity: Instant,
94}
95
96#[derive(Debug, Clone, PartialEq)]
98pub enum TunnelState {
99 Disconnected,
101 Connecting,
103 Connected,
105 Failed(String),
107 Disconnecting,
109}
110
111#[async_trait]
113pub trait Tunnel: Send + Sync {
114 fn protocol(&self) -> TunnelProtocol;
116
117 fn config(&self) -> &TunnelConfig;
119
120 async fn state(&self) -> TunnelState;
122
123 async fn metrics(&self) -> TunnelMetrics;
125
126 async fn connect(&mut self) -> Result<()>;
128
129 async fn disconnect(&mut self) -> Result<()>;
131
132 async fn is_active(&self) -> bool;
134
135 async fn encapsulate(&self, ipv6_packet: &[u8]) -> Result<Vec<u8>>;
137
138 async fn decapsulate(&self, ipv4_packet: &[u8]) -> Result<Vec<u8>>;
140
141 async fn send(&mut self, packet: &[u8]) -> Result<()>;
143
144 async fn receive(&mut self) -> Result<Vec<u8>>;
146
147 async fn maintain(&mut self) -> Result<()>;
149
150 async fn local_ipv6_addr(&self) -> Result<Ipv6Addr>;
152
153 async fn local_ipv4_addr(&self) -> Result<Ipv4Addr>;
155
156 async fn ping(&mut self, timeout: Duration) -> Result<Duration>;
158}
159
160pub struct TunnelManager {
162 tunnels: RwLock<Vec<Box<dyn Tunnel>>>,
164 active_tunnel: RwLock<Option<usize>>,
166 config: TunnelManagerConfig,
168}
169
170#[derive(Debug, Clone)]
172pub struct TunnelManagerConfig {
173 pub protocol_preference: Vec<TunnelProtocol>,
175 pub health_check_interval: Duration,
177 pub health_check_timeout: Duration,
179 pub auto_failover: bool,
181 pub max_concurrent_attempts: usize,
183}
184
185#[derive(Debug, Clone)]
187pub struct TunnelSelection {
188 pub protocol: TunnelProtocol,
190 pub reason: String,
192 pub selection_time: Duration,
194 pub is_fallback: bool,
196}
197
198#[derive(Debug, Clone)]
200pub struct NetworkCapabilities {
201 pub has_ipv6: bool,
203 pub has_ipv4: bool,
205 pub behind_nat: bool,
207 pub public_ipv4: Option<Ipv4Addr>,
209 pub ipv6_addresses: Vec<Ipv6Addr>,
211 pub has_upnp: bool,
213 pub interface_mtu: u16,
215}
216
217#[derive(Debug, Clone)]
219pub struct TunnelQualityMetric {
220 pub protocol: TunnelProtocol,
222 pub state: TunnelState,
224 pub rtt: Option<Duration>,
226 pub packet_loss: Option<f32>,
228 pub throughput: Option<f64>,
230 pub reliability_score: f32,
232 pub last_activity: Instant,
234}
235
236impl Default for TunnelConfig {
237 fn default() -> Self {
238 Self {
239 protocol: TunnelProtocol::SixToFour,
240 local_ipv4: None,
241 remote_ipv4: None,
242 ipv6_prefix: None,
243 aftr_ipv6: None,
244 aftr_name: None,
245 mtu: 1280, keepalive_interval: Duration::from_secs(30),
247 establishment_timeout: Duration::from_secs(10),
248 }
249 }
250}
251
252impl Default for TunnelManagerConfig {
253 fn default() -> Self {
254 Self {
255 protocol_preference: vec![
256 TunnelProtocol::DsLite, TunnelProtocol::Isatap, TunnelProtocol::SixToFour, TunnelProtocol::Teredo, TunnelProtocol::SixInFour, ],
262 health_check_interval: Duration::from_secs(60),
263 health_check_timeout: Duration::from_secs(5),
264 auto_failover: true,
265 max_concurrent_attempts: 3,
266 }
267 }
268}
269
270impl Default for TunnelMetrics {
271 fn default() -> Self {
272 Self {
273 bytes_sent: 0,
274 bytes_received: 0,
275 packets_sent: 0,
276 packets_received: 0,
277 packets_dropped: 0,
278 rtt: None,
279 establishment_time: Duration::ZERO,
280 last_activity: Instant::now(),
281 }
282 }
283}
284
285impl TunnelManager {
286 pub fn new() -> Self {
288 Self::with_config(TunnelManagerConfig::default())
289 }
290
291 pub fn with_config(config: TunnelManagerConfig) -> Self {
293 Self {
294 tunnels: RwLock::new(Vec::new()),
295 active_tunnel: RwLock::new(None),
296 config,
297 }
298 }
299
300 pub async fn add_tunnel(&self, tunnel: Box<dyn Tunnel>) {
302 let mut tunnels = self.tunnels.write().await;
303 tunnels.push(tunnel);
304 }
305
306 pub async fn active_tunnel(&self) -> Option<TunnelProtocol> {
308 let active_idx = self.active_tunnel.read().await;
309 if let Some(idx) = *active_idx {
310 let tunnels = self.tunnels.read().await;
311 if let Some(tunnel) = tunnels.get(idx) {
312 return Some(tunnel.protocol());
313 }
314 }
315 None
316 }
317
318 pub async fn select_tunnel(&self, capabilities: &NetworkCapabilities) -> Option<TunnelSelection> {
320 let start_time = Instant::now();
321
322 if capabilities.has_ipv6 && !capabilities.ipv6_addresses.is_empty() {
324 info!("Native IPv6 connectivity detected, no tunneling required");
325 return None;
326 }
327
328 info!("Selecting optimal tunnel protocol based on network conditions");
329 debug!("Network capabilities: {:?}", capabilities);
330
331 let selection = self.intelligent_protocol_selection(capabilities).await;
333
334 if let Some(ref selection) = selection {
335 info!("Selected {} tunnel: {}",
336 format!("{:?}", selection.protocol), selection.reason);
337 } else {
338 warn!("No suitable tunnel protocol found for current network conditions");
339 }
340
341 selection.map(|mut sel| {
342 sel.selection_time = start_time.elapsed();
343 sel
344 })
345 }
346
347 async fn intelligent_protocol_selection(&self, capabilities: &NetworkCapabilities) -> Option<TunnelSelection> {
349 let tunnels = self.tunnels.read().await;
350
351 let mut scored_protocols: Vec<(TunnelProtocol, f32, String)> = Vec::new();
353
354 for tunnel in tunnels.iter() {
355 let protocol = tunnel.protocol();
356 let (score, reason) = self.score_protocol(&protocol, capabilities).await;
357
358 debug!("Protocol {:?} scored {:.2}: {}", protocol, score, reason);
359
360 if score > 0.0 {
361 scored_protocols.push((protocol, score, reason));
362 }
363 }
364
365 scored_protocols.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
367
368 for (protocol, score, reason) in scored_protocols {
370 if let Some(tunnel_idx) = self.find_tunnel_index(&protocol, &tunnels).await {
371 if self.config.max_concurrent_attempts > 0 {
373 if let Ok(_) = self.test_protocol_viability(&protocol, tunnel_idx).await {
374 let mut active = self.active_tunnel.write().await;
375 *active = Some(tunnel_idx);
376
377 return Some(TunnelSelection {
378 protocol,
379 reason: format!("{} (score: {:.2})", reason, score),
380 selection_time: Duration::ZERO, is_fallback: score < 0.7, });
383 } else {
384 warn!("Protocol {:?} failed viability test despite good score", protocol);
385 }
386 } else {
387 let mut active = self.active_tunnel.write().await;
389 *active = Some(tunnel_idx);
390
391 return Some(TunnelSelection {
392 protocol,
393 reason: format!("{} (score: {:.2})", reason, score),
394 selection_time: Duration::ZERO,
395 is_fallback: score < 0.7,
396 });
397 }
398 }
399 }
400
401 None
402 }
403
404 async fn score_protocol(&self, protocol: &TunnelProtocol, capabilities: &NetworkCapabilities) -> (f32, String) {
406 let mut score = 0.0;
407 let mut reasons = Vec::new();
408
409 match protocol {
410 TunnelProtocol::SixToFour => {
411 if !capabilities.has_ipv4 {
412 return (0.0, "No IPv4 connectivity".to_string());
413 }
414
415 if capabilities.behind_nat {
416 return (0.0, "6to4 requires public IPv4 address, behind NAT".to_string());
417 }
418
419 if capabilities.public_ipv4.is_some() {
420 score += 0.8; reasons.push("has public IPv4");
422 } else {
423 return (0.0, "6to4 requires public IPv4 address".to_string());
424 }
425
426 if capabilities.interface_mtu >= 1500 {
428 score += 0.2;
429 reasons.push("good MTU");
430 }
431
432 (score, format!("6to4 suitable: {}", reasons.join(", ")))
433 }
434
435 TunnelProtocol::Teredo => {
436 if !capabilities.has_ipv4 {
437 return (0.0, "No IPv4 connectivity".to_string());
438 }
439
440 score += 0.6; reasons.push("works with any IPv4");
442
443 if capabilities.behind_nat {
444 score += 0.3; reasons.push("excellent NAT traversal");
446 } else {
447 score += 0.1; }
449
450 if capabilities.has_upnp {
451 score += 0.1; reasons.push("UPnP available");
453 }
454
455 (score, format!("Teredo suitable: {}", reasons.join(", ")))
456 }
457
458 TunnelProtocol::SixInFour => {
459 if !capabilities.has_ipv4 {
460 return (0.0, "No IPv4 connectivity".to_string());
461 }
462
463 score += 0.4;
465 reasons.push("requires manual configuration");
466
467 if !capabilities.behind_nat && capabilities.public_ipv4.is_some() {
468 score += 0.3; reasons.push("has public IPv4");
470 }
471
472 if capabilities.interface_mtu >= 1500 {
474 score += 0.2;
475 reasons.push("good MTU");
476 }
477
478 (score, format!("6in4 suitable: {}", reasons.join(", ")))
479 }
480
481 TunnelProtocol::DsLite => {
482 if !capabilities.has_ipv6 {
483 return (0.0, "DS-Lite requires IPv6 connectivity".to_string());
484 }
485
486 score += 0.9;
488 reasons.push("ISP-provided infrastructure");
489
490 if capabilities.has_ipv6 && !capabilities.ipv6_addresses.is_empty() {
492 score += 0.1;
493 reasons.push("native IPv6 available");
494 }
495
496 if capabilities.behind_nat {
498 reasons.push("AFTR provides centralized NAT");
500 } else {
501 score += 0.05; reasons.push("direct connectivity");
503 }
504
505 if capabilities.interface_mtu >= 1520 {
507 score += 0.05;
508 reasons.push("supports optimal MTU");
509 }
510
511 (score, format!("DS-Lite suitable: {}", reasons.join(", ")))
512 }
513
514 TunnelProtocol::Isatap => {
515 if !capabilities.has_ipv4 {
516 return (0.0, "ISATAP requires IPv4 connectivity".to_string());
517 }
518
519 score += 0.8;
521 reasons.push("enterprise-grade tunneling");
522
523 if capabilities.behind_nat {
525 score += 0.1; reasons.push("corporate NAT compatible");
527 } else {
528 score += 0.15; reasons.push("direct enterprise connectivity");
530 }
531
532 if capabilities.interface_mtu >= 1500 {
534 score += 0.1;
535 reasons.push("enterprise MTU");
536 }
537
538 if let Some(ipv4) = capabilities.public_ipv4 {
540 if ipv4.is_private() {
541 score += 0.2; reasons.push("private network detected");
543 }
544 }
545
546 (score, format!("ISATAP suitable: {}", reasons.join(", ")))
547 }
548
549 TunnelProtocol::MapE => {
550 if !capabilities.has_ipv4 {
551 return (0.0, "MAP-E requires IPv4 connectivity".to_string());
552 }
553
554 score += 0.9;
556 reasons.push("ISP-grade address sharing");
557
558 if capabilities.public_ipv4.is_some() {
560 score += 0.1;
561 reasons.push("public IPv4 available");
562 }
563
564 if capabilities.interface_mtu >= 1460 {
566 reasons.push("sufficient MTU for encapsulation");
567 } else {
568 score -= 0.1; reasons.push("low MTU may affect performance");
570 }
571
572 (score, format!("MAP-E suitable: {}", reasons.join(", ")))
573 }
574
575 TunnelProtocol::MapT => {
576 if !capabilities.has_ipv4 {
577 return (0.0, "MAP-T requires IPv4 connectivity".to_string());
578 }
579
580 score += 0.85;
582 reasons.push("stateless IPv4/IPv6 translation");
583
584 if capabilities.public_ipv4.is_some() {
586 score += 0.1;
587 reasons.push("public IPv4 available");
588 }
589
590 score += 0.05;
592 reasons.push("no encapsulation overhead");
593
594 (score, format!("MAP-T suitable: {}", reasons.join(", ")))
595 }
596 }
597 }
598
599 async fn find_tunnel_index(&self, protocol: &TunnelProtocol, tunnels: &[Box<dyn Tunnel>]) -> Option<usize> {
601 for (idx, tunnel) in tunnels.iter().enumerate() {
602 if tunnel.protocol() == *protocol {
603 return Some(idx);
604 }
605 }
606 None
607 }
608
609 async fn test_protocol_viability(&self, _protocol: &TunnelProtocol, tunnel_idx: usize) -> Result<()> {
611 let tunnels = self.tunnels.read().await;
612
613 if let Some(tunnel) = tunnels.get(tunnel_idx) {
614 match tunnel.state().await {
616 TunnelState::Connected => Ok(()),
617 TunnelState::Failed(_) => Err(P2PError::Network("Tunnel in failed state".to_string())),
618 _ => {
619 Ok(()) }
625 }
626 } else {
627 Err(P2PError::Network("Tunnel not found".to_string()))
628 }
629 }
630
631 #[allow(dead_code)]
633 fn is_protocol_suitable(&self, protocol: &TunnelProtocol, capabilities: &NetworkCapabilities) -> bool {
634 match protocol {
635 TunnelProtocol::SixToFour => {
636 capabilities.has_ipv4 && capabilities.public_ipv4.is_some() && !capabilities.behind_nat
638 }
639 TunnelProtocol::Teredo => {
640 capabilities.has_ipv4
642 }
643 TunnelProtocol::SixInFour => {
644 capabilities.has_ipv4
646 }
647 TunnelProtocol::DsLite => {
648 capabilities.has_ipv6
650 }
651 TunnelProtocol::Isatap => {
652 capabilities.has_ipv4
654 }
655 TunnelProtocol::MapE => {
656 capabilities.has_ipv4
658 }
659 TunnelProtocol::MapT => {
660 capabilities.has_ipv4
662 }
663 }
664 }
665
666 pub async fn connect(&self) -> Result<()> {
668 let active_idx = {
669 let active = self.active_tunnel.read().await;
670 *active
671 };
672
673 if let Some(idx) = active_idx {
674 let mut tunnels = self.tunnels.write().await;
675 if let Some(tunnel) = tunnels.get_mut(idx) {
676 tunnel.connect().await?;
677 info!("Successfully connected using {} tunnel",
678 format!("{:?}", tunnel.protocol()));
679 return Ok(());
680 }
681 }
682
683 Err(P2PError::Network("No active tunnel selected".to_string()).into())
684 }
685
686 pub async fn disconnect(&self) -> Result<()> {
688 let active_idx = {
689 let active = self.active_tunnel.read().await;
690 *active
691 };
692
693 if let Some(idx) = active_idx {
694 let mut tunnels = self.tunnels.write().await;
695 if let Some(tunnel) = tunnels.get_mut(idx) {
696 tunnel.disconnect().await?;
697 debug!("Disconnected {} tunnel", format!("{:?}", tunnel.protocol()));
698 }
699 }
700
701 Ok(())
702 }
703
704 pub async fn send(&self, packet: &[u8]) -> Result<()> {
706 let active_idx = {
707 let active = self.active_tunnel.read().await;
708 *active
709 };
710
711 if let Some(idx) = active_idx {
712 let mut tunnels = self.tunnels.write().await;
713 if let Some(tunnel) = tunnels.get_mut(idx) {
714 return tunnel.send(packet).await;
715 }
716 }
717
718 Err(P2PError::Network("No active tunnel for sending".to_string()).into())
719 }
720
721 pub async fn receive(&self) -> Result<Vec<u8>> {
723 let active_idx = {
724 let active = self.active_tunnel.read().await;
725 *active
726 };
727
728 if let Some(idx) = active_idx {
729 let mut tunnels = self.tunnels.write().await;
730 if let Some(tunnel) = tunnels.get_mut(idx) {
731 return tunnel.receive().await;
732 }
733 }
734
735 Err(P2PError::Network("No active tunnel for receiving".to_string()).into())
736 }
737
738 pub async fn metrics(&self) -> Option<TunnelMetrics> {
740 let active_idx = {
741 let active = self.active_tunnel.read().await;
742 *active
743 };
744
745 if let Some(idx) = active_idx {
746 let tunnels = self.tunnels.read().await;
747 if let Some(tunnel) = tunnels.get(idx) {
748 return Some(tunnel.metrics().await);
749 }
750 }
751
752 None
753 }
754
755 pub async fn health_check(&self) -> Result<()> {
757 let mut tunnels = self.tunnels.write().await;
758 let current_active = {
759 let active = self.active_tunnel.read().await;
760 *active
761 };
762
763 let mut active_tunnel_failed = false;
764
765 for (idx, tunnel) in tunnels.iter_mut().enumerate() {
766 match tunnel.ping(self.config.health_check_timeout).await {
767 Ok(rtt) => {
768 debug!("Health check passed for {} tunnel (RTT: {:?})",
769 format!("{:?}", tunnel.protocol()), rtt);
770 }
771 Err(e) => {
772 warn!("Health check failed for {} tunnel: {}",
773 format!("{:?}", tunnel.protocol()), e);
774
775 if current_active == Some(idx) {
777 active_tunnel_failed = true;
778 }
779
780 if self.config.auto_failover {
781 if let Err(reconnect_err) = tunnel.connect().await {
783 warn!("Failed to reconnect {} tunnel: {}",
784 format!("{:?}", tunnel.protocol()), reconnect_err);
785 }
786 }
787 }
788 }
789 }
790
791 if active_tunnel_failed && self.config.auto_failover {
793 drop(tunnels); self.perform_automatic_failover().await?;
795 }
796
797 Ok(())
798 }
799
800 pub async fn perform_automatic_failover(&self) -> Result<()> {
802 info!("Performing automatic tunnel failover...");
803
804 let capabilities = detect_network_capabilities().await?;
806
807 if let Some(selection) = self.select_tunnel(&capabilities).await {
809 info!("Failover successful: switched to {} tunnel ({})",
810 format!("{:?}", selection.protocol), selection.reason);
811
812 self.connect().await?;
814
815 Ok(())
816 } else {
817 let error_msg = "No suitable backup tunnel available for failover";
818 warn!("{}", error_msg);
819 Err(P2PError::Network(error_msg.to_string()))
820 }
821 }
822
823 pub async fn get_tunnel_quality_metrics(&self) -> Vec<TunnelQualityMetric> {
825 let tunnels = self.tunnels.read().await;
826 let mut metrics = Vec::new();
827
828 for tunnel in tunnels.iter() {
829 let tunnel_metrics = tunnel.metrics().await;
830 let state = tunnel.state().await;
831
832 let quality = TunnelQualityMetric {
833 protocol: tunnel.protocol(),
834 state: state.clone(),
835 rtt: tunnel_metrics.rtt,
836 packet_loss: if tunnel_metrics.packets_sent > 0 {
837 Some((tunnel_metrics.packets_dropped as f32 / tunnel_metrics.packets_sent as f32) * 100.0)
838 } else {
839 None
840 },
841 throughput: calculate_throughput(&tunnel_metrics),
842 reliability_score: calculate_reliability_score(&state, &tunnel_metrics),
843 last_activity: tunnel_metrics.last_activity,
844 };
845
846 metrics.push(quality);
847 }
848
849 metrics
850 }
851
852 pub async fn start_monitoring(&self) -> Result<()> {
854 if self.config.health_check_interval.is_zero() {
855 debug!("Health check monitoring disabled (interval is zero)");
856 return Ok(());
857 }
858
859 info!("Starting tunnel monitoring with interval {:?}", self.config.health_check_interval);
860
861 debug!("Tunnel monitoring task would be spawned here");
864
865 Ok(())
866 }
867
868 pub async fn maintain(&self) -> Result<()> {
870 let mut tunnels = self.tunnels.write().await;
871
872 for tunnel in tunnels.iter_mut() {
873 if let Err(e) = tunnel.maintain().await {
874 warn!("Maintenance failed for {} tunnel: {}",
875 format!("{:?}", tunnel.protocol()), e);
876 }
877 }
878
879 Ok(())
880 }
881}
882
883impl Default for TunnelManager {
884 fn default() -> Self {
885 Self::new()
886 }
887}
888
889pub async fn detect_network_capabilities() -> Result<NetworkCapabilities> {
891 debug!("Detecting network capabilities...");
892
893 let mut capabilities = NetworkCapabilities {
894 has_ipv6: false,
895 has_ipv4: false,
896 behind_nat: false,
897 public_ipv4: None,
898 ipv6_addresses: Vec::new(),
899 has_upnp: false,
900 interface_mtu: 1500,
901 };
902
903 capabilities.has_ipv4 = detect_ipv4_connectivity().await;
905 debug!("IPv4 connectivity: {}", capabilities.has_ipv4);
906
907 let ipv6_result = detect_ipv6_connectivity().await;
909 capabilities.has_ipv6 = !ipv6_result.is_empty();
910 capabilities.ipv6_addresses = ipv6_result;
911 debug!("IPv6 connectivity: {}, addresses: {:?}", capabilities.has_ipv6, capabilities.ipv6_addresses);
912
913 if capabilities.has_ipv4 {
915 let nat_detection = detect_nat_and_public_ip().await;
916 capabilities.behind_nat = nat_detection.0;
917 capabilities.public_ipv4 = nat_detection.1;
918 debug!("NAT detection: behind_nat={}, public_ipv4={:?}", capabilities.behind_nat, capabilities.public_ipv4);
919 }
920
921 capabilities.has_upnp = test_upnp_availability().await;
923 debug!("UPnP availability: {}", capabilities.has_upnp);
924
925 capabilities.interface_mtu = detect_interface_mtu().await;
927 debug!("Interface MTU: {}", capabilities.interface_mtu);
928
929 info!("Network capabilities detected: IPv4={}, IPv6={}, NAT={}, UPnP={}, MTU={}",
930 capabilities.has_ipv4, capabilities.has_ipv6, capabilities.behind_nat,
931 capabilities.has_upnp, capabilities.interface_mtu);
932
933 Ok(capabilities)
934}
935
936async fn detect_ipv4_connectivity() -> bool {
938 let test_addresses = [
940 "8.8.8.8:53", "1.1.1.1:53", "208.67.222.222:53", ];
944
945 for addr in &test_addresses {
946 if let Ok(_) = tokio::time::timeout(
947 Duration::from_secs(3),
948 tokio::net::TcpStream::connect(addr)
949 ).await {
950 debug!("IPv4 connectivity confirmed via {}", addr);
951 return true;
952 }
953 }
954
955 debug!("IPv4 connectivity test failed");
956 false
957}
958
959async fn detect_ipv6_connectivity() -> Vec<Ipv6Addr> {
961 let mut ipv6_addrs = Vec::new();
962
963 if let Ok(interfaces) = get_network_interfaces().await {
965 for interface in interfaces {
966 for addr in interface.ipv6_addrs {
967 if !addr.is_loopback() && !addr.is_multicast() {
968 ipv6_addrs.push(addr);
969 }
970 }
971 }
972 }
973
974 if !ipv6_addrs.is_empty() {
976 let test_addresses = [
977 "[2001:4860:4860::8888]:53", "[2606:4700:4700::1111]:53", ];
980
981 for addr in &test_addresses {
982 if let Ok(_) = tokio::time::timeout(
983 Duration::from_secs(3),
984 tokio::net::TcpStream::connect(addr)
985 ).await {
986 debug!("IPv6 connectivity confirmed via {}", addr);
987 return ipv6_addrs;
988 }
989 }
990
991 debug!("IPv6 addresses found but no external connectivity");
992 ipv6_addrs.clear(); }
994
995 ipv6_addrs
996}
997
998async fn detect_nat_and_public_ip() -> (bool, Option<Ipv4Addr>) {
1000 let local_ipv4 = get_local_ipv4_addr().await;
1002
1003 if let Ok(public_ip) = discover_public_ipv4().await {
1005 let behind_nat = local_ipv4.map_or(true, |local| local != public_ip);
1006 return (behind_nat, Some(public_ip));
1007 }
1008
1009 if let Some(local) = local_ipv4 {
1011 let behind_nat = local.is_private();
1012 (behind_nat, if behind_nat { None } else { Some(local) })
1013 } else {
1014 (true, None)
1015 }
1016}
1017
1018async fn discover_public_ipv4() -> Result<Ipv4Addr> {
1020 let services = [
1022 "https://api.ipify.org",
1023 "https://icanhazip.com",
1024 "https://ifconfig.me/ip",
1025 ];
1026
1027 for service in &services {
1028 if let Ok(response) = tokio::time::timeout(
1029 Duration::from_secs(5),
1030 reqwest::get(*service)
1031 ).await {
1032 if let Ok(response) = response {
1033 if let Ok(ip_str) = response.text().await {
1034 if let Ok(ip) = ip_str.trim().parse::<Ipv4Addr>() {
1035 debug!("Public IPv4 discovered via {}: {}", service, ip);
1036 return Ok(ip);
1037 }
1038 }
1039 }
1040 }
1041 }
1042
1043 Err(P2PError::Network("Failed to discover public IPv4 address".to_string()))
1044}
1045
1046async fn get_local_ipv4_addr() -> Option<Ipv4Addr> {
1048 if let Ok(interfaces) = get_network_interfaces().await {
1049 for interface in interfaces {
1050 for addr in interface.ipv4_addrs {
1051 if !addr.is_loopback() && !addr.is_multicast() {
1052 return Some(addr);
1053 }
1054 }
1055 }
1056 }
1057 None
1058}
1059
1060async fn test_upnp_availability() -> bool {
1062 debug!("UPnP testing not implemented, assuming unavailable");
1069 false
1070}
1071
1072async fn detect_interface_mtu() -> u16 {
1074 1500
1081}
1082
1083#[allow(dead_code)]
1085#[derive(Debug)]
1086struct NetworkInterface {
1087 _name: String,
1088 ipv4_addrs: Vec<Ipv4Addr>,
1089 ipv6_addrs: Vec<Ipv6Addr>,
1090}
1091
1092async fn get_network_interfaces() -> Result<Vec<NetworkInterface>> {
1094 let interface = NetworkInterface {
1099 _name: "eth0".to_string(),
1100 ipv4_addrs: vec![Ipv4Addr::new(192, 168, 1, 100)],
1101 ipv6_addrs: vec![],
1102 };
1103
1104 Ok(vec![interface])
1105}
1106
1107fn calculate_throughput(metrics: &TunnelMetrics) -> Option<f64> {
1109 let elapsed = metrics.last_activity.elapsed();
1110 if elapsed.as_secs() > 0 {
1111 let total_bytes = metrics.bytes_sent + metrics.bytes_received;
1112 Some(total_bytes as f64 / elapsed.as_secs_f64())
1113 } else {
1114 None
1115 }
1116}
1117
1118fn calculate_reliability_score(state: &TunnelState, metrics: &TunnelMetrics) -> f32 {
1120 let mut score = match state {
1121 TunnelState::Connected => 1.0,
1122 TunnelState::Connecting => 0.5,
1123 TunnelState::Disconnected => 0.0,
1124 TunnelState::Failed(_) => 0.0,
1125 TunnelState::Disconnecting => 0.2,
1126 };
1127
1128 if metrics.packets_sent > 0 {
1130 let packet_loss = metrics.packets_dropped as f32 / metrics.packets_sent as f32;
1131 score *= (1.0 - packet_loss).max(0.0);
1132 }
1133
1134 let inactive_time = metrics.last_activity.elapsed();
1136 if inactive_time > Duration::from_secs(300) { score *= 0.5; }
1139
1140 score.min(1.0).max(0.0)
1141}
1142
1143pub mod sixto4;
1145pub mod teredo;
1146pub mod sixinfour;
1147pub mod dslite;
1148pub mod isatap;
1149pub mod map;
1150
1151pub use sixto4::SixToFourTunnel;
1152pub use teredo::TeredoTunnel;
1153pub use sixinfour::SixInFourTunnel;
1154pub use dslite::DsLiteTunnel;
1155pub use isatap::IsatapTunnel;
1156pub use map::{MapTunnel, MapProtocol, MapRule, PortParameters, PortSet};
1157
1158#[cfg(test)]
1159mod tests {
1160 use super::*;
1161 use std::sync::Arc;
1162 use std::sync::atomic::{AtomicUsize, Ordering};
1163 use tokio::sync::Mutex;
1164
1165 struct MockTunnel {
1167 protocol: TunnelProtocol,
1168 config: TunnelConfig,
1169 state: Arc<Mutex<TunnelState>>,
1170 metrics: Arc<Mutex<TunnelMetrics>>,
1171 should_fail: bool,
1172 packet_counter: AtomicUsize,
1173 }
1174
1175 impl MockTunnel {
1176 fn new(config: TunnelConfig) -> Self {
1177 Self {
1178 protocol: config.protocol.clone(),
1179 config,
1180 state: Arc::new(Mutex::new(TunnelState::Disconnected)),
1181 metrics: Arc::new(Mutex::new(TunnelMetrics::default())),
1182 should_fail: false,
1183 packet_counter: AtomicUsize::new(0),
1184 }
1185 }
1186
1187 fn with_failure(mut self) -> Self {
1188 self.should_fail = true;
1189 self
1190 }
1191
1192 async fn set_state(&self, new_state: TunnelState) {
1193 let mut state = self.state.lock().await;
1194 *state = new_state;
1195 }
1196 }
1197
1198 #[async_trait]
1199 impl Tunnel for MockTunnel {
1200 fn protocol(&self) -> TunnelProtocol {
1201 self.protocol.clone()
1202 }
1203
1204 fn config(&self) -> &TunnelConfig {
1205 &self.config
1206 }
1207
1208 async fn state(&self) -> TunnelState {
1209 self.state.lock().await.clone()
1210 }
1211
1212 async fn metrics(&self) -> TunnelMetrics {
1213 self.metrics.lock().await.clone()
1214 }
1215
1216 async fn connect(&mut self) -> Result<()> {
1217 if self.should_fail {
1218 let mut state = self.state.lock().await;
1219 *state = TunnelState::Failed("Connection failed".to_string());
1220 return Err(P2PError::Network("Mock connection failure".to_string()));
1221 }
1222
1223 let mut state = self.state.lock().await;
1224 *state = TunnelState::Connecting;
1225 tokio::time::sleep(Duration::from_millis(10)).await;
1226 *state = TunnelState::Connected;
1227
1228 let mut metrics = self.metrics.lock().await;
1229 metrics.establishment_time = Duration::from_millis(10);
1230 metrics.last_activity = Instant::now();
1231
1232 Ok(())
1233 }
1234
1235 async fn disconnect(&mut self) -> Result<()> {
1236 let mut state = self.state.lock().await;
1237 *state = TunnelState::Disconnecting;
1238 tokio::time::sleep(Duration::from_millis(5)).await;
1239 *state = TunnelState::Disconnected;
1240 Ok(())
1241 }
1242
1243 async fn is_active(&self) -> bool {
1244 matches!(self.state().await, TunnelState::Connected)
1245 }
1246
1247 async fn encapsulate(&self, ipv6_packet: &[u8]) -> Result<Vec<u8>> {
1248 if !self.is_active().await {
1249 return Err(P2PError::Network("Tunnel not active".to_string()));
1250 }
1251
1252 let mut ipv4_packet = vec![0x45, 0x00, 0x00, 0x00]; ipv4_packet.extend_from_slice(ipv6_packet);
1255 Ok(ipv4_packet)
1256 }
1257
1258 async fn decapsulate(&self, ipv4_packet: &[u8]) -> Result<Vec<u8>> {
1259 if !self.is_active().await {
1260 return Err(P2PError::Network("Tunnel not active".to_string()));
1261 }
1262
1263 if ipv4_packet.len() < 4 {
1264 return Err(P2PError::Network("Invalid IPv4 packet".to_string()));
1265 }
1266
1267 Ok(ipv4_packet[4..].to_vec())
1269 }
1270
1271 async fn send(&mut self, packet: &[u8]) -> Result<()> {
1272 if !self.is_active().await {
1273 return Err(P2PError::Network("Tunnel not active".to_string()));
1274 }
1275
1276 let mut metrics = self.metrics.lock().await;
1277 metrics.bytes_sent += packet.len() as u64;
1278 metrics.packets_sent += 1;
1279 metrics.last_activity = Instant::now();
1280
1281 self.packet_counter.fetch_add(1, Ordering::Relaxed);
1282 Ok(())
1283 }
1284
1285 async fn receive(&mut self) -> Result<Vec<u8>> {
1286 if !self.is_active().await {
1287 return Err(P2PError::Network("Tunnel not active".to_string()));
1288 }
1289
1290 let packet = b"mock_packet".to_vec();
1291 let mut metrics = self.metrics.lock().await;
1292 metrics.bytes_received += packet.len() as u64;
1293 metrics.packets_received += 1;
1294 metrics.last_activity = Instant::now();
1295
1296 Ok(packet)
1297 }
1298
1299 async fn maintain(&mut self) -> Result<()> {
1300 let mut metrics = self.metrics.lock().await;
1301 metrics.last_activity = Instant::now();
1302 Ok(())
1303 }
1304
1305 async fn local_ipv6_addr(&self) -> Result<Ipv6Addr> {
1306 self.config.ipv6_prefix
1307 .ok_or_else(|| P2PError::Network("No IPv6 prefix configured".to_string()))
1308 }
1309
1310 async fn local_ipv4_addr(&self) -> Result<Ipv4Addr> {
1311 self.config.local_ipv4
1312 .ok_or_else(|| P2PError::Network("No IPv4 address configured".to_string()))
1313 }
1314
1315 async fn ping(&mut self, timeout: Duration) -> Result<Duration> {
1316 if self.should_fail {
1317 return Err(P2PError::Network("Ping failed".to_string()));
1318 }
1319
1320 if !self.is_active().await {
1321 return Err(P2PError::Network("Tunnel not active".to_string()));
1322 }
1323
1324 let rtt = Duration::from_millis(10 + (timeout.as_millis() % 50) as u64);
1326
1327 let mut metrics = self.metrics.lock().await;
1328 metrics.rtt = Some(rtt);
1329 metrics.last_activity = Instant::now();
1330
1331 Ok(rtt)
1332 }
1333 }
1334
1335 fn create_test_tunnel_config(protocol: TunnelProtocol) -> TunnelConfig {
1336 TunnelConfig {
1337 protocol,
1338 local_ipv4: Some(Ipv4Addr::new(192, 168, 1, 100)),
1339 remote_ipv4: Some(Ipv4Addr::new(203, 0, 113, 1)),
1340 ipv6_prefix: Some(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1341 aftr_ipv6: Some(Ipv6Addr::new(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1)),
1342 aftr_name: Some("aftr.test.com".to_string()),
1343 mtu: 1280,
1344 keepalive_interval: Duration::from_secs(30),
1345 establishment_timeout: Duration::from_secs(10),
1346 }
1347 }
1348
1349 fn create_test_network_capabilities() -> NetworkCapabilities {
1350 NetworkCapabilities {
1351 has_ipv6: false,
1352 has_ipv4: true,
1353 behind_nat: false,
1354 public_ipv4: Some(Ipv4Addr::new(203, 0, 113, 100)),
1355 ipv6_addresses: vec![],
1356 has_upnp: false,
1357 interface_mtu: 1500,
1358 }
1359 }
1360
1361 #[test]
1362 fn test_tunnel_protocol_equality() {
1363 assert_eq!(TunnelProtocol::SixToFour, TunnelProtocol::SixToFour);
1364 assert_ne!(TunnelProtocol::SixToFour, TunnelProtocol::Teredo);
1365 assert_eq!(TunnelProtocol::MapE, TunnelProtocol::MapE);
1366 }
1367
1368 #[test]
1369 fn test_tunnel_state_variants() {
1370 let disconnected = TunnelState::Disconnected;
1371 let connecting = TunnelState::Connecting;
1372 let connected = TunnelState::Connected;
1373 let failed = TunnelState::Failed("test error".to_string());
1374 let disconnecting = TunnelState::Disconnecting;
1375
1376 assert!(matches!(disconnected, TunnelState::Disconnected));
1377 assert!(matches!(connecting, TunnelState::Connecting));
1378 assert!(matches!(connected, TunnelState::Connected));
1379 assert!(matches!(failed, TunnelState::Failed(_)));
1380 assert!(matches!(disconnecting, TunnelState::Disconnecting));
1381 }
1382
1383 #[test]
1384 fn test_tunnel_config_default() {
1385 let config = TunnelConfig::default();
1386
1387 assert_eq!(config.protocol, TunnelProtocol::SixToFour);
1388 assert_eq!(config.mtu, 1280);
1389 assert_eq!(config.keepalive_interval, Duration::from_secs(30));
1390 assert_eq!(config.establishment_timeout, Duration::from_secs(10));
1391 assert!(config.local_ipv4.is_none());
1392 assert!(config.remote_ipv4.is_none());
1393 }
1394
1395 #[test]
1396 fn test_tunnel_manager_config_default() {
1397 let config = TunnelManagerConfig::default();
1398
1399 assert_eq!(config.protocol_preference.len(), 5);
1400 assert_eq!(config.protocol_preference[0], TunnelProtocol::DsLite);
1401 assert_eq!(config.health_check_interval, Duration::from_secs(60));
1402 assert!(config.auto_failover);
1403 assert_eq!(config.max_concurrent_attempts, 3);
1404 }
1405
1406 #[test]
1407 fn test_tunnel_metrics_default() {
1408 let metrics = TunnelMetrics::default();
1409
1410 assert_eq!(metrics.bytes_sent, 0);
1411 assert_eq!(metrics.bytes_received, 0);
1412 assert_eq!(metrics.packets_sent, 0);
1413 assert_eq!(metrics.packets_received, 0);
1414 assert_eq!(metrics.packets_dropped, 0);
1415 assert!(metrics.rtt.is_none());
1416 assert_eq!(metrics.establishment_time, Duration::ZERO);
1417 }
1418
1419 #[tokio::test]
1420 async fn test_tunnel_manager_creation() {
1421 let manager = TunnelManager::new();
1422 assert!(manager.active_tunnel().await.is_none());
1423
1424 let custom_config = TunnelManagerConfig {
1425 auto_failover: false,
1426 max_concurrent_attempts: 1,
1427 ..Default::default()
1428 };
1429 let custom_manager = TunnelManager::with_config(custom_config);
1430 assert!(custom_manager.active_tunnel().await.is_none());
1431 }
1432
1433 #[tokio::test]
1434 async fn test_tunnel_addition_and_retrieval() {
1435 let manager = TunnelManager::new();
1436 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1437 let tunnel = MockTunnel::new(config);
1438
1439 manager.add_tunnel(Box::new(tunnel)).await;
1440
1441 let tunnels = manager.tunnels.read().await;
1442 assert_eq!(tunnels.len(), 1);
1443 assert_eq!(tunnels[0].protocol(), TunnelProtocol::SixToFour);
1444 }
1445
1446 #[tokio::test]
1447 async fn test_mock_tunnel_lifecycle() -> Result<()> {
1448 let config = create_test_tunnel_config(TunnelProtocol::Teredo);
1449 let mut tunnel = MockTunnel::new(config);
1450
1451 assert_eq!(tunnel.state().await, TunnelState::Disconnected);
1453 assert!(!tunnel.is_active().await);
1454
1455 tunnel.connect().await?;
1457 assert_eq!(tunnel.state().await, TunnelState::Connected);
1458 assert!(tunnel.is_active().await);
1459
1460 let ipv6 = tunnel.local_ipv6_addr().await?;
1462 let ipv4 = tunnel.local_ipv4_addr().await?;
1463 assert_eq!(ipv6, Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
1464 assert_eq!(ipv4, Ipv4Addr::new(192, 168, 1, 100));
1465
1466 let rtt = tunnel.ping(Duration::from_secs(1)).await?;
1468 assert!(rtt > Duration::ZERO);
1469
1470 tunnel.disconnect().await?;
1472 assert_eq!(tunnel.state().await, TunnelState::Disconnected);
1473 assert!(!tunnel.is_active().await);
1474
1475 Ok(())
1476 }
1477
1478 #[tokio::test]
1479 async fn test_tunnel_packet_operations() -> Result<()> {
1480 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1481 let mut tunnel = MockTunnel::new(config);
1482
1483 tunnel.connect().await?;
1484
1485 let ipv6_packet = vec![0x60, 0x00, 0x00, 0x00]; let ipv4_packet = tunnel.encapsulate(&ipv6_packet).await?;
1488 assert_eq!(ipv4_packet.len(), ipv6_packet.len() + 4);
1489
1490 let decapsulated = tunnel.decapsulate(&ipv4_packet).await?;
1492 assert_eq!(decapsulated, ipv6_packet);
1493
1494 let test_packet = b"test data";
1496 tunnel.send(test_packet).await?;
1497
1498 let received = tunnel.receive().await?;
1499 assert_eq!(received, b"mock_packet");
1500
1501 let metrics = tunnel.metrics().await;
1503 assert_eq!(metrics.packets_sent, 1);
1504 assert_eq!(metrics.packets_received, 1);
1505 assert_eq!(metrics.bytes_sent, test_packet.len() as u64);
1506
1507 Ok(())
1508 }
1509
1510 #[tokio::test]
1511 async fn test_tunnel_failure_handling() {
1512 let config = create_test_tunnel_config(TunnelProtocol::Teredo);
1513 let mut failing_tunnel = MockTunnel::new(config).with_failure();
1514
1515 let result = failing_tunnel.connect().await;
1517 assert!(result.is_err());
1518 assert!(matches!(failing_tunnel.state().await, TunnelState::Failed(_)));
1519
1520 let packet = vec![1, 2, 3, 4];
1522 assert!(failing_tunnel.send(&packet).await.is_err());
1523 assert!(failing_tunnel.receive().await.is_err());
1524 assert!(failing_tunnel.ping(Duration::from_secs(1)).await.is_err());
1525 }
1526
1527 #[tokio::test]
1528 async fn test_tunnel_operations_when_disconnected() {
1529 let config = create_test_tunnel_config(TunnelProtocol::SixInFour);
1530 let tunnel = MockTunnel::new(config);
1531
1532 let packet = vec![1, 2, 3, 4];
1534 assert!(tunnel.encapsulate(&packet).await.is_err());
1535 assert!(tunnel.decapsulate(&packet).await.is_err());
1536 }
1537
1538 #[tokio::test]
1539 async fn test_tunnel_selection_with_native_ipv6() {
1540 let manager = TunnelManager::new();
1541 let capabilities = NetworkCapabilities {
1542 has_ipv6: true,
1543 ipv6_addresses: vec![Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)],
1544 ..create_test_network_capabilities()
1545 };
1546
1547 let selection = manager.select_tunnel(&capabilities).await;
1548 assert!(selection.is_none()); }
1550
1551 #[tokio::test]
1552 async fn test_tunnel_selection_scoring() {
1553 let manager = TunnelManager::new();
1554 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1555 let tunnel = MockTunnel::new(config);
1556 manager.add_tunnel(Box::new(tunnel)).await;
1557
1558 let capabilities = create_test_network_capabilities();
1559 let selection = manager.select_tunnel(&capabilities).await;
1560
1561 assert!(selection.is_some());
1562 let selection = selection.unwrap();
1563 assert_eq!(selection.protocol, TunnelProtocol::SixToFour);
1564 assert!(selection.reason.contains("6to4 suitable"));
1565 assert!(!selection.is_fallback);
1566 }
1567
1568 #[tokio::test]
1569 async fn test_tunnel_selection_behind_nat() {
1570 let manager = TunnelManager::new();
1571
1572 let teredo_config = create_test_tunnel_config(TunnelProtocol::Teredo);
1574 let teredo_tunnel = MockTunnel::new(teredo_config);
1575 manager.add_tunnel(Box::new(teredo_tunnel)).await;
1576
1577 let capabilities = NetworkCapabilities {
1578 behind_nat: true,
1579 public_ipv4: None,
1580 ..create_test_network_capabilities()
1581 };
1582
1583 let selection = manager.select_tunnel(&capabilities).await;
1584 assert!(selection.is_some());
1585 let selection = selection.unwrap();
1586 assert_eq!(selection.protocol, TunnelProtocol::Teredo);
1587 assert!(selection.reason.contains("NAT traversal"));
1588 }
1589
1590 #[tokio::test]
1591 async fn test_tunnel_selection_ds_lite() {
1592 let manager = TunnelManager::new();
1593
1594 let dslite_config = create_test_tunnel_config(TunnelProtocol::DsLite);
1595 let dslite_tunnel = MockTunnel::new(dslite_config);
1596 manager.add_tunnel(Box::new(dslite_tunnel)).await;
1597
1598 let capabilities = NetworkCapabilities {
1599 has_ipv6: true,
1600 ipv6_addresses: vec![], ..create_test_network_capabilities()
1602 };
1603
1604 let selection = manager.select_tunnel(&capabilities).await;
1605 assert!(selection.is_some());
1606 let selection = selection.unwrap();
1607 assert_eq!(selection.protocol, TunnelProtocol::DsLite);
1608 assert!(selection.reason.contains("ISP-provided"));
1609 }
1610
1611 #[tokio::test]
1612 async fn test_tunnel_manager_connection() -> Result<()> {
1613 let manager = TunnelManager::new();
1614 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1615 let tunnel = MockTunnel::new(config);
1616 manager.add_tunnel(Box::new(tunnel)).await;
1617
1618 let capabilities = create_test_network_capabilities();
1620 manager.select_tunnel(&capabilities).await;
1621
1622 manager.connect().await?;
1624
1625 assert_eq!(manager.active_tunnel().await, Some(TunnelProtocol::SixToFour));
1627
1628 Ok(())
1629 }
1630
1631 #[tokio::test]
1632 async fn test_tunnel_manager_send_receive() -> Result<()> {
1633 let manager = TunnelManager::new();
1634 let config = create_test_tunnel_config(TunnelProtocol::Teredo);
1635 let tunnel = MockTunnel::new(config);
1636 manager.add_tunnel(Box::new(tunnel)).await;
1637
1638 let capabilities = create_test_network_capabilities();
1639 manager.select_tunnel(&capabilities).await;
1640 manager.connect().await?;
1641
1642 let packet = b"test packet";
1644 manager.send(packet).await?;
1645
1646 let received = manager.receive().await?;
1648 assert_eq!(received, b"mock_packet");
1649
1650 let metrics = manager.metrics().await;
1652 assert!(metrics.is_some());
1653 let metrics = metrics.unwrap();
1654 assert_eq!(metrics.packets_sent, 1);
1655
1656 Ok(())
1657 }
1658
1659 #[tokio::test]
1660 async fn test_tunnel_manager_no_active_tunnel() {
1661 let manager = TunnelManager::new();
1662
1663 assert!(manager.connect().await.is_err());
1665 assert!(manager.send(b"test").await.is_err());
1666 assert!(manager.receive().await.is_err());
1667 assert!(manager.metrics().await.is_none());
1668 }
1669
1670 #[tokio::test]
1671 async fn test_tunnel_manager_health_check() -> Result<()> {
1672 let manager = TunnelManager::new();
1673 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1674 let tunnel = MockTunnel::new(config);
1675 manager.add_tunnel(Box::new(tunnel)).await;
1676
1677 let capabilities = create_test_network_capabilities();
1678 manager.select_tunnel(&capabilities).await;
1679 manager.connect().await?;
1680
1681 manager.health_check().await?;
1683
1684 Ok(())
1685 }
1686
1687 #[tokio::test]
1688 async fn test_tunnel_manager_health_check_with_failure() -> Result<()> {
1689 let config = TunnelManagerConfig {
1691 auto_failover: false,
1692 ..Default::default()
1693 };
1694 let manager = TunnelManager::with_config(config);
1695
1696 let tunnel_config = create_test_tunnel_config(TunnelProtocol::Teredo);
1697 let failing_tunnel = MockTunnel::new(tunnel_config).with_failure();
1698 manager.add_tunnel(Box::new(failing_tunnel)).await;
1699
1700 let capabilities = create_test_network_capabilities();
1701 manager.select_tunnel(&capabilities).await;
1702
1703 manager.health_check().await?;
1705
1706 Ok(())
1707 }
1708
1709 #[tokio::test]
1710 async fn test_tunnel_manager_monitoring() -> Result<()> {
1711 let manager = TunnelManager::new();
1712
1713 manager.start_monitoring().await?;
1715
1716 Ok(())
1717 }
1718
1719 #[tokio::test]
1720 async fn test_tunnel_manager_maintenance() -> Result<()> {
1721 let manager = TunnelManager::new();
1722 let config = create_test_tunnel_config(TunnelProtocol::SixInFour);
1723 let tunnel = MockTunnel::new(config);
1724 manager.add_tunnel(Box::new(tunnel)).await;
1725
1726 manager.maintain().await?;
1728
1729 Ok(())
1730 }
1731
1732 #[tokio::test]
1733 async fn test_tunnel_quality_metrics() {
1734 let manager = TunnelManager::new();
1735 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1736 let tunnel = MockTunnel::new(config);
1737 tunnel.set_state(TunnelState::Connected).await;
1738 manager.add_tunnel(Box::new(tunnel)).await;
1739
1740 let quality_metrics = manager.get_tunnel_quality_metrics().await;
1741 assert_eq!(quality_metrics.len(), 1);
1742
1743 let metric = &quality_metrics[0];
1744 assert_eq!(metric.protocol, TunnelProtocol::SixToFour);
1745 assert_eq!(metric.state, TunnelState::Connected);
1746 assert!(metric.reliability_score > 0.0);
1747 }
1748
1749 #[tokio::test]
1750 async fn test_network_capabilities_detection() -> Result<()> {
1751 let capabilities = detect_network_capabilities().await?;
1752
1753 assert!(capabilities.interface_mtu > 0);
1755 Ok(())
1758 }
1759
1760 #[test]
1761 fn test_create_tunnel_config_sixto4() {
1762 let capabilities = create_test_network_capabilities();
1763 let config = create_tunnel_config(TunnelProtocol::SixToFour, &capabilities);
1764
1765 assert_eq!(config.protocol, TunnelProtocol::SixToFour);
1766 assert_eq!(config.local_ipv4, capabilities.public_ipv4);
1767 assert!(config.ipv6_prefix.is_some());
1768
1769 let ipv6 = config.ipv6_prefix.unwrap();
1771 let segments = ipv6.segments();
1772 assert_eq!(segments[0], 0x2002);
1773 }
1774
1775 #[test]
1776 fn test_create_tunnel_config_teredo() {
1777 let capabilities = create_test_network_capabilities();
1778 let config = create_tunnel_config(TunnelProtocol::Teredo, &capabilities);
1779
1780 assert_eq!(config.protocol, TunnelProtocol::Teredo);
1781 assert_eq!(config.mtu, 1280);
1782
1783 let ipv6 = config.ipv6_prefix.unwrap();
1785 let segments = ipv6.segments();
1786 assert_eq!(segments[0], 0x2001);
1787 }
1788
1789 #[test]
1790 fn test_create_tunnel_config_dslite() {
1791 let capabilities = create_test_network_capabilities();
1792 let config = create_tunnel_config(TunnelProtocol::DsLite, &capabilities);
1793
1794 assert_eq!(config.protocol, TunnelProtocol::DsLite);
1795 assert_eq!(config.mtu, 1520);
1796 assert!(config.aftr_name.is_some());
1797 assert_eq!(config.aftr_name.unwrap(), "aftr.example.com");
1798 }
1799
1800 #[test]
1801 fn test_create_tunnel_config_map_protocols() {
1802 let capabilities = create_test_network_capabilities();
1803
1804 let map_e_config = create_tunnel_config(TunnelProtocol::MapE, &capabilities);
1805 assert_eq!(map_e_config.protocol, TunnelProtocol::MapE);
1806 assert_eq!(map_e_config.mtu, 1460);
1807 assert_eq!(map_e_config.local_ipv4, capabilities.public_ipv4);
1808
1809 let map_t_config = create_tunnel_config(TunnelProtocol::MapT, &capabilities);
1810 assert_eq!(map_t_config.protocol, TunnelProtocol::MapT);
1811 assert_eq!(map_t_config.mtu, 1500);
1812 assert_eq!(map_t_config.local_ipv4, capabilities.public_ipv4);
1813 }
1814
1815 #[test]
1816 fn test_calculate_reliability_score() {
1817 let metrics = TunnelMetrics {
1818 packets_sent: 100,
1819 packets_dropped: 5,
1820 last_activity: Instant::now(),
1821 ..Default::default()
1822 };
1823
1824 let score_connected = calculate_reliability_score(&TunnelState::Connected, &metrics);
1825 assert!(score_connected > 0.9); let score_failed = calculate_reliability_score(&TunnelState::Failed("error".to_string()), &metrics);
1828 assert_eq!(score_failed, 0.0); let score_connecting = calculate_reliability_score(&TunnelState::Connecting, &metrics);
1831 assert!(score_connecting > 0.4 && score_connecting < 0.6); }
1833
1834 #[test]
1835 fn test_calculate_throughput() {
1836 let old_activity = Instant::now() - Duration::from_secs(10);
1837 let metrics = TunnelMetrics {
1838 bytes_sent: 1000,
1839 bytes_received: 500,
1840 last_activity: old_activity,
1841 ..Default::default()
1842 };
1843
1844 let throughput = calculate_throughput(&metrics);
1845 assert!(throughput.is_some());
1846 assert!(throughput.unwrap() > 0.0);
1847
1848 let recent_metrics = TunnelMetrics {
1850 last_activity: Instant::now(),
1851 ..Default::default()
1852 };
1853 let recent_throughput = calculate_throughput(&recent_metrics);
1854 assert!(recent_throughput.is_none());
1855 }
1856
1857 #[tokio::test]
1858 async fn test_protocol_scoring_comprehensive() {
1859 let manager = TunnelManager::new();
1860
1861 let public_capabilities = create_test_network_capabilities();
1863 let (score, reason) = manager.score_protocol(&TunnelProtocol::SixToFour, &public_capabilities).await;
1864 assert!(score > 0.8);
1865 assert!(reason.contains("6to4 suitable"));
1866
1867 let nat_capabilities = NetworkCapabilities {
1869 behind_nat: true,
1870 public_ipv4: None,
1871 ..public_capabilities
1872 };
1873 let (nat_score, nat_reason) = manager.score_protocol(&TunnelProtocol::SixToFour, &nat_capabilities).await;
1874 assert_eq!(nat_score, 0.0);
1875 assert!(nat_reason.contains("behind NAT"));
1876
1877 let (teredo_score, teredo_reason) = manager.score_protocol(&TunnelProtocol::Teredo, &nat_capabilities).await;
1879 assert!(teredo_score > 0.8);
1880 assert!(teredo_reason.contains("NAT traversal"));
1881
1882 let enterprise_capabilities = NetworkCapabilities {
1884 public_ipv4: Some(Ipv4Addr::new(10, 0, 0, 1)), ..create_test_network_capabilities()
1886 };
1887 let (isatap_score, isatap_reason) = manager.score_protocol(&TunnelProtocol::Isatap, &enterprise_capabilities).await;
1888 assert!(isatap_score > 0.9);
1889 assert!(isatap_reason.contains("private network"));
1890 }
1891
1892 #[tokio::test]
1893 async fn test_tunnel_selection_no_suitable_protocols() {
1894 let manager = TunnelManager::new();
1895
1896 let dslite_config = create_test_tunnel_config(TunnelProtocol::DsLite);
1898 let dslite_tunnel = MockTunnel::new(dslite_config);
1899 manager.add_tunnel(Box::new(dslite_tunnel)).await;
1900
1901 let ipv4_only_capabilities = NetworkCapabilities {
1903 has_ipv6: false,
1904 ipv6_addresses: vec![],
1905 ..create_test_network_capabilities()
1906 };
1907
1908 let selection = manager.select_tunnel(&ipv4_only_capabilities).await;
1909 assert!(selection.is_none());
1910 }
1911
1912 #[tokio::test]
1913 async fn test_tunnel_manager_disconnect() -> Result<()> {
1914 let manager = TunnelManager::new();
1915 let config = create_test_tunnel_config(TunnelProtocol::SixToFour);
1916 let tunnel = MockTunnel::new(config);
1917 manager.add_tunnel(Box::new(tunnel)).await;
1918
1919 let capabilities = create_test_network_capabilities();
1920 manager.select_tunnel(&capabilities).await;
1921 manager.connect().await?;
1922
1923 manager.disconnect().await?;
1925
1926 Ok(())
1927 }
1928
1929 #[test]
1930 fn test_tunnel_selection_structure() {
1931 let selection = TunnelSelection {
1932 protocol: TunnelProtocol::MapE,
1933 reason: "Test reason".to_string(),
1934 selection_time: Duration::from_millis(100),
1935 is_fallback: false,
1936 };
1937
1938 assert_eq!(selection.protocol, TunnelProtocol::MapE);
1939 assert_eq!(selection.reason, "Test reason");
1940 assert_eq!(selection.selection_time, Duration::from_millis(100));
1941 assert!(!selection.is_fallback);
1942 }
1943
1944 #[test]
1945 fn test_tunnel_protocol_suitability_checks() {
1946 let manager = TunnelManager::new();
1947 let capabilities = create_test_network_capabilities();
1948
1949 assert!(manager.is_protocol_suitable(&TunnelProtocol::SixToFour, &capabilities));
1951 assert!(manager.is_protocol_suitable(&TunnelProtocol::Teredo, &capabilities));
1952 assert!(manager.is_protocol_suitable(&TunnelProtocol::SixInFour, &capabilities));
1953 assert!(manager.is_protocol_suitable(&TunnelProtocol::Isatap, &capabilities));
1954 assert!(manager.is_protocol_suitable(&TunnelProtocol::MapE, &capabilities));
1955 assert!(manager.is_protocol_suitable(&TunnelProtocol::MapT, &capabilities));
1956
1957 assert!(!manager.is_protocol_suitable(&TunnelProtocol::DsLite, &capabilities));
1959
1960 let ipv6_capabilities = NetworkCapabilities {
1961 has_ipv6: true,
1962 ..capabilities
1963 };
1964 assert!(manager.is_protocol_suitable(&TunnelProtocol::DsLite, &ipv6_capabilities));
1965 }
1966}
1967
1968pub fn create_tunnel_config(protocol: TunnelProtocol, capabilities: &NetworkCapabilities) -> TunnelConfig {
1970 let mut config = TunnelConfig::default();
1971 config.protocol = protocol.clone();
1972
1973 match protocol {
1974 TunnelProtocol::SixToFour => {
1975 if let Some(ipv4) = capabilities.public_ipv4 {
1977 config.local_ipv4 = Some(ipv4);
1978 let octets = ipv4.octets();
1980 let ipv6_bytes = [
1981 0x20, 0x02, octets[0], octets[1], octets[2], octets[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ];
1985 config.ipv6_prefix = Some(Ipv6Addr::from(ipv6_bytes));
1986 }
1987 }
1988 TunnelProtocol::Teredo => {
1989 let teredo_prefix = Ipv6Addr::new(0x2001, 0, 0, 0, 0, 0, 0, 1);
1991 config.ipv6_prefix = Some(teredo_prefix);
1992 config.mtu = 1280; }
1994 TunnelProtocol::SixInFour => {
1995 config.mtu = 1480; }
2000 TunnelProtocol::DsLite => {
2001 config.mtu = 1520; config.aftr_name = Some("aftr.example.com".to_string());
2006 }
2007 TunnelProtocol::Isatap => {
2008 config.mtu = 1500; config.ipv6_prefix = Some("fe80::".parse().unwrap());
2012 if let Some(ipv4) = capabilities.public_ipv4 {
2014 config.local_ipv4 = Some(ipv4);
2015 }
2016 }
2017 TunnelProtocol::MapE => {
2018 config.mtu = 1460; if let Some(ipv4) = capabilities.public_ipv4 {
2022 config.local_ipv4 = Some(ipv4);
2023 }
2024 }
2026 TunnelProtocol::MapT => {
2027 config.mtu = 1500; if let Some(ipv4) = capabilities.public_ipv4 {
2031 config.local_ipv4 = Some(ipv4);
2032 }
2033 }
2035 }
2036
2037 config
2038}
2039
2040pub fn create_tunnel(config: TunnelConfig) -> Result<Box<dyn Tunnel>> {
2042 match config.protocol {
2043 TunnelProtocol::SixToFour => {
2044 let tunnel = SixToFourTunnel::new(config)?;
2045 Ok(Box::new(tunnel))
2046 }
2047 TunnelProtocol::Teredo => {
2048 let tunnel = TeredoTunnel::new(config)?;
2049 Ok(Box::new(tunnel))
2050 }
2051 TunnelProtocol::SixInFour => {
2052 let tunnel = SixInFourTunnel::new(config)?;
2053 Ok(Box::new(tunnel))
2054 }
2055 TunnelProtocol::DsLite => {
2056 let tunnel = DsLiteTunnel::new(config)?;
2057 Ok(Box::new(tunnel))
2058 }
2059 TunnelProtocol::Isatap => {
2060 let tunnel = IsatapTunnel::new(config)?;
2061 Ok(Box::new(tunnel))
2062 }
2063 TunnelProtocol::MapE => {
2064 let tunnel = MapTunnel::new(config, MapProtocol::MapE)?;
2065 Ok(Box::new(tunnel))
2066 }
2067 TunnelProtocol::MapT => {
2068 let tunnel = MapTunnel::new(config, MapProtocol::MapT)?;
2069 Ok(Box::new(tunnel))
2070 }
2071 }
2072}