@@ -86,27 +86,22 @@ var (
8686// New returns a new Pinger struct pointer.
8787func New (addr string ) * Pinger {
8888 r := rand .New (rand .NewSource (getSeed ()))
89- firstUUID := uuid .New ()
90- var firstSequence = map [uuid.UUID ]map [int ]struct {}{}
91- firstSequence [firstUUID ] = make (map [int ]struct {})
9289 return & Pinger {
9390 Count : - 1 ,
9491 Interval : time .Second ,
9592 RecordRtts : true ,
9693 Size : timeSliceLength + trackerLength ,
9794 Timeout : time .Duration (math .MaxInt64 ),
9895
99- addr : addr ,
100- done : make (chan interface {}),
101- id : r .Intn (math .MaxUint16 ),
102- trackerUUIDs : []uuid.UUID {firstUUID },
103- ipaddr : nil ,
104- ipv4 : false ,
105- network : "ip" ,
106- protocol : "udp" ,
107- awaitingSequences : firstSequence ,
108- TTL : 64 ,
109- logger : StdLogger {Logger : log .New (log .Writer (), log .Prefix (), log .Flags ())},
96+ addr : addr ,
97+ done : make (chan interface {}),
98+ id : r .Intn (math .MaxUint16 ),
99+ ipaddr : nil ,
100+ ipv4 : false ,
101+ network : "ip" ,
102+ protocol : "udp" ,
103+ TTL : 64 ,
104+ logger : StdLogger {Logger : log .New (log .Writer (), log .Prefix (), log .Flags ())},
110105 }
111106}
112107
@@ -142,6 +137,9 @@ type Pinger struct {
142137 // Number of duplicate packets received
143138 PacketsRecvDuplicates int
144139
140+ // Per-packet timeout
141+ PacketTimeout time.Duration
142+
145143 // Round trip time statistics
146144 minRtt time.Duration
147145 maxRtt time.Duration
@@ -188,14 +186,11 @@ type Pinger struct {
188186 ipaddr * net.IPAddr
189187 addr string
190188
191- // trackerUUIDs is the list of UUIDs being used for sending packets.
192- trackerUUIDs []uuid.UUID
193-
194189 ipv4 bool
195190 id int
196191 sequence int
197- // awaitingSequences are in-flight sequence numbers we keep track of to help remove duplicate receipts
198- awaitingSequences map [uuid. UUID ] map [ int ] struct {}
192+ // tracker is a PacketTrackrer of UUIDs and sequence numbers.
193+ tracker * PacketTracker
199194 // network is one of "ip", "ip4", or "ip6".
200195 network string
201196 // protocol is "icmp" or "udp".
@@ -412,6 +407,9 @@ func (p *Pinger) Run() error {
412407 if err != nil {
413408 return err
414409 }
410+
411+ p .tracker = newPacketTracker (p .PacketTimeout )
412+
415413 if conn , err = p .listen (); err != nil {
416414 return err
417415 }
@@ -614,19 +612,12 @@ func (p *Pinger) getPacketUUID(pkt []byte) (*uuid.UUID, error) {
614612 return nil , fmt .Errorf ("error decoding tracking UUID: %w" , err )
615613 }
616614
617- for _ , item := range p .trackerUUIDs {
618- if item == packetUUID {
619- return & packetUUID , nil
620- }
615+ if p .tracker .HasUUID (packetUUID ) {
616+ return & packetUUID , nil
621617 }
622618 return nil , nil
623619}
624620
625- // getCurrentTrackerUUID grabs the latest tracker UUID.
626- func (p * Pinger ) getCurrentTrackerUUID () uuid.UUID {
627- return p .trackerUUIDs [len (p .trackerUUIDs )- 1 ]
628- }
629-
630621func (p * Pinger ) processPacket (recv * packet ) error {
631622 receivedAt := time .Now ()
632623 var proto int
@@ -675,15 +666,15 @@ func (p *Pinger) processPacket(recv *packet) error {
675666 inPkt .Rtt = receivedAt .Sub (timestamp )
676667 inPkt .Seq = pkt .Seq
677668 // If we've already received this sequence, ignore it.
678- if _ , inflight := p. awaitingSequences [ * pktUUID ][ pkt.Seq ]; ! inflight {
669+ if ! p . tracker . HasPacket ( * pktUUID , pkt .Seq ) {
679670 p .PacketsRecvDuplicates ++
680671 if p .OnDuplicateRecv != nil {
681672 p .OnDuplicateRecv (inPkt )
682673 }
683674 return nil
684675 }
685- // remove it from the list of sequences we're waiting for so we don't get duplicates.
686- delete ( p . awaitingSequences [ * pktUUID ] , pkt .Seq )
676+ // Remove it from the list of sequences we're waiting for so we don't get duplicates.
677+ p . tracker . DeletePacket ( * pktUUID , pkt .Seq )
687678 p .updateStatistics (inPkt )
688679 default :
689680 // Very bad, not sure how this can happen
@@ -704,7 +695,7 @@ func (p *Pinger) sendICMP(conn packetConn) error {
704695 dst = & net.UDPAddr {IP : p .ipaddr .IP , Zone : p .ipaddr .Zone }
705696 }
706697
707- currentUUID := p .getCurrentTrackerUUID ()
698+ currentUUID := p .tracker . CurrentUUID ()
708699 uuidEncoded , err := currentUUID .MarshalBinary ()
709700 if err != nil {
710701 return fmt .Errorf ("unable to marshal UUID binary: %w" , err )
@@ -752,15 +743,8 @@ func (p *Pinger) sendICMP(conn packetConn) error {
752743 handler (outPkt )
753744 }
754745 // mark this sequence as in-flight
755- p.awaitingSequences [ currentUUID ][p. sequence ] = struct {}{}
746+ p .sequence = p . tracker . AddPacket ()
756747 p .PacketsSent ++
757- p .sequence ++
758- if p .sequence > 65535 {
759- newUUID := uuid .New ()
760- p .trackerUUIDs = append (p .trackerUUIDs , newUUID )
761- p .awaitingSequences [newUUID ] = make (map [int ]struct {})
762- p .sequence = 0
763- }
764748 break
765749 }
766750
0 commit comments