fix(measurexlite): expose TCP connect event (#934)
See https://github.com/ooni/probe/issues/2254
This commit is contained in:
parent
3766ab2721
commit
a72a9284f1
|
@ -53,6 +53,8 @@ func (tx *Trace) OnConnectDone(
|
||||||
started time.Time, network, domain, remoteAddr string, err error, finished time.Time) {
|
started time.Time, network, domain, remoteAddr string, err error, finished time.Time) {
|
||||||
switch network {
|
switch network {
|
||||||
case "tcp", "tcp4", "tcp6":
|
case "tcp", "tcp4", "tcp6":
|
||||||
|
|
||||||
|
// insert into the tcpConnect buffer
|
||||||
select {
|
select {
|
||||||
case tx.tcpConnect <- NewArchivalTCPConnectResult(
|
case tx.tcpConnect <- NewArchivalTCPConnectResult(
|
||||||
tx.Index,
|
tx.Index,
|
||||||
|
@ -63,6 +65,23 @@ func (tx *Trace) OnConnectDone(
|
||||||
):
|
):
|
||||||
default: // buffer is full
|
default: // buffer is full
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert into the networkEvent buffer
|
||||||
|
// see https://github.com/ooni/probe/issues/2254
|
||||||
|
select {
|
||||||
|
case tx.networkEvent <- NewArchivalNetworkEvent(
|
||||||
|
tx.Index,
|
||||||
|
started.Sub(tx.ZeroTime),
|
||||||
|
netxlite.ConnectOperation,
|
||||||
|
"tcp",
|
||||||
|
remoteAddr,
|
||||||
|
0,
|
||||||
|
err,
|
||||||
|
finished.Sub(tx.ZeroTime),
|
||||||
|
):
|
||||||
|
default: // buffer is full
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// ignore UDP connect attempts because they cannot fail
|
// ignore UDP connect attempts because they cannot fail
|
||||||
// in interesting ways that make sense for censorship
|
// in interesting ways that make sense for censorship
|
||||||
|
|
|
@ -97,31 +97,59 @@ func TestNewDialerWithoutResolver(t *testing.T) {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
t.Fatal("expected nil conn")
|
t.Fatal("expected nil conn")
|
||||||
}
|
}
|
||||||
events := trace.TCPConnects()
|
|
||||||
if len(events) != 1 {
|
|
||||||
t.Fatal("expected to see single TCPConnect event")
|
|
||||||
}
|
|
||||||
expectedFailure := netxlite.FailureInterrupted
|
expectedFailure := netxlite.FailureInterrupted
|
||||||
expect := &model.ArchivalTCPConnectResult{
|
|
||||||
IP: "1.1.1.1",
|
t.Run("for TCPConnect", func(t *testing.T) {
|
||||||
Port: 443,
|
events := trace.TCPConnects()
|
||||||
Status: model.ArchivalTCPConnectStatus{
|
if len(events) != 1 {
|
||||||
Blocked: nil,
|
t.Fatal("expected to see single TCPConnect event")
|
||||||
Failure: &expectedFailure,
|
}
|
||||||
Success: false,
|
expect := &model.ArchivalTCPConnectResult{
|
||||||
},
|
IP: "1.1.1.1",
|
||||||
T: time.Second.Seconds(),
|
Port: 443,
|
||||||
}
|
Status: model.ArchivalTCPConnectStatus{
|
||||||
got := events[0]
|
Blocked: nil,
|
||||||
if diff := cmp.Diff(expect, got); diff != "" {
|
Failure: &expectedFailure,
|
||||||
t.Fatal(diff)
|
Success: false,
|
||||||
}
|
},
|
||||||
|
T: time.Second.Seconds(),
|
||||||
|
}
|
||||||
|
got := events[0]
|
||||||
|
if diff := cmp.Diff(expect, got); diff != "" {
|
||||||
|
t.Fatal(diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("for NetworkEvents", func(t *testing.T) {
|
||||||
|
events := trace.NetworkEvents()
|
||||||
|
if len(events) != 1 {
|
||||||
|
t.Fatal("expected to see single NetworkEvent event")
|
||||||
|
}
|
||||||
|
expectedFailure := netxlite.FailureInterrupted
|
||||||
|
expect := &model.ArchivalNetworkEvent{
|
||||||
|
Address: "1.1.1.1:443",
|
||||||
|
Failure: &expectedFailure,
|
||||||
|
NumBytes: 0,
|
||||||
|
Operation: netxlite.ConnectOperation,
|
||||||
|
Proto: "tcp",
|
||||||
|
T0: 0,
|
||||||
|
T: time.Second.Seconds(),
|
||||||
|
TransactionID: 0,
|
||||||
|
Tags: []string{},
|
||||||
|
}
|
||||||
|
got := events[0]
|
||||||
|
if diff := cmp.Diff(expect, got); diff != "" {
|
||||||
|
t.Fatal(diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("DialContext discards events when buffer is full", func(t *testing.T) {
|
t.Run("DialContext discards events when buffer is full", func(t *testing.T) {
|
||||||
zeroTime := time.Now()
|
zeroTime := time.Now()
|
||||||
trace := NewTrace(0, zeroTime)
|
trace := NewTrace(0, zeroTime)
|
||||||
trace.tcpConnect = make(chan *model.ArchivalTCPConnectResult) // no buffer
|
trace.tcpConnect = make(chan *model.ArchivalTCPConnectResult) // no buffer
|
||||||
|
trace.networkEvent = make(chan *model.ArchivalNetworkEvent) // ditto
|
||||||
dialer := trace.NewDialerWithoutResolver(model.DiscardLogger)
|
dialer := trace.NewDialerWithoutResolver(model.DiscardLogger)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
cancel() // we cancel immediately so connect is ~instantaneous
|
cancel() // we cancel immediately so connect is ~instantaneous
|
||||||
|
@ -132,10 +160,20 @@ func TestNewDialerWithoutResolver(t *testing.T) {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
t.Fatal("expected nil conn")
|
t.Fatal("expected nil conn")
|
||||||
}
|
}
|
||||||
events := trace.TCPConnects()
|
|
||||||
if len(events) != 0 {
|
t.Run("for TCPConnect", func(t *testing.T) {
|
||||||
t.Fatal("expected to see no TCPConnect events")
|
events := trace.TCPConnects()
|
||||||
}
|
if len(events) != 0 {
|
||||||
|
t.Fatal("expected to see no TCPConnect events")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("for NetworkEvents", func(t *testing.T) {
|
||||||
|
events := trace.NetworkEvents()
|
||||||
|
if len(events) != 0 {
|
||||||
|
t.Fatal("expected to see no NetworkEvent events")
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("DialContext ignores UDP connect attempts", func(t *testing.T) {
|
t.Run("DialContext ignores UDP connect attempts", func(t *testing.T) {
|
||||||
|
@ -151,10 +189,20 @@ func TestNewDialerWithoutResolver(t *testing.T) {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
t.Fatal("expected nil conn")
|
t.Fatal("expected nil conn")
|
||||||
}
|
}
|
||||||
events := trace.TCPConnects()
|
|
||||||
if len(events) != 0 {
|
t.Run("for TCP connect", func(t *testing.T) {
|
||||||
t.Fatal("expected to see no TCPConnect events")
|
events := trace.TCPConnects()
|
||||||
}
|
if len(events) != 0 {
|
||||||
|
t.Fatal("expected to see no TCPConnect events")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("for NetworkEvents", func(t *testing.T) {
|
||||||
|
events := trace.NetworkEvents()
|
||||||
|
if len(events) != 0 {
|
||||||
|
t.Fatal("expected to see no NetworkEvent events")
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("DialContext uses a dialer without a resolver", func(t *testing.T) {
|
t.Run("DialContext uses a dialer without a resolver", func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user