cleanup: remove ConnID, DialID, TransactionID (#395)

We are not using them anymore. The only nettest still using the
legacy netx implementation is tor, for which setting these fields
is useless, because it performs each measurement into a separate
goroutine. Hence, let us start removing this part of the legacy
netx codebase, which is hampering progress in other areas.

Occurred to me while doing testing for the recent changes in
error mapping (https://github.com/ooni/probe/issues/1505).
This commit is contained in:
Simone Basso 2021-06-23 13:36:45 +02:00 committed by GitHub
parent 1fefe5d9b8
commit c74c94d616
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 78 additions and 896 deletions

View File

@ -112,9 +112,6 @@ func TestSuccess(t *testing.T) {
if request.T != 0 { if request.T != 0 {
t.Fatal("invalid Requests[0].T") t.Fatal("invalid Requests[0].T")
} }
if request.TransactionID != 0 {
t.Fatal("invalid Requests[0].TransactionID")
}
if tk.SOCKSProxy != nil { if tk.SOCKSProxy != nil {
t.Fatal("invalid SOCKSProxy") t.Fatal("invalid SOCKSProxy")
} }
@ -223,9 +220,6 @@ func TestCancelledContext(t *testing.T) {
if request.T != 0 { if request.T != 0 {
t.Fatal("invalid Requests[0].T") t.Fatal("invalid Requests[0].T")
} }
if request.TransactionID != 0 {
t.Fatal("invalid Requests[0].TransactionID")
}
if tk.SOCKSProxy != nil { if tk.SOCKSProxy != nil {
t.Fatal("invalid SOCKSProxy") t.Fatal("invalid SOCKSProxy")
} }

View File

@ -1,31 +0,0 @@
// Package connid contains code to generate the connectionID
package connid
import (
"net"
"strconv"
"strings"
)
// Compute computes the connectionID from the local socket address. The zero
// value is conventionally returned to mean "unknown".
func Compute(network, address string) int64 {
_, portstring, err := net.SplitHostPort(address)
if err != nil {
return 0
}
portnum, err := strconv.Atoi(portstring)
if err != nil {
return 0
}
if portnum < 0 || portnum > 65535 {
return 0
}
result := int64(portnum)
if strings.Contains(network, "udp") {
result *= -1
} else if !strings.Contains(network, "tcp") {
result = 0
}
return result
}

View File

@ -1,80 +0,0 @@
package connid
import "testing"
func TestTCP(t *testing.T) {
num := Compute("tcp", "1.2.3.4:6789")
if num != 6789 {
t.Fatal("unexpected result")
}
}
func TestTCP4(t *testing.T) {
num := Compute("tcp4", "130.192.91.211:34566")
if num != 34566 {
t.Fatal("unexpected result")
}
}
func TestTCP6(t *testing.T) {
num := Compute("tcp4", "[::1]:4444")
if num != 4444 {
t.Fatal("unexpected result")
}
}
func TestUDP(t *testing.T) {
num := Compute("udp", "1.2.3.4:6789")
if num != -6789 {
t.Fatal("unexpected result")
}
}
func TestUDP4(t *testing.T) {
num := Compute("udp4", "130.192.91.211:34566")
if num != -34566 {
t.Fatal("unexpected result")
}
}
func TestUDP6(t *testing.T) {
num := Compute("udp6", "[::1]:4444")
if num != -4444 {
t.Fatal("unexpected result")
}
}
func TestInvalidAddress(t *testing.T) {
num := Compute("udp6", "[::1]")
if num != 0 {
t.Fatal("unexpected result")
}
}
func TestInvalidPort(t *testing.T) {
num := Compute("udp6", "[::1]:antani")
if num != 0 {
t.Fatal("unexpected result")
}
}
func TestNegativePort(t *testing.T) {
num := Compute("udp6", "[::1]:-1")
if num != 0 {
t.Fatal("unexpected result")
}
}
func TestLargePort(t *testing.T) {
num := Compute("udp6", "[::1]:65536")
if num != 0 {
t.Fatal("unexpected result")
}
}
func TestInvalidNetwork(t *testing.T) {
num := Compute("unix", "[::1]:65531")
if num != 0 {
t.Fatal("unexpected result")
}
}

View File

@ -1,24 +0,0 @@
package dialid
import (
"context"
"github.com/ooni/probe-cli/v3/internal/atomicx"
)
type contextkey struct{}
var id = &atomicx.Int64{}
// WithDialID returns a copy of ctx with DialID
func WithDialID(ctx context.Context) context.Context {
return context.WithValue(
ctx, contextkey{}, id.Add(1),
)
}
// ContextDialID returns the DialID of the context, or zero
func ContextDialID(ctx context.Context) int64 {
id, _ := ctx.Value(contextkey{}).(int64)
return id
}

View File

@ -1,24 +0,0 @@
package dialid
import (
"context"
"testing"
)
func TestGood(t *testing.T) {
ctx := context.Background()
id := ContextDialID(ctx)
if id != 0 {
t.Fatal("unexpected ID for empty context")
}
ctx = WithDialID(ctx)
id = ContextDialID(ctx)
if id != 1 {
t.Fatal("expected ID equal to 1")
}
ctx = WithDialID(ctx)
id = ContextDialID(ctx)
if id != 2 {
t.Fatal("expected ID equal to 2")
}
}

View File

@ -5,10 +5,7 @@ import (
"net" "net"
"time" "time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/connid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
) )
@ -25,14 +22,11 @@ func (d EmitterDialer) DialContext(ctx context.Context, network, address string)
root := modelx.ContextMeasurementRootOrDefault(ctx) root := modelx.ContextMeasurementRootOrDefault(ctx)
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
Connect: &modelx.ConnectEvent{ Connect: &modelx.ConnectEvent{
ConnID: safeConnID(network, conn),
DialID: dialid.ContextDialID(ctx),
DurationSinceBeginning: stop.Sub(root.Beginning), DurationSinceBeginning: stop.Sub(root.Beginning),
Error: err, Error: err,
Network: network, Network: network,
RemoteAddress: address, RemoteAddress: address,
SyscallDuration: stop.Sub(start), SyscallDuration: stop.Sub(start),
TransactionID: transactionid.ContextTransactionID(ctx),
}, },
}) })
if err != nil { if err != nil {
@ -42,7 +36,6 @@ func (d EmitterDialer) DialContext(ctx context.Context, network, address string)
Conn: conn, Conn: conn,
Beginning: root.Beginning, Beginning: root.Beginning,
Handler: root.Handler, Handler: root.Handler,
ID: safeConnID(network, conn),
}, nil }, nil
} }
@ -51,7 +44,6 @@ type EmitterConn struct {
net.Conn net.Conn
Beginning time.Time Beginning time.Time
Handler modelx.Handler Handler modelx.Handler
ID int64
} }
// Read implements net.Conn.Read // Read implements net.Conn.Read
@ -61,7 +53,6 @@ func (c EmitterConn) Read(b []byte) (n int, err error) {
stop := time.Now() stop := time.Now()
c.Handler.OnMeasurement(modelx.Measurement{ c.Handler.OnMeasurement(modelx.Measurement{
Read: &modelx.ReadEvent{ Read: &modelx.ReadEvent{
ConnID: c.ID,
DurationSinceBeginning: stop.Sub(c.Beginning), DurationSinceBeginning: stop.Sub(c.Beginning),
Error: err, Error: err,
NumBytes: int64(n), NumBytes: int64(n),
@ -78,7 +69,6 @@ func (c EmitterConn) Write(b []byte) (n int, err error) {
stop := time.Now() stop := time.Now()
c.Handler.OnMeasurement(modelx.Measurement{ c.Handler.OnMeasurement(modelx.Measurement{
Write: &modelx.WriteEvent{ Write: &modelx.WriteEvent{
ConnID: c.ID,
DurationSinceBeginning: stop.Sub(c.Beginning), DurationSinceBeginning: stop.Sub(c.Beginning),
Error: err, Error: err,
NumBytes: int64(n), NumBytes: int64(n),
@ -95,7 +85,6 @@ func (c EmitterConn) Close() (err error) {
stop := time.Now() stop := time.Now()
c.Handler.OnMeasurement(modelx.Measurement{ c.Handler.OnMeasurement(modelx.Measurement{
Close: &modelx.CloseEvent{ Close: &modelx.CloseEvent{
ConnID: c.ID,
DurationSinceBeginning: stop.Sub(c.Beginning), DurationSinceBeginning: stop.Sub(c.Beginning),
Error: err, Error: err,
SyscallDuration: stop.Sub(start), SyscallDuration: stop.Sub(start),
@ -103,14 +92,3 @@ func (c EmitterConn) Close() (err error) {
}) })
return return
} }
func safeLocalAddress(conn net.Conn) (s string) {
if conn != nil && conn.LocalAddr() != nil {
s = conn.LocalAddr().String()
}
return
}
func safeConnID(network string, conn net.Conn) int64 {
return connid.Compute(network, safeLocalAddress(conn))
}

View File

@ -8,21 +8,18 @@ import (
"testing" "testing"
"time" "time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/mockablex" "github.com/ooni/probe-cli/v3/internal/engine/netx/mockablex"
) )
func TestEmitterFailure(t *testing.T) { func TestEmitterFailure(t *testing.T) {
ctx := dialid.WithDialID(context.Background()) ctx := context.Background()
saver := &handlers.SavingHandler{} saver := &handlers.SavingHandler{}
ctx = modelx.WithMeasurementRoot(ctx, &modelx.MeasurementRoot{ ctx = modelx.WithMeasurementRoot(ctx, &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),
Handler: saver, Handler: saver,
}) })
ctx = transactionid.WithTransactionID(ctx)
d := EmitterDialer{Dialer: mockablex.Dialer{ d := EmitterDialer{Dialer: mockablex.Dialer{
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) { MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
return nil, io.EOF return nil, io.EOF
@ -43,17 +40,11 @@ func TestEmitterFailure(t *testing.T) {
t.Fatal("expected non nil Connect") t.Fatal("expected non nil Connect")
} }
conninfo := events[0].Connect conninfo := events[0].Connect
if conninfo.ConnID != 0 {
t.Fatal("unexpected ConnID value")
}
emitterCheckConnectEventCommon(t, conninfo, io.EOF) emitterCheckConnectEventCommon(t, conninfo, io.EOF)
} }
func emitterCheckConnectEventCommon( func emitterCheckConnectEventCommon(
t *testing.T, conninfo *modelx.ConnectEvent, err error) { t *testing.T, conninfo *modelx.ConnectEvent, err error) {
if conninfo.DialID == 0 {
t.Fatal("unexpected DialID value")
}
if conninfo.DurationSinceBeginning == 0 { if conninfo.DurationSinceBeginning == 0 {
t.Fatal("unexpected DurationSinceBeginning value") t.Fatal("unexpected DurationSinceBeginning value")
} }
@ -69,19 +60,15 @@ func emitterCheckConnectEventCommon(
if conninfo.SyscallDuration == 0 { if conninfo.SyscallDuration == 0 {
t.Fatal("unexpected SyscallDuration value") t.Fatal("unexpected SyscallDuration value")
} }
if conninfo.TransactionID == 0 {
t.Fatal("unexpected TransactionID value")
}
} }
func TestEmitterSuccess(t *testing.T) { func TestEmitterSuccess(t *testing.T) {
ctx := dialid.WithDialID(context.Background()) ctx := context.Background()
saver := &handlers.SavingHandler{} saver := &handlers.SavingHandler{}
ctx = modelx.WithMeasurementRoot(ctx, &modelx.MeasurementRoot{ ctx = modelx.WithMeasurementRoot(ctx, &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),
Handler: saver, Handler: saver,
}) })
ctx = transactionid.WithTransactionID(ctx)
d := EmitterDialer{Dialer: mockablex.Dialer{ d := EmitterDialer{Dialer: mockablex.Dialer{
MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) { MockDialContext: func(ctx context.Context, network string, address string) (net.Conn, error) {
return &mockablex.Conn{ return &mockablex.Conn{
@ -118,9 +105,6 @@ func TestEmitterSuccess(t *testing.T) {
t.Fatal("expected non nil Connect") t.Fatal("expected non nil Connect")
} }
conninfo := events[0].Connect conninfo := events[0].Connect
if conninfo.ConnID == 0 {
t.Fatal("unexpected ConnID value")
}
emitterCheckConnectEventCommon(t, conninfo, nil) emitterCheckConnectEventCommon(t, conninfo, nil)
if events[1].Read == nil { if events[1].Read == nil {
t.Fatal("expected non nil Read") t.Fatal("expected non nil Read")
@ -137,9 +121,6 @@ func TestEmitterSuccess(t *testing.T) {
} }
func emitterCheckReadEvent(t *testing.T, ev *modelx.ReadEvent) { func emitterCheckReadEvent(t *testing.T, ev *modelx.ReadEvent) {
if ev.ConnID == 0 {
t.Fatal("unexpected ConnID")
}
if ev.DurationSinceBeginning == 0 { if ev.DurationSinceBeginning == 0 {
t.Fatal("unexpected DurationSinceBeginning") t.Fatal("unexpected DurationSinceBeginning")
} }
@ -155,9 +136,6 @@ func emitterCheckReadEvent(t *testing.T, ev *modelx.ReadEvent) {
} }
func emitterCheckWriteEvent(t *testing.T, ev *modelx.WriteEvent) { func emitterCheckWriteEvent(t *testing.T, ev *modelx.WriteEvent) {
if ev.ConnID == 0 {
t.Fatal("unexpected ConnID")
}
if ev.DurationSinceBeginning == 0 { if ev.DurationSinceBeginning == 0 {
t.Fatal("unexpected DurationSinceBeginning") t.Fatal("unexpected DurationSinceBeginning")
} }
@ -173,9 +151,6 @@ func emitterCheckWriteEvent(t *testing.T, ev *modelx.WriteEvent) {
} }
func emitterCheckCloseEvent(t *testing.T, ev *modelx.CloseEvent) { func emitterCheckCloseEvent(t *testing.T, ev *modelx.CloseEvent) {
if ev.ConnID == 0 {
t.Fatal("unexpected ConnID")
}
if ev.DurationSinceBeginning == 0 { if ev.DurationSinceBeginning == 0 {
t.Fatal("unexpected DurationSinceBeginning") t.Fatal("unexpected DurationSinceBeginning")
} }

View File

@ -22,9 +22,6 @@ import (
// uses a monotonic clock and is relative to a preconfigured "zero". // uses a monotonic clock and is relative to a preconfigured "zero".
type Measurement struct { type Measurement struct {
// DNS events // DNS events
//
// These are all identifed by a DialID. A ResolveEvent optionally has
// a reference to the TransactionID that started the dial, if any.
ResolveStart *ResolveStartEvent `json:",omitempty"` ResolveStart *ResolveStartEvent `json:",omitempty"`
DNSQuery *DNSQueryEvent `json:",omitempty"` DNSQuery *DNSQueryEvent `json:",omitempty"`
DNSReply *DNSReplyEvent `json:",omitempty"` DNSReply *DNSReplyEvent `json:",omitempty"`
@ -32,9 +29,6 @@ type Measurement struct {
// Syscalls // Syscalls
// //
// These are all identified by a ConnID. A ConnectEvent has a reference
// to the DialID that caused this connection to be attempted.
//
// Because they are syscalls, we don't split them in start/done pairs // Because they are syscalls, we don't split them in start/done pairs
// but we record the amount of time in which we were blocked. // but we record the amount of time in which we were blocked.
Connect *ConnectEvent `json:",omitempty"` Connect *ConnectEvent `json:",omitempty"`
@ -43,11 +37,6 @@ type Measurement struct {
Close *CloseEvent `json:",omitempty"` Close *CloseEvent `json:",omitempty"`
// TLS events // TLS events
//
// Identified by either ConnID or TransactionID. In the former case
// the TLS handshake is managed by net code, in the latter case it is
// instead managed by Golang's HTTP engine. It should not happen to
// have both ConnID and TransactionID different from zero.
TLSHandshakeStart *TLSHandshakeStartEvent `json:",omitempty"` TLSHandshakeStart *TLSHandshakeStartEvent `json:",omitempty"`
TLSHandshakeDone *TLSHandshakeDoneEvent `json:",omitempty"` TLSHandshakeDone *TLSHandshakeDoneEvent `json:",omitempty"`
@ -55,10 +44,6 @@ type Measurement struct {
// //
// A round trip starts when we need a connection to send a request // A round trip starts when we need a connection to send a request
// and ends when we've got the response headers or an error. // and ends when we've got the response headers or an error.
//
// The identifer here is TransactionID, where the transaction is
// like the round trip except that it terminates when we've finished
// reading the whole response body.
HTTPRoundTripStart *HTTPRoundTripStartEvent `json:",omitempty"` HTTPRoundTripStart *HTTPRoundTripStartEvent `json:",omitempty"`
HTTPConnectionReady *HTTPConnectionReadyEvent `json:",omitempty"` HTTPConnectionReady *HTTPConnectionReadyEvent `json:",omitempty"`
HTTPRequestHeader *HTTPRequestHeaderEvent `json:",omitempty"` HTTPRequestHeader *HTTPRequestHeaderEvent `json:",omitempty"`
@ -68,10 +53,6 @@ type Measurement struct {
HTTPRoundTripDone *HTTPRoundTripDoneEvent `json:",omitempty"` HTTPRoundTripDone *HTTPRoundTripDoneEvent `json:",omitempty"`
// HTTP body events // HTTP body events
//
// They are identified by the TransactionID. You are not going to see
// these events if you don't fully read response bodies. But that's
// something you are supposed to do, so you should be fine.
HTTPResponseBodyPart *HTTPResponseBodyPartEvent `json:",omitempty"` HTTPResponseBodyPart *HTTPResponseBodyPartEvent `json:",omitempty"`
HTTPResponseDone *HTTPResponseDoneEvent `json:",omitempty"` HTTPResponseDone *HTTPResponseDoneEvent `json:",omitempty"`
@ -86,9 +67,6 @@ type Measurement struct {
// CloseEvent is emitted when the CLOSE syscall returns. // CloseEvent is emitted when the CLOSE syscall returns.
type CloseEvent struct { type CloseEvent struct {
// ConnID is the identifier of this connection.
ConnID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -103,13 +81,6 @@ type CloseEvent struct {
// ConnectEvent is emitted when the CONNECT syscall returns. // ConnectEvent is emitted when the CONNECT syscall returns.
type ConnectEvent struct { type ConnectEvent struct {
// ConnID is the identifier of this connection.
ConnID int64
// DialID is the identifier of the dial operation as
// part of which we called CONNECT.
DialID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -126,10 +97,6 @@ type ConnectEvent struct {
// SyscallDuration is the number of nanoseconds we were // SyscallDuration is the number of nanoseconds we were
// blocked waiting for the syscall to return. // blocked waiting for the syscall to return.
SyscallDuration time.Duration SyscallDuration time.Duration
// TransactionID is the ID of the HTTP transaction that caused the
// current dial to run, or zero if there's no such transaction.
TransactionID int64 `json:",omitempty"`
} }
// DNSQueryEvent is emitted when we send a DNS query. // DNSQueryEvent is emitted when we send a DNS query.
@ -137,10 +104,6 @@ type DNSQueryEvent struct {
// Data is the raw data we're sending to the server. // Data is the raw data we're sending to the server.
Data []byte Data []byte
// DialID is the identifier of the dial operation as
// part of which we're sending this query.
DialID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -155,10 +118,6 @@ type DNSReplyEvent struct {
// Data is the raw data we've received and parsed. // Data is the raw data we've received and parsed.
Data []byte Data []byte
// DialID is the identifier of the dial operation as
// part of which we've received this query.
DialID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -180,10 +139,6 @@ type ExtensionEvent struct {
// Severity of the emitted message ("WARN", "INFO", "DEBUG") // Severity of the emitted message ("WARN", "INFO", "DEBUG")
Severity string Severity string
// TransactionID is the identifier of this transaction, provided
// that we have an active one, otherwise is zero.
TransactionID int64
// Value is the extension dependent message. This message // Value is the extension dependent message. This message
// has the only requirement of being JSON serializable. // has the only requirement of being JSON serializable.
Value interface{} Value interface{}
@ -196,12 +151,6 @@ type ExtensionEvent struct {
// "transaction" here starts with this event and does not finish // "transaction" here starts with this event and does not finish
// until we have also finished receiving the response body. // until we have also finished receiving the response body.
type HTTPRoundTripStartEvent struct { type HTTPRoundTripStartEvent struct {
// DialID is the identifier of the dial operation that
// caused this round trip to start. Typically, this occures
// when doing DoH. If zero, means that this round trip has
// not been started by any dial operation.
DialID int64 `json:",omitempty"`
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -209,9 +158,6 @@ type HTTPRoundTripStartEvent struct {
// Method is the request method // Method is the request method
Method string Method string
// TransactionID is the identifier of this transaction
TransactionID int64
// URL is the request URL // URL is the request URL
URL string URL string
} }
@ -219,16 +165,9 @@ type HTTPRoundTripStartEvent struct {
// HTTPConnectionReadyEvent is emitted when the HTTP transport has got // HTTPConnectionReadyEvent is emitted when the HTTP transport has got
// a connection which is ready for sending the request. // a connection which is ready for sending the request.
type HTTPConnectionReadyEvent struct { type HTTPConnectionReadyEvent struct {
// ConnID is the identifier of the connection that is ready. Knowing
// this ID allows you to bind HTTP events to net events.
ConnID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
// TransactionID is the identifier of this transaction
TransactionID int64
} }
// HTTPRequestHeaderEvent is emitted when we have written a header, // HTTPRequestHeaderEvent is emitted when we have written a header,
@ -241,9 +180,6 @@ type HTTPRequestHeaderEvent struct {
// Key is the header key // Key is the header key
Key string Key string
// TransactionID is the identifier of this transaction
TransactionID int64
// Value is the value/values of this header. // Value is the value/values of this header.
Value []string Value []string
} }
@ -264,9 +200,6 @@ type HTTPRequestHeadersDoneEvent struct {
// for the same reason of Headers. // for the same reason of Headers.
Method string Method string
// TransactionID is the identifier of this transaction
TransactionID int64
// URL is the original request URL. This is here // URL is the original request URL. This is here
// for the same reason of Headers. We use an object // for the same reason of Headers. We use an object
// rather than a string, because here you want to // rather than a string, because here you want to
@ -287,9 +220,6 @@ type HTTPRequestDoneEvent struct {
// as well. This error however tells you that the issue was // as well. This error however tells you that the issue was
// when sending the request, not when receiving the response. // when sending the request, not when receiving the response.
Error error Error error
// TransactionID is the identifier of this transaction
TransactionID int64
} }
// HTTPResponseStartEvent is emitted when we receive the byte from // HTTPResponseStartEvent is emitted when we receive the byte from
@ -298,9 +228,6 @@ type HTTPResponseStartEvent struct {
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
// TransactionID is the identifier of this transaction
TransactionID int64
} }
const defaultBodySnapSize int64 = 1 << 20 const defaultBodySnapSize int64 = 1 << 20
@ -368,9 +295,6 @@ type HTTPRoundTripDoneEvent struct {
// MaxBodySnapSize is the maximum size of the bodies snapshot. // MaxBodySnapSize is the maximum size of the bodies snapshot.
MaxBodySnapSize int64 MaxBodySnapSize int64
// TransactionID is the identifier of this transaction
TransactionID int64
} }
// HTTPResponseBodyPartEvent is emitted after we have received // HTTPResponseBodyPartEvent is emitted after we have received
@ -393,9 +317,6 @@ type HTTPResponseBodyPartEvent struct {
// Data is a reference to the body we've just read. // Data is a reference to the body we've just read.
Data []byte Data []byte
// TransactionID is the identifier of this transaction
TransactionID int64
} }
// HTTPResponseDoneEvent is emitted after we have received the body, // HTTPResponseDoneEvent is emitted after we have received the body,
@ -407,16 +328,10 @@ type HTTPResponseDoneEvent struct {
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
// TransactionID is the identifier of this transaction
TransactionID int64
} }
// ReadEvent is emitted when the READ/RECV syscall returns. // ReadEvent is emitted when the READ/RECV syscall returns.
type ReadEvent struct { type ReadEvent struct {
// ConnID is the identifier of this connection.
ConnID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -435,10 +350,6 @@ type ReadEvent struct {
// ResolveStartEvent is emitted when we start resolving a domain name. // ResolveStartEvent is emitted when we start resolving a domain name.
type ResolveStartEvent struct { type ResolveStartEvent struct {
// DialID is the identifier of the dial operation as
// part of which we're resolving this domain.
DialID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -446,10 +357,6 @@ type ResolveStartEvent struct {
// Hostname is the domain name to resolve. // Hostname is the domain name to resolve.
Hostname string Hostname string
// TransactionID is the ID of the HTTP transaction that caused the
// current dial to run, or zero if there's no such transaction.
TransactionID int64 `json:",omitempty"`
// TransportNetwork is the network used by the DNS transport, which // TransportNetwork is the network used by the DNS transport, which
// can be one of "doh", "dot", "tcp", "udp", or "system". // can be one of "doh", "dot", "tcp", "udp", or "system".
TransportNetwork string TransportNetwork string
@ -469,10 +376,6 @@ type ResolveDoneEvent struct {
// or more IP addresses that classify as bogons. // or more IP addresses that classify as bogons.
ContainsBogons bool ContainsBogons bool
// DialID is the identifier of the dial operation as
// part of which we're resolving this domain.
DialID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
@ -483,10 +386,6 @@ type ResolveDoneEvent struct {
// Hostname is the domain name to resolve. // Hostname is the domain name to resolve.
Hostname string Hostname string
// TransactionID is the ID of the HTTP transaction that caused the
// current dial to run, or zero if there's no such transaction.
TransactionID int64 `json:",omitempty"`
// TransportNetwork is the network used by the DNS transport, which // TransportNetwork is the network used by the DNS transport, which
// can be one of "doh", "dot", "tcp", "udp", or "system". // can be one of "doh", "dot", "tcp", "udp", or "system".
TransportNetwork string TransportNetwork string
@ -532,24 +431,12 @@ func SimplifyCerts(in []*x509.Certificate) (out []X509Certificate) {
// TLSHandshakeStartEvent is emitted when the TLS handshake starts. // TLSHandshakeStartEvent is emitted when the TLS handshake starts.
type TLSHandshakeStartEvent struct { type TLSHandshakeStartEvent struct {
// ConnID is the ID of the connection that started the TLS
// handshake, or zero if we don't know it. Typically, it is
// zero for connections managed by the HTTP transport, for
// which we know instead the TransactionID.
ConnID int64 `json:",omitempty"`
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
// SNI is the SNI used when we force a specific SNI. // SNI is the SNI used when we force a specific SNI.
SNI string SNI string
// TransactionID is the ID of the transaction that started
// this TLS handshake, or zero if we don't know it. Typically,
// it is zero for explicit dials, and it's nonzero instead
// when a connection is managed by HTTP code.
TransactionID int64 `json:",omitempty"`
} }
// TLSHandshakeDoneEvent is emitted when conn.Handshake returns. // TLSHandshakeDoneEvent is emitted when conn.Handshake returns.
@ -558,31 +445,16 @@ type TLSHandshakeDoneEvent struct {
// error type, some fields may have little meaning. // error type, some fields may have little meaning.
ConnectionState TLSConnectionState ConnectionState TLSConnectionState
// ConnID is the ID of the connection that started the TLS
// handshake, or zero if we don't know it. Typically, it is
// zero for connections managed by the HTTP transport, for
// which we know instead the TransactionID.
ConnID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration
// Error is the result of the TLS handshake. // Error is the result of the TLS handshake.
Error error Error error
// TransactionID is the ID of the transaction that started
// this TLS handshake, or zero if we don't know it. Typically,
// it is zero for explicit dials, and it's nonzero instead
// when a connection is managed by HTTP code.
TransactionID int64
} }
// WriteEvent is emitted when the WRITE/SEND syscall returns. // WriteEvent is emitted when the WRITE/SEND syscall returns.
type WriteEvent struct { type WriteEvent struct {
// ConnID is the identifier of this connection.
ConnID int64
// DurationSinceBeginning is the number of nanoseconds since // DurationSinceBeginning is the number of nanoseconds since
// the time configured as the "zero" time. // the time configured as the "zero" time.
DurationSinceBeginning time.Duration DurationSinceBeginning time.Duration

View File

@ -6,7 +6,6 @@ import (
"time" "time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
) )
// BodyTracer performs single HTTP transactions and emits // BodyTracer performs single HTTP transactions and emits
@ -33,7 +32,6 @@ func (t *BodyTracer) RoundTrip(req *http.Request) (resp *http.Response, err erro
resp.Body = &bodyWrapper{ resp.Body = &bodyWrapper{
ReadCloser: resp.Body, ReadCloser: resp.Body,
root: modelx.ContextMeasurementRootOrDefault(req.Context()), root: modelx.ContextMeasurementRootOrDefault(req.Context()),
tid: transactionid.ContextTransactionID(req.Context()),
} }
return return
} }
@ -52,7 +50,6 @@ func (t *BodyTracer) CloseIdleConnections() {
type bodyWrapper struct { type bodyWrapper struct {
io.ReadCloser io.ReadCloser
root *modelx.MeasurementRoot root *modelx.MeasurementRoot
tid int64
} }
func (bw *bodyWrapper) Read(b []byte) (n int, err error) { func (bw *bodyWrapper) Read(b []byte) (n int, err error) {
@ -64,7 +61,6 @@ func (bw *bodyWrapper) Read(b []byte) (n int, err error) {
Data: b[:n], Data: b[:n],
Error: err, Error: err,
DurationSinceBeginning: time.Since(bw.root.Beginning), DurationSinceBeginning: time.Since(bw.root.Beginning),
TransactionID: bw.tid,
}, },
}) })
return return
@ -75,7 +71,6 @@ func (bw *bodyWrapper) Close() (err error) {
bw.root.Handler.OnMeasurement(modelx.Measurement{ bw.root.Handler.OnMeasurement(modelx.Measurement{
HTTPResponseDone: &modelx.HTTPResponseDoneEvent{ HTTPResponseDone: &modelx.HTTPResponseDoneEvent{
DurationSinceBeginning: time.Since(bw.root.Beginning), DurationSinceBeginning: time.Since(bw.root.Beginning),
TransactionID: bw.tid,
}, },
}) })
return return

View File

@ -15,8 +15,7 @@ type Transport struct {
// New creates a new Transport. // New creates a new Transport.
func New(roundTripper http.RoundTripper) *Transport { func New(roundTripper http.RoundTripper) *Transport {
return &Transport{ return &Transport{
roundTripper: NewTransactioner(NewBodyTracer( roundTripper: NewBodyTracer(NewTraceTripper(roundTripper)),
NewTraceTripper(roundTripper))),
} }
} }

View File

@ -11,10 +11,7 @@ import (
"time" "time"
"github.com/ooni/probe-cli/v3/internal/atomicx" "github.com/ooni/probe-cli/v3/internal/atomicx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/connid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/iox" "github.com/ooni/probe-cli/v3/internal/iox"
) )
@ -76,13 +73,10 @@ func readSnap(
func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) { func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
root := modelx.ContextMeasurementRootOrDefault(req.Context()) root := modelx.ContextMeasurementRootOrDefault(req.Context())
tid := transactionid.ContextTransactionID(req.Context())
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
HTTPRoundTripStart: &modelx.HTTPRoundTripStartEvent{ HTTPRoundTripStart: &modelx.HTTPRoundTripStartEvent{
DialID: dialid.ContextDialID(req.Context()),
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
Method: req.Method, Method: req.Method,
TransactionID: tid,
URL: req.URL.String(), URL: req.URL.String(),
}, },
}) })
@ -116,7 +110,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
TLSHandshakeStart: &modelx.TLSHandshakeStartEvent{ TLSHandshakeStart: &modelx.TLSHandshakeStartEvent{
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
TransactionID: tid,
}, },
}) })
}, },
@ -126,7 +119,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
err = errorx.SafeErrWrapperBuilder{ err = errorx.SafeErrWrapperBuilder{
Error: err, Error: err,
Operation: errorx.TLSHandshakeOperation, Operation: errorx.TLSHandshakeOperation,
TransactionID: tid,
}.MaybeBuild() }.MaybeBuild()
durationSinceBeginning := time.Since(root.Beginning) durationSinceBeginning := time.Since(root.Beginning)
// Event emitted by net/http when DialTLS is not // Event emitted by net/http when DialTLS is not
@ -136,7 +128,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
ConnectionState: modelx.NewTLSConnectionState(state), ConnectionState: modelx.NewTLSConnectionState(state),
Error: err, Error: err,
DurationSinceBeginning: durationSinceBeginning, DurationSinceBeginning: durationSinceBeginning,
TransactionID: tid,
}, },
}) })
}, },
@ -146,12 +137,7 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
majorOpMu.Unlock() majorOpMu.Unlock()
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
HTTPConnectionReady: &modelx.HTTPConnectionReadyEvent{ HTTPConnectionReady: &modelx.HTTPConnectionReadyEvent{
ConnID: connid.Compute(
info.Conn.LocalAddr().Network(),
info.Conn.LocalAddr().String(),
),
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
TransactionID: tid,
}, },
}) })
}, },
@ -168,7 +154,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
HTTPRequestHeader: &modelx.HTTPRequestHeaderEvent{ HTTPRequestHeader: &modelx.HTTPRequestHeaderEvent{
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
Key: key, Key: key,
TransactionID: tid,
Value: values, Value: values,
}, },
}) })
@ -179,7 +164,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
Headers: requestHeaders, // [*] Headers: requestHeaders, // [*]
Method: req.Method, // [*] Method: req.Method, // [*]
TransactionID: tid,
URL: req.URL, // [*] URL: req.URL, // [*]
}, },
}) })
@ -190,13 +174,11 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
err := errorx.SafeErrWrapperBuilder{ err := errorx.SafeErrWrapperBuilder{
Error: info.Err, Error: info.Err,
Operation: errorx.HTTPRoundTripOperation, Operation: errorx.HTTPRoundTripOperation,
TransactionID: tid,
}.MaybeBuild() }.MaybeBuild()
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
HTTPRequestDone: &modelx.HTTPRequestDoneEvent{ HTTPRequestDone: &modelx.HTTPRequestDoneEvent{
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
Error: err, Error: err,
TransactionID: tid,
}, },
}) })
}, },
@ -204,7 +186,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
HTTPResponseStart: &modelx.HTTPResponseStartEvent{ HTTPResponseStart: &modelx.HTTPResponseStartEvent{
DurationSinceBeginning: time.Since(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
TransactionID: tid,
}, },
}) })
}, },
@ -229,7 +210,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
err = errorx.SafeErrWrapperBuilder{ err = errorx.SafeErrWrapperBuilder{
Error: err, Error: err,
Operation: majorOp, Operation: majorOp,
TransactionID: tid,
}.MaybeBuild() }.MaybeBuild()
// [*] Require less event joining work by providing info that // [*] Require less event joining work by providing info that
// makes this event alone actionable for OONI // makes this event alone actionable for OONI
@ -241,7 +221,6 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
RequestMethod: req.Method, // [*] RequestMethod: req.Method, // [*]
RequestURL: req.URL.String(), // [*] RequestURL: req.URL.String(), // [*]
MaxBodySnapSize: snapSize, MaxBodySnapSize: snapSize,
TransactionID: tid,
} }
if resp != nil { if resp != nil {
event.ResponseHeaders = resp.Header event.ResponseHeaders = resp.Header

View File

@ -1,38 +0,0 @@
package oldhttptransport
import (
"net/http"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
)
// Transactioner performs single HTTP transactions.
type Transactioner struct {
roundTripper http.RoundTripper
}
// NewTransactioner creates a new Transport.
func NewTransactioner(roundTripper http.RoundTripper) *Transactioner {
return &Transactioner{
roundTripper: roundTripper,
}
}
// RoundTrip executes a single HTTP transaction, returning
// a Response for the provided Request.
func (t *Transactioner) RoundTrip(req *http.Request) (*http.Response, error) {
return t.roundTripper.RoundTrip(req.WithContext(
transactionid.WithTransactionID(req.Context()),
))
}
// CloseIdleConnections closes the idle connections.
func (t *Transactioner) CloseIdleConnections() {
// Adapted from net/http code
type closeIdler interface {
CloseIdleConnections()
}
if tr, ok := t.roundTripper.(closeIdler); ok {
tr.CloseIdleConnections()
}
}

View File

@ -1,58 +0,0 @@
package oldhttptransport
import (
"context"
"net/http"
"testing"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/iox"
)
type transactionerCheckTransactionID struct {
roundTripper http.RoundTripper
t *testing.T
}
func (t *transactionerCheckTransactionID) RoundTrip(req *http.Request) (*http.Response, error) {
ctx := req.Context()
if id := transactionid.ContextTransactionID(ctx); id == 0 {
t.t.Fatal("transaction ID not set")
}
return t.roundTripper.RoundTrip(req)
}
func TestTransactionerSuccess(t *testing.T) {
client := &http.Client{
Transport: NewTransactioner(&transactionerCheckTransactionID{
roundTripper: http.DefaultTransport,
t: t,
}),
}
resp, err := client.Get("https://www.google.com")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
_, err = iox.ReadAllContext(context.Background(), resp.Body)
if err != nil {
t.Fatal(err)
}
client.CloseIdleConnections()
}
func TestTransactionerFailure(t *testing.T) {
client := &http.Client{
Transport: NewTransactioner(http.DefaultTransport),
}
// This fails the request because we attempt to speak cleartext HTTP with
// a server that instead is expecting TLS.
resp, err := client.Get("http://www.google.com:443")
if err == nil {
t.Fatal("expected an error here")
}
if resp != nil {
t.Fatal("expected a nil response here")
}
client.CloseIdleConnections()
}

View File

@ -1,25 +0,0 @@
// Package transactionid contains code to share the transactionID
package transactionid
import (
"context"
"github.com/ooni/probe-cli/v3/internal/atomicx"
)
type contextkey struct{}
var id = &atomicx.Int64{}
// WithTransactionID returns a copy of ctx with TransactionID
func WithTransactionID(ctx context.Context) context.Context {
return context.WithValue(
ctx, contextkey{}, id.Add(1),
)
}
// ContextTransactionID returns the TransactionID of the context, or zero
func ContextTransactionID(ctx context.Context) int64 {
id, _ := ctx.Value(contextkey{}).(int64)
return id
}

View File

@ -1,24 +0,0 @@
package transactionid
import (
"context"
"testing"
)
func TestGood(t *testing.T) {
ctx := context.Background()
id := ContextTransactionID(ctx)
if id != 0 {
t.Fatal("unexpected ID for empty context")
}
ctx = WithTransactionID(ctx)
id = ContextTransactionID(ctx)
if id != 1 {
t.Fatal("expected ID equal to 1")
}
ctx = WithTransactionID(ctx)
id = ContextTransactionID(ctx)
if id != 2 {
t.Fatal("expected ID equal to 2")
}
}

View File

@ -33,15 +33,13 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
// DNS // DNS
if m.ResolveStart != nil { if m.ResolveStart != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] resolving: %s", "resolving: %s",
m.ResolveStart.TransactionID,
m.ResolveStart.Hostname, m.ResolveStart.Hostname,
) )
} }
if m.ResolveDone != nil { if m.ResolveDone != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] resolve done: %s, %s", "resolve done: %s, %s",
m.ResolveDone.TransactionID,
fmtError(m.ResolveDone.Error), fmtError(m.ResolveDone.Error),
m.ResolveDone.Addresses, m.ResolveDone.Addresses,
) )
@ -50,8 +48,7 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
// Syscalls // Syscalls
if m.Connect != nil { if m.Connect != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] connect done: %s, %s (rtt=%s)", "connect done: %s, %s (rtt=%s)",
m.Connect.TransactionID,
fmtError(m.Connect.Error), fmtError(m.Connect.Error),
m.Connect.RemoteAddress, m.Connect.RemoteAddress,
m.Connect.SyscallDuration, m.Connect.SyscallDuration,
@ -61,15 +58,13 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
// TLS // TLS
if m.TLSHandshakeStart != nil { if m.TLSHandshakeStart != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] TLS handshake: (forceSNI='%s')", "TLS handshake: (forceSNI='%s')",
m.TLSHandshakeStart.TransactionID,
m.TLSHandshakeStart.SNI, m.TLSHandshakeStart.SNI,
) )
} }
if m.TLSHandshakeDone != nil { if m.TLSHandshakeDone != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] TLS done: %s, %s (alpn='%s')", "TLS done: %s, %s (alpn='%s')",
m.TLSHandshakeDone.TransactionID,
fmtError(m.TLSHandshakeDone.Error), fmtError(m.TLSHandshakeDone.Error),
tlsx.VersionString(m.TLSHandshakeDone.ConnectionState.Version), tlsx.VersionString(m.TLSHandshakeDone.ConnectionState.Version),
m.TLSHandshakeDone.ConnectionState.NegotiatedProtocol, m.TLSHandshakeDone.ConnectionState.NegotiatedProtocol,
@ -86,16 +81,14 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
} }
} }
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] > %s %s %s", "> %s %s %s",
m.HTTPRequestHeadersDone.TransactionID,
m.HTTPRequestHeadersDone.Method, m.HTTPRequestHeadersDone.Method,
m.HTTPRequestHeadersDone.URL.RequestURI(), m.HTTPRequestHeadersDone.URL.RequestURI(),
proto, proto,
) )
if proto == "HTTP/2.0" { if proto == "HTTP/2.0" {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] > Host: %s", "> Host: %s",
m.HTTPRequestHeadersDone.TransactionID,
m.HTTPRequestHeadersDone.URL.Host, m.HTTPRequestHeadersDone.URL.Host,
) )
} }
@ -105,31 +98,22 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
} }
for _, value := range values { for _, value := range values {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] > %s: %s", "> %s: %s",
m.HTTPRequestHeadersDone.TransactionID,
key, value, key, value,
) )
} }
} }
h.logger.Debugf( h.logger.Debug(">")
"[httpTxID: %d] >", m.HTTPRequestHeadersDone.TransactionID)
} }
if m.HTTPRequestDone != nil { if m.HTTPRequestDone != nil {
h.logger.Debugf( h.logger.Debug("request sent; waiting for response")
"[httpTxID: %d] request sent; waiting for response",
m.HTTPRequestDone.TransactionID,
)
} }
if m.HTTPResponseStart != nil { if m.HTTPResponseStart != nil {
h.logger.Debugf( h.logger.Debug("start receiving response")
"[httpTxID: %d] start receiving response",
m.HTTPResponseStart.TransactionID,
)
} }
if m.HTTPRoundTripDone != nil && m.HTTPRoundTripDone.Error == nil { if m.HTTPRoundTripDone != nil && m.HTTPRoundTripDone.Error == nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] < %s %d %s", "< %s %d %s",
m.HTTPRoundTripDone.TransactionID,
m.HTTPRoundTripDone.ResponseProto, m.HTTPRoundTripDone.ResponseProto,
m.HTTPRoundTripDone.ResponseStatusCode, m.HTTPRoundTripDone.ResponseStatusCode,
http.StatusText(int(m.HTTPRoundTripDone.ResponseStatusCode)), http.StatusText(int(m.HTTPRoundTripDone.ResponseStatusCode)),
@ -137,29 +121,25 @@ func (h *Handler) OnMeasurement(m modelx.Measurement) {
for key, values := range m.HTTPRoundTripDone.ResponseHeaders { for key, values := range m.HTTPRoundTripDone.ResponseHeaders {
for _, value := range values { for _, value := range values {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] < %s: %s", "< %s: %s",
m.HTTPRoundTripDone.TransactionID,
key, value, key, value,
) )
} }
} }
h.logger.Debugf( h.logger.Debug("<")
"[httpTxID: %d] <", m.HTTPRoundTripDone.TransactionID)
} }
// HTTP response body // HTTP response body
if m.HTTPResponseBodyPart != nil { if m.HTTPResponseBodyPart != nil {
h.logger.Debugf( h.logger.Debugf(
"[httpTxID: %d] body part: %s, %d", "body part: %s, %d",
m.HTTPResponseBodyPart.TransactionID,
fmtError(m.HTTPResponseBodyPart.Error), fmtError(m.HTTPResponseBodyPart.Error),
len(m.HTTPResponseBodyPart.Data), len(m.HTTPResponseBodyPart.Data),
) )
} }
if m.HTTPResponseDone != nil { if m.HTTPResponseDone != nil {
h.logger.Debugf( h.logger.Debug(
"[httpTxID: %d] end of response", "end of response",
m.HTTPResponseDone.TransactionID,
) )
} }
} }

View File

@ -63,13 +63,10 @@ type TCPConnectStatus struct {
// TCPConnectEntry contains one of the entries that are part // TCPConnectEntry contains one of the entries that are part
// of the "tcp_connect" key of a OONI report. // of the "tcp_connect" key of a OONI report.
type TCPConnectEntry struct { type TCPConnectEntry struct {
ConnID int64 `json:"conn_id,omitempty"`
DialID int64 `json:"dial_id,omitempty"`
IP string `json:"ip"` IP string `json:"ip"`
Port int `json:"port"` Port int `json:"port"`
Status TCPConnectStatus `json:"status"` Status TCPConnectStatus `json:"status"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// TCPConnectList is a list of TCPConnectEntry // TCPConnectList is a list of TCPConnectEntry
@ -83,8 +80,6 @@ func NewTCPConnectList(results oonitemplates.Results) TCPConnectList {
ip, sport, _ := net.SplitHostPort(connect.RemoteAddress) ip, sport, _ := net.SplitHostPort(connect.RemoteAddress)
iport, _ := strconv.Atoi(sport) iport, _ := strconv.Atoi(sport)
out = append(out, TCPConnectEntry{ out = append(out, TCPConnectEntry{
ConnID: connect.ConnID,
DialID: connect.DialID,
IP: ip, IP: ip,
Port: iport, Port: iport,
Status: TCPConnectStatus{ Status: TCPConnectStatus{
@ -92,7 +87,6 @@ func NewTCPConnectList(results oonitemplates.Results) TCPConnectList {
Success: connect.Error == nil, Success: connect.Error == nil,
}, },
T: connect.DurationSinceBeginning.Seconds(), T: connect.DurationSinceBeginning.Seconds(),
TransactionID: connect.TransactionID,
}) })
} }
return out return out
@ -262,7 +256,6 @@ type RequestEntry struct {
Failure *string `json:"failure"` Failure *string `json:"failure"`
Request HTTPRequest `json:"request"` Request HTTPRequest `json:"request"`
Response HTTPResponse `json:"response"` Response HTTPResponse `json:"response"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// RequestList is a list of RequestEntry // RequestList is a list of RequestEntry
@ -316,7 +309,6 @@ func NewRequestList(results oonitemplates.Results) RequestList {
entry.Response.Body.Value = string(in[idx].ResponseBodySnap) entry.Response.Body.Value = string(in[idx].ResponseBodySnap)
entry.Response.BodyIsTruncated = in[idx].MaxBodySnapSize > 0 && entry.Response.BodyIsTruncated = in[idx].MaxBodySnapSize > 0 &&
int64(len(in[idx].ResponseBodySnap)) >= in[idx].MaxBodySnapSize int64(len(in[idx].ResponseBodySnap)) >= in[idx].MaxBodySnapSize
entry.TransactionID = in[idx].TransactionID
out = append(out, entry) out = append(out, entry)
} }
return out return out
@ -334,7 +326,6 @@ type DNSAnswerEntry struct {
// DNSQueryEntry is a DNS query with possibly an answer // DNSQueryEntry is a DNS query with possibly an answer
type DNSQueryEntry struct { type DNSQueryEntry struct {
Answers []DNSAnswerEntry `json:"answers"` Answers []DNSAnswerEntry `json:"answers"`
DialID int64 `json:"dial_id,omitempty"`
Engine string `json:"engine"` Engine string `json:"engine"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
@ -343,7 +334,6 @@ type DNSQueryEntry struct {
ResolverPort *string `json:"resolver_port"` ResolverPort *string `json:"resolver_port"`
ResolverAddress string `json:"resolver_address"` ResolverAddress string `json:"resolver_address"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
type ( type (
@ -393,28 +383,23 @@ func (qtype dnsQueryType) makeanswerentry(addr string) DNSAnswerEntry {
func (qtype dnsQueryType) makequeryentry(resolve *modelx.ResolveDoneEvent) DNSQueryEntry { func (qtype dnsQueryType) makequeryentry(resolve *modelx.ResolveDoneEvent) DNSQueryEntry {
return DNSQueryEntry{ return DNSQueryEntry{
DialID: resolve.DialID,
Engine: resolve.TransportNetwork, Engine: resolve.TransportNetwork,
Failure: makeFailure(resolve.Error), Failure: makeFailure(resolve.Error),
Hostname: resolve.Hostname, Hostname: resolve.Hostname,
QueryType: string(qtype), QueryType: string(qtype),
ResolverAddress: resolve.TransportAddress, ResolverAddress: resolve.TransportAddress,
T: resolve.DurationSinceBeginning.Seconds(), T: resolve.DurationSinceBeginning.Seconds(),
TransactionID: resolve.TransactionID,
} }
} }
// NetworkEvent is a network event. // NetworkEvent is a network event.
type NetworkEvent struct { type NetworkEvent struct {
Address string `json:"address,omitempty"` Address string `json:"address,omitempty"`
ConnID int64 `json:"conn_id,omitempty"`
DialID int64 `json:"dial_id,omitempty"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
NumBytes int64 `json:"num_bytes,omitempty"` NumBytes int64 `json:"num_bytes,omitempty"`
Operation string `json:"operation"` Operation string `json:"operation"`
Proto string `json:"proto"` Proto string `json:"proto"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// NetworkEventsList is a list of network events. // NetworkEventsList is a list of network events.
@ -432,34 +417,26 @@ func NewNetworkEventsList(results oonitemplates.Results) NetworkEventsList {
if in.Connect != nil { if in.Connect != nil {
out = append(out, &NetworkEvent{ out = append(out, &NetworkEvent{
Address: in.Connect.RemoteAddress, Address: in.Connect.RemoteAddress,
ConnID: in.Connect.ConnID,
DialID: in.Connect.DialID,
Failure: makeFailure(in.Connect.Error), Failure: makeFailure(in.Connect.Error),
Operation: errorx.ConnectOperation, Operation: errorx.ConnectOperation,
Proto: protocolName[in.Connect.ConnID >= 0],
T: in.Connect.DurationSinceBeginning.Seconds(), T: in.Connect.DurationSinceBeginning.Seconds(),
TransactionID: in.Connect.TransactionID,
}) })
// fallthrough // fallthrough
} }
if in.Read != nil { if in.Read != nil {
out = append(out, &NetworkEvent{ out = append(out, &NetworkEvent{
ConnID: in.Read.ConnID,
Failure: makeFailure(in.Read.Error), Failure: makeFailure(in.Read.Error),
Operation: errorx.ReadOperation, Operation: errorx.ReadOperation,
NumBytes: in.Read.NumBytes, NumBytes: in.Read.NumBytes,
Proto: protocolName[in.Read.ConnID >= 0],
T: in.Read.DurationSinceBeginning.Seconds(), T: in.Read.DurationSinceBeginning.Seconds(),
}) })
// fallthrough // fallthrough
} }
if in.Write != nil { if in.Write != nil {
out = append(out, &NetworkEvent{ out = append(out, &NetworkEvent{
ConnID: in.Write.ConnID,
Failure: makeFailure(in.Write.Error), Failure: makeFailure(in.Write.Error),
Operation: errorx.WriteOperation, Operation: errorx.WriteOperation,
NumBytes: in.Write.NumBytes, NumBytes: in.Write.NumBytes,
Proto: protocolName[in.Write.ConnID >= 0],
T: in.Write.DurationSinceBeginning.Seconds(), T: in.Write.DurationSinceBeginning.Seconds(),
}) })
// fallthrough // fallthrough
@ -471,13 +448,11 @@ func NewNetworkEventsList(results oonitemplates.Results) NetworkEventsList {
// TLSHandshake contains TLS handshake data // TLSHandshake contains TLS handshake data
type TLSHandshake struct { type TLSHandshake struct {
CipherSuite string `json:"cipher_suite"` CipherSuite string `json:"cipher_suite"`
ConnID int64 `json:"conn_id,omitempty"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
NegotiatedProtocol string `json:"negotiated_protocol"` NegotiatedProtocol string `json:"negotiated_protocol"`
PeerCertificates []MaybeBinaryValue `json:"peer_certificates"` PeerCertificates []MaybeBinaryValue `json:"peer_certificates"`
T float64 `json:"t"` T float64 `json:"t"`
TLSVersion string `json:"tls_version"` TLSVersion string `json:"tls_version"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// TLSHandshakesList is a list of TLS handshakes // TLSHandshakesList is a list of TLS handshakes
@ -489,13 +464,11 @@ func NewTLSHandshakesList(results oonitemplates.Results) TLSHandshakesList {
for _, in := range results.TLSHandshakes { for _, in := range results.TLSHandshakes {
out = append(out, TLSHandshake{ out = append(out, TLSHandshake{
CipherSuite: tlsx.CipherSuiteString(in.ConnectionState.CipherSuite), CipherSuite: tlsx.CipherSuiteString(in.ConnectionState.CipherSuite),
ConnID: in.ConnID,
Failure: makeFailure(in.Error), Failure: makeFailure(in.Error),
NegotiatedProtocol: in.ConnectionState.NegotiatedProtocol, NegotiatedProtocol: in.ConnectionState.NegotiatedProtocol,
PeerCertificates: makePeerCerts(in.ConnectionState.PeerCertificates), PeerCertificates: makePeerCerts(in.ConnectionState.PeerCertificates),
T: in.DurationSinceBeginning.Seconds(), T: in.DurationSinceBeginning.Seconds(),
TLSVersion: tlsx.VersionString(in.ConnectionState.Version), TLSVersion: tlsx.VersionString(in.ConnectionState.Version),
TransactionID: in.TransactionID,
}) })
} }
return out return out

View File

@ -823,22 +823,18 @@ func TestNewNetworkEventsListGood(t *testing.T) {
NetworkEvents: []*modelx.Measurement{ NetworkEvents: []*modelx.Measurement{
{ {
Connect: &modelx.ConnectEvent{ Connect: &modelx.ConnectEvent{
ConnID: 555,
DurationSinceBeginning: 10 * time.Millisecond, DurationSinceBeginning: 10 * time.Millisecond,
DialID: 17,
RemoteAddress: "1.1.1.1:443", RemoteAddress: "1.1.1.1:443",
}, },
}, },
{ {
Read: &modelx.ReadEvent{ Read: &modelx.ReadEvent{
ConnID: 555,
DurationSinceBeginning: 20 * time.Millisecond, DurationSinceBeginning: 20 * time.Millisecond,
NumBytes: 1789, NumBytes: 1789,
}, },
}, },
{ {
Write: &modelx.WriteEvent{ Write: &modelx.WriteEvent{
ConnID: 555,
DurationSinceBeginning: 30 * time.Millisecond, DurationSinceBeginning: 30 * time.Millisecond,
NumBytes: 17714, NumBytes: 17714,
}, },
@ -852,12 +848,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[0].Address != "1.1.1.1:443" { if out[0].Address != "1.1.1.1:443" {
t.Fatal("wrong out[0].Address") t.Fatal("wrong out[0].Address")
} }
if out[0].ConnID != 555 {
t.Fatal("wrong out[0].ConnID")
}
if out[0].DialID != 17 {
t.Fatal("wrong out[0].DialID")
}
if out[0].Failure != nil { if out[0].Failure != nil {
t.Fatal("wrong out[0].Failure") t.Fatal("wrong out[0].Failure")
} }
@ -867,9 +857,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[0].Operation != errorx.ConnectOperation { if out[0].Operation != errorx.ConnectOperation {
t.Fatal("wrong out[0].Operation") t.Fatal("wrong out[0].Operation")
} }
if out[0].Proto != "tcp" {
t.Fatal("wrong out[0].Proto")
}
if !floatEquals(out[0].T, 0.010) { if !floatEquals(out[0].T, 0.010) {
t.Fatal("wrong out[0].T") t.Fatal("wrong out[0].T")
} }
@ -877,12 +864,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[1].Address != "" { if out[1].Address != "" {
t.Fatal("wrong out[1].Address") t.Fatal("wrong out[1].Address")
} }
if out[1].ConnID != 555 {
t.Fatal("wrong out[1].ConnID")
}
if out[1].DialID != 0 {
t.Fatal("wrong out[1].DialID")
}
if out[1].Failure != nil { if out[1].Failure != nil {
t.Fatal("wrong out[1].Failure") t.Fatal("wrong out[1].Failure")
} }
@ -892,9 +873,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[1].Operation != errorx.ReadOperation { if out[1].Operation != errorx.ReadOperation {
t.Fatal("wrong out[1].Operation") t.Fatal("wrong out[1].Operation")
} }
if out[1].Proto != "tcp" {
t.Fatal("wrong out[1].Proto")
}
if !floatEquals(out[1].T, 0.020) { if !floatEquals(out[1].T, 0.020) {
t.Fatal("wrong out[1].T") t.Fatal("wrong out[1].T")
} }
@ -902,12 +880,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[2].Address != "" { if out[2].Address != "" {
t.Fatal("wrong out[2].Address") t.Fatal("wrong out[2].Address")
} }
if out[2].ConnID != 555 {
t.Fatal("wrong out[2].ConnID")
}
if out[2].DialID != 0 {
t.Fatal("wrong out[2].DialID")
}
if out[2].Failure != nil { if out[2].Failure != nil {
t.Fatal("wrong out[2].Failure") t.Fatal("wrong out[2].Failure")
} }
@ -917,9 +889,6 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[2].Operation != errorx.WriteOperation { if out[2].Operation != errorx.WriteOperation {
t.Fatal("wrong out[2].Operation") t.Fatal("wrong out[2].Operation")
} }
if out[2].Proto != "tcp" {
t.Fatal("wrong out[2].Proto")
}
if !floatEquals(out[2].T, 0.030) { if !floatEquals(out[2].T, 0.030) {
t.Fatal("wrong out[2].T") t.Fatal("wrong out[2].T")
} }
@ -930,16 +899,13 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
NetworkEvents: []*modelx.Measurement{ NetworkEvents: []*modelx.Measurement{
{ {
Connect: &modelx.ConnectEvent{ Connect: &modelx.ConnectEvent{
ConnID: -555,
DurationSinceBeginning: 10 * time.Millisecond, DurationSinceBeginning: 10 * time.Millisecond,
DialID: 17,
Error: errors.New("mocked error"), Error: errors.New("mocked error"),
RemoteAddress: "1.1.1.1:443", RemoteAddress: "1.1.1.1:443",
}, },
}, },
{ {
Read: &modelx.ReadEvent{ Read: &modelx.ReadEvent{
ConnID: -555,
DurationSinceBeginning: 20 * time.Millisecond, DurationSinceBeginning: 20 * time.Millisecond,
Error: errors.New("mocked error"), Error: errors.New("mocked error"),
NumBytes: 1789, NumBytes: 1789,
@ -947,7 +913,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
}, },
{ {
Write: &modelx.WriteEvent{ Write: &modelx.WriteEvent{
ConnID: -555,
DurationSinceBeginning: 30 * time.Millisecond, DurationSinceBeginning: 30 * time.Millisecond,
Error: errors.New("mocked error"), Error: errors.New("mocked error"),
NumBytes: 17714, NumBytes: 17714,
@ -962,12 +927,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[0].Address != "1.1.1.1:443" { if out[0].Address != "1.1.1.1:443" {
t.Fatal("wrong out[0].Address") t.Fatal("wrong out[0].Address")
} }
if out[0].ConnID != -555 {
t.Fatal("wrong out[0].ConnID")
}
if out[0].DialID != 17 {
t.Fatal("wrong out[0].DialID")
}
if *out[0].Failure != "mocked error" { if *out[0].Failure != "mocked error" {
t.Fatal("wrong out[0].Failure") t.Fatal("wrong out[0].Failure")
} }
@ -977,9 +936,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[0].Operation != errorx.ConnectOperation { if out[0].Operation != errorx.ConnectOperation {
t.Fatal("wrong out[0].Operation") t.Fatal("wrong out[0].Operation")
} }
if out[0].Proto != "udp" {
t.Fatal("wrong out[0].Proto")
}
if !floatEquals(out[0].T, 0.010) { if !floatEquals(out[0].T, 0.010) {
t.Fatal("wrong out[0].T") t.Fatal("wrong out[0].T")
} }
@ -987,12 +943,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[1].Address != "" { if out[1].Address != "" {
t.Fatal("wrong out[1].Address") t.Fatal("wrong out[1].Address")
} }
if out[1].ConnID != -555 {
t.Fatal("wrong out[1].ConnID")
}
if out[1].DialID != 0 {
t.Fatal("wrong out[1].DialID")
}
if *out[1].Failure != "mocked error" { if *out[1].Failure != "mocked error" {
t.Fatal("wrong out[1].Failure") t.Fatal("wrong out[1].Failure")
} }
@ -1002,9 +952,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[1].Operation != errorx.ReadOperation { if out[1].Operation != errorx.ReadOperation {
t.Fatal("wrong out[1].Operation") t.Fatal("wrong out[1].Operation")
} }
if out[1].Proto != "udp" {
t.Fatal("wrong out[1].Proto")
}
if !floatEquals(out[1].T, 0.020) { if !floatEquals(out[1].T, 0.020) {
t.Fatal("wrong out[1].T") t.Fatal("wrong out[1].T")
} }
@ -1012,12 +959,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[2].Address != "" { if out[2].Address != "" {
t.Fatal("wrong out[2].Address") t.Fatal("wrong out[2].Address")
} }
if out[2].ConnID != -555 {
t.Fatal("wrong out[2].ConnID")
}
if out[2].DialID != 0 {
t.Fatal("wrong out[2].DialID")
}
if *out[2].Failure != "mocked error" { if *out[2].Failure != "mocked error" {
t.Fatal("wrong out[2].Failure") t.Fatal("wrong out[2].Failure")
} }
@ -1027,9 +968,6 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[2].Operation != errorx.WriteOperation { if out[2].Operation != errorx.WriteOperation {
t.Fatal("wrong out[2].Operation") t.Fatal("wrong out[2].Operation")
} }
if out[2].Proto != "udp" {
t.Fatal("wrong out[2].Proto")
}
if !floatEquals(out[2].T, 0.030) { if !floatEquals(out[2].T, 0.030) {
t.Fatal("wrong out[2].T") t.Fatal("wrong out[2].T")
} }
@ -1052,7 +990,6 @@ func TestNewTLSHandshakesListSuccess(t *testing.T) {
TLSHandshakes: []*modelx.TLSHandshakeDoneEvent{ TLSHandshakes: []*modelx.TLSHandshakeDoneEvent{
{}, {},
{ {
ConnID: 12345,
Error: errors.New("mocked error"), Error: errors.New("mocked error"),
}, },
{ {
@ -1080,9 +1017,6 @@ func TestNewTLSHandshakesListSuccess(t *testing.T) {
if out[0].CipherSuite != "" { if out[0].CipherSuite != "" {
t.Fatal("invalid out[0].CipherSuite") t.Fatal("invalid out[0].CipherSuite")
} }
if out[0].ConnID != 0 {
t.Fatal("invalid out[0].ConnID")
}
if out[0].Failure != nil { if out[0].Failure != nil {
t.Fatal("invalid out[0].Failure") t.Fatal("invalid out[0].Failure")
} }
@ -1102,9 +1036,6 @@ func TestNewTLSHandshakesListSuccess(t *testing.T) {
if out[1].CipherSuite != "" { if out[1].CipherSuite != "" {
t.Fatal("invalid out[1].CipherSuite") t.Fatal("invalid out[1].CipherSuite")
} }
if out[1].ConnID != 12345 {
t.Fatal("invalid out[1].ConnID")
}
if *out[1].Failure != "mocked error" { if *out[1].Failure != "mocked error" {
t.Fatal("invalid out[1].Failure") t.Fatal("invalid out[1].Failure")
} }
@ -1124,9 +1055,6 @@ func TestNewTLSHandshakesListSuccess(t *testing.T) {
if out[2].CipherSuite != "TLS_AES_128_GCM_SHA256" { if out[2].CipherSuite != "TLS_AES_128_GCM_SHA256" {
t.Fatal("invalid out[2].CipherSuite") t.Fatal("invalid out[2].CipherSuite")
} }
if out[2].ConnID != 0 {
t.Fatal("invalid out[2].ConnID")
}
if out[2].Failure != nil { if out[2].Failure != nil {
t.Fatal("invalid out[2].Failure") t.Fatal("invalid out[2].Failure")
} }

View File

@ -71,45 +71,8 @@ type Results struct {
TLSHandshakes []*modelx.TLSHandshakeDoneEvent TLSHandshakes []*modelx.TLSHandshakeDoneEvent
} }
type connmapper struct {
counter int64
mu sync.Mutex
once sync.Once
table map[int64]int64
}
// scramble maps a ConnID to a different number to avoid emitting
// the port numbers. We preserve the sign because it's used to
// distinguish between TCP (positive) and UDP (negative). A special
// case is zero, which is always mapped to zero, since the zero
// port means "unspecified" in netx code.
func (m *connmapper) scramble(cid int64) int64 {
m.once.Do(func() {
m.table = make(map[int64]int64)
m.table[0] = 0 // means unspecified in netx
})
// See https://stackoverflow.com/a/38140573/4354461
m.mu.Lock()
defer m.mu.Unlock()
if value, found := m.table[cid]; found {
return value
}
var factor int64 = 1
if cid < 0 {
factor = -1
}
m.counter++ // we must never emit zero
value := factor * m.counter
m.table[cid] = value
return value
}
// cm is the global connmapper
var cm connmapper
func (r *Results) onMeasurement(m modelx.Measurement, lowLevel bool) { func (r *Results) onMeasurement(m modelx.Measurement, lowLevel bool) {
if m.Connect != nil { if m.Connect != nil {
m.Connect.ConnID = cm.scramble(m.Connect.ConnID)
r.Connects = append(r.Connects, m.Connect) r.Connects = append(r.Connects, m.Connect)
if lowLevel { if lowLevel {
r.NetworkEvents = append(r.NetworkEvents, &m) r.NetworkEvents = append(r.NetworkEvents, &m)
@ -122,17 +85,14 @@ func (r *Results) onMeasurement(m modelx.Measurement, lowLevel bool) {
r.Resolves = append(r.Resolves, m.ResolveDone) r.Resolves = append(r.Resolves, m.ResolveDone)
} }
if m.TLSHandshakeDone != nil { if m.TLSHandshakeDone != nil {
m.TLSHandshakeDone.ConnID = cm.scramble(m.TLSHandshakeDone.ConnID)
r.TLSHandshakes = append(r.TLSHandshakes, m.TLSHandshakeDone) r.TLSHandshakes = append(r.TLSHandshakes, m.TLSHandshakeDone)
} }
if m.Read != nil { if m.Read != nil {
m.Read.ConnID = cm.scramble(m.Read.ConnID)
if lowLevel { if lowLevel {
r.NetworkEvents = append(r.NetworkEvents, &m) r.NetworkEvents = append(r.NetworkEvents, &m)
} }
} }
if m.Write != nil { if m.Write != nil {
m.Write.ConnID = cm.scramble(m.Write.ConnID)
if lowLevel { if lowLevel {
r.NetworkEvents = append(r.NetworkEvents, &m) r.NetworkEvents = append(r.NetworkEvents, &m)
} }

View File

@ -387,22 +387,3 @@ func (txp *faketransport) ClientFactory(stateDir string) (obfs4base.ClientFactor
func (txp *faketransport) ServerFactory(stateDir string, args *goptlib.Args) (obfs4base.ServerFactory, error) { func (txp *faketransport) ServerFactory(stateDir string, args *goptlib.Args) (obfs4base.ServerFactory, error) {
return txp.txp.ServerFactory(stateDir, args) return txp.txp.ServerFactory(stateDir, args)
} }
func TestConnmapper(t *testing.T) {
var mapper connmapper
if mapper.scramble(-1) >= 0 {
t.Fatal("unexpected value for negative input")
}
if mapper.scramble(1234) != 2 {
t.Fatal("unexpected second value")
}
if mapper.scramble(12) != 3 {
t.Fatal("unexpected third value")
}
if mapper.scramble(12) != mapper.scramble(12) {
t.Fatal("not idempotent")
}
if mapper.scramble(0) != 0 {
t.Fatal("unexpected value for zero input")
}
}

View File

@ -70,13 +70,10 @@ type TCPConnectStatus struct {
// TCPConnectEntry contains one of the entries that are part // TCPConnectEntry contains one of the entries that are part
// of the "tcp_connect" key of a OONI report. // of the "tcp_connect" key of a OONI report.
type TCPConnectEntry struct { type TCPConnectEntry struct {
ConnID int64 `json:"conn_id,omitempty"`
DialID int64 `json:"dial_id,omitempty"`
IP string `json:"ip"` IP string `json:"ip"`
Port int `json:"port"` Port int `json:"port"`
Status TCPConnectStatus `json:"status"` Status TCPConnectStatus `json:"status"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// NewTCPConnectList creates a new TCPConnectList // NewTCPConnectList creates a new TCPConnectList
@ -293,7 +290,6 @@ type RequestEntry struct {
Request HTTPRequest `json:"request"` Request HTTPRequest `json:"request"`
Response HTTPResponse `json:"response"` Response HTTPResponse `json:"response"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
func addheaders( func addheaders(
@ -382,7 +378,6 @@ type DNSAnswerEntry struct {
// DNSQueryEntry is a DNS query with possibly an answer // DNSQueryEntry is a DNS query with possibly an answer
type DNSQueryEntry struct { type DNSQueryEntry struct {
Answers []DNSAnswerEntry `json:"answers"` Answers []DNSAnswerEntry `json:"answers"`
DialID int64 `json:"dial_id,omitempty"`
Engine string `json:"engine"` Engine string `json:"engine"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
@ -391,7 +386,6 @@ type DNSQueryEntry struct {
ResolverPort *string `json:"resolver_port"` ResolverPort *string `json:"resolver_port"`
ResolverAddress string `json:"resolver_address"` ResolverAddress string `json:"resolver_address"`
T float64 `json:"t"` T float64 `json:"t"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
type dnsQueryType string type dnsQueryType string
@ -468,15 +462,12 @@ func (qtype dnsQueryType) makequeryentry(begin time.Time, ev trace.Event) DNSQue
// for them to be there _and_ we have data to show. // for them to be there _and_ we have data to show.
type NetworkEvent struct { type NetworkEvent struct {
Address string `json:"address,omitempty"` Address string `json:"address,omitempty"`
ConnID int64 `json:"conn_id,omitempty"`
DialID int64 `json:"dial_id,omitempty"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
NumBytes int64 `json:"num_bytes,omitempty"` NumBytes int64 `json:"num_bytes,omitempty"`
Operation string `json:"operation"` Operation string `json:"operation"`
Proto string `json:"proto,omitempty"` Proto string `json:"proto,omitempty"`
T float64 `json:"t"` T float64 `json:"t"`
Tags []string `json:"tags,omitempty"` Tags []string `json:"tags,omitempty"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// NewNetworkEventsList returns a list of DNS queries. // NewNetworkEventsList returns a list of DNS queries.
@ -543,7 +534,6 @@ func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent
// TLSHandshake contains TLS handshake data // TLSHandshake contains TLS handshake data
type TLSHandshake struct { type TLSHandshake struct {
CipherSuite string `json:"cipher_suite"` CipherSuite string `json:"cipher_suite"`
ConnID int64 `json:"conn_id,omitempty"`
Failure *string `json:"failure"` Failure *string `json:"failure"`
NegotiatedProtocol string `json:"negotiated_protocol"` NegotiatedProtocol string `json:"negotiated_protocol"`
NoTLSVerify bool `json:"no_tls_verify"` NoTLSVerify bool `json:"no_tls_verify"`
@ -552,7 +542,6 @@ type TLSHandshake struct {
T float64 `json:"t"` T float64 `json:"t"`
Tags []string `json:"tags"` Tags []string `json:"tags"`
TLSVersion string `json:"tls_version"` TLSVersion string `json:"tls_version"`
TransactionID int64 `json:"transaction_id,omitempty"`
} }
// NewTLSHandshakesList creates a new TLSHandshakesList // NewTLSHandshakesList creates a new TLSHandshakesList

View File

@ -143,12 +143,6 @@ var ErrDNSBogon = errors.New("dns: detected bogon address")
// this structure is to properly set Failure, which is also returned by // this structure is to properly set Failure, which is also returned by
// the Error() method, so be one of the OONI defined strings. // the Error() method, so be one of the OONI defined strings.
type ErrWrapper struct { type ErrWrapper struct {
// ConnID is the connection ID, or zero if not known.
ConnID int64
// DialID is the dial ID, or zero if not known.
DialID int64
// Failure is the OONI failure string. The failure strings are // Failure is the OONI failure string. The failure strings are
// loosely backward compatible with Measurement Kit. // loosely backward compatible with Measurement Kit.
// //
@ -181,9 +175,6 @@ type ErrWrapper struct {
// supposed to refer to the major operation that failed. // supposed to refer to the major operation that failed.
Operation string Operation string
// TransactionID is the transaction ID, or zero if not known.
TransactionID int64
// WrappedErr is the error that we're wrapping. // WrappedErr is the error that we're wrapping.
WrappedErr error WrappedErr error
} }
@ -201,12 +192,6 @@ func (e *ErrWrapper) Unwrap() error {
// SafeErrWrapperBuilder contains a builder for ErrWrapper that // SafeErrWrapperBuilder contains a builder for ErrWrapper that
// is safe, i.e., behaves correctly when the error is nil. // is safe, i.e., behaves correctly when the error is nil.
type SafeErrWrapperBuilder struct { type SafeErrWrapperBuilder struct {
// ConnID is the connection ID, if any
ConnID int64
// DialID is the dial ID, if any
DialID int64
// Error is the error, if any // Error is the error, if any
Error error Error error
@ -216,9 +201,6 @@ type SafeErrWrapperBuilder struct {
// Operation is the operation that failed // Operation is the operation that failed
Operation string Operation string
// TransactionID is the transaction ID, if any
TransactionID int64
} }
// MaybeBuild builds a new ErrWrapper, if b.Error is not nil, and returns // MaybeBuild builds a new ErrWrapper, if b.Error is not nil, and returns
@ -230,11 +212,8 @@ func (b SafeErrWrapperBuilder) MaybeBuild() (err error) {
classifier = toFailureString classifier = toFailureString
} }
err = &ErrWrapper{ err = &ErrWrapper{
ConnID: b.ConnID,
DialID: b.DialID,
Failure: classifier(b.Error), Failure: classifier(b.Error),
Operation: toOperationString(b.Error, b.Operation), Operation: toOperationString(b.Error, b.Operation),
TransactionID: b.TransactionID,
WrappedErr: b.Error, WrappedErr: b.Error,
} }
} }

View File

@ -17,27 +17,15 @@ import (
func TestMaybeBuildFactory(t *testing.T) { func TestMaybeBuildFactory(t *testing.T) {
err := SafeErrWrapperBuilder{ err := SafeErrWrapperBuilder{
ConnID: 1,
DialID: 10,
Error: errors.New("mocked error"), Error: errors.New("mocked error"),
TransactionID: 100,
}.MaybeBuild() }.MaybeBuild()
var target *ErrWrapper var target *ErrWrapper
if errors.As(err, &target) == false { if errors.As(err, &target) == false {
t.Fatal("not the expected error type") t.Fatal("not the expected error type")
} }
if target.ConnID != 1 {
t.Fatal("wrong ConnID")
}
if target.DialID != 10 {
t.Fatal("wrong DialID")
}
if target.Failure != "unknown_failure: mocked error" { if target.Failure != "unknown_failure: mocked error" {
t.Fatal("the failure string is wrong") t.Fatal("the failure string is wrong")
} }
if target.TransactionID != 100 {
t.Fatal("the transactionID is wrong")
}
if target.WrappedErr.Error() != "mocked error" { if target.WrappedErr.Error() != "mocked error" {
t.Fatal("the wrapped error is wrong") t.Fatal("the wrapped error is wrong")
} }

View File

@ -6,7 +6,6 @@ import (
"net" "net"
"github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
) )
@ -30,7 +29,6 @@ func (d DNSDialer) DialContext(
if tlsCfg.ServerName == "" { if tlsCfg.ServerName == "" {
tlsCfg.ServerName = onlyhost tlsCfg.ServerName = onlyhost
} }
ctx = dialid.WithDialID(ctx)
var addrs []string var addrs []string
addrs, err = d.LookupHost(ctx, onlyhost) addrs, err = d.LookupHost(ctx, onlyhost)
if err != nil { if err != nil {

View File

@ -5,7 +5,6 @@ import (
"crypto/tls" "crypto/tls"
"github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
) )
@ -18,13 +17,9 @@ type ErrorWrapperDialer struct {
func (d ErrorWrapperDialer) DialContext( func (d ErrorWrapperDialer) DialContext(
ctx context.Context, network string, host string, ctx context.Context, network string, host string,
tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error) { tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error) {
dialID := dialid.ContextDialID(ctx)
sess, err := d.Dialer.DialContext(ctx, network, host, tlsCfg, cfg) sess, err := d.Dialer.DialContext(ctx, network, host, tlsCfg, cfg)
err = errorx.SafeErrWrapperBuilder{ err = errorx.SafeErrWrapperBuilder{
// ConnID does not make any sense if we've failed and the error
// does not make any sense (and is nil) if we succeeded.
Classifier: errorx.ClassifyQUICFailure, Classifier: errorx.ClassifyQUICFailure,
DialID: dialID,
Error: err, Error: err,
Operation: errorx.QUICHandshakeOperation, Operation: errorx.QUICHandshakeOperation,
}.MaybeBuild() }.MaybeBuild()

View File

@ -8,13 +8,12 @@ import (
"testing" "testing"
"github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer"
) )
func TestErrorWrapperFailure(t *testing.T) { func TestErrorWrapperFailure(t *testing.T) {
ctx := dialid.WithDialID(context.Background()) ctx := context.Background()
d := quicdialer.ErrorWrapperDialer{ d := quicdialer.ErrorWrapperDialer{
Dialer: MockDialer{Sess: nil, Err: io.EOF}} Dialer: MockDialer{Sess: nil, Err: io.EOF}}
sess, err := d.DialContext( sess, err := d.DialContext(
@ -33,9 +32,6 @@ func errorWrapperCheckErr(t *testing.T, err error, op string) {
if !errors.As(err, &errWrapper) { if !errors.As(err, &errWrapper) {
t.Fatal("cannot cast to ErrWrapper") t.Fatal("cannot cast to ErrWrapper")
} }
if errWrapper.DialID == 0 {
t.Fatal("unexpected DialID")
}
if errWrapper.Operation != op { if errWrapper.Operation != op {
t.Fatal("unexpected Operation") t.Fatal("unexpected Operation")
} }
@ -68,7 +64,7 @@ func TestErrorWrapperInvalidCertificate(t *testing.T) {
} }
func TestErrorWrapperSuccess(t *testing.T) { func TestErrorWrapperSuccess(t *testing.T) {
ctx := dialid.WithDialID(context.Background()) ctx := context.Background()
tlsConf := &tls.Config{ tlsConf := &tls.Config{
NextProtos: []string{"h3"}, NextProtos: []string{"h3"},
ServerName: "www.google.com", ServerName: "www.google.com",

View File

@ -4,9 +4,7 @@ import (
"context" "context"
"time" "time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
) )
// EmitterTransport is a RoundTripper that emits events when they occur. // EmitterTransport is a RoundTripper that emits events when they occur.
@ -20,8 +18,7 @@ func (txp EmitterTransport) RoundTrip(ctx context.Context, querydata []byte) ([]
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
DNSQuery: &modelx.DNSQueryEvent{ DNSQuery: &modelx.DNSQueryEvent{
Data: querydata, Data: querydata,
DialID: dialid.ContextDialID(ctx), DurationSinceBeginning: time.Since(root.Beginning),
DurationSinceBeginning: time.Now().Sub(root.Beginning),
}, },
}) })
replydata, err := txp.RoundTripper.RoundTrip(ctx, querydata) replydata, err := txp.RoundTripper.RoundTrip(ctx, querydata)
@ -31,8 +28,7 @@ func (txp EmitterTransport) RoundTrip(ctx context.Context, querydata []byte) ([]
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
DNSReply: &modelx.DNSReplyEvent{ DNSReply: &modelx.DNSReplyEvent{
Data: replydata, Data: replydata,
DialID: dialid.ContextDialID(ctx), DurationSinceBeginning: time.Since(root.Beginning),
DurationSinceBeginning: time.Now().Sub(root.Beginning),
}, },
}) })
return replydata, nil return replydata, nil
@ -56,15 +52,11 @@ func (r EmitterResolver) LookupHost(ctx context.Context, hostname string) ([]str
txp := qr.Transport() txp := qr.Transport()
network, address = txp.Network(), txp.Address() network, address = txp.Network(), txp.Address()
} }
dialID := dialid.ContextDialID(ctx)
txID := transactionid.ContextTransactionID(ctx)
root := modelx.ContextMeasurementRootOrDefault(ctx) root := modelx.ContextMeasurementRootOrDefault(ctx)
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
ResolveStart: &modelx.ResolveStartEvent{ ResolveStart: &modelx.ResolveStartEvent{
DialID: dialID, DurationSinceBeginning: time.Since(root.Beginning),
DurationSinceBeginning: time.Now().Sub(root.Beginning),
Hostname: hostname, Hostname: hostname,
TransactionID: txID,
TransportAddress: address, TransportAddress: address,
TransportNetwork: network, TransportNetwork: network,
}, },
@ -73,11 +65,9 @@ func (r EmitterResolver) LookupHost(ctx context.Context, hostname string) ([]str
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
ResolveDone: &modelx.ResolveDoneEvent{ ResolveDone: &modelx.ResolveDoneEvent{
Addresses: addrs, Addresses: addrs,
DialID: dialID, DurationSinceBeginning: time.Since(root.Beginning),
DurationSinceBeginning: time.Now().Sub(root.Beginning),
Error: err, Error: err,
Hostname: hostname, Hostname: hostname,
TransactionID: txID,
TransportAddress: address, TransportAddress: address,
TransportNetwork: network, TransportNetwork: network,
}, },

View File

@ -10,16 +10,13 @@ import (
"time" "time"
"github.com/miekg/dns" "github.com/miekg/dns"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver" "github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
) )
func TestEmitterTransportSuccess(t *testing.T) { func TestEmitterTransportSuccess(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = dialid.WithDialID(ctx)
handler := &handlers.SavingHandler{} handler := &handlers.SavingHandler{}
root := &modelx.MeasurementRoot{ root := &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),
@ -48,9 +45,6 @@ func TestEmitterTransportSuccess(t *testing.T) {
if !bytes.Equal(events[0].DNSQuery.Data, querydata) { if !bytes.Equal(events[0].DNSQuery.Data, querydata) {
t.Fatal("invalid query data") t.Fatal("invalid query data")
} }
if events[0].DNSQuery.DialID == 0 {
t.Fatal("invalid query DialID")
}
if events[0].DNSQuery.DurationSinceBeginning <= 0 { if events[0].DNSQuery.DurationSinceBeginning <= 0 {
t.Fatal("invalid duration since beginning") t.Fatal("invalid duration since beginning")
} }
@ -60,9 +54,6 @@ func TestEmitterTransportSuccess(t *testing.T) {
if !bytes.Equal(events[1].DNSReply.Data, replydata) { if !bytes.Equal(events[1].DNSReply.Data, replydata) {
t.Fatal("missing reply data") t.Fatal("missing reply data")
} }
if events[1].DNSReply.DialID != 1 {
t.Fatal("invalid query DialID")
}
if events[1].DNSReply.DurationSinceBeginning <= 0 { if events[1].DNSReply.DurationSinceBeginning <= 0 {
t.Fatal("invalid duration since beginning") t.Fatal("invalid duration since beginning")
} }
@ -70,7 +61,6 @@ func TestEmitterTransportSuccess(t *testing.T) {
func TestEmitterTransportFailure(t *testing.T) { func TestEmitterTransportFailure(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = dialid.WithDialID(ctx)
handler := &handlers.SavingHandler{} handler := &handlers.SavingHandler{}
root := &modelx.MeasurementRoot{ root := &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),
@ -103,9 +93,6 @@ func TestEmitterTransportFailure(t *testing.T) {
if !bytes.Equal(events[0].DNSQuery.Data, querydata) { if !bytes.Equal(events[0].DNSQuery.Data, querydata) {
t.Fatal("invalid query data") t.Fatal("invalid query data")
} }
if events[0].DNSQuery.DialID == 0 {
t.Fatal("invalid query DialID")
}
if events[0].DNSQuery.DurationSinceBeginning <= 0 { if events[0].DNSQuery.DurationSinceBeginning <= 0 {
t.Fatal("invalid duration since beginning") t.Fatal("invalid duration since beginning")
} }
@ -113,8 +100,6 @@ func TestEmitterTransportFailure(t *testing.T) {
func TestEmitterResolverFailure(t *testing.T) { func TestEmitterResolverFailure(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = dialid.WithDialID(ctx)
ctx = transactionid.WithTransactionID(ctx)
handler := &handlers.SavingHandler{} handler := &handlers.SavingHandler{}
root := &modelx.MeasurementRoot{ root := &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),
@ -143,18 +128,12 @@ func TestEmitterResolverFailure(t *testing.T) {
if events[0].ResolveStart == nil { if events[0].ResolveStart == nil {
t.Fatal("missing ResolveStart field") t.Fatal("missing ResolveStart field")
} }
if events[0].ResolveStart.DialID == 0 {
t.Fatal("invalid DialID")
}
if events[0].ResolveStart.DurationSinceBeginning <= 0 { if events[0].ResolveStart.DurationSinceBeginning <= 0 {
t.Fatal("invalid duration since beginning") t.Fatal("invalid duration since beginning")
} }
if events[0].ResolveStart.Hostname != "www.google.com" { if events[0].ResolveStart.Hostname != "www.google.com" {
t.Fatal("invalid Hostname") t.Fatal("invalid Hostname")
} }
if events[0].ResolveStart.TransactionID == 0 {
t.Fatal("invalid TransactionID")
}
if events[0].ResolveStart.TransportAddress != "https://dns.google.com/" { if events[0].ResolveStart.TransportAddress != "https://dns.google.com/" {
t.Fatal("invalid TransportAddress") t.Fatal("invalid TransportAddress")
} }
@ -164,9 +143,6 @@ func TestEmitterResolverFailure(t *testing.T) {
if events[1].ResolveDone == nil { if events[1].ResolveDone == nil {
t.Fatal("missing ResolveDone field") t.Fatal("missing ResolveDone field")
} }
if events[1].ResolveDone.DialID == 0 {
t.Fatal("invalid DialID")
}
if events[1].ResolveDone.DurationSinceBeginning <= 0 { if events[1].ResolveDone.DurationSinceBeginning <= 0 {
t.Fatal("invalid duration since beginning") t.Fatal("invalid duration since beginning")
} }
@ -176,9 +152,6 @@ func TestEmitterResolverFailure(t *testing.T) {
if events[1].ResolveDone.Hostname != "www.google.com" { if events[1].ResolveDone.Hostname != "www.google.com" {
t.Fatal("invalid Hostname") t.Fatal("invalid Hostname")
} }
if events[1].ResolveDone.TransactionID == 0 {
t.Fatal("invalid TransactionID")
}
if events[1].ResolveDone.TransportAddress != "https://dns.google.com/" { if events[1].ResolveDone.TransportAddress != "https://dns.google.com/" {
t.Fatal("invalid TransportAddress") t.Fatal("invalid TransportAddress")
} }
@ -189,8 +162,6 @@ func TestEmitterResolverFailure(t *testing.T) {
func TestEmitterResolverSuccess(t *testing.T) { func TestEmitterResolverSuccess(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = dialid.WithDialID(ctx)
ctx = transactionid.WithTransactionID(ctx)
handler := &handlers.SavingHandler{} handler := &handlers.SavingHandler{}
root := &modelx.MeasurementRoot{ root := &modelx.MeasurementRoot{
Beginning: time.Now(), Beginning: time.Now(),

View File

@ -3,8 +3,6 @@ package resolver
import ( import (
"context" "context"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
) )
@ -15,15 +13,11 @@ type ErrorWrapperResolver struct {
// LookupHost implements Resolver.LookupHost // LookupHost implements Resolver.LookupHost
func (r ErrorWrapperResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) { func (r ErrorWrapperResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) {
dialID := dialid.ContextDialID(ctx)
txID := transactionid.ContextTransactionID(ctx)
addrs, err := r.Resolver.LookupHost(ctx, hostname) addrs, err := r.Resolver.LookupHost(ctx, hostname)
err = errorx.SafeErrWrapperBuilder{ err = errorx.SafeErrWrapperBuilder{
Classifier: errorx.ClassifyResolveFailure, Classifier: errorx.ClassifyResolveFailure,
DialID: dialID,
Error: err, Error: err,
Operation: errorx.ResolveOperation, Operation: errorx.ResolveOperation,
TransactionID: txID,
}.MaybeBuild() }.MaybeBuild()
return addrs, err return addrs, err
} }

View File

@ -5,8 +5,6 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/dialid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/transactionid"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver" "github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
) )
@ -30,8 +28,6 @@ func TestErrorWrapperFailure(t *testing.T) {
Resolver: resolver.NewFakeResolverThatFails(), Resolver: resolver.NewFakeResolverThatFails(),
} }
ctx := context.Background() ctx := context.Background()
ctx = dialid.WithDialID(ctx)
ctx = transactionid.WithTransactionID(ctx)
addrs, err := r.LookupHost(ctx, "dns.google.com") addrs, err := r.LookupHost(ctx, "dns.google.com")
if addrs != nil { if addrs != nil {
t.Fatal("expected nil addr here") t.Fatal("expected nil addr here")
@ -43,15 +39,6 @@ func TestErrorWrapperFailure(t *testing.T) {
if errWrapper.Failure != errorx.FailureDNSNXDOMAINError { if errWrapper.Failure != errorx.FailureDNSNXDOMAINError {
t.Fatal("unexpected failure") t.Fatal("unexpected failure")
} }
if errWrapper.ConnID != 0 {
t.Fatal("unexpected ConnID")
}
if errWrapper.DialID == 0 {
t.Fatal("unexpected DialID")
}
if errWrapper.TransactionID == 0 {
t.Fatal("unexpected TransactionID")
}
if errWrapper.Operation != errorx.ResolveOperation { if errWrapper.Operation != errorx.ResolveOperation {
t.Fatal("unexpected Operation") t.Fatal("unexpected Operation")
} }

View File

@ -7,7 +7,6 @@ import (
"net" "net"
"time" "time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/connid"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx" "github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
) )
@ -68,11 +67,9 @@ type ErrorWrapperTLSHandshaker struct {
func (h ErrorWrapperTLSHandshaker) Handshake( func (h ErrorWrapperTLSHandshaker) Handshake(
ctx context.Context, conn net.Conn, config *tls.Config, ctx context.Context, conn net.Conn, config *tls.Config,
) (net.Conn, tls.ConnectionState, error) { ) (net.Conn, tls.ConnectionState, error) {
connID := connid.Compute(conn.RemoteAddr().Network(), conn.RemoteAddr().String())
tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config) tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config)
err = errorx.SafeErrWrapperBuilder{ err = errorx.SafeErrWrapperBuilder{
Classifier: errorx.ClassifyTLSFailure, Classifier: errorx.ClassifyTLSFailure,
ConnID: connID,
Error: err, Error: err,
Operation: errorx.TLSHandshakeOperation, Operation: errorx.TLSHandshakeOperation,
}.MaybeBuild() }.MaybeBuild()
@ -88,22 +85,19 @@ type EmitterTLSHandshaker struct {
func (h EmitterTLSHandshaker) Handshake( func (h EmitterTLSHandshaker) Handshake(
ctx context.Context, conn net.Conn, config *tls.Config, ctx context.Context, conn net.Conn, config *tls.Config,
) (net.Conn, tls.ConnectionState, error) { ) (net.Conn, tls.ConnectionState, error) {
connID := connid.Compute(conn.RemoteAddr().Network(), conn.RemoteAddr().String())
root := modelx.ContextMeasurementRootOrDefault(ctx) root := modelx.ContextMeasurementRootOrDefault(ctx)
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
TLSHandshakeStart: &modelx.TLSHandshakeStartEvent{ TLSHandshakeStart: &modelx.TLSHandshakeStartEvent{
ConnID: connID, DurationSinceBeginning: time.Since(root.Beginning),
DurationSinceBeginning: time.Now().Sub(root.Beginning),
SNI: config.ServerName, SNI: config.ServerName,
}, },
}) })
tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config) tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config)
root.Handler.OnMeasurement(modelx.Measurement{ root.Handler.OnMeasurement(modelx.Measurement{
TLSHandshakeDone: &modelx.TLSHandshakeDoneEvent{ TLSHandshakeDone: &modelx.TLSHandshakeDoneEvent{
ConnID: connID,
ConnectionState: modelx.NewTLSConnectionState(state), ConnectionState: modelx.NewTLSConnectionState(state),
Error: err, Error: err,
DurationSinceBeginning: time.Now().Sub(root.Beginning), DurationSinceBeginning: time.Since(root.Beginning),
}, },
}) })
return tlsconn, state, err return tlsconn, state, err

View File

@ -109,9 +109,6 @@ func TestErrorWrapperTLSHandshakerFailure(t *testing.T) {
if !errors.As(err, &errWrapper) { if !errors.As(err, &errWrapper) {
t.Fatal("cannot cast to ErrWrapper") t.Fatal("cannot cast to ErrWrapper")
} }
if errWrapper.ConnID == 0 {
t.Fatal("unexpected ConnID")
}
if errWrapper.Failure != errorx.FailureEOFError { if errWrapper.Failure != errorx.FailureEOFError {
t.Fatal("unexpected Failure") t.Fatal("unexpected Failure")
} }
@ -143,9 +140,6 @@ func TestEmitterTLSHandshakerFailure(t *testing.T) {
if events[0].TLSHandshakeStart == nil { if events[0].TLSHandshakeStart == nil {
t.Fatal("missing TLSHandshakeStart event") t.Fatal("missing TLSHandshakeStart event")
} }
if events[0].TLSHandshakeStart.ConnID == 0 {
t.Fatal("expected nonzero ConnID")
}
if events[0].TLSHandshakeStart.DurationSinceBeginning == 0 { if events[0].TLSHandshakeStart.DurationSinceBeginning == 0 {
t.Fatal("expected nonzero DurationSinceBeginning") t.Fatal("expected nonzero DurationSinceBeginning")
} }
@ -155,9 +149,6 @@ func TestEmitterTLSHandshakerFailure(t *testing.T) {
if events[1].TLSHandshakeDone == nil { if events[1].TLSHandshakeDone == nil {
t.Fatal("missing TLSHandshakeDone event") t.Fatal("missing TLSHandshakeDone event")
} }
if events[1].TLSHandshakeDone.ConnID == 0 {
t.Fatal("expected nonzero ConnID")
}
if events[1].TLSHandshakeDone.DurationSinceBeginning == 0 { if events[1].TLSHandshakeDone.DurationSinceBeginning == 0 {
t.Fatal("expected nonzero DurationSinceBeginning") t.Fatal("expected nonzero DurationSinceBeginning")
} }