Skip to content

Commit

Permalink
refactor(tlstool): make space for several splitting techniques
Browse files Browse the repository at this point in the history
Part of #622
  • Loading branch information
bassosimone committed Nov 11, 2020
1 parent c1b4d6f commit a7203e9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package internal
package patternsplitter

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package internal
// Package patternsplitter contains code to split TCP segments in
// the middle of a specific byte pattern.
package patternsplitter

import (
"bytes"
Expand All @@ -9,8 +11,9 @@ import (
"github.com/ooni/probe-engine/netx"
)

// SplitDialer is a dialer that splits writes according to a
// pattern and may delay the second write of delay milliseconds.
// SplitDialer is a dialer that splits TCP segments in the middle of
// a specific byte pattern and may optionally delay writing the second
// half of the segment by a specific number of milliseconds.
type SplitDialer struct {
netx.Dialer
Delay int64
Expand All @@ -26,7 +29,13 @@ func (d SplitDialer) DialContext(ctx context.Context, network, address string) (
return SplitConn{Conn: conn, Delay: d.Delay, Pattern: []byte(d.Pattern)}, nil
}

// SplitConn is a conn that splits writes.
// SplitConn is the net.Conn generated by SplitDialer.
//
// Caveat
//
// The connection will keep splitting segments when it sees the
// specified byte pattern. This behaviour is fine as long as we're
// just checking whether the TLS handshake works.
type SplitConn struct {
net.Conn
BeforeSecondWrite func() // for testing
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package internal_test
package patternsplitter_test

import (
"context"
"errors"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-engine/experiment/tlstool/internal"
"github.com/ooni/probe-engine/experiment/tlstool/internal/patternsplitter"
)

func TestSplitDialerFailure(t *testing.T) {
expected := errors.New("mocked error")
d := internal.SplitDialer{Dialer: internal.FakeDialer{Err: expected}}
d := patternsplitter.SplitDialer{Dialer: patternsplitter.FakeDialer{Err: expected}}
conn, err := d.DialContext(context.Background(), "tcp", "1.1.1.1:853")
if !errors.Is(err, expected) {
t.Fatalf("not the error we expected: %+v", err)
Expand All @@ -22,19 +22,19 @@ func TestSplitDialerFailure(t *testing.T) {
}

func TestSplitDialerSuccess(t *testing.T) {
innerconn := &internal.FakeConn{}
d := internal.SplitDialer{
Dialer: internal.FakeDialer{Conn: innerconn},
innerconn := &patternsplitter.FakeConn{}
d := patternsplitter.SplitDialer{
Dialer: patternsplitter.FakeDialer{Conn: innerconn},
Delay: 1234,
Pattern: "abcdef",
}
conn, err := d.DialContext(context.Background(), "tcp", "1.1.1.1:853")
if err != nil {
t.Fatal(err)
}
realconn, ok := conn.(internal.SplitConn)
realconn, ok := conn.(patternsplitter.SplitConn)
if !ok {
t.Fatal("cannot cast conn to internal.SplitConn")
t.Fatal("cannot cast conn to patternsplitter.SplitConn")
}
if realconn.Delay != 1234 {
t.Fatal("invalid Delay value")
Expand All @@ -52,8 +52,8 @@ func TestWriteSuccessNoSplit(t *testing.T) {
pattern = "abc.def"
data = "deadbeefdeafbeef"
)
innerconn := &internal.FakeConn{}
conn := internal.SplitConn{
innerconn := &patternsplitter.FakeConn{}
conn := patternsplitter.SplitConn{
Conn: innerconn,
Pattern: []byte(pattern),
}
Expand All @@ -78,10 +78,10 @@ func TestWriteFailureNoSplit(t *testing.T) {
data = "deadbeefdeafbeef"
)
expected := errors.New("mocked error")
innerconn := &internal.FakeConn{
innerconn := &patternsplitter.FakeConn{
WriteError: expected,
}
conn := internal.SplitConn{
conn := patternsplitter.SplitConn{
Conn: innerconn,
Pattern: []byte(pattern),
}
Expand All @@ -99,8 +99,8 @@ func TestWriteSuccessSplit(t *testing.T) {
pattern = "abc.def"
data = "deadbeefabc.defdeafbeef"
)
innerconn := &internal.FakeConn{}
conn := internal.SplitConn{
innerconn := &patternsplitter.FakeConn{}
conn := patternsplitter.SplitConn{
Conn: innerconn,
Pattern: []byte(pattern),
}
Expand Down Expand Up @@ -128,10 +128,10 @@ func TestWriteFailureSplitFirstWrite(t *testing.T) {
data = "deadbeefabc.defdeafbeef"
)
expected := errors.New("mocked error")
innerconn := &internal.FakeConn{
innerconn := &patternsplitter.FakeConn{
WriteError: expected,
}
conn := internal.SplitConn{
conn := patternsplitter.SplitConn{
Conn: innerconn,
Pattern: []byte(pattern),
}
Expand All @@ -153,8 +153,8 @@ func TestWriteFailureSplitSecondWrite(t *testing.T) {
data = "deadbeefabc.defdeafbeef"
)
expected := errors.New("mocked error")
innerconn := &internal.FakeConn{}
conn := internal.SplitConn{
innerconn := &patternsplitter.FakeConn{}
conn := patternsplitter.SplitConn{
BeforeSecondWrite: func() {
innerconn.WriteError = expected // second write will then fail
},
Expand Down
16 changes: 8 additions & 8 deletions experiment/tlstool/tlstool.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"fmt"
"net"

"github.com/ooni/probe-engine/experiment/tlstool/internal"
"github.com/ooni/probe-engine/experiment/tlstool/internal/patternsplitter"
"github.com/ooni/probe-engine/internal/runtimex"
"github.com/ooni/probe-engine/model"
"github.com/ooni/probe-engine/netx"
Expand All @@ -29,13 +29,13 @@ const (
// Config contains the experiment configuration.
type Config struct {
Delay int64 `ooni:"Milliseconds to wait between writes"`
SNI string `ooni:"Set the specified SNI"`
SNI string `ooni:"Force using the specified SNI"`
}

// TestKeys contains the experiment results.
type TestKeys struct {
VanillaFailure *string `json:"vanilla_failure"`
SplitFailure *string `json:"split_failure"`
VanillaFailure *string `json:"vanilla_failure"`
SNISplitFailure *string `json:"sni_split_failure"`
}

// Measurer performs the measurement.
Expand Down Expand Up @@ -66,9 +66,9 @@ func (m Measurer) Run(
err := m.vanillaRun(ctx, sess.Logger(), address)
callbacks.OnProgress(0.5, fmt.Sprintf("vanilla: %+v", err))
tk.VanillaFailure = archival.NewFailure(err)
err = m.splitRun(ctx, sess.Logger(), address)
err = m.sniSplitRun(ctx, sess.Logger(), address)
callbacks.OnProgress(1.0, fmt.Sprintf("split: %+v", err))
tk.SplitFailure = archival.NewFailure(err)
tk.SNISplitFailure = archival.NewFailure(err)
return nil
}

Expand Down Expand Up @@ -96,8 +96,8 @@ func (m Measurer) vanillaRun(ctx context.Context, logger model.Logger, address s
return nil
}

func (m Measurer) splitRun(ctx context.Context, logger model.Logger, address string) error {
dialer := &internal.SplitDialer{
func (m Measurer) sniSplitRun(ctx context.Context, logger model.Logger, address string) error {
dialer := &patternsplitter.SplitDialer{
Dialer: m.newDialer(logger),
Delay: m.config.Delay,
Pattern: m.pattern(address),
Expand Down

0 comments on commit a7203e9

Please sign in to comment.