1use super::{Tunnel, TunnelConfig, TunnelMetrics, TunnelState, TunnelProtocol};
16use crate::{P2PError, Result};
17use async_trait::async_trait;
18use std::net::{Ipv4Addr, Ipv6Addr};
19use std::time::{Duration, Instant};
20use tokio::sync::RwLock;
21use tracing::{debug, info};
22
23const IPV6_IN_IPV4_PROTOCOL: u8 = 41;
25
26const DEFAULT_IPV6_PREFIX: [u16; 4] = [0x2001, 0x0db8, 0x6140, 0x0000]; pub struct SixInFourTunnel {
31 config: TunnelConfig,
33 state: RwLock<TunnelState>,
35 metrics: RwLock<TunnelMetrics>,
37 local_ipv4: Option<Ipv4Addr>,
39 remote_ipv4: Option<Ipv4Addr>,
41 local_ipv6: Option<Ipv6Addr>,
43 ipv6_prefix: Option<Ipv6Addr>,
45 established_at: Option<Instant>,
47 last_activity: Option<Instant>,
49}
50
51impl SixInFourTunnel {
52 pub fn new(config: TunnelConfig) -> Result<Self> {
54 if config.protocol != TunnelProtocol::SixInFour {
55 return Err(P2PError::Network(
56 "Invalid protocol for 6in4 tunnel".to_string()
57 ).into());
58 }
59
60 Ok(Self {
61 config,
62 state: RwLock::new(TunnelState::Disconnected),
63 metrics: RwLock::new(TunnelMetrics::default()),
64 local_ipv4: None,
65 remote_ipv4: None,
66 local_ipv6: None,
67 ipv6_prefix: None,
68 established_at: None,
69 last_activity: None,
70 })
71 }
72
73 fn generate_ipv6_address(
75 prefix: Option<Ipv6Addr>,
76 local_ipv4: Ipv4Addr,
77 ) -> Ipv6Addr {
78 if let Some(configured_prefix) = prefix {
79 let prefix_segments = configured_prefix.segments();
81 let ipv4_octets = local_ipv4.octets();
82
83 let interface_id = [
85 prefix_segments[0], prefix_segments[1], prefix_segments[2], prefix_segments[3],
86 0x0000, 0x0000,
87 ((ipv4_octets[0] as u16) << 8) | (ipv4_octets[1] as u16),
88 ((ipv4_octets[2] as u16) << 8) | (ipv4_octets[3] as u16),
89 ];
90
91 Ipv6Addr::from(interface_id)
92 } else {
93 let ipv4_octets = local_ipv4.octets();
95 Ipv6Addr::new(
96 DEFAULT_IPV6_PREFIX[0],
97 DEFAULT_IPV6_PREFIX[1],
98 DEFAULT_IPV6_PREFIX[2],
99 DEFAULT_IPV6_PREFIX[3],
100 0x0000,
101 0x0000,
102 ((ipv4_octets[0] as u16) << 8) | (ipv4_octets[1] as u16),
103 ((ipv4_octets[2] as u16) << 8) | (ipv4_octets[3] as u16),
104 )
105 }
106 }
107
108 fn create_ipv4_header(&self, payload_len: usize) -> Result<Vec<u8>> {
110 let local_ipv4 = self.local_ipv4.ok_or_else(|| {
111 P2PError::Network("Local IPv4 address not configured".to_string())
112 })?;
113
114 let remote_ipv4 = self.remote_ipv4.ok_or_else(|| {
115 P2PError::Network("Remote IPv4 address not configured".to_string())
116 })?;
117
118 let mut header = vec![0u8; 20]; header[0] = 0x45;
122
123 header[1] = 0x00;
125
126 let total_len = 20 + payload_len;
128 header[2] = (total_len >> 8) as u8;
129 header[3] = (total_len & 0xFF) as u8;
130
131 header[4] = 0x00;
133 header[5] = 0x01;
134
135 header[6] = 0x40; header[7] = 0x00;
138
139 header[8] = 64;
141
142 header[9] = IPV6_IN_IPV4_PROTOCOL;
144
145 header[10] = 0x00;
147 header[11] = 0x00;
148
149 let src_octets = local_ipv4.octets();
151 header[12..16].copy_from_slice(&src_octets);
152
153 let dst_octets = remote_ipv4.octets();
155 header[16..20].copy_from_slice(&dst_octets);
156
157 let checksum = self.calculate_ipv4_checksum(&header);
159 header[10] = (checksum >> 8) as u8;
160 header[11] = (checksum & 0xFF) as u8;
161
162 Ok(header)
163 }
164
165 fn calculate_ipv4_checksum(&self, header: &[u8]) -> u16 {
167 let mut sum: u32 = 0;
168
169 for i in (0..header.len()).step_by(2) {
171 if i + 1 < header.len() {
172 if i == 10 {
174 continue;
175 }
176 let word = ((header[i] as u32) << 8) + (header[i + 1] as u32);
177 sum = sum.wrapping_add(word);
178 }
179 }
180
181 while (sum >> 16) != 0 {
183 sum = (sum & 0xFFFF) + (sum >> 16);
184 }
185
186 (!sum) as u16
188 }
189
190 fn validate_configuration(&self) -> Result<()> {
192 if self.config.local_ipv4.is_none() {
193 return Err(P2PError::Network(
194 "6in4 tunnel requires local IPv4 address".to_string()
195 ).into());
196 }
197
198 if self.config.remote_ipv4.is_none() {
199 return Err(P2PError::Network(
200 "6in4 tunnel requires remote IPv4 address".to_string()
201 ).into());
202 }
203
204 if self.config.local_ipv4 == self.config.remote_ipv4 {
206 return Err(P2PError::Network(
207 "Local and remote IPv4 addresses must be different".to_string()
208 ).into());
209 }
210
211 Ok(())
212 }
213
214 async fn test_connectivity(&mut self) -> Result<Duration> {
216 let start = Instant::now();
217
218 let ping_packet = self.create_icmpv6_ping()?;
220
221 self.send(&ping_packet).await?;
223
224 let simulated_rtt = Duration::from_millis(10 + (rand::random::<u64>() % 40));
226 tokio::time::sleep(simulated_rtt).await;
227
228 let actual_rtt = start.elapsed();
229 self.last_activity = Some(Instant::now());
230
231 debug!("6in4 tunnel connectivity test successful: RTT = {:?}", actual_rtt);
232 Ok(actual_rtt)
233 }
234
235 fn create_icmpv6_ping(&self) -> Result<Vec<u8>> {
237 let local_ipv6 = self.local_ipv6.ok_or_else(|| {
238 P2PError::Network("Local IPv6 address not assigned".to_string())
239 })?;
240
241 let mut packet = vec![0u8; 48]; packet[0] = 0x60; packet[1] = 0x00; packet[2] = 0x00; packet[3] = 0x00; packet[4] = 0x00; packet[5] = 0x08;
250 packet[6] = 0x3A; packet[7] = 0x40; let src_bytes = local_ipv6.octets();
255 packet[8..24].copy_from_slice(&src_bytes);
256
257 packet[24..40].copy_from_slice(&src_bytes);
259
260 packet[40] = 0x80; packet[41] = 0x00; packet[42] = 0x00; packet[43] = 0x00; packet[44] = 0x00; packet[45] = 0x01; packet[46] = 0x00; packet[47] = 0x01; Ok(packet)
271 }
272
273 async fn update_send_metrics(&self, bytes: usize) {
275 let mut metrics = self.metrics.write().await;
276 metrics.bytes_sent += bytes as u64;
277 metrics.packets_sent += 1;
278 metrics.last_activity = Instant::now();
279 }
280
281 async fn update_receive_metrics(&self, bytes: usize) {
283 let mut metrics = self.metrics.write().await;
284 metrics.bytes_received += bytes as u64;
285 metrics.packets_received += 1;
286 metrics.last_activity = Instant::now();
287 }
288}
289
290#[async_trait]
291impl Tunnel for SixInFourTunnel {
292 fn protocol(&self) -> TunnelProtocol {
293 TunnelProtocol::SixInFour
294 }
295
296 fn config(&self) -> &TunnelConfig {
297 &self.config
298 }
299
300 async fn state(&self) -> TunnelState {
301 let state = self.state.read().await;
302 state.clone()
303 }
304
305 async fn metrics(&self) -> TunnelMetrics {
306 let metrics = self.metrics.read().await;
307 metrics.clone()
308 }
309
310 async fn connect(&mut self) -> Result<()> {
311 info!("Establishing 6in4 tunnel connection");
312
313 {
314 let mut state = self.state.write().await;
315 *state = TunnelState::Connecting;
316 }
317
318 self.validate_configuration()?;
320
321 self.local_ipv4 = self.config.local_ipv4;
323 self.remote_ipv4 = self.config.remote_ipv4;
324
325 if let Some(local_ipv4) = self.local_ipv4 {
327 self.local_ipv6 = Some(Self::generate_ipv6_address(
328 self.config.ipv6_prefix,
329 local_ipv4
330 ));
331 self.ipv6_prefix = self.config.ipv6_prefix;
332 }
333
334 {
336 let mut state = self.state.write().await;
337 *state = TunnelState::Connected;
338 }
339
340 let rtt = self.test_connectivity().await?;
342
343 self.established_at = Some(Instant::now());
345
346 {
348 let mut state = self.state.write().await;
349 *state = TunnelState::Connected;
350 }
351
352 {
354 let mut metrics = self.metrics.write().await;
355 if let Some(established) = self.established_at {
356 metrics.establishment_time = established.elapsed();
357 }
358 metrics.rtt = Some(rtt);
359 }
360
361 info!("6in4 tunnel established: {:?} -> {:?} (IPv6: {:?})",
362 self.local_ipv4, self.remote_ipv4, self.local_ipv6);
363
364 Ok(())
365 }
366
367 async fn disconnect(&mut self) -> Result<()> {
368 info!("Disconnecting 6in4 tunnel");
369
370 {
371 let mut state = self.state.write().await;
372 *state = TunnelState::Disconnecting;
373 }
374
375 self.local_ipv4 = None;
377 self.remote_ipv4 = None;
378 self.local_ipv6 = None;
379 self.ipv6_prefix = None;
380 self.established_at = None;
381 self.last_activity = None;
382
383 {
384 let mut state = self.state.write().await;
385 *state = TunnelState::Disconnected;
386 }
387
388 debug!("6in4 tunnel disconnected");
389 Ok(())
390 }
391
392 async fn is_active(&self) -> bool {
393 let state = self.state.read().await;
394 matches!(*state, TunnelState::Connected)
395 }
396
397 async fn encapsulate(&self, ipv6_packet: &[u8]) -> Result<Vec<u8>> {
398 if !self.is_active().await {
399 return Err(P2PError::Network("6in4 tunnel not active".to_string()).into());
400 }
401
402 let ipv4_header = self.create_ipv4_header(ipv6_packet.len())?;
404
405 let mut encapsulated = Vec::with_capacity(ipv4_header.len() + ipv6_packet.len());
407 encapsulated.extend_from_slice(&ipv4_header);
408 encapsulated.extend_from_slice(ipv6_packet);
409
410 debug!("Encapsulated {} bytes for 6in4 transmission to {:?}",
411 encapsulated.len(), self.remote_ipv4);
412
413 Ok(encapsulated)
414 }
415
416 async fn decapsulate(&self, ipv4_packet: &[u8]) -> Result<Vec<u8>> {
417 if !self.is_active().await {
418 return Err(P2PError::Network("6in4 tunnel not active".to_string()).into());
419 }
420
421 if ipv4_packet.len() < 20 {
422 return Err(P2PError::Network("IPv4 packet too short".to_string()).into());
423 }
424
425 if ipv4_packet[9] != IPV6_IN_IPV4_PROTOCOL {
427 return Err(P2PError::Network("Not an IPv6-in-IPv4 packet".to_string()).into());
428 }
429
430 let header_len = ((ipv4_packet[0] & 0x0F) * 4) as usize;
432
433 if ipv4_packet.len() <= header_len {
434 return Err(P2PError::Network("IPv4 packet has no payload".to_string()).into());
435 }
436
437 let ipv6_payload = ipv4_packet[header_len..].to_vec();
439
440 debug!("Decapsulated {} bytes from 6in4 packet", ipv6_payload.len());
441 Ok(ipv6_payload)
442 }
443
444 async fn send(&mut self, packet: &[u8]) -> Result<()> {
445 let encapsulated = self.encapsulate(packet).await?;
446
447 debug!("Sending {} bytes via 6in4 tunnel to {:?}",
450 encapsulated.len(), self.remote_ipv4);
451
452 tokio::time::sleep(Duration::from_millis(2)).await;
454
455 self.update_send_metrics(encapsulated.len()).await;
456 Ok(())
457 }
458
459 async fn receive(&mut self) -> Result<Vec<u8>> {
460 debug!("Receiving packet via 6in4 tunnel");
463
464 tokio::time::sleep(Duration::from_millis(3)).await;
466
467 let simulated_packet = vec![0u8; 68]; let decapsulated = self.decapsulate(&simulated_packet).await?;
471 self.update_receive_metrics(decapsulated.len()).await;
472
473 Ok(decapsulated)
474 }
475
476 async fn maintain(&mut self) -> Result<()> {
477 if !self.is_active().await {
478 return Ok(());
479 }
480
481 debug!("Performing 6in4 tunnel maintenance");
482
483 {
485 let mut metrics = self.metrics.write().await;
486 if let Some(established) = self.established_at {
487 metrics.establishment_time = established.elapsed();
488 }
489 }
490
491 if let Some(last_activity) = self.last_activity {
493 if last_activity.elapsed() > Duration::from_secs(30) {
494 debug!("Testing 6in4 tunnel connectivity (periodic check)");
495 match self.test_connectivity().await {
496 Ok(rtt) => {
497 let mut metrics = self.metrics.write().await;
498 metrics.rtt = Some(rtt);
499 }
500 Err(e) => {
501 debug!("6in4 connectivity test failed: {}", e);
502 }
504 }
505 }
506 }
507
508 Ok(())
515 }
516
517 async fn local_ipv6_addr(&self) -> Result<Ipv6Addr> {
518 self.local_ipv6.ok_or_else(|| {
519 P2PError::Network("6in4 tunnel not established".to_string()).into()
520 })
521 }
522
523 async fn local_ipv4_addr(&self) -> Result<Ipv4Addr> {
524 self.local_ipv4.ok_or_else(|| {
525 P2PError::Network("6in4 tunnel not established".to_string()).into()
526 })
527 }
528
529 async fn ping(&mut self, timeout: Duration) -> Result<Duration> {
530 if !self.is_active().await {
531 return Err(P2PError::Network("6in4 tunnel not active".to_string()).into());
532 }
533
534 debug!("Pinging via 6in4 tunnel with timeout {:?}", timeout);
535
536 let rtt = tokio::time::timeout(timeout, self.test_connectivity()).await
538 .map_err(|_| P2PError::Network("6in4 ping timeout".to_string()))?
539 .map_err(|e| P2PError::Network(format!("6in4 ping failed: {}", e)))?;
540
541 {
543 let mut metrics = self.metrics.write().await;
544 metrics.rtt = Some(rtt);
545 }
546
547 debug!("6in4 tunnel ping successful: RTT = {:?}", rtt);
548 Ok(rtt)
549 }
550}
551
552#[cfg(test)]
553mod tests {
554 use super::*;
555
556 #[test]
557 fn test_ipv6_address_generation() {
558 let local_ipv4 = Ipv4Addr::new(10, 0, 0, 1);
559 let ipv6 = SixInFourTunnel::generate_ipv6_address(None, local_ipv4);
560
561 assert_eq!(ipv6.segments()[0], 0x2001);
563 assert_eq!(ipv6.segments()[1], 0x0db8);
564 assert_eq!(ipv6.segments()[2], 0x6140);
565
566 assert_eq!(ipv6.segments()[6], 0x0a00); assert_eq!(ipv6.segments()[7], 0x0001); }
570
571 #[test]
572 fn test_ipv6_address_generation_with_prefix() {
573 let local_ipv4 = Ipv4Addr::new(192, 168, 1, 100);
574 let custom_prefix = Ipv6Addr::new(0x2001, 0x470, 0x1234, 0x5678, 0, 0, 0, 0);
575 let ipv6 = SixInFourTunnel::generate_ipv6_address(Some(custom_prefix), local_ipv4);
576
577 assert_eq!(ipv6.segments()[0], 0x2001);
579 assert_eq!(ipv6.segments()[1], 0x470);
580 assert_eq!(ipv6.segments()[2], 0x1234);
581 assert_eq!(ipv6.segments()[3], 0x5678);
582
583 assert_eq!(ipv6.segments()[6], 0xc0a8); assert_eq!(ipv6.segments()[7], 0x0164); }
587
588 #[tokio::test]
589 async fn test_tunnel_creation() {
590 let config = TunnelConfig {
591 protocol: TunnelProtocol::SixInFour,
592 local_ipv4: Some(Ipv4Addr::new(10, 0, 0, 1)),
593 remote_ipv4: Some(Ipv4Addr::new(10, 0, 0, 2)),
594 ..Default::default()
595 };
596
597 let tunnel = SixInFourTunnel::new(config).unwrap();
598 assert_eq!(tunnel.protocol(), TunnelProtocol::SixInFour);
599 assert_eq!(tunnel.state().await, TunnelState::Disconnected);
600 }
601
602 #[tokio::test]
603 async fn test_invalid_protocol() {
604 let config = TunnelConfig {
605 protocol: TunnelProtocol::SixToFour, ..Default::default()
607 };
608
609 let result = SixInFourTunnel::new(config);
610 assert!(result.is_err());
611 }
612
613 #[tokio::test]
614 async fn test_configuration_validation() {
615 let config1 = TunnelConfig {
617 protocol: TunnelProtocol::SixInFour,
618 local_ipv4: None,
619 remote_ipv4: Some(Ipv4Addr::new(10, 0, 0, 2)),
620 ..Default::default()
621 };
622
623 let mut tunnel1 = SixInFourTunnel::new(config1).unwrap();
624 assert!(tunnel1.connect().await.is_err());
625
626 let config2 = TunnelConfig {
628 protocol: TunnelProtocol::SixInFour,
629 local_ipv4: Some(Ipv4Addr::new(10, 0, 0, 1)),
630 remote_ipv4: None,
631 ..Default::default()
632 };
633
634 let mut tunnel2 = SixInFourTunnel::new(config2).unwrap();
635 assert!(tunnel2.connect().await.is_err());
636
637 let config3 = TunnelConfig {
639 protocol: TunnelProtocol::SixInFour,
640 local_ipv4: Some(Ipv4Addr::new(10, 0, 0, 1)),
641 remote_ipv4: Some(Ipv4Addr::new(10, 0, 0, 1)),
642 ..Default::default()
643 };
644
645 let mut tunnel3 = SixInFourTunnel::new(config3).unwrap();
646 assert!(tunnel3.connect().await.is_err());
647 }
648
649 #[tokio::test]
650 async fn test_tunnel_connection() {
651 let config = TunnelConfig {
652 protocol: TunnelProtocol::SixInFour,
653 local_ipv4: Some(Ipv4Addr::new(203, 0, 113, 1)),
654 remote_ipv4: Some(Ipv4Addr::new(203, 0, 113, 2)),
655 ..Default::default()
656 };
657
658 let mut tunnel = SixInFourTunnel::new(config).unwrap();
659
660 assert!(!tunnel.is_active().await);
661
662 tunnel.connect().await.unwrap();
663
664 assert!(tunnel.is_active().await);
665 assert_eq!(tunnel.state().await, TunnelState::Connected);
666
667 let ipv6_addr = tunnel.local_ipv6_addr().await.unwrap();
668 assert_eq!(ipv6_addr.segments()[0], 0x2001); let ipv4_addr = tunnel.local_ipv4_addr().await.unwrap();
671 assert_eq!(ipv4_addr, Ipv4Addr::new(203, 0, 113, 1));
672 }
673}