@@ -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