Skip to content

Commit 292a2b0

Browse files
fix: correct captured byte accounting for ebpf reassembly
1 parent 2d08297 commit 292a2b0

1 file changed

Lines changed: 67 additions & 2 deletions

File tree

agent/src/common/meta_packet.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,13 @@ impl<'a> MetaPacket<'a> {
10361036
#[inline]
10371037
pub fn get_captured_byte(&self) -> usize {
10381038
if self.tap_port.is_from(TapPort::FROM_EBPF) {
1039+
// For eBPF reassembly segments, upper layers merge multiple packets
1040+
// by accumulating each segment's captured length. `reasm_bytes` is a
1041+
// cumulative counter on the socket, so using it here would double
1042+
// count across segment merges (100 + 200 + 300 ...).
1043+
if self.is_reassembly_segment() {
1044+
return self.l4_payload_len as usize;
1045+
}
10391046
if self.reasm_bytes > 0 {
10401047
return self.reasm_bytes as usize;
10411048
}
@@ -1065,6 +1072,16 @@ impl<'a> MetaPacket<'a> {
10651072
0
10661073
}
10671074

1075+
#[cfg(all(unix, feature = "libtrace"))]
1076+
fn is_reassembly_segment(&self) -> bool {
1077+
self.segment_flags != SegmentFlags::None
1078+
}
1079+
1080+
#[cfg(not(all(unix, feature = "libtrace")))]
1081+
fn is_reassembly_segment(&self) -> bool {
1082+
false
1083+
}
1084+
10681085
#[inline]
10691086
pub fn merge(&mut self, packet: &mut MetaPacket) {
10701087
if self.ebpf_type == EbpfType::None {
@@ -1435,12 +1452,12 @@ impl CacheItem for MetaPacket<'static> {
14351452
self.l7_protocol_from_ebpf
14361453
}
14371454

1438-
#[cfg(feature = "libtrace")]
1455+
#[cfg(all(unix, feature = "libtrace"))]
14391456
fn is_segment_start(&self) -> bool {
14401457
self.segment_flags == SegmentFlags::Start
14411458
}
14421459

1443-
#[cfg(not(feature = "libtrace"))]
1460+
#[cfg(not(all(unix, feature = "libtrace")))]
14441461
fn is_segment_start(&self) -> bool {
14451462
false
14461463
}
@@ -1619,4 +1636,52 @@ mod tests {
16191636

16201637
assert_eq!(pkt.get_captured_byte(), 200_000);
16211638
}
1639+
1640+
#[cfg(all(unix, feature = "libtrace"))]
1641+
#[test]
1642+
fn get_captured_byte_for_ebpf_reasm_segment_should_use_current_segment_len() {
1643+
let mut pkt = MetaPacket::default();
1644+
pkt.tap_port = TapPort::from_ebpf(1, 0);
1645+
pkt.segment_flags = SegmentFlags::Seg;
1646+
pkt.reasm_bytes = 200_000;
1647+
pkt.raw_from_ebpf = vec![0u8; 4096];
1648+
pkt.l4_payload_len = 4096;
1649+
1650+
assert_eq!(pkt.get_captured_byte(), 4096);
1651+
}
1652+
1653+
#[cfg(all(unix, feature = "libtrace"))]
1654+
#[test]
1655+
fn get_captured_byte_for_merged_ebpf_reasm_start_should_use_merged_payload_len() {
1656+
let mut start = MetaPacket::default();
1657+
start.tap_port = TapPort::from_ebpf(1, 0);
1658+
start.ebpf_type = EbpfType::GoHttp2Uprobe;
1659+
start.segment_flags = SegmentFlags::Start;
1660+
start.reasm_bytes = 16_384;
1661+
start.raw_from_ebpf = vec![0u8; 16_384];
1662+
start.l4_payload_len = 16_384;
1663+
start.payload_len = 16_384;
1664+
start.packet_len = 16_384 + 54;
1665+
start.cap_start_seq = 10;
1666+
start.cap_end_seq = 10;
1667+
start.sub_packets.push(SubPacket::default());
1668+
1669+
let mut seg = MetaPacket::default();
1670+
seg.tap_port = TapPort::from_ebpf(1, 0);
1671+
seg.ebpf_type = EbpfType::GoHttp2Uprobe;
1672+
seg.segment_flags = SegmentFlags::Seg;
1673+
seg.reasm_bytes = 32_768;
1674+
seg.raw_from_ebpf = vec![0u8; 16_384];
1675+
seg.l4_payload_len = 16_384;
1676+
seg.payload_len = 16_384;
1677+
seg.packet_len = 16_384 + 54;
1678+
seg.cap_start_seq = 11;
1679+
seg.cap_end_seq = 11;
1680+
1681+
start.merge(&mut seg);
1682+
1683+
assert_eq!(start.l4_payload_len, 32_768);
1684+
assert_eq!(start.reasm_bytes, 32_768);
1685+
assert_eq!(start.get_captured_byte(), 32_768);
1686+
}
16221687
}

0 commit comments

Comments
 (0)