diff options
| -rw-r--r-- | go.mod | 5 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | lgc/lgc.go | 9 | ||||
| -rw-r--r-- | networkQuality.go | 19 | ||||
| -rw-r--r-- | utilities/utilities.go | 54 |
5 files changed, 88 insertions, 1 deletions
@@ -4,4 +4,7 @@ go 1.18 require golang.org/x/net v0.0.0-20220225172249-27dd8689420f -require golang.org/x/text v0.3.7 // indirect +require ( + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/text v0.3.7 // indirect +) @@ -1,4 +1,6 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -38,6 +38,7 @@ type LoadGeneratingConnection interface { Client() *http.Client IsValid() bool ClientId() uint64 + Stats() *stats.TraceStats } // TODO: All 64-bit fields that are accessed atomically must @@ -284,6 +285,10 @@ func (lbd *LoadGeneratingConnectionDownload) IsValid() bool { return lbd.valid } +func (lbd *LoadGeneratingConnectionDownload) Stats() *stats.TraceStats { + return &lbd.stats +} + func (lbd *LoadGeneratingConnectionDownload) doDownload(ctx context.Context) { var request *http.Request = nil var get *http.Response = nil @@ -420,3 +425,7 @@ func (lgu *LoadGeneratingConnectionUpload) Start( go lgu.doUpload(ctx) return true } + +func (lbd *LoadGeneratingConnectionUpload) Stats() *stats.TraceStats { + return nil +} diff --git a/networkQuality.go b/networkQuality.go index ab9517e..7593714 100644 --- a/networkQuality.go +++ b/networkQuality.go @@ -21,6 +21,7 @@ import ( "fmt" _ "io" _ "log" + "net" "net/http" "os" "runtime/pprof" @@ -323,6 +324,24 @@ func main() { continue } + if *debugCliFlag { + // Note: This code is just an example of how to use utilities.GetTCPInfo. + rawConn := downloadSaturation.LGCs[randomLGCsIndex].Stats().ConnInfo.Conn + tlsConn, ok := rawConn.(*tls.Conn) + if !ok { + fmt.Printf("OOPS: Could not get the TCP info for the connection (not a TLS connection)!\n") + } + tcpConn, ok := tlsConn.NetConn().(*net.TCPConn) + if !ok { + fmt.Printf("OOPS: Could not get the TCP info for the connection (not a TCP connection)!\n") + } + if info, err := utilities.GetTCPInfo(tcpConn); err != nil { + fmt.Printf("OOPS: Could not get the TCP info for the connection: %v!\n", err) + } else { + utilities.PrintTCPInfo(info) + } + } + unsaturatedMeasurementTransport := http2.Transport{} unsaturatedMeasurementTransport.TLSClientConfig = &tls.Config{} if sslKeyFileConcurrentWriter != nil { diff --git a/utilities/utilities.go b/utilities/utilities.go index a143d31..e4c8a0d 100644 --- a/utilities/utilities.go +++ b/utilities/utilities.go @@ -18,10 +18,13 @@ import ( "fmt" "math" "math/rand" + "net" "os" "reflect" "sync/atomic" "time" + + "golang.org/x/sys/unix" ) func IsInterfaceNil(ifc interface{}) bool { @@ -122,3 +125,54 @@ func (optional Optional[S]) String() string { func RandBetween(max int) int { return rand.New(rand.NewSource(int64(time.Now().Nanosecond()))).Int() % max } + +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) +} |
