Skip to content

Commit

Permalink
pinger uses only SO_TIMESTAMPING to calculate RTT
Browse files Browse the repository at this point in the history
  • Loading branch information
def committed Feb 21, 2022
1 parent 21d3efc commit 2bd0422
Showing 1 changed file with 16 additions and 22 deletions.
38 changes: 16 additions & 22 deletions pinger/pinger.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/vishvananda/netns"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/sys/unix"
"inet.af/netaddr"
"k8s.io/klog/v2"
"net"
Expand All @@ -19,11 +20,8 @@ import (
)

const (
pingReplyPollTimeout = 10 * time.Millisecond
protocolICMP = 1 // Internet Control Message
SOF_TIMESTAMPING_TX_SOFTWARE = 1 << 1
SOF_TIMESTAMPING_TX_SCHED = 1 << 8
SOF_TIMESTAMPING_RX_SOFTWARE = 1 << 3
pingReplyPollTimeout = 10 * time.Millisecond
protocolICMP = 1 // Internet Control Message
)

var (
Expand Down Expand Up @@ -72,7 +70,7 @@ func Ping(ns netns.NsHandle, originNs netns.NsHandle, targets []netaddr.IP, time
if strings.HasPrefix(err.Error(), "resource temporarily unavailable") {
continue
}
return nil, fmt.Errorf("failed to get RX timestamp: %s", err)
return nil, fmt.Errorf("failed to get TX timestamp: %s", err)
}
ids[ip] = pkt
}
Expand Down Expand Up @@ -134,21 +132,20 @@ func send(conn *net.IPConn, seq int, ip net.Addr) error {
}

func getTimestampFromOutOfBandData(oob []byte, oobn int) (time.Time, error) {
var t time.Time
cms, err := syscall.ParseSocketControlMessage(oob[:oobn])
if err != nil {
return t, err
return time.Time{}, err
}
for _, cm := range cms {
if cm.Header.Level == syscall.SOL_SOCKET && cm.Header.Type == syscall.SO_TIMESTAMP {
var tv syscall.Timeval
if err := binary.Read(bytes.NewBuffer(cm.Data), binary.LittleEndian, &tv); err != nil {
return t, err
if cm.Header.Level == syscall.SOL_SOCKET || cm.Header.Type == syscall.SO_TIMESTAMPING {
var t unix.ScmTimestamping
if err := binary.Read(bytes.NewBuffer(cm.Data), binary.LittleEndian, &t); err != nil {
return time.Time{}, err
}
return time.Unix(tv.Unix()), nil
return time.Unix(t.Ts[0].Unix()), nil
}
}
return t, errors.New("no timestamp found")
return time.Time{}, fmt.Errorf("no timestamp found")
}

func getTxTimestamp(socketFd int) (time.Time, error) {
Expand Down Expand Up @@ -222,19 +219,16 @@ func openConn() (*net.IPConn, error) {
}
defer f.Close()
fd := int(f.Fd())

flags := SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_RX_SOFTWARE
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TIMESTAMPING, flags); err != nil {
return nil, err
}
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TIMESTAMP, 1); err != nil {
flags := unix.SOF_TIMESTAMPING_SOFTWARE | unix.SOF_TIMESTAMPING_RX_SOFTWARE | unix.SOF_TIMESTAMPING_TX_SCHED |
unix.SOF_TIMESTAMPING_OPT_CMSG | unix.SOF_TIMESTAMPING_OPT_TSONLY
if err := syscall.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_TIMESTAMPING, flags); err != nil {
return nil, err
}
timeout := syscall.Timeval{Sec: 0, Usec: 1000}
if err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &timeout); err != nil {
if err := syscall.SetsockoptTimeval(fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &timeout); err != nil {
return nil, err
}
if err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &timeout); err != nil {
if err := syscall.SetsockoptTimeval(fd, unix.SOL_SOCKET, unix.SO_SNDTIMEO, &timeout); err != nil {
return nil, err
}
return ipconn, nil
Expand Down

0 comments on commit 2bd0422

Please sign in to comment.