diff options
Diffstat (limited to 'lgc/lgc.go')
| -rw-r--r-- | lgc/lgc.go | 269 |
1 files changed, 148 insertions, 121 deletions
@@ -25,7 +25,8 @@ import ( "sync/atomic" "time" - "github.com/network-quality/goresponsiveness/constants" + "github.com/network-quality/goresponsiveness/debug" + "github.com/network-quality/goresponsiveness/traceable" "github.com/network-quality/goresponsiveness/utilities" "golang.org/x/net/http2" ) @@ -38,7 +39,7 @@ var GenerateConnectionId func() uint64 = func() func() uint64 { }() type LoadGeneratingConnection interface { - Start(context.Context, constants.DebugLevel) bool + Start(context.Context, debug.DebugLevel) bool Transferred() uint64 Client() *http.Client IsValid() bool @@ -51,12 +52,13 @@ type LoadGeneratingConnectionStats struct { connInfo httptrace.GotConnInfo httpInfo httptrace.WroteRequestInfo tlsConnInfo tls.ConnectionState + connectDoneError error dnsStartTime time.Time - dnsCompleteTime time.Time + dnsDoneTime time.Time tlsStartTime time.Time tlsCompleteTime time.Time connectStartTime time.Time - connectCompleteTime time.Time + connectDoneTime time.Time getConnectionStartTime time.Time getConnectionCompleteTime time.Time } @@ -65,7 +67,7 @@ type LoadGeneratingConnectionDownload struct { Path string downloaded uint64 client *http.Client - debug constants.DebugLevel + debug debug.DebugLevel valid bool KeyLogger io.Writer clientId uint64 @@ -73,110 +75,135 @@ type LoadGeneratingConnectionDownload struct { stats LoadGeneratingConnectionStats } -func generateHttpTimingTracer( - lgd *LoadGeneratingConnectionDownload, -) *httptrace.ClientTrace { - newTracer := httptrace.ClientTrace{ - DNSStart: func(dnsStartInfo httptrace.DNSStartInfo) { - lgd.stats.dnsStartTime = time.Now() - lgd.stats.dnsStart = dnsStartInfo - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "DNS Start for %v: %v\n", - lgd.ClientId(), - dnsStartInfo, - ) - } - }, - DNSDone: func(dnsDoneInfo httptrace.DNSDoneInfo) { - lgd.stats.dnsCompleteTime = time.Now() - lgd.stats.dnsDone = dnsDoneInfo - if utilities.IsDebug(lgd.debug) { - fmt.Printf("DNS Done for %v: %v\n", lgd.ClientId(), dnsDoneInfo) - } - }, - ConnectStart: func(network, address string) { - lgd.stats.connectStartTime = time.Now() - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "TCP Start of %v: %v: %v\n", - lgd.ClientId(), - network, - address, - ) - } - }, - ConnectDone: func(network, address string, err error) { - lgd.stats.connectCompleteTime = time.Now() - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "TCP Done for %v: %v: %v (%v)\n", - lgd.ClientId(), - network, - address, - err, - ) - } - }, - GetConn: func(hostPort string) { - lgd.stats.getConnectionStartTime = time.Now() - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "GetConn host port for %v: %v\n", - lgd.ClientId(), - hostPort, - ) - } - }, - GotConn: func(connInfo httptrace.GotConnInfo) { - if connInfo.Reused { - panic(!connInfo.Reused) - } - lgd.stats.connInfo = connInfo - lgd.stats.getConnectionCompleteTime = time.Now() - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "GetConn host port for %v: %v\n", - lgd.ClientId(), - connInfo, - ) - } - }, - TLSHandshakeStart: func() { - lgd.stats.tlsStartTime = time.Now() - if utilities.IsDebug(lgd.debug) { - fmt.Printf("TLSHandshakeStart for %v\n", lgd.ClientId()) - } - }, - TLSHandshakeDone: func(tlsConnState tls.ConnectionState, err error) { - lgd.stats.tlsCompleteTime = time.Now() - lgd.stats.tlsConnInfo = tlsConnState - if utilities.IsDebug(lgd.debug) { - fmt.Printf( - "TLSHandshakeDone for %v: %v\n", - lgd.ClientId(), - tlsConnState, - ) - } - }, +func (lgd *LoadGeneratingConnectionDownload) SetDnsStartTimeInfo( + now time.Time, + dnsStartInfo httptrace.DNSStartInfo, +) { + lgd.stats.dnsStartTime = now + lgd.stats.dnsStart = dnsStartInfo + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "DNS Start for %v: %v\n", + lgd.ClientId(), + dnsStartInfo, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetDnsDoneTimeInfo( + now time.Time, + dnsDoneInfo httptrace.DNSDoneInfo, +) { + lgd.stats.dnsDoneTime = now + lgd.stats.dnsDone = dnsDoneInfo + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "DNS Done for %v: %v\n", + lgd.ClientId(), + lgd.stats.dnsDone, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetConnectStartTime( + now time.Time, +) { + lgd.stats.connectStartTime = now + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "TCP Start for %v at %v\n", + lgd.ClientId(), + lgd.stats.connectStartTime, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetConnectDoneTimeError( + now time.Time, + err error, +) { + lgd.stats.connectDoneTime = now + lgd.stats.connectDoneError = err + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "TCP Done for %v (with error %v) @ %v\n", + lgd.ClientId(), + lgd.stats.connectDoneError, + lgd.stats.connectDoneTime, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetGetConnTime(now time.Time) { + lgd.stats.getConnectionStartTime = now + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "Started getting connection for %v @ %v\n", + lgd.ClientId(), + lgd.stats.getConnectionStartTime, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetGotConnTimeInfo( + now time.Time, + gotConnInfo httptrace.GotConnInfo, +) { + lgd.stats.getConnectionCompleteTime = now + lgd.stats.connInfo = gotConnInfo + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "Got connection for %v at %v with info %v\n", + lgd.ClientId(), + lgd.stats.getConnectionCompleteTime, + lgd.stats.connInfo, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetTLSHandshakeStartTime( + now time.Time, +) { + lgd.stats.tlsStartTime = now + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "Started TLS Handshake for %v @ %v\n", + lgd.ClientId(), + lgd.stats.tlsStartTime, + ) + } +} + +func (lgd *LoadGeneratingConnectionDownload) SetTLSHandshakeDoneTimeState( + now time.Time, + connectionState tls.ConnectionState, +) { + lgd.stats.tlsCompleteTime = now + lgd.stats.tlsConnInfo = connectionState + if debug.IsDebug(lgd.debug) { + fmt.Printf( + "Completed TLS handshake for %v at %v with info %v\n", + lgd.ClientId(), + lgd.stats.tlsCompleteTime, + lgd.stats.tlsConnInfo, + ) } - return &newTracer } -func (lbd *LoadGeneratingConnectionDownload) ClientId() uint64 { - return lbd.clientId +func (lgd *LoadGeneratingConnectionDownload) ClientId() uint64 { + return lgd.clientId } -func (lbd *LoadGeneratingConnectionDownload) Transferred() uint64 { - transferred := atomic.LoadUint64(&lbd.downloaded) - if utilities.IsDebug(lbd.debug) { +func (lgd *LoadGeneratingConnectionDownload) Transferred() uint64 { + transferred := atomic.LoadUint64(&lgd.downloaded) + if debug.IsDebug(lgd.debug) { fmt.Printf("download: Transferred: %v\n", transferred) } return transferred } -func (lbd *LoadGeneratingConnectionDownload) Client() *http.Client { - return lbd.client +func (lgd *LoadGeneratingConnectionDownload) Client() *http.Client { + return lgd.client } type countingReader struct { @@ -194,17 +221,17 @@ func (cr *countingReader) Read(p []byte) (n int, err error) { return } -func (lbd *LoadGeneratingConnectionDownload) Start( +func (lgd *LoadGeneratingConnectionDownload) Start( ctx context.Context, - debug constants.DebugLevel, + debugLevel debug.DebugLevel, ) bool { - lbd.downloaded = 0 - lbd.clientId = GenerateConnectionId() + lgd.downloaded = 0 + lgd.clientId = GenerateConnectionId() transport := http2.Transport{} transport.TLSClientConfig = &tls.Config{} - if !utilities.IsInterfaceNil(lbd.KeyLogger) { - if utilities.IsDebug(lbd.debug) { + if !utilities.IsInterfaceNil(lgd.KeyLogger) { + if debug.IsDebug(lgd.debug) { fmt.Printf( "Using an SSL Key Logger for this load-generating download.\n", ) @@ -217,22 +244,22 @@ func (lbd *LoadGeneratingConnectionDownload) Start( // depend on whether the url contains // https:// or http://: // https://github.com/golang/go/blob/7ca6902c171b336d98adbb103d701a013229c806/src/net/http/transport.go#L74 - transport.TLSClientConfig.KeyLogWriter = lbd.KeyLogger + transport.TLSClientConfig.KeyLogWriter = lgd.KeyLogger } transport.TLSClientConfig.InsecureSkipVerify = true - lbd.client = &http.Client{Transport: &transport} - lbd.debug = debug - lbd.valid = true - lbd.tracer = generateHttpTimingTracer(lbd) + lgd.client = &http.Client{Transport: &transport} + lgd.debug = debugLevel + lgd.valid = true + lgd.tracer = traceable.GenerateHttpTimingTracer(lgd, lgd.debug) - if utilities.IsDebug(debug) { + if debug.IsDebug(lgd.debug) { fmt.Printf( "Started a load-generating download (id: %v).\n", - lbd.clientId, + lgd.clientId, ) } - go lbd.doDownload(ctx) + go lgd.doDownload(ctx) return true } func (lbd *LoadGeneratingConnectionDownload) IsValid() bool { @@ -261,7 +288,7 @@ func (lbd *LoadGeneratingConnectionDownload) doDownload(ctx context.Context) { cr := &countingReader{n: &lbd.downloaded, ctx: ctx, readable: get.Body} _, _ = io.Copy(ioutil.Discard, cr) get.Body.Close() - if utilities.IsDebug(lbd.debug) { + if debug.IsDebug(lbd.debug) { fmt.Printf("Ending a load-generating download.\n") } } @@ -270,7 +297,7 @@ type LoadGeneratingConnectionUpload struct { Path string uploaded uint64 client *http.Client - debug constants.DebugLevel + debug debug.DebugLevel valid bool KeyLogger io.Writer clientId uint64 @@ -282,7 +309,7 @@ func (lbu *LoadGeneratingConnectionUpload) ClientId() uint64 { func (lbu *LoadGeneratingConnectionUpload) Transferred() uint64 { transferred := atomic.LoadUint64(&lbu.uploaded) - if utilities.IsDebug(lbu.debug) { + if debug.IsDebug(lbu.debug) { fmt.Printf("upload: Transferred: %v\n", transferred) } return transferred @@ -323,7 +350,7 @@ func (lbu *LoadGeneratingConnectionUpload) doUpload(ctx context.Context) bool { return false } resp.Body.Close() - if utilities.IsDebug(lbu.debug) { + if debug.IsDebug(lbu.debug) { fmt.Printf("Ending a load-generating upload.\n") } return true @@ -331,10 +358,11 @@ func (lbu *LoadGeneratingConnectionUpload) doUpload(ctx context.Context) bool { func (lbu *LoadGeneratingConnectionUpload) Start( ctx context.Context, - debug constants.DebugLevel, + debugLevel debug.DebugLevel, ) bool { lbu.uploaded = 0 lbu.clientId = GenerateConnectionId() + lbu.debug = debugLevel // See above for the rationale of doing http2.Transport{} here // to ensure that we are using h2. @@ -342,7 +370,7 @@ func (lbu *LoadGeneratingConnectionUpload) Start( transport.TLSClientConfig = &tls.Config{} if !utilities.IsInterfaceNil(lbu.KeyLogger) { - if utilities.IsDebug(lbu.debug) { + if debug.IsDebug(lbu.debug) { fmt.Printf( "Using an SSL Key Logger for this load-generating upload.\n", ) @@ -352,10 +380,9 @@ func (lbu *LoadGeneratingConnectionUpload) Start( transport.TLSClientConfig.InsecureSkipVerify = true lbu.client = &http.Client{Transport: &transport} - lbu.debug = debug lbu.valid = true - if utilities.IsDebug(lbu.debug) { + if debug.IsDebug(lbu.debug) { fmt.Printf("Started a load-generating upload (id: %v).\n", lbu.clientId) } go lbu.doUpload(ctx) |
