summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datalogger/logger.go11
-rw-r--r--extendedstats/other.go6
-rw-r--r--extendedstats/unix.go29
-rw-r--r--go.mod2
-rw-r--r--go.sum6
-rw-r--r--networkQuality.go2
-rw-r--r--rpm/rpm.go18
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)
diff --git a/go.mod b/go.mod
index 5fcee76..c017675 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 3fe6d08..75307bd 100644
--- a/go.sum
+++ b/go.sum
@@ -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,
)
}
diff --git a/rpm/rpm.go b/rpm/rpm.go
index 19da8f5..fe8184e 100644
--- a/rpm/rpm.go
+++ b/rpm/rpm.go
@@ -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)
}