forked from lightningnetwork/lnd
-
Notifications
You must be signed in to change notification settings - Fork 24
/
net.go
140 lines (114 loc) · 4.43 KB
/
net.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package tor
import (
"context"
"errors"
"net"
"time"
)
// TODO: this interface and its implementations should ideally be moved
// elsewhere as they are not Tor-specific.
const (
// DefaultConnTimeout is the maximum amount of time a dial will wait for
// a connect to complete.
DefaultConnTimeout time.Duration = time.Second * 120
)
// DialFunc is a type defines the signature of a dialer used by our Net
// interface.
type DialFunc func(net, addr string, timeout time.Duration) (net.Conn, error)
// Net is an interface housing a Dial function and several DNS functions that
// allows us to abstract the implementations of these functions over different
// networks, e.g. clearnet, Tor net, etc.
type Net interface {
// Dial connects to the address on the named network.
Dial(network, address string, timeout time.Duration) (net.Conn, error)
// LookupHost performs DNS resolution on a given host and returns its
// addresses.
LookupHost(host string) ([]string, error)
// LookupSRV tries to resolve an SRV query of the given service,
// protocol, and domain name.
LookupSRV(service, proto, name string,
timeout time.Duration) (string, []*net.SRV, error)
// ResolveTCPAddr resolves TCP addresses.
ResolveTCPAddr(network, address string) (*net.TCPAddr, error)
}
// ClearNet is an implementation of the Net interface that defines behaviour
// for regular network connections.
type ClearNet struct{}
// Dial on the regular network uses net.Dial
func (r *ClearNet) Dial(
network, address string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout(network, address, timeout)
}
// LookupHost for regular network uses the net.LookupHost function
func (r *ClearNet) LookupHost(host string) ([]string, error) {
return net.LookupHost(host)
}
// LookupSRV for regular network uses net.LookupSRV function
func (r *ClearNet) LookupSRV(service, proto, name string,
timeout time.Duration) (string, []*net.SRV, error) {
// Create a context with a timeout value.
ctxt, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
return net.DefaultResolver.LookupSRV(ctxt, service, proto, name)
}
// ResolveTCPAddr for regular network uses net.ResolveTCPAddr function
func (r *ClearNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) {
return net.ResolveTCPAddr(network, address)
}
// ProxyNet is an implementation of the Net interface that defines behavior
// for Tor network connections.
type ProxyNet struct {
// SOCKS is the host:port which Tor's exposed SOCKS5 proxy is listening
// on.
SOCKS string
// DNS is the host:port of the DNS server for Tor to use for SRV
// queries.
DNS string
// StreamIsolation is a bool that determines if we should force the
// creation of a new circuit for this connection. If true, then this
// means that our traffic may be harder to correlate as each connection
// will now use a distinct circuit.
StreamIsolation bool
// SkipProxyForClearNetTargets allows the proxy network to use direct
// connections to non-onion service targets. If enabled, the node IP
// address will be revealed while communicating with such targets.
SkipProxyForClearNetTargets bool
}
// Dial uses the Tor Dial function in order to establish connections through
// Tor. Since Tor only supports TCP connections, only TCP networks are allowed.
func (p *ProxyNet) Dial(network, address string,
timeout time.Duration) (net.Conn, error) {
switch network {
case "tcp", "tcp4", "tcp6":
default:
return nil, errors.New("cannot dial non-tcp network via Tor")
}
return Dial(
address, p.SOCKS, p.StreamIsolation,
p.SkipProxyForClearNetTargets, timeout,
)
}
// LookupHost uses the Tor LookupHost function in order to resolve hosts over
// Tor.
func (p *ProxyNet) LookupHost(host string) ([]string, error) {
return LookupHost(host, p.SOCKS)
}
// LookupSRV uses the Tor LookupSRV function in order to resolve SRV DNS queries
// over Tor.
func (p *ProxyNet) LookupSRV(service, proto,
name string, timeout time.Duration) (string, []*net.SRV, error) {
return LookupSRV(
service, proto, name, p.SOCKS, p.DNS, p.StreamIsolation,
p.SkipProxyForClearNetTargets, timeout,
)
}
// ResolveTCPAddr uses the Tor ResolveTCPAddr function in order to resolve TCP
// addresses over Tor.
func (p *ProxyNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) {
switch network {
case "tcp", "tcp4", "tcp6":
default:
return nil, errors.New("cannot dial non-tcp network via Tor")
}
return ResolveTCPAddr(address, p.SOCKS)
}