Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amir's Changes to Test Connectivity #275

Open
wants to merge 63 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
d7ed47d
Add DNS and TCP reports to test-connectivity
fortuna Sep 4, 2024
089afc6
Add DNS duration and start time
fortuna Sep 4, 2024
01d1495
Add TODOs
fortuna Sep 4, 2024
7c69351
refactor: seperate context logic into a new func
amircybersec Sep 6, 2024
bf25e49
change name setupTraceContext
amircybersec Sep 6, 2024
37cc3c5
Merge branch 'main' into fortuna-tc
fortuna Sep 6, 2024
404ef4f
Start PacketDialer
fortuna May 8, 2024
0c6446d
Add stuff
fortuna May 8, 2024
2af18be
fix: associate command typo
amircybersec Jul 2, 2024
0aa4c43
feat: impelment read/write encapsulation
amircybersec Jul 2, 2024
1d017b7
some debugging lines added
amircybersec Jul 2, 2024
291c376
test: packet dialer tests
amircybersec Jul 2, 2024
5443859
tests: with local udp echoserver and socks5 proxy
amircybersec Jul 8, 2024
47395ba
refactor: clean up
amircybersec Jul 8, 2024
c486f24
ading wrapPacketDialerWithSOCKS5
amircybersec Jul 8, 2024
b4fb6bc
registering socks5 packet dialer type
amircybersec Jul 8, 2024
866283a
update go mod/sum
amircybersec Jul 8, 2024
7a93b7e
removed logging and some improvements
amircybersec Jul 8, 2024
f0147d2
code review improvements
amircybersec Jul 10, 2024
7fc9aa6
add spec reference to udp dialer
amircybersec Jul 15, 2024
f3c2df3
feat: use slicepool + readAdress refactor
amircybersec Jul 16, 2024
ac76052
refactor: use readAdress with proxyConn in stread dialer
amircybersec Jul 16, 2024
bc74500
preallocate buffer size in read address
amircybersec Jul 16, 2024
bce576c
feat: use packet listenter interface
amircybersec Jul 18, 2024
3f6b1a7
refactor: define readAddress and use for stream and packetlogic
amircybersec Jul 18, 2024
93533ed
refactor: rename new dialer to new client
amircybersec Jul 18, 2024
0f1439a
refactor: rename new dialer to new client in stream dialer
amircybersec Jul 18, 2024
8b3127e
update wrapPacketDialerWithSOCKS5 with packet listener
amircybersec Jul 18, 2024
204175f
using bytes.NewBuffer to read from buffer + code refactor
amircybersec Jul 21, 2024
ae97fd7
testing Read Address
amircybersec Jul 21, 2024
83ee12e
defining address struct and updating readAddress
amircybersec Jul 21, 2024
1117beb
Refactor: request and remove redundant code
amircybersec Jul 21, 2024
e82c72d
use innerSD to dial for associate command
amircybersec Jul 21, 2024
d34c88f
fixing small issues in tests
amircybersec Jul 21, 2024
395a8df
tighten API with io.close use & netip.Addr
amircybersec Jul 23, 2024
5739b47
tests: make more clear and add benchmark for readAddr
amircybersec Jul 23, 2024
18266bc
use unit16 for port, netip.Addr & refactor readAddress
amircybersec Jul 23, 2024
ffffa13
tests: removed hardcoded ports & wait for server to be ready
amircybersec Jul 24, 2024
0e6f64c
fix error
amircybersec Jul 24, 2024
9d20f52
ensure addrLength is under 255
amircybersec Jul 24, 2024
c2c4354
Update transport/socks5/stream_dialer.go
amircybersec Jul 24, 2024
d87f98f
Update transport/socks5/stream_dialer.go
amircybersec Jul 24, 2024
ad1c930
Update transport/socks5/socks5_test.go
amircybersec Jul 24, 2024
371b31a
Update transport/socks5/stream_dialer.go
amircybersec Jul 24, 2024
a6b4c31
tests: use string for IPv4
amircybersec Jul 24, 2024
7155047
Update transport/socks5/packet_listener_test.go
amircybersec Jul 25, 2024
e7e3407
reverse the last change
amircybersec Jul 25, 2024
69e426f
test:removing unnecessary wait for server listening
amircybersec Jul 25, 2024
3d25b66
test:removing casting addrLength to type int
amircybersec Jul 25, 2024
f23e8cf
test:removing unnecessary wait for server listening from stream
amircybersec Jul 25, 2024
50a1b7c
ensure socks server goroutine terminates by closing the listener
amircybersec Jul 26, 2024
d3ddfd1
Use Psiphon clientlib (#252)
fortuna Jun 24, 2024
37db84b
feat: allow unencoded `userinfo` as per SIP002 (#260)
sbruens Jul 16, 2024
9f80296
Update go.mod
amircybersec Jul 26, 2024
5239364
Update go.sum
amircybersec Jul 26, 2024
d5d3070
Update go.sum
amircybersec Jul 26, 2024
1f4f317
update mod files
amircybersec Jul 26, 2024
c2f6282
check return err values
amircybersec Jul 26, 2024
58e09cf
update go.sum
amircybersec Jul 29, 2024
34e50b8
update go.mod and go.sum
amircybersec Jul 29, 2024
db46d9f
update go.mod and go.sum to @470a929
amircybersec Jul 29, 2024
6eea6fb
update doc.go for socks5
amircybersec Jul 29, 2024
20268ad
Merge branch 'fortuna-tc' into amir-tc
amircybersec Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 102 additions & 3 deletions x/examples/test-connectivity/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import (
"log"
"net"
"net/http"
"net/http/httptrace"
"net/url"
"os"
"path"
"strings"
"time"

"github.com/Jigsaw-Code/outline-sdk/dns"
"github.com/Jigsaw-Code/outline-sdk/transport"
"github.com/Jigsaw-Code/outline-sdk/x/config"
"github.com/Jigsaw-Code/outline-sdk/x/connectivity"
"github.com/Jigsaw-Code/outline-sdk/x/report"
Expand All @@ -41,6 +43,12 @@ var debugLog log.Logger = *log.New(io.Discard, "", 0)
// var errorLog log.Logger = *log.New(os.Stderr, "[ERROR] ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)

type connectivityReport struct {
Test testReport `json:"test"`
DNSQueries []dnsReport `json:"dns_queries,omitempty"`
TCPConnections []tcpReport `json:"tcp_connections,omitempty"`
}

type testReport struct {
// Inputs
Resolver string `json:"resolver"`
Proto string `json:"proto"`
Expand All @@ -53,6 +61,23 @@ type connectivityReport struct {
Error *errorJSON `json:"error"`
}

type dnsReport struct {
QueryName string `json:"query_name"`
Time time.Time `json:"time"`
DurationMs int64 `json:"duration_ms"`
AnswerIPs []string `json:"answer_ips"`
Error string `json:"error"`
}

type tcpReport struct {
Hostname string `json:"hostname"`
IP string `json:"ip"`
Port string `json:"port"`
Error string `json:"error"`
Time time.Time `json:"time"`
DurationMs int64 `json:"duration_ms"`
}

type errorJSON struct {
// TODO: add Shadowsocks/Transport error
Op string `json:"op,omitempty"`
Expand Down Expand Up @@ -84,7 +109,7 @@ func unwrapAll(err error) error {
}

func (r connectivityReport) IsSuccess() bool {
if r.Error == nil {
if r.Test.Error == nil {
return true
} else {
return false
Expand All @@ -98,6 +123,55 @@ func init() {
}
}

func getReportFromTrace(ctx context.Context, r *connectivityReport, hostname string) context.Context {
var dnsStart, connectStart time.Time
ctx = httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
DNSStart: func(di httptrace.DNSStartInfo) {
dnsStart = time.Now()
},
DNSDone: func(di httptrace.DNSDoneInfo) {
report := dnsReport{
QueryName: hostname,
Time: dnsStart.UTC().Truncate(time.Second),
DurationMs: time.Since(dnsStart).Milliseconds(),
}
if di.Err != nil {
report.Error = di.Err.Error()
}
for _, ip := range di.Addrs {
report.AnswerIPs = append(report.AnswerIPs, ip.IP.String())
}
// TODO(fortuna): Use a Mutex.
r.DNSQueries = append(r.DNSQueries, report)
},
ConnectStart: func(network, addr string) {
connectStart = time.Now()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the correct behavior. In Happy Eyeballs we can have overlapping connection attempts.

We need a map network, addr -> start time instead.

},
ConnectDone: func(network, addr string, connErr error) {
ip, port, err := net.SplitHostPort(addr)
if err != nil {
return
}
if network == "tcp" {
report := tcpReport{
Hostname: hostname,
IP: ip,
Port: port,
Time: connectStart.UTC().Truncate(time.Second),
DurationMs: time.Since(connectStart).Milliseconds(),
}
if connErr != nil {
report.Error = connErr.Error()
}
// TODO(fortuna): Use a Mutex.
r.TCPConnections = append(r.TCPConnections, report)
}
},
})

return ctx
}

func main() {
verboseFlag := flag.Bool("v", false, "Enable debug output")
transportFlag := flag.String("transport", "", "Transport config")
Expand Down Expand Up @@ -161,21 +235,44 @@ func main() {
success := false
jsonEncoder := json.NewEncoder(os.Stdout)
jsonEncoder.SetEscapeHTML(false)
configToDialer := config.NewDefaultConfigToDialer()
for _, resolverHost := range strings.Split(*resolverFlag, ",") {
resolverHost := strings.TrimSpace(resolverHost)
resolverAddress := net.JoinHostPort(resolverHost, "53")
for _, proto := range strings.Split(*protoFlag, ",") {
r := &connectivityReport{
Test: testReport{},
DNSQueries: []dnsReport{},
TCPConnections: []tcpReport{},
}
proto = strings.TrimSpace(proto)
var resolver dns.Resolver
switch proto {
case "tcp":
configToDialer := config.NewDefaultConfigToDialer()
configToDialer.BaseStreamDialer = transport.FuncStreamDialer(func(ctx context.Context, addr string) (transport.StreamConn, error) {
hostname, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
ctx = getReportFromTrace(ctx, r, hostname)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of our codes have a race condition. We need a mutex to append to the DNS queries and TCP connections.

I was imagining a different function here, one that takes callbacks with the dns and tcp reports instead, and the function can then append to whatever we need. That way the function doesn't depend on the specific report format.

BTW, it shouldn't depend on r, because the scope is too broad. It only needs the dns and tcp reports.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna yes the race condition issue stands. I was planning to do that next. I can reduce the dependency on the report format

return (&transport.TCPDialer{}).DialStream(ctx, addr)
})
streamDialer, err := configToDialer.NewStreamDialer(*transportFlag)
if err != nil {
log.Fatalf("Failed to create StreamDialer: %v", err)
}
resolver = dns.NewTCPResolver(streamDialer, resolverAddress)

case "udp":
configToDialer := config.NewDefaultConfigToDialer()
configToDialer.BasePacketDialer = transport.FuncPacketDialer(func(ctx context.Context, addr string) (net.Conn, error) {
hostname, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
ctx = getReportFromTrace(ctx, r, hostname)
return (&transport.UDPDialer{}).DialPacket(ctx, addr)
})
packetDialer, err := configToDialer.NewPacketDialer(*transportFlag)
if err != nil {
log.Fatalf("Failed to create PacketDialer: %v", err)
Expand All @@ -198,7 +295,8 @@ func main() {
if err != nil {
log.Fatalf("Failed to sanitize config: %v", err)
}
var r report.Report = connectivityReport{

r.Test = testReport{
Resolver: resolverAddress,
Proto: proto,
Time: startTime.UTC().Truncate(time.Second),
Expand All @@ -207,6 +305,7 @@ func main() {
DurationMs: testDuration.Milliseconds(),
Error: makeErrorRecord(result),
}

if reportCollector != nil {
err = reportCollector.Collect(context.Background(), r)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions x/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea h1:9C2rdYRp8Vzwhm3sbFX0yYfB+70zKFRjn7cnPCucHSw=
github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea/go.mod h1:MdyNkAe06D7xmJsf+MsLvbZKYNXuOHLKJrvw+x4LlcQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/Jigsaw-Code/outline-sdk v0.0.17-0.20240708052545-4f51b366fe75 h1:1t6cnyP4liW9hjmnVrDn6Bc5m2qlAcjPurf9UEye4Hg=
github.com/Jigsaw-Code/outline-sdk v0.0.17-0.20240708052545-4f51b366fe75/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
Expand Down