-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathdirectproxy.go
147 lines (130 loc) · 3.76 KB
/
directproxy.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
141
142
143
144
145
146
147
package proxyclient
import (
"net"
"errors"
"fmt"
"strings"
"time"
)
type DirectTCPConn struct {
net.TCPConn
proxyClient ProxyClient
}
type DirectUDPConn struct {
net.UDPConn
proxyClient ProxyClient
}
type directProxyClient struct {
TCPLocalAddr net.TCPAddr
UDPLocalAddr net.UDPAddr
query map[string][]string
}
// 创建代理客户端
// 直连 direct://0.0.0.0:0000/?LocalAddr=123.123.123.123:0
func NewDriectProxyClient(localAddr string, query map[string][]string) (ProxyClient, error) {
if localAddr == "" {
localAddr = "0.0.0.0:0"
}
tcpAddr, err := net.ResolveTCPAddr("tcp", localAddr)
if err != nil {
return nil, errors.New("LocalAddr 错误的格式")
}
udpAddr, err := net.ResolveUDPAddr("udp", localAddr)
if err != nil {
return nil, errors.New("LocalAddr 错误的格式")
}
return &directProxyClient{*tcpAddr, *udpAddr, query}, nil
}
func (p *directProxyClient) Dial(network, address string) (net.Conn, error) {
if strings.HasPrefix(network, "tcp") {
addr, err := net.ResolveTCPAddr(network, address)
if err != nil {
return nil, fmt.Errorf("地址解析错误:%v", err)
}
return p.DialTCP(network, &p.TCPLocalAddr, addr)
} else if strings.HasPrefix(network, "udp") {
addr, err := net.ResolveUDPAddr(network, address)
if err != nil {
return nil, fmt.Errorf("地址解析错误:%v", err)
}
return p.DialUDP(network, &p.UDPLocalAddr, addr)
} else {
return nil, errors.New("未知的 network 类型。")
}
}
func (p *directProxyClient) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
switch network {
case "tcp", "tcp4", "tcp6":
case "udp", "udp4", "udp6":
default:
return nil, fmt.Errorf("不支持的 network 类型:%v", network)
}
d := net.Dialer{Timeout:timeout, LocalAddr:&p.TCPLocalAddr}
conn, err := d.Dial(network, address)
if err != nil {
return nil, err
}
switch conn := conn.(type) {
case *net.TCPConn:
return &DirectTCPConn{*conn, p}, nil
case *net.UDPConn:
return &DirectUDPConn{*conn, p}, nil
default:
return nil, fmt.Errorf("内部错误:未知的连接类型。")
}
}
func (p *directProxyClient) DialTCP(network string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
if laddr == nil {
laddr = &p.TCPLocalAddr
}
conn, err := net.DialTCP(network, laddr, raddr)
if err != nil {
return nil, err
}
return &DirectTCPConn{*conn, p}, nil
}
func (p *directProxyClient)DialTCPSAddr(network string, raddr string) (ProxyTCPConn, error) {
return p.DialTCPSAddrTimeout(network, raddr, 0)
}
// DialTCPSAddrTimeout 同 DialTCPSAddr 函数,增加了超时功能
func (p *directProxyClient)DialTCPSAddrTimeout(network string, raddr string, timeout time.Duration) (rconn ProxyTCPConn, rerr error) {
switch network {
case "tcp", "tcp4", "tcp6":
default:
return nil, fmt.Errorf("不支持的 network 类型:%v", network)
}
d := net.Dialer{Timeout:timeout, LocalAddr:&p.TCPLocalAddr}
conn, err := d.Dial(network, raddr)
if err != nil {
return nil, err
}
if tcpConn, ok := conn.(*net.TCPConn); ok {
return &DirectTCPConn{*tcpConn, p}, nil
}
return nil, fmt.Errorf("内部错误")
}
func (p *directProxyClient) DialUDP(network string, laddr, raddr *net.UDPAddr) (net.Conn, error) {
if laddr == nil {
laddr = &p.UDPLocalAddr
}
conn, err := net.DialUDP(network, laddr, raddr)
if err != nil {
return nil, err
}
return &DirectUDPConn{*conn, p}, nil
}
func (p *directProxyClient) UpProxy() ProxyClient {
return nil
}
func (p *directProxyClient) SetUpProxy(upProxy ProxyClient) error {
return errors.New("直连不支持上层代理。")
}
func (c *DirectTCPConn) ProxyClient() ProxyClient {
return c.proxyClient
}
func (c *DirectUDPConn) ProxyClient() ProxyClient {
return c.proxyClient
}
func (c *directProxyClient)GetProxyAddrQuery() map[string][]string {
return c.query
}