mirror of
https://github.com/go-ping/ping.git
synced 2025-07-13 22:04:20 +00:00
Add packet timeout callback #50
This commit is contained in:
parent
779d1e9195
commit
2c3c45023c
@ -77,6 +77,9 @@ func main() {
|
|||||||
fmt.Printf("%d bytes from %s: icmp_seq=%d time=%v ttl=%v (DUP!)\n",
|
fmt.Printf("%d bytes from %s: icmp_seq=%d time=%v ttl=%v (DUP!)\n",
|
||||||
pkt.Nbytes, pkt.IPAddr, pkt.Seq, pkt.Rtt, pkt.Ttl)
|
pkt.Nbytes, pkt.IPAddr, pkt.Seq, pkt.Rtt, pkt.Ttl)
|
||||||
}
|
}
|
||||||
|
pinger.OnTimeout = func(await *ping.AwaitingPacket) {
|
||||||
|
fmt.Printf("TIMEOUT icmp_seq=%d time=%v\n", await.Seq, await.DispatchedTime)
|
||||||
|
}
|
||||||
pinger.OnFinish = func(stats *ping.Statistics) {
|
pinger.OnFinish = func(stats *ping.Statistics) {
|
||||||
fmt.Printf("\n--- %s ping statistics ---\n", stats.Addr)
|
fmt.Printf("\n--- %s ping statistics ---\n", stats.Addr)
|
||||||
fmt.Printf("%d packets transmitted, %d packets received, %d duplicates, %v%% packet loss\n",
|
fmt.Printf("%d packets transmitted, %d packets received, %d duplicates, %v%% packet loss\n",
|
||||||
|
40
ping.go
40
ping.go
@ -91,11 +91,13 @@ func New(addr string) *Pinger {
|
|||||||
var firstSequence = map[uuid.UUID]map[int]struct{}{}
|
var firstSequence = map[uuid.UUID]map[int]struct{}{}
|
||||||
firstSequence[firstUUID] = make(map[int]struct{})
|
firstSequence[firstUUID] = make(map[int]struct{})
|
||||||
return &Pinger{
|
return &Pinger{
|
||||||
Count: -1,
|
Count: -1,
|
||||||
Interval: time.Second,
|
Interval: time.Second,
|
||||||
RecordRtts: true,
|
RecordRtts: true,
|
||||||
Size: timeSliceLength + trackerLength,
|
Size: timeSliceLength + trackerLength,
|
||||||
Timeout: time.Duration(math.MaxInt64),
|
Timeout: time.Duration(math.MaxInt64),
|
||||||
|
PacketTimeout: time.Duration(1 * time.Second),
|
||||||
|
Tracker: r.Uint64(),
|
||||||
|
|
||||||
addr: addr,
|
addr: addr,
|
||||||
done: make(chan interface{}),
|
done: make(chan interface{}),
|
||||||
@ -126,6 +128,10 @@ type Pinger struct {
|
|||||||
// packets have been received.
|
// packets have been received.
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
|
|
||||||
|
// PacketTimeout specifies a timeout before the OnTimeout function is called
|
||||||
|
// for a packet not being received
|
||||||
|
PacketTimeout time.Duration
|
||||||
|
|
||||||
// Count tells pinger to stop after sending (and receiving) Count echo
|
// Count tells pinger to stop after sending (and receiving) Count echo
|
||||||
// packets. If this option is not specified, pinger will operate until
|
// packets. If this option is not specified, pinger will operate until
|
||||||
// interrupted.
|
// interrupted.
|
||||||
@ -170,6 +176,9 @@ type Pinger struct {
|
|||||||
// OnFinish is called when Pinger exits
|
// OnFinish is called when Pinger exits
|
||||||
OnFinish func(*Statistics)
|
OnFinish func(*Statistics)
|
||||||
|
|
||||||
|
// OnTimeout is called when packet timeout
|
||||||
|
OnTimeout func(*AwaitingPacket)
|
||||||
|
|
||||||
// OnDuplicateRecv is called when a packet is received that has already been received.
|
// OnDuplicateRecv is called when a packet is received that has already been received.
|
||||||
OnDuplicateRecv func(*Packet)
|
OnDuplicateRecv func(*Packet)
|
||||||
|
|
||||||
@ -207,6 +216,11 @@ type Pinger struct {
|
|||||||
TTL int
|
TTL int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AwaitingPacket struct {
|
||||||
|
DispatchedTime time.Time
|
||||||
|
Seq int
|
||||||
|
}
|
||||||
|
|
||||||
type packet struct {
|
type packet struct {
|
||||||
bytes []byte
|
bytes []byte
|
||||||
nbytes int
|
nbytes int
|
||||||
@ -477,6 +491,7 @@ func (p *Pinger) runLoop(
|
|||||||
return nil
|
return nil
|
||||||
|
|
||||||
case <-timeout.C:
|
case <-timeout.C:
|
||||||
|
p.CheckAwaitingSequences()
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case r := <-recvCh:
|
case r := <-recvCh:
|
||||||
@ -487,11 +502,13 @@ func (p *Pinger) runLoop(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case <-interval.C:
|
case <-interval.C:
|
||||||
|
p.CheckAwaitingSequences()
|
||||||
if p.Count > 0 && p.PacketsSent >= p.Count {
|
if p.Count > 0 && p.PacketsSent >= p.Count {
|
||||||
interval.Stop()
|
interval.Stop()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err := p.sendICMP(conn)
|
err := p.sendICMP(conn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME: this logs as FATAL but continues
|
// FIXME: this logs as FATAL but continues
|
||||||
logger.Fatalf("sending packet: %s", err)
|
logger.Fatalf("sending packet: %s", err)
|
||||||
@ -503,6 +520,19 @@ func (p *Pinger) runLoop(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pinger) CheckAwaitingSequences() {
|
||||||
|
// Loop through each item in map
|
||||||
|
currentTime := time.Now()
|
||||||
|
for seq, awaiting := range p.awaitingSequences {
|
||||||
|
if awaiting.DispatchedTime.Add(p.PacketTimeout).Before(currentTime) {
|
||||||
|
delete(p.awaitingSequences, seq)
|
||||||
|
if p.OnTimeout != nil {
|
||||||
|
p.OnTimeout(&awaiting)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Pinger) Stop() {
|
func (p *Pinger) Stop() {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user