diff options
| -rw-r--r-- | datalogger/logger.go | 11 | ||||
| -rw-r--r-- | extendedstats/other.go | 6 | ||||
| -rw-r--r-- | extendedstats/unix.go | 29 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 6 | ||||
| -rw-r--r-- | networkQuality.go | 2 | ||||
| -rw-r--r-- | rpm/rpm.go | 18 |
7 files changed, 42 insertions, 32 deletions
diff --git a/datalogger/logger.go b/datalogger/logger.go index 1a4cd20..6236b59 100644 --- a/datalogger/logger.go +++ b/datalogger/logger.go @@ -66,19 +66,20 @@ func doCustomFormatting(value reflect.Value, tag reflect.StructTag) (string, err } formatMethodArgument, success := tag.Lookup("FormatterArgument") if !success { - return "", fmt.Errorf("Could not find the formatter name") + formatMethodArgument = "" } formatMethod := value.MethodByName(formatMethodName) if formatMethod == reflect.ValueOf(0) { return "", fmt.Errorf("Type %v does not support a method named %v", value.Type(), formatMethodName) } - - formatMethodArgumentUsable := make([]reflect.Value, 1) - formatMethodArgumentUsable[0] = reflect.ValueOf(formatMethodArgument) + var formatMethodArgumentUsable []reflect.Value = make([]reflect.Value, 0) + if formatMethodArgument != "" { + formatMethodArgumentUsable = append(formatMethodArgumentUsable, reflect.ValueOf(formatMethodArgument)) + } result := formatMethod.Call(formatMethodArgumentUsable) if len(result) == 1 { - return result[0].String(), nil + return fmt.Sprintf("%v", result[0]), nil } return "", fmt.Errorf("Too many results returned by the format method's invocation.") } diff --git a/extendedstats/other.go b/extendedstats/other.go index b4eae18..50caef6 100644 --- a/extendedstats/other.go +++ b/extendedstats/other.go @@ -11,7 +11,7 @@ import ( type ExtendedStats struct{} func (es *ExtendedStats) IncorporateConnectionStats(conn net.Conn) error { - return fmt.Errorf("OOPS: IncorporateConnectionStats is not supported on this platform") + return fmt.Errorf("IncorporateConnectionStats is not supported on this platform") } func (es *ExtendedStats) Repr() string { @@ -21,3 +21,7 @@ func (es *ExtendedStats) Repr() string { func ExtendedStatsAvailable() bool { return false } + +func GetTCPInfo(basicConn net.Conn) (interface, error) { + return nil, fmt.Errorf("GetTCPInfo is not supported on this platform") +} diff --git a/extendedstats/unix.go b/extendedstats/unix.go index a2d4d30..3db94fc 100644 --- a/extendedstats/unix.go +++ b/extendedstats/unix.go @@ -27,20 +27,8 @@ func ExtendedStatsAvailable() bool { return true } -func (es *ExtendedStats) IncorporateConnectionStats(rawConn net.Conn) error { - tlsConn, ok := rawConn.(*tls.Conn) - if !ok { - return fmt.Errorf( - "OOPS: Could not get the TCP info for the connection (not a TLS connection)", - ) - } - tcpConn, ok := tlsConn.NetConn().(*net.TCPConn) - if !ok { - return fmt.Errorf( - "OOPS: Could not get the TCP info for the connection (not a TCP connection)", - ) - } - if info, err := getTCPInfo(tcpConn); err != nil { +func (es *ExtendedStats) IncorporateConnectionStats(basicConn net.Conn) error { + if info, err := GetTCPInfo(basicConn); err != nil { return fmt.Errorf("OOPS: Could not get the TCP info for the connection: %v", err) } else { es.MaxPathMtu = utilities.Max(es.MaxPathMtu, uint64(info.Pmtu)) @@ -67,16 +55,21 @@ func (es *ExtendedStats) Repr() string { `, es.MaxPathMtu, es.MaxSendMss, es.MaxRecvMss, es.TotalRetransmissions, es.TotalReorderings, es.AverageRtt) } -func getTCPInfo(connection net.Conn) (*unix.TCPInfo, error) { - tcpConn, ok := connection.(*net.TCPConn) +func GetTCPInfo(basicConn net.Conn) (*unix.TCPInfo, error) { + tlsConn, ok := basicConn.(*tls.Conn) if !ok { - return nil, fmt.Errorf("connection is not a net.TCPConn") + return nil, fmt.Errorf("OOPS: Outermost connection is not a TLS connection") + } + tcpConn, ok := tlsConn.NetConn().(*net.TCPConn) + if !ok { + return nil, fmt.Errorf( + "OOPS: Could not get the TCP info for the connection (not a TCP connection)", + ) } 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) @@ -4,7 +4,7 @@ go 1.18 require ( golang.org/x/net v0.0.0-20220225172249-27dd8689420f - golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 + golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 ) require golang.org/x/text v0.3.7 // indirect @@ -1,8 +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-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 h1:wEZYwx+kK+KlZ0hpvP2Ls1Xr4+RWnlzGFwPP0aiDjIU= -golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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/networkQuality.go b/networkQuality.go index f20ca7d..53b2817 100644 --- a/networkQuality.go +++ b/networkQuality.go @@ -406,7 +406,7 @@ func main() { if err := extendedStats.IncorporateConnectionStats(downloadDataCollectionResult.LGCs[i].Stats().ConnInfo.Conn); err != nil { fmt.Fprintf( os.Stderr, - "Warning: Could not add extended stats for the connection: %v", + "Warning: Could not add extended stats for the connection: %v\n", err, ) } @@ -27,6 +27,7 @@ import ( "github.com/network-quality/goresponsiveness/constants" "github.com/network-quality/goresponsiveness/datalogger" "github.com/network-quality/goresponsiveness/debug" + "github.com/network-quality/goresponsiveness/extendedstats" "github.com/network-quality/goresponsiveness/lgc" "github.com/network-quality/goresponsiveness/ma" "github.com/network-quality/goresponsiveness/stats" @@ -63,7 +64,9 @@ type ProbeConfiguration struct { type ProbeDataPoint struct { Time time.Time `Description:"Time of the generation of the data point." Formatter:"Format" FormatterArgument:"01-02-2006-15-04-05.000"` RoundTripCount uint64 `Description:"The number of round trips measured by this data point."` - Duration time.Duration `Description:"The duration for this measurement."` + Duration time.Duration `Description:"The duration for this measurement." Formatter:"Seconds"` + TCPRtt time.Duration `Description:"The underlying connection's RTT at probe time." Formatter:"Seconds"` + TCPCwnd uint32 `Description:"The underlying connection's congestion window at probe time."` } type ThroughputDataPoint struct { @@ -186,7 +189,18 @@ func Probe( ) } }() - dataPoint := ProbeDataPoint{Time: time_before_probe, RoundTripCount: roundTripCount, Duration: totalDelay} + tcpRtt := time.Duration(0 * time.Second) + tcpCwnd := uint32(0) + if extendedstats.ExtendedStatsAvailable() { + tcpInfo, err := extendedstats.GetTCPInfo(probeTracer.stats.ConnInfo.Conn) + if err == nil { + tcpRtt = time.Duration(tcpInfo.Rtt) * time.Microsecond + tcpCwnd = tcpInfo.Snd_cwnd + } else { + fmt.Printf("Warning: Could not fetch the extended stats for a probe: %v\n", err) + } + } + dataPoint := ProbeDataPoint{Time: time_before_probe, RoundTripCount: roundTripCount, Duration: totalDelay, TCPRtt: tcpRtt, TCPCwnd: tcpCwnd} if !utilities.IsInterfaceNil(logger) { logger.LogRecord(dataPoint) } |
