From 9be87fa5ec89c9e393c9c93b3cb36668c71593d6 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 4 Jun 2022 21:24:19 -0400 Subject: [Feature] Add conditional compilation support for GetTCPInfo Now there is functionality for conditionally supporting GetTCPInfo depending on the platform. If the platform supports it, then the client can call utilities.GetTCPInfo. In the case that the platform does not support the GetTCPInfo function call, the result is an error of the type `NotImplemented`. --- utilities/tcpinfo_unix.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 utilities/tcpinfo_unix.go (limited to 'utilities/tcpinfo_unix.go') diff --git a/utilities/tcpinfo_unix.go b/utilities/tcpinfo_unix.go new file mode 100644 index 0000000..b0b5252 --- /dev/null +++ b/utilities/tcpinfo_unix.go @@ -0,0 +1,62 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd +// +build darwin dragonfly freebsd linux netbsd openbsd + +package utilities + +import ( + "fmt" + "net" + + "golang.org/x/sys/unix" +) + +func GetTCPInfo(connection net.Conn) (*unix.TCPInfo, error) { + tcpConn, ok := connection.(*net.TCPConn) + if !ok { + return nil, fmt.Errorf("connection is not a net.TCPConn") + } + rawConn, err := tcpConn.SyscallConn() + if err != nil { + return nil, err + } + + var info *unix.TCPInfo = nil + rawConn.Control(func(fd uintptr) { + info, err = unix.GetsockoptTCPInfo(int(fd), unix.SOL_TCP, unix.TCP_INFO) + }) + return info, err +} + +func PrintTCPInfo(info *unix.TCPInfo) { + fmt.Printf("TCPInfo: \n") + fmt.Printf(" State: %v\n", info.State) + fmt.Printf(" Ca_state: %v\n", info.Ca_state) + fmt.Printf(" Retransmits: %v\n", info.Retransmits) + fmt.Printf(" Probes: %v\n", info.Probes) + fmt.Printf(" Backoff: %v\n", info.Backoff) + fmt.Printf(" Options: %v\n", info.Options) + fmt.Printf(" Rto: %v\n", info.Rto) + fmt.Printf(" Ato: %v\n", info.Ato) + fmt.Printf(" Snd_mss: %v\n", info.Snd_mss) + fmt.Printf(" Rcv_mss: %v\n", info.Rcv_mss) + fmt.Printf(" Unacked: %v\n", info.Unacked) + fmt.Printf(" Sacked: %v\n", info.Sacked) + fmt.Printf(" Lost: %v\n", info.Lost) + fmt.Printf(" Retrans: %v\n", info.Retrans) + fmt.Printf(" Fackets: %v\n", info.Fackets) + fmt.Printf(" Last_data_sent: %v\n", info.Last_data_sent) + fmt.Printf(" Last_ack_sent: %v\n", info.Last_ack_sent) + fmt.Printf(" Last_data_recv: %v\n", info.Last_data_recv) + fmt.Printf(" Last_ack_recv: %v\n", info.Last_ack_recv) + fmt.Printf(" Pmtu: %v\n", info.Pmtu) + fmt.Printf(" Rcv_ssthresh: %v\n", info.Rcv_ssthresh) + fmt.Printf(" Rtt: %v\n", info.Rtt) + fmt.Printf(" Rttvar: %v\n", info.Rttvar) + fmt.Printf(" Snd_ssthresh: %v\n", info.Snd_ssthresh) + fmt.Printf(" Snd_cwnd: %v\n", info.Snd_cwnd) + fmt.Printf(" Advmss: %v\n", info.Advmss) + fmt.Printf(" Reordering: %v\n", info.Reordering) + fmt.Printf(" Rcv_rtt: %v\n", info.Rcv_rtt) + fmt.Printf(" Rcv_space: %v\n", info.Rcv_space) + fmt.Printf(" Total_retrans: %v\n", info.Total_retrans) +} -- cgit v1.2.3