@@ -5,14 +5,15 @@ use std::net::IpAddr;
5
5
use anyhow:: Result ;
6
6
7
7
use itertools:: Itertools ;
8
- use pantrace:: formats:: internal:: Traceroute ;
8
+ use pantrace:: formats:: internal:: { Traceroute , TracerouteHop } ;
9
9
use pantrace:: traits:: TracerouteWriter ;
10
10
11
11
pub struct ClassicTracerouteWriter < W : Write > {
12
12
output : W ,
13
13
min_ttl : u8 ,
14
14
max_ttl : u8 ,
15
15
dst_addr : IpAddr ,
16
+ total_flows : usize ,
16
17
}
17
18
18
19
impl < W : Write > ClassicTracerouteWriter < W > {
@@ -21,12 +22,14 @@ impl<W: Write> ClassicTracerouteWriter<W> {
21
22
min_ttl : u8 ,
22
23
max_ttl : u8 ,
23
24
dst_addr : IpAddr ,
25
+ total_flows : usize ,
24
26
) -> ClassicTracerouteWriter < W > {
25
27
ClassicTracerouteWriter {
26
28
output,
27
29
min_ttl,
28
30
max_ttl,
29
31
dst_addr,
32
+ total_flows,
30
33
}
31
34
}
32
35
}
@@ -39,20 +42,37 @@ where
39
42
let packet_size = traceroute. flows [ 0 ] . hops [ 0 ] . probes [ 0 ] . size ;
40
43
write ! (
41
44
self . output,
42
- "traceroute to {}({}), {} hops max, {} bytes packets" ,
43
- traceroute. dst_addr, traceroute. dst_addr, self . max_ttl, packet_size
45
+ "traceroute to {}({}), {} hops max, {} bytes packets, flow {}/{}\n " ,
46
+ traceroute. dst_addr,
47
+ traceroute. dst_addr,
48
+ self . max_ttl,
49
+ packet_size,
50
+ 1 ,
51
+ self . total_flows
44
52
)
45
53
. unwrap ( ) ;
46
- let flow = & traceroute. flows [ 0 ] ;
47
- let hops_by_ttl = flow. hops . iter ( ) . group_by ( |hop| hop. ttl ) ;
48
- let hops_by_ttl = hops_by_ttl
49
- . into_iter ( )
50
- . fold ( HashMap :: new ( ) , |mut acc, ( ttl, hops) | {
51
- acc. insert ( ttl, hops. collect_vec ( ) ) ;
52
- acc
53
- } ) ;
54
54
55
- write ! ( self . output, "\n " ) . unwrap ( ) ;
55
+ let all_hops = traceroute
56
+ . flows
57
+ . iter ( )
58
+ . flat_map ( |flow| flow. hops . iter ( ) )
59
+ // .map(|flow| &flow.hops)
60
+ // .flatten()
61
+ . collect :: < Vec < _ > > ( ) ;
62
+
63
+ let hops_by_ttl = all_hops
64
+ . into_iter ( )
65
+ . group_by ( |hop| hop. ttl )
66
+ . into_iter ( )
67
+ . fold (
68
+ HashMap :: < u8 , Vec < & TracerouteHop > > :: new ( ) ,
69
+ |mut acc, ( ttl, group) | {
70
+ acc. entry ( ttl)
71
+ . or_insert_with ( Vec :: new)
72
+ . extend ( group. into_iter ( ) ) ;
73
+ acc
74
+ } ,
75
+ ) ;
56
76
57
77
let mut found_dst = false ;
58
78
@@ -62,29 +82,40 @@ where
62
82
}
63
83
write ! ( self . output, "{}" , ttl) . unwrap ( ) ;
64
84
if let Some ( hops) = hops_by_ttl. get ( & ttl) {
65
- let hop = & hops[ 0 ] ;
66
- let probes_by_host = hop
67
- . probes
68
- . iter ( )
69
- . filter ( |probe| probe. reply . is_some ( ) )
70
- . group_by ( |probe| probe. reply . as_ref ( ) . map ( |r| r. addr ) ) ;
71
- for ( ip, probes) in probes_by_host. into_iter ( ) {
72
- let probes = probes. collect_vec ( ) ;
73
- if let Some ( ip) = ip {
74
- write ! ( self . output, " {} ({})" , ip, ip) . unwrap ( ) ;
75
- for probe in probes. iter ( ) {
76
- let reply = probe. reply . as_ref ( ) . unwrap ( ) ;
77
- write ! ( self . output, " {:.3} ms" , reply. rtt / 10.0 ) . unwrap ( ) ;
78
- found_dst = found_dst || ( ip == self . dst_addr ) ;
79
- }
80
- write ! ( self . output, "\n " ) . unwrap ( ) ;
81
- } else {
82
- write ! ( self . output, " *\n " ) . unwrap ( ) ;
83
- }
85
+ let all_probes = hops
86
+ . into_iter ( )
87
+ . flat_map ( |hop| hop. probes . iter ( ) )
88
+ . collect :: < Vec < _ > > ( ) ;
89
+ let all_replies_by_host = all_probes
90
+ . into_iter ( )
91
+ . filter_map ( |probe| probe. reply . as_ref ( ) . map ( |reply| ( reply. addr , reply. rtt ) ) )
92
+ . fold (
93
+ HashMap :: < IpAddr , Vec < f64 > > :: new ( ) ,
94
+ |mut acc, ( addr, rtt) | {
95
+ acc. entry ( addr) . or_insert_with ( Vec :: new) . push ( rtt) ;
96
+ acc
97
+ } ,
98
+ ) ;
99
+
100
+ for ( ip, rtts) in all_replies_by_host. into_iter ( ) {
101
+ found_dst |= ip == self . dst_addr ;
102
+
103
+ write ! ( self . output, " {} ({})" , ip, ip) . unwrap ( ) ;
104
+ let mean_rtt = rtts. iter ( ) . sum :: < f64 > ( ) / rtts. len ( ) as f64 ;
105
+ write ! (
106
+ self . output,
107
+ " {:.3} ms ({} probes)" ,
108
+ mean_rtt / 10.0 ,
109
+ rtts. len( )
110
+ )
111
+ . unwrap ( ) ;
112
+ write ! ( self . output, "\n " ) . unwrap ( ) ;
84
113
}
114
+ // write!(self.output, "\n").unwrap();
85
115
} else {
86
116
write ! ( self . output, " *\n " ) . unwrap ( ) ;
87
117
}
118
+ write ! ( self . output, "\n " ) . unwrap ( ) ;
88
119
}
89
120
90
121
Ok ( ( ) )
0 commit comments