|
@@ -53,7 +53,6 @@ package probing
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
- "fmt"
|
|
|
"math"
|
|
|
"math/rand"
|
|
|
"net"
|
|
@@ -62,24 +61,24 @@ import (
|
|
|
"time"
|
|
|
"trial/ping/probing/icmp"
|
|
|
|
|
|
- "github.com/google/uuid"
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
)
|
|
|
|
|
|
-var receive_buffer_count = mcfg.GetInt("ping.recv.buf.count", 10)
|
|
|
+var receive_buffer_count = mcfg.GetInt("ping.recv.buf.count", 500)
|
|
|
var ping_ttl = mcfg.GetInt("ping.ttl", 64)
|
|
|
-var ping_interval = mcfg.GetDuration("ping.interval", 1000*time.Millisecond)
|
|
|
-var concurlimit_ping = mcfg.GetInt("concurlimit.ping", 100)
|
|
|
-var concurchan_ping = make(chan struct{}, concurlimit_ping)
|
|
|
-var lastpingtimemutex sync.Mutex
|
|
|
-var lastpingtime = map[string]time.Time{}
|
|
|
|
|
|
-var ETIMEDOUT error = fmt.Errorf("timeout")
|
|
|
+// var ping_interval = mcfg.GetDuration("ping.interval", 1000*time.Millisecond)
|
|
|
+// var concurlimit_ping = mcfg.GetInt("concurlimit.ping", 100)
|
|
|
+// var concurchan_ping = make(chan struct{}, concurlimit_ping)
|
|
|
+// var lastpingtimemutex sync.Mutex
|
|
|
+// var lastpingtime = map[string]time.Time{}
|
|
|
|
|
|
-const (
|
|
|
- timeSliceLength = 8
|
|
|
- trackerLength = len(uuid.UUID{})
|
|
|
-)
|
|
|
+// var ETIMEDOUT error = fmt.Errorf("timeout")
|
|
|
+
|
|
|
+// const (
|
|
|
+// timeSliceLength = 8
|
|
|
+// trackerLength = len(uuid.UUID{})
|
|
|
+// )
|
|
|
|
|
|
// New returns a new Pinger struct pointer.
|
|
|
func New(addr string) *Pinger {
|
|
@@ -88,7 +87,7 @@ func New(addr string) *Pinger {
|
|
|
Count: -1,
|
|
|
Interval: time.Second,
|
|
|
RecordRtts: true,
|
|
|
- Size: timeSliceLength + trackerLength,
|
|
|
+ Size: 64, // timeSliceLength + trackerLength,
|
|
|
Timeout: time.Duration(math.MaxInt64),
|
|
|
|
|
|
addr: addr,
|
|
@@ -247,7 +246,8 @@ func (p *Pinger) updateStatistics(pkt *Packet) {
|
|
|
|
|
|
p.PacketsRecv++
|
|
|
if p.RecordRtts {
|
|
|
- p.rtts = append(p.rtts, pkt.Rtt)
|
|
|
+ // p.rtts = append(p.rtts, pkt.Rtt)
|
|
|
+ p.rtts[pkt.Seq] = pkt.Rtt
|
|
|
}
|
|
|
|
|
|
if p.PacketsRecv == 1 || pkt.Rtt < p.minRtt {
|
|
@@ -425,7 +425,20 @@ func (p *Pinger) Run() (err error) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+func (p *Pinger) init() *mpinfo {
|
|
|
+ pinfo := getPingInfo(p.ipaddr)
|
|
|
+ pinfo.host = p.addr
|
|
|
+ pinfo.size = p.Size
|
|
|
+ pinfo.timeout = p.Timeout
|
|
|
+ p.sequence_base = pinfo.lastseq
|
|
|
+ if p.RecordRtts {
|
|
|
+ p.rtts = make([]time.Duration, p.Count)
|
|
|
+ }
|
|
|
+ return pinfo
|
|
|
+}
|
|
|
+
|
|
|
func (p *Pinger) run() (time.Time, error) {
|
|
|
+ pinfo := p.init()
|
|
|
defer p.finish()
|
|
|
|
|
|
err := MPConn(p.ipv4, p.protocol).Listen()
|
|
@@ -442,15 +455,14 @@ func (p *Pinger) run() (time.Time, error) {
|
|
|
|
|
|
g.Go(func() (err error) {
|
|
|
defer p.Stop()
|
|
|
- last_send_time, err = p.runLoop()
|
|
|
+ last_send_time, err = p.runLoop(pinfo)
|
|
|
return err
|
|
|
})
|
|
|
|
|
|
return last_send_time, g.Wait()
|
|
|
}
|
|
|
|
|
|
-func (p *Pinger) runLoop() (time.Time, error) {
|
|
|
-
|
|
|
+func (p *Pinger) runLoop(pinfo *mpinfo) (time.Time, error) {
|
|
|
timeout := time.NewTimer(p.Timeout)
|
|
|
interval := time.NewTimer(0)
|
|
|
timeout.Stop()
|
|
@@ -461,22 +473,19 @@ func (p *Pinger) runLoop() (time.Time, error) {
|
|
|
received := make(chan interface{}, 1)
|
|
|
|
|
|
last_send_time := time.Now()
|
|
|
- pinfo := getPingInfo(p.ipaddr)
|
|
|
- pinfo.host = p.addr
|
|
|
- pinfo.size = p.Size
|
|
|
- pinfo.timeout = p.Timeout
|
|
|
pinfo.OnSend = func(pkt *icmp.Packet) {
|
|
|
last_send_time = pkt.SendTime
|
|
|
- if p.PacketsSent == 0 {
|
|
|
- p.sequence_base = pkt.Seq
|
|
|
+ seq := pkt.Seq - p.sequence_base
|
|
|
+ if seq < 0 || seq >= p.Count {
|
|
|
+ return
|
|
|
}
|
|
|
p.PacketsSent++
|
|
|
if p.OnSend != nil {
|
|
|
p.OnSend(&Packet{
|
|
|
Host: p.addr,
|
|
|
IPAddr: pkt.IPAddr,
|
|
|
- ID: pkt.ID,
|
|
|
- Seq: pkt.Seq - p.sequence_base,
|
|
|
+ ID: p.id,
|
|
|
+ Seq: seq,
|
|
|
Nbytes: pkt.Nbytes,
|
|
|
TTL: pkt.TTL,
|
|
|
Rtt: pkt.Rtt,
|
|
@@ -484,11 +493,15 @@ func (p *Pinger) runLoop() (time.Time, error) {
|
|
|
}
|
|
|
}
|
|
|
pinfo.OnRecv = func(pkt *icmp.Packet) {
|
|
|
+ seq := pkt.Seq - p.sequence_base
|
|
|
+ if seq < 0 || seq >= p.Count {
|
|
|
+ return
|
|
|
+ }
|
|
|
inpkt := &Packet{
|
|
|
Host: p.addr,
|
|
|
IPAddr: pkt.IPAddr,
|
|
|
- ID: pkt.ID,
|
|
|
- Seq: pkt.Seq - p.sequence_base,
|
|
|
+ ID: p.id,
|
|
|
+ Seq: seq,
|
|
|
Nbytes: pkt.Nbytes,
|
|
|
TTL: pkt.TTL,
|
|
|
Rtt: pkt.Rtt,
|
|
@@ -500,11 +513,15 @@ func (p *Pinger) runLoop() (time.Time, error) {
|
|
|
received <- nil
|
|
|
}
|
|
|
pinfo.OnRecvDup = func(pkt *icmp.Packet) {
|
|
|
+ seq := pkt.Seq - p.sequence_base
|
|
|
+ if seq < 0 || seq >= p.Count {
|
|
|
+ return
|
|
|
+ }
|
|
|
inpkt := &Packet{
|
|
|
Host: p.addr,
|
|
|
IPAddr: pkt.IPAddr,
|
|
|
- ID: pkt.ID,
|
|
|
- Seq: pkt.Seq - p.sequence_base,
|
|
|
+ ID: p.id,
|
|
|
+ Seq: seq,
|
|
|
Nbytes: pkt.Nbytes,
|
|
|
TTL: pkt.TTL,
|
|
|
Rtt: pkt.Rtt,
|
|
@@ -512,7 +529,24 @@ func (p *Pinger) runLoop() (time.Time, error) {
|
|
|
if p.OnDuplicateRecv != nil {
|
|
|
p.OnDuplicateRecv(inpkt)
|
|
|
}
|
|
|
- p.updateStatistics(inpkt)
|
|
|
+ }
|
|
|
+ pinfo.OnRecvTimeout = func(pkt *icmp.Packet) {
|
|
|
+ seq := pkt.Seq - p.sequence_base
|
|
|
+ if seq < 0 || seq >= p.Count {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ outpkt := &Packet{
|
|
|
+ Host: p.addr,
|
|
|
+ IPAddr: pkt.IPAddr,
|
|
|
+ ID: p.id,
|
|
|
+ Seq: seq,
|
|
|
+ Nbytes: pkt.Nbytes,
|
|
|
+ TTL: pkt.TTL,
|
|
|
+ Rtt: pkt.Rtt,
|
|
|
+ }
|
|
|
+ if p.OnTimeout != nil {
|
|
|
+ p.OnTimeout(outpkt)
|
|
|
+ }
|
|
|
}
|
|
|
for {
|
|
|
select {
|