manycastr/worker/inbound/
tcp.rs1use crate::custom_module::manycastr::reply::ReplyData;
2use crate::custom_module::manycastr::{DiscoveryReply, MeasurementReply, Reply, TraceReply};
3use crate::net::TCPPacket;
4use crate::worker::inbound::ReplyMeta;
5use crate::worker::trace_codec::TraceTag;
6
7pub fn parse_tcp(
22 packet_bytes: &[u8],
23 sport: u16,
24 is_traceroute: bool,
25 meta: ReplyMeta,
26) -> Option<Reply> {
27 let ReplyMeta { src, ttl, rx_time } = meta;
28 if (src.is_v6() && (packet_bytes[13] & 0x04) == 0)
30 || (!src.is_v6() && (packet_bytes[33] & 0x04) == 0)
31 {
32 return None;
33 }
34
35 let tcp_packet = if src.is_v6() {
36 TCPPacket::from(packet_bytes)
37 } else {
38 TCPPacket::from(&packet_bytes[20..])
39 };
40
41 if tcp_packet.dport != sport {
43 return None;
44 }
45
46 let identifier = tcp_packet.seq.wrapping_sub(1); let is_discovery = (identifier >> 31) & 1 == 1;
48
49 if is_discovery {
50 Some(Reply {
52 reply_data: Some(ReplyData::Discovery(DiscoveryReply {
53 src: Some(src),
54 session_id: 0, })),
56 })
57 } else if is_traceroute {
58 let tag = TraceTag::decode_tcp_seq(identifier);
60 Some(Reply {
61 reply_data: Some(ReplyData::Trace(TraceReply {
62 hop_addr: Some(src),
63 ttl,
64 rtt: super::rtt_ms(rx_time, tag.ts14 as u64, super::TxEncoding::Trace14),
65 tx_id: tag.worker_id,
66 trace_dst: Some(src),
67 hop_count: tag.ttl as u32,
68 })),
69 })
70 } else {
71 let tx_id = (identifier >> 21) & 0x3FF;
72 let tx_time_21b = identifier & 0x1FFFFF;
73 Some(Reply {
74 reply_data: Some(ReplyData::Measurement(MeasurementReply {
75 src: Some(src),
76 ttl,
77 rtt: super::rtt_ms(rx_time, tx_time_21b as u64, super::TxEncoding::Tcp21),
78 tx_id,
79 chaos: None,
80 session_id: 0, })),
82 })
83 }
84}