This repository has been archived by the owner on May 22, 2020. It is now read-only.
/
dialer.go
77 lines (68 loc) · 2.41 KB
/
dialer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package tapdance
import (
"context"
"net"
)
var sessionsTotal CounterUint64
// Dialer contains options and implements advanced functions for establishing TapDance connection.
type Dialer struct {
SplitFlows bool
TcpDialer func(context.Context, string, string) (net.Conn, error)
}
// Dial connects to the address on the named network.
//
// The only supported network at this time: "tcp".
// The address has the form "host:port".
// The host must be a literal IP address, or a host name that can be
// resolved to IP addresses.
// To avoid abuse, only certain whitelisted ports are allowed.
//
// Example: Dial("tcp", "golang.org:80")
func Dial(network, address string) (net.Conn, error) {
var d Dialer
return d.Dial(network, address)
}
// Dial connects to the address on the named network.
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
return d.DialContext(context.Background(), network, address)
}
// DialContext connects to the address on the named network using the provided context.
// Long deadline is strongly advised, since tapdance will try multiple decoys.
//
// The only supported network at this time: "tcp".
// The address has the form "host:port".
// The host must be a literal IP address, or a host name that can be
// resolved to IP addresses.
// To avoid abuse, only certain whitelisted ports are allowed.
//
// Example: Dial("tcp", "golang.org:80")
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
if network != "tcp" {
return nil, &net.OpError{Op: "dial", Net: network, Err: net.UnknownNetworkError(network)}
}
if len(address) > 0 {
_, _, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
}
if !d.SplitFlows {
flow, err := makeTdFlow(flowBidirectional, nil, address)
if err != nil {
return nil, err
}
flow.tdRaw.TcpDialer = d.TcpDialer
return flow, flow.DialContext(ctx)
}
return dialSplitFlow(ctx, d.TcpDialer, address)
}
// DialProxy establishes direct connection to TapDance station proxy.
// Users are expected to send HTTP CONNECT request next.
func (d *Dialer) DialProxy() (net.Conn, error) {
return d.DialProxyContext(context.Background())
}
// DialProxy establishes direct connection to TapDance station proxy using the provided context.
// Users are expected to send HTTP CONNECT request next.
func (d *Dialer) DialProxyContext(ctx context.Context) (net.Conn, error) {
return d.DialContext(ctx, "tcp", "")
}