mirror of
https://github.com/go-ping/ping.git
synced 2025-08-02 05:53:48 +00:00
Use a UUID for packet tracking
Replace the random 8 byte tracker with a 16 byte UUID. * Implement as a slice so that it can be extended later. * Deprecate the exported `Pinger.Tracker` value. https://github.com/go-ping/ping/issues/142 Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
parent
ff8be33200
commit
3818264768
@ -40,7 +40,7 @@ func main() {
|
|||||||
timeout := flag.Duration("t", time.Second*100000, "")
|
timeout := flag.Duration("t", time.Second*100000, "")
|
||||||
interval := flag.Duration("i", time.Second, "")
|
interval := flag.Duration("i", time.Second, "")
|
||||||
count := flag.Int("c", -1, "")
|
count := flag.Int("c", -1, "")
|
||||||
size := flag.Int("s", 16, "")
|
size := flag.Int("s", 24, "")
|
||||||
privileged := flag.Bool("privileged", false, "")
|
privileged := flag.Bool("privileged", false, "")
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
fmt.Print(usage)
|
fmt.Print(usage)
|
||||||
@ -55,7 +55,7 @@ func main() {
|
|||||||
host := flag.Arg(0)
|
host := flag.Arg(0)
|
||||||
pinger, err := ping.NewPinger(host)
|
pinger, err := ping.NewPinger(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: %s\n", err.Error())
|
fmt.Println("ERROR:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +93,6 @@ func main() {
|
|||||||
fmt.Printf("PING %s (%s):\n", pinger.Addr(), pinger.IPAddr())
|
fmt.Printf("PING %s (%s):\n", pinger.Addr(), pinger.IPAddr())
|
||||||
err = pinger.Run()
|
err = pinger.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to ping target host: %s", err)
|
fmt.Println("Failed to ping target host:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
go.mod
5
go.mod
@ -3,6 +3,7 @@ module github.com/go-ping/ping
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73
|
github.com/google/uuid v1.2.0
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
)
|
)
|
||||||
|
20
go.sum
20
go.sum
@ -1,12 +1,12 @@
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E=
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005 h1:pDMpM2zh2MT0kHy037cKlSby2nEhD50SYqwQk76Nm40=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
80
ping.go
80
ping.go
@ -54,7 +54,6 @@ package ping
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@ -66,6 +65,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
@ -74,7 +74,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
timeSliceLength = 8
|
timeSliceLength = 8
|
||||||
trackerLength = 8
|
trackerLength = len(uuid.UUID{})
|
||||||
protocolICMP = 1
|
protocolICMP = 1
|
||||||
protocolIPv6ICMP = 58
|
protocolIPv6ICMP = 58
|
||||||
)
|
)
|
||||||
@ -87,22 +87,25 @@ var (
|
|||||||
// New returns a new Pinger struct pointer.
|
// New returns a new Pinger struct pointer.
|
||||||
func New(addr string) *Pinger {
|
func New(addr string) *Pinger {
|
||||||
r := rand.New(rand.NewSource(getSeed()))
|
r := rand.New(rand.NewSource(getSeed()))
|
||||||
|
firstUUID := uuid.New()
|
||||||
|
var firstSequence = map[uuid.UUID]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),
|
||||||
Tracker: r.Uint64(),
|
|
||||||
|
|
||||||
addr: addr,
|
addr: addr,
|
||||||
done: make(chan interface{}),
|
done: make(chan interface{}),
|
||||||
id: r.Intn(math.MaxUint16),
|
id: r.Intn(math.MaxUint16),
|
||||||
|
trackerUUIDs: []uuid.UUID{firstUUID},
|
||||||
ipaddr: nil,
|
ipaddr: nil,
|
||||||
ipv4: false,
|
ipv4: false,
|
||||||
network: "ip",
|
network: "ip",
|
||||||
protocol: "udp",
|
protocol: "udp",
|
||||||
awaitingSequences: map[int]struct{}{},
|
awaitingSequences: firstSequence,
|
||||||
logger: StdLogger{Logger: log.New(log.Writer(), log.Prefix(), log.Flags())},
|
logger: StdLogger{Logger: log.New(log.Writer(), log.Prefix(), log.Flags())},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +175,7 @@ type Pinger struct {
|
|||||||
// Size of packet being sent
|
// Size of packet being sent
|
||||||
Size int
|
Size int
|
||||||
|
|
||||||
// Tracker: Used to uniquely identify packets
|
// Tracker: Used to uniquely identify packets - Deprecated
|
||||||
Tracker uint64
|
Tracker uint64
|
||||||
|
|
||||||
// Source is the source IP address
|
// Source is the source IP address
|
||||||
@ -185,11 +188,14 @@ type Pinger struct {
|
|||||||
ipaddr *net.IPAddr
|
ipaddr *net.IPAddr
|
||||||
addr string
|
addr string
|
||||||
|
|
||||||
|
// trackerUUIDs is the list of UUIDs being used for sending packets.
|
||||||
|
trackerUUIDs []uuid.UUID
|
||||||
|
|
||||||
ipv4 bool
|
ipv4 bool
|
||||||
id int
|
id int
|
||||||
sequence int
|
sequence int
|
||||||
// awaitingSequences are in-flight sequence numbers we keep track of to help remove duplicate receipts
|
// awaitingSequences are in-flight sequence numbers we keep track of to help remove duplicate receipts
|
||||||
awaitingSequences map[int]struct{}
|
awaitingSequences map[uuid.UUID]map[int]struct{}
|
||||||
// network is one of "ip", "ip4", or "ip6".
|
// network is one of "ip", "ip4", or "ip6".
|
||||||
network string
|
network string
|
||||||
// protocol is "icmp" or "udp".
|
// protocol is "icmp" or "udp".
|
||||||
@ -382,6 +388,9 @@ func (p *Pinger) SetLogger(logger Logger) {
|
|||||||
func (p *Pinger) Run() error {
|
func (p *Pinger) Run() error {
|
||||||
var conn packetConn
|
var conn packetConn
|
||||||
var err error
|
var err error
|
||||||
|
if p.Size < timeSliceLength+trackerLength {
|
||||||
|
return fmt.Errorf("size %d is less than minimum required size %d", p.Size, timeSliceLength+trackerLength)
|
||||||
|
}
|
||||||
if p.ipaddr == nil {
|
if p.ipaddr == nil {
|
||||||
err = p.Resolve()
|
err = p.Resolve()
|
||||||
}
|
}
|
||||||
@ -582,6 +591,27 @@ func (p *Pinger) recvICMP(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPacketUUID scans the tracking slice for matches.
|
||||||
|
func (p *Pinger) getPacketUUID(pkt []byte) (*uuid.UUID, error) {
|
||||||
|
var packetUUID uuid.UUID
|
||||||
|
err := packetUUID.UnmarshalBinary(pkt[timeSliceLength : timeSliceLength+trackerLength])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error decoding tracking UUID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range p.trackerUUIDs {
|
||||||
|
if item == packetUUID {
|
||||||
|
return &packetUUID, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCurrentTrackerUUID grabs the latest tracker UUID.
|
||||||
|
func (p *Pinger) getCurrentTrackerUUID() uuid.UUID {
|
||||||
|
return p.trackerUUIDs[len(p.trackerUUIDs)-1]
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Pinger) processPacket(recv *packet) error {
|
func (p *Pinger) processPacket(recv *packet) error {
|
||||||
receivedAt := time.Now()
|
receivedAt := time.Now()
|
||||||
var proto int
|
var proto int
|
||||||
@ -620,17 +650,16 @@ func (p *Pinger) processPacket(recv *packet) error {
|
|||||||
len(pkt.Data), pkt.Data)
|
len(pkt.Data), pkt.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
tracker := bytesToUint(pkt.Data[timeSliceLength:])
|
pktUUID, err := p.getPacketUUID(pkt.Data)
|
||||||
timestamp := bytesToTime(pkt.Data[:timeSliceLength])
|
if err != nil || pktUUID == nil {
|
||||||
|
return err
|
||||||
if tracker != p.Tracker {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timestamp := bytesToTime(pkt.Data[:timeSliceLength])
|
||||||
inPkt.Rtt = receivedAt.Sub(timestamp)
|
inPkt.Rtt = receivedAt.Sub(timestamp)
|
||||||
inPkt.Seq = pkt.Seq
|
inPkt.Seq = pkt.Seq
|
||||||
// If we've already received this sequence, ignore it.
|
// If we've already received this sequence, ignore it.
|
||||||
if _, inflight := p.awaitingSequences[pkt.Seq]; !inflight {
|
if _, inflight := p.awaitingSequences[*pktUUID][pkt.Seq]; !inflight {
|
||||||
p.PacketsRecvDuplicates++
|
p.PacketsRecvDuplicates++
|
||||||
if p.OnDuplicateRecv != nil {
|
if p.OnDuplicateRecv != nil {
|
||||||
p.OnDuplicateRecv(inPkt)
|
p.OnDuplicateRecv(inPkt)
|
||||||
@ -638,7 +667,7 @@ func (p *Pinger) processPacket(recv *packet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// remove it from the list of sequences we're waiting for so we don't get duplicates.
|
// remove it from the list of sequences we're waiting for so we don't get duplicates.
|
||||||
delete(p.awaitingSequences, pkt.Seq)
|
delete(p.awaitingSequences[*pktUUID], pkt.Seq)
|
||||||
p.updateStatistics(inPkt)
|
p.updateStatistics(inPkt)
|
||||||
default:
|
default:
|
||||||
// Very bad, not sure how this can happen
|
// Very bad, not sure how this can happen
|
||||||
@ -659,7 +688,12 @@ func (p *Pinger) sendICMP(conn packetConn) error {
|
|||||||
dst = &net.UDPAddr{IP: p.ipaddr.IP, Zone: p.ipaddr.Zone}
|
dst = &net.UDPAddr{IP: p.ipaddr.IP, Zone: p.ipaddr.Zone}
|
||||||
}
|
}
|
||||||
|
|
||||||
t := append(timeToBytes(time.Now()), uintToBytes(p.Tracker)...)
|
currentUUID := p.getCurrentTrackerUUID()
|
||||||
|
uuidEncoded, err := currentUUID.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to marshal UUID binary: %w", err)
|
||||||
|
}
|
||||||
|
t := append(timeToBytes(time.Now()), uuidEncoded...)
|
||||||
if remainSize := p.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := p.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
t = append(t, bytes.Repeat([]byte{1}, remainSize)...)
|
t = append(t, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -701,9 +735,15 @@ func (p *Pinger) sendICMP(conn packetConn) error {
|
|||||||
handler(outPkt)
|
handler(outPkt)
|
||||||
}
|
}
|
||||||
// mark this sequence as in-flight
|
// mark this sequence as in-flight
|
||||||
p.awaitingSequences[p.sequence] = struct{}{}
|
p.awaitingSequences[currentUUID][p.sequence] = struct{}{}
|
||||||
p.PacketsSent++
|
p.PacketsSent++
|
||||||
p.sequence++
|
p.sequence++
|
||||||
|
if p.sequence > 65535 {
|
||||||
|
newUUID := uuid.New()
|
||||||
|
p.trackerUUIDs = append(p.trackerUUIDs, newUUID)
|
||||||
|
p.awaitingSequences[newUUID] = make(map[int]struct{})
|
||||||
|
p.sequence = 0
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,16 +794,6 @@ func timeToBytes(t time.Time) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func bytesToUint(b []byte) uint64 {
|
|
||||||
return uint64(binary.BigEndian.Uint64(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func uintToBytes(tracker uint64) []byte {
|
|
||||||
b := make([]byte, 8)
|
|
||||||
binary.BigEndian.PutUint64(b, tracker)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
var seed int64 = time.Now().UnixNano()
|
var seed int64 = time.Now().UnixNano()
|
||||||
|
|
||||||
// getSeed returns a goroutine-safe unique seed
|
// getSeed returns a goroutine-safe unique seed
|
||||||
|
68
ping_test.go
68
ping_test.go
@ -3,12 +3,14 @@ package ping
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
)
|
)
|
||||||
@ -21,7 +23,12 @@ func TestProcessPacket(t *testing.T) {
|
|||||||
shouldBe1++
|
shouldBe1++
|
||||||
}
|
}
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID := pinger.getCurrentTrackerUUID()
|
||||||
|
uuidEncoded, err := currentUUID.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), uuidEncoded...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -31,7 +38,7 @@ func TestProcessPacket(t *testing.T) {
|
|||||||
Seq: pinger.sequence,
|
Seq: pinger.sequence,
|
||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
pinger.awaitingSequences[pinger.sequence] = struct{}{}
|
pinger.awaitingSequences[currentUUID][pinger.sequence] = struct{}{}
|
||||||
|
|
||||||
msg := &icmp.Message{
|
msg := &icmp.Message{
|
||||||
Type: ipv4.ICMPTypeEchoReply,
|
Type: ipv4.ICMPTypeEchoReply,
|
||||||
@ -47,7 +54,7 @@ func TestProcessPacket(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
AssertTrue(t, shouldBe1 == 1)
|
AssertTrue(t, shouldBe1 == 1)
|
||||||
}
|
}
|
||||||
@ -60,7 +67,11 @@ func TestProcessPacket_IgnoreNonEchoReplies(t *testing.T) {
|
|||||||
shouldBe0++
|
shouldBe0++
|
||||||
}
|
}
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID, err := pinger.getCurrentTrackerUUID().MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), currentUUID...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -85,7 +96,7 @@ func TestProcessPacket_IgnoreNonEchoReplies(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
AssertTrue(t, shouldBe0 == 0)
|
AssertTrue(t, shouldBe0 == 0)
|
||||||
}
|
}
|
||||||
@ -99,7 +110,11 @@ func TestProcessPacket_IDMismatch(t *testing.T) {
|
|||||||
shouldBe0++
|
shouldBe0++
|
||||||
}
|
}
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID, err := pinger.getCurrentTrackerUUID().MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), currentUUID...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -124,7 +139,7 @@ func TestProcessPacket_IDMismatch(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
AssertTrue(t, shouldBe0 == 0)
|
AssertTrue(t, shouldBe0 == 0)
|
||||||
}
|
}
|
||||||
@ -137,7 +152,11 @@ func TestProcessPacket_TrackerMismatch(t *testing.T) {
|
|||||||
shouldBe0++
|
shouldBe0++
|
||||||
}
|
}
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(999)...)
|
testUUID, err := uuid.New().MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), testUUID...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -162,7 +181,7 @@ func TestProcessPacket_TrackerMismatch(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
AssertTrue(t, shouldBe0 == 0)
|
AssertTrue(t, shouldBe0 == 0)
|
||||||
}
|
}
|
||||||
@ -171,7 +190,11 @@ func TestProcessPacket_LargePacket(t *testing.T) {
|
|||||||
pinger := makeTestPinger()
|
pinger := makeTestPinger()
|
||||||
pinger.Size = 4096
|
pinger.Size = 4096
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID, err := pinger.getCurrentTrackerUUID().MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), currentUUID...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -196,7 +219,7 @@ func TestProcessPacket_LargePacket(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +484,6 @@ func makeTestPinger() *Pinger {
|
|||||||
pinger.addr = "127.0.0.1"
|
pinger.addr = "127.0.0.1"
|
||||||
pinger.protocol = "icmp"
|
pinger.protocol = "icmp"
|
||||||
pinger.id = 123
|
pinger.id = 123
|
||||||
pinger.Tracker = 456
|
|
||||||
pinger.Size = 0
|
pinger.Size = 0
|
||||||
|
|
||||||
return pinger
|
return pinger
|
||||||
@ -520,17 +542,20 @@ func BenchmarkProcessPacket(b *testing.B) {
|
|||||||
pinger.addr = "127.0.0.1"
|
pinger.addr = "127.0.0.1"
|
||||||
pinger.protocol = "ip4:icmp"
|
pinger.protocol = "ip4:icmp"
|
||||||
pinger.id = 123
|
pinger.id = 123
|
||||||
pinger.Tracker = 456
|
|
||||||
|
|
||||||
t := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID, err := pinger.getCurrentTrackerUUID().MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), currentUUID...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
t = append(t, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
body := &icmp.Echo{
|
body := &icmp.Echo{
|
||||||
ID: pinger.id,
|
ID: pinger.id,
|
||||||
Seq: pinger.sequence,
|
Seq: pinger.sequence,
|
||||||
Data: t,
|
Data: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &icmp.Message{
|
msg := &icmp.Message{
|
||||||
@ -567,7 +592,12 @@ func TestProcessPacket_IgnoresDuplicateSequence(t *testing.T) {
|
|||||||
dups++
|
dups++
|
||||||
}
|
}
|
||||||
|
|
||||||
data := append(timeToBytes(time.Now()), uintToBytes(pinger.Tracker)...)
|
currentUUID := pinger.getCurrentTrackerUUID()
|
||||||
|
uuidEncoded, err := currentUUID.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(fmt.Sprintf("unable to marshal UUID binary: %s", err))
|
||||||
|
}
|
||||||
|
data := append(timeToBytes(time.Now()), uuidEncoded...)
|
||||||
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
if remainSize := pinger.Size - timeSliceLength - trackerLength; remainSize > 0 {
|
||||||
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
data = append(data, bytes.Repeat([]byte{1}, remainSize)...)
|
||||||
}
|
}
|
||||||
@ -578,7 +608,7 @@ func TestProcessPacket_IgnoresDuplicateSequence(t *testing.T) {
|
|||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
// register the sequence as sent
|
// register the sequence as sent
|
||||||
pinger.awaitingSequences[0] = struct{}{}
|
pinger.awaitingSequences[currentUUID][0] = struct{}{}
|
||||||
|
|
||||||
msg := &icmp.Message{
|
msg := &icmp.Message{
|
||||||
Type: ipv4.ICMPTypeEchoReply,
|
Type: ipv4.ICMPTypeEchoReply,
|
||||||
@ -594,7 +624,7 @@ func TestProcessPacket_IgnoresDuplicateSequence(t *testing.T) {
|
|||||||
ttl: 24,
|
ttl: 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
AssertNoError(t, err)
|
AssertNoError(t, err)
|
||||||
// receive a duplicate
|
// receive a duplicate
|
||||||
err = pinger.processPacket(&pkt)
|
err = pinger.processPacket(&pkt)
|
||||||
|
Loading…
Reference in New Issue
Block a user