tailscale/net/sockstats/sockstats_tsgo_darwin.go
Mihai Parparita f4f8ed98d9 sockstats: add validation for TCP socket stats
We can use the TCP_CONNECTION_INFO getsockopt() on Darwin to get
OS-collected tx/rx bytes for TCP sockets. Since this API is not available
for UDP sockets (or on Linux/Android), we can't rely on it for actual
stats gathering.

However, we can use it to validate the stats that we collect ourselves
using read/write hooks, so that we can be more confident in them. We
do need additional hooks from the Go standard library (added in
tailscale/go#59) to be able to collect them.

Updates tailscale/corp#9230
Updates #3363

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-03-08 13:39:30 -08:00

31 lines
555 B
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build tailscale_go && (darwin || ios)
package sockstats
import (
"syscall"
"golang.org/x/sys/unix"
)
func init() {
tcpConnStats = darwinTcpConnStats
}
func darwinTcpConnStats(c syscall.RawConn) (tx, rx uint64) {
c.Control(func(fd uintptr) {
if rawInfo, err := unix.GetsockoptTCPConnectionInfo(
int(fd),
unix.IPPROTO_TCP,
unix.TCP_CONNECTION_INFO,
); err == nil {
tx = uint64(rawInfo.Txbytes)
rx = uint64(rawInfo.Rxbytes)
}
})
return
}