@@ -87,27 +87,22 @@ var (
87
87
// New returns a new Pinger struct pointer.
88
88
func New (addr string ) * Pinger {
89
89
r := rand .New (rand .NewSource (getSeed ()))
90
- firstUUID := uuid .New ()
91
- var firstSequence = map [uuid.UUID ]map [int ]struct {}{}
92
- firstSequence [firstUUID ] = make (map [int ]struct {})
93
90
return & Pinger {
94
91
Count : - 1 ,
95
92
Interval : time .Second ,
96
93
RecordRtts : true ,
97
94
Size : timeSliceLength + trackerLength ,
98
95
Timeout : time .Duration (math .MaxInt64 ),
99
96
100
- addr : addr ,
101
- done : make (chan interface {}),
102
- id : r .Intn (math .MaxUint16 ),
103
- trackerUUIDs : []uuid.UUID {firstUUID },
104
- ipaddr : nil ,
105
- ipv4 : false ,
106
- network : "ip" ,
107
- protocol : "udp" ,
108
- awaitingSequences : firstSequence ,
109
- TTL : 64 ,
110
- logger : StdLogger {Logger : log .New (log .Writer (), log .Prefix (), log .Flags ())},
97
+ addr : addr ,
98
+ done : make (chan interface {}),
99
+ id : r .Intn (math .MaxUint16 ),
100
+ ipaddr : nil ,
101
+ ipv4 : false ,
102
+ network : "ip" ,
103
+ protocol : "udp" ,
104
+ TTL : 64 ,
105
+ logger : StdLogger {Logger : log .New (log .Writer (), log .Prefix (), log .Flags ())},
111
106
}
112
107
}
113
108
@@ -143,6 +138,9 @@ type Pinger struct {
143
138
// Number of duplicate packets received
144
139
PacketsRecvDuplicates int
145
140
141
+ // Per-packet timeout
142
+ PacketTimeout time.Duration
143
+
146
144
// Round trip time statistics
147
145
minRtt time.Duration
148
146
maxRtt time.Duration
@@ -189,14 +187,11 @@ type Pinger struct {
189
187
ipaddr * net.IPAddr
190
188
addr string
191
189
192
- // trackerUUIDs is the list of UUIDs being used for sending packets.
193
- trackerUUIDs []uuid.UUID
194
-
195
190
ipv4 bool
196
191
id int
197
192
sequence int
198
- // awaitingSequences are in-flight sequence numbers we keep track of to help remove duplicate receipts
199
- awaitingSequences map [uuid. UUID ] map [ int ] struct {}
193
+ // tracker is a PacketTrackrer of UUIDs and sequence numbers.
194
+ tracker * PacketTracker
200
195
// network is one of "ip", "ip4", or "ip6".
201
196
network string
202
197
// protocol is "icmp" or "udp".
@@ -413,6 +408,9 @@ func (p *Pinger) Run() error {
413
408
if err != nil {
414
409
return err
415
410
}
411
+
412
+ p .tracker = newPacketTracker (p .PacketTimeout )
413
+
416
414
if conn , err = p .listen (); err != nil {
417
415
return err
418
416
}
@@ -615,19 +613,12 @@ func (p *Pinger) getPacketUUID(pkt []byte) (*uuid.UUID, error) {
615
613
return nil , fmt .Errorf ("error decoding tracking UUID: %w" , err )
616
614
}
617
615
618
- for _ , item := range p .trackerUUIDs {
619
- if item == packetUUID {
620
- return & packetUUID , nil
621
- }
616
+ if p .tracker .HasUUID (packetUUID ) {
617
+ return & packetUUID , nil
622
618
}
623
619
return nil , nil
624
620
}
625
621
626
- // getCurrentTrackerUUID grabs the latest tracker UUID.
627
- func (p * Pinger ) getCurrentTrackerUUID () uuid.UUID {
628
- return p .trackerUUIDs [len (p .trackerUUIDs )- 1 ]
629
- }
630
-
631
622
func (p * Pinger ) processPacket (recv * packet ) error {
632
623
receivedAt := time .Now ()
633
624
var proto int
@@ -676,15 +667,15 @@ func (p *Pinger) processPacket(recv *packet) error {
676
667
inPkt .Rtt = receivedAt .Sub (timestamp )
677
668
inPkt .Seq = pkt .Seq
678
669
// If we've already received this sequence, ignore it.
679
- if _ , inflight := p. awaitingSequences [ * pktUUID ][ pkt.Seq ]; ! inflight {
670
+ if ! p . tracker . HasPacket ( * pktUUID , pkt .Seq ) {
680
671
p .PacketsRecvDuplicates ++
681
672
if p .OnDuplicateRecv != nil {
682
673
p .OnDuplicateRecv (inPkt )
683
674
}
684
675
return nil
685
676
}
686
- // remove it from the list of sequences we're waiting for so we don't get duplicates.
687
- delete ( p . awaitingSequences [ * pktUUID ] , pkt .Seq )
677
+ // Remove it from the list of sequences we're waiting for so we don't get duplicates.
678
+ p . tracker . DeletePacket ( * pktUUID , pkt .Seq )
688
679
p .updateStatistics (inPkt )
689
680
default :
690
681
// Very bad, not sure how this can happen
@@ -705,7 +696,7 @@ func (p *Pinger) sendICMP(conn packetConn) error {
705
696
dst = & net.UDPAddr {IP : p .ipaddr .IP , Zone : p .ipaddr .Zone }
706
697
}
707
698
708
- currentUUID := p .getCurrentTrackerUUID ()
699
+ currentUUID := p .tracker . CurrentUUID ()
709
700
uuidEncoded , err := currentUUID .MarshalBinary ()
710
701
if err != nil {
711
702
return fmt .Errorf ("unable to marshal UUID binary: %w" , err )
@@ -753,15 +744,8 @@ func (p *Pinger) sendICMP(conn packetConn) error {
753
744
handler (outPkt )
754
745
}
755
746
// mark this sequence as in-flight
756
- p.awaitingSequences [ currentUUID ][p. sequence ] = struct {}{}
747
+ p .sequence = p . tracker . AddPacket ()
757
748
p .PacketsSent ++
758
- p .sequence ++
759
- if p .sequence > 65535 {
760
- newUUID := uuid .New ()
761
- p .trackerUUIDs = append (p .trackerUUIDs , newUUID )
762
- p .awaitingSequences [newUUID ] = make (map [int ]struct {})
763
- p .sequence = 0
764
- }
765
749
break
766
750
}
767
751
0 commit comments