summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--lgc/lgc.go9
-rw-r--r--networkQuality.go19
-rw-r--r--utilities/utilities.go54
5 files changed, 88 insertions, 1 deletions
diff --git a/go.mod b/go.mod
index d60ef0a..39b9252 100644
--- a/go.mod
+++ b/go.mod
@@ -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
+)
diff --git a/go.sum b/go.sum
index 4832ce9..ce291cf 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/lgc/lgc.go b/lgc/lgc.go
index 13f2c06..5b35fd1 100644
--- a/lgc/lgc.go
+++ b/lgc/lgc.go
@@ -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)
+}