Skip to content

Commit e52d9e5

Browse files
committed
quic support
1 parent 4494db6 commit e52d9e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2896
-4786
lines changed

brooklink.go

+319
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
// Copyright (c) 2016-present Cloud <[email protected]>
2+
//
3+
// This program is free software; you can redistribute it and/or
4+
// modify it under the terms of version 3 of the GNU General Public
5+
// License as published by the Free Software Foundation.
6+
//
7+
// This program is distributed in the hope that it will be useful, but
8+
// WITHOUT ANY WARRANTY; without even the implied warranty of
9+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
// General Public License for more details.
11+
//
12+
// You should have received a copy of the GNU General Public License
13+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
14+
15+
package brook
16+
17+
import (
18+
"crypto/tls"
19+
"crypto/x509"
20+
"errors"
21+
"log"
22+
"net"
23+
"net/url"
24+
25+
"github.com/txthinking/brook/limits"
26+
crypto1 "github.com/txthinking/crypto"
27+
"github.com/txthinking/socks5"
28+
)
29+
30+
type BrookLink struct {
31+
kind string
32+
address string
33+
host string
34+
path string
35+
password []byte
36+
v url.Values
37+
tc *tls.Config
38+
39+
s5 *socks5.Server
40+
pcf *PacketConnFactory
41+
tt int
42+
ut int
43+
}
44+
45+
func NewBrookLink(link string) (*BrookLink, error) {
46+
var address, host, path string
47+
kind, server, _, password, v, err := ParseLinkExtra(link)
48+
if err != nil {
49+
return nil, err
50+
}
51+
p := []byte(password)
52+
if kind == "server" {
53+
address = server
54+
}
55+
var tc *tls.Config
56+
if kind == "wsserver" || kind == "wssserver" || kind == "quicserver" {
57+
u, err := url.Parse(server)
58+
if err != nil {
59+
return nil, err
60+
}
61+
host = u.Host
62+
path = u.Path
63+
if path == "" {
64+
path = "/ws"
65+
}
66+
address = host
67+
if v.Get("address") != "" {
68+
address = v.Get("address")
69+
}
70+
if kind == "wssserver" || kind == "quicserver" {
71+
h, _, err := net.SplitHostPort(u.Host)
72+
if err != nil {
73+
return nil, err
74+
}
75+
tc = &tls.Config{ServerName: h}
76+
if v.Get("insecure") == "true" {
77+
tc.InsecureSkipVerify = true
78+
}
79+
if v.Get("ca") != "" {
80+
roots := x509.NewCertPool()
81+
ok := roots.AppendCertsFromPEM([]byte(v.Get("ca")))
82+
if !ok {
83+
return nil, errors.New("failed to parse root certificate")
84+
}
85+
tc.RootCAs = roots
86+
}
87+
if kind == "quicserver" {
88+
tc.NextProtos = []string{"h3"}
89+
}
90+
}
91+
if v.Get("withoutBrookProtocol") == "true" {
92+
p, err = crypto1.SHA256Bytes([]byte(password))
93+
if err != nil {
94+
return nil, err
95+
}
96+
}
97+
}
98+
return &BrookLink{
99+
kind: kind,
100+
address: address,
101+
host: host,
102+
path: path,
103+
password: p,
104+
v: v,
105+
tc: tc,
106+
}, nil
107+
}
108+
109+
// The caller is responsible for closing the connection in Exchanger.
110+
func (blk *BrookLink) CreateExchanger(network, src string, dstb []byte, tcptimeout, udptimeout int) (Exchanger, error) {
111+
if blk.kind == "server" {
112+
if network == "tcp" {
113+
rc, err := DialTCP("tcp", "", blk.address)
114+
if err != nil {
115+
return nil, err
116+
}
117+
sc, err := NewStreamClient("tcp", blk.password, src, rc, tcptimeout, dstb)
118+
if err != nil {
119+
rc.Close()
120+
return nil, err
121+
}
122+
return sc, nil
123+
}
124+
if blk.v.Get("udpovertcp") == "true" {
125+
rc, err := NATDial("tcp", src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.address)
126+
if err != nil {
127+
return nil, err
128+
}
129+
sc, err := NewStreamClient("udp", blk.password, src, rc, udptimeout, dstb)
130+
if err != nil {
131+
rc.Close()
132+
return nil, err
133+
}
134+
return sc, nil
135+
}
136+
rc, err := NATDial("udp", src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.address)
137+
if err != nil {
138+
return nil, err
139+
}
140+
sc, err := NewPacketClient(blk.password, src, rc, udptimeout, dstb)
141+
if err != nil {
142+
rc.Close()
143+
return nil, err
144+
}
145+
return sc, nil
146+
}
147+
if blk.kind == "wsserver" || blk.kind == "wssserver" {
148+
if network == "tcp" {
149+
rc, err := WebSocketDial("", "", blk.address, blk.host, blk.path, blk.tc, tcptimeout)
150+
if err != nil {
151+
return nil, err
152+
}
153+
var sc Exchanger
154+
if blk.v.Get("withoutBrookProtocol") != "true" {
155+
sc, err = NewStreamClient("tcp", blk.password, src, rc, tcptimeout, dstb)
156+
}
157+
if blk.v.Get("withoutBrookProtocol") == "true" {
158+
sc, err = NewSimpleStreamClient("tcp", blk.password, src, rc, tcptimeout, dstb)
159+
}
160+
if err != nil {
161+
rc.Close()
162+
return nil, err
163+
}
164+
return sc, nil
165+
}
166+
rc, err := WebSocketDial(src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.address, blk.host, blk.path, blk.tc, tcptimeout)
167+
if err != nil {
168+
return nil, err
169+
}
170+
var sc Exchanger
171+
if blk.v.Get("withoutBrookProtocol") != "true" {
172+
sc, err = NewStreamClient("udp", blk.password, src, rc, udptimeout, dstb)
173+
}
174+
if blk.v.Get("withoutBrookProtocol") == "true" {
175+
sc, err = NewSimpleStreamClient("udp", blk.password, src, rc, udptimeout, dstb)
176+
}
177+
if err != nil {
178+
rc.Close()
179+
return nil, err
180+
}
181+
return sc, nil
182+
}
183+
if blk.kind == "quicserver" {
184+
if network == "tcp" {
185+
rc, err := QUICDialTCP("", "", blk.address, blk.host, blk.tc, tcptimeout)
186+
if err != nil {
187+
return nil, err
188+
}
189+
var sc Exchanger
190+
if blk.v.Get("withoutBrookProtocol") != "true" {
191+
sc, err = NewStreamClient("tcp", blk.password, src, rc, tcptimeout, dstb)
192+
}
193+
if blk.v.Get("withoutBrookProtocol") == "true" {
194+
sc, err = NewSimpleStreamClient("tcp", blk.password, src, rc, tcptimeout, dstb)
195+
}
196+
if err != nil {
197+
rc.Close()
198+
return nil, err
199+
}
200+
return sc, nil
201+
}
202+
rc, err := QUICDialUDP(src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.address, blk.host, blk.tc, udptimeout)
203+
if err != nil {
204+
return nil, err
205+
}
206+
var sc Exchanger
207+
if blk.v.Get("withoutBrookProtocol") != "true" {
208+
sc, err = NewPacketClient(blk.password, src, rc, udptimeout, dstb)
209+
}
210+
if blk.v.Get("withoutBrookProtocol") == "true" {
211+
sc, err = NewSimplePacketClient(blk.password, src, rc, udptimeout, dstb)
212+
}
213+
if err != nil {
214+
rc.Close()
215+
return nil, err
216+
}
217+
return sc, nil
218+
}
219+
return nil, errors.New("cannot create exchanger from " + blk.kind)
220+
}
221+
222+
func (x *BrookLink) PrepareSocks5Server(addr, ip string, tcptimeout, udptimeout int) error {
223+
var err error
224+
x.s5, err = socks5.NewClassicServer(addr, ip, "", "", tcptimeout, udptimeout)
225+
if err != nil {
226+
return err
227+
}
228+
if err := limits.Raise(); err != nil {
229+
log.Println("Try to raise system limits, got", err)
230+
}
231+
x.pcf = NewPacketConnFactory()
232+
x.tt = tcptimeout
233+
x.ut = udptimeout
234+
return nil
235+
}
236+
237+
func (x *BrookLink) ListenAndServe() error {
238+
return x.s5.ListenAndServe(x)
239+
}
240+
241+
func (x *BrookLink) TCPHandle(s *socks5.Server, c *net.TCPConn, r *socks5.Request) error {
242+
if r.Cmd == socks5.CmdConnect {
243+
dstb := append(append([]byte{r.Atyp}, r.DstAddr...), r.DstPort...)
244+
sc, err := x.CreateExchanger("tcp", c.RemoteAddr().String(), dstb, x.tt, x.ut)
245+
if err != nil {
246+
return ErrorReply(r, c, err)
247+
}
248+
defer sc.Clean()
249+
laddr := ""
250+
if v, ok := sc.(*StreamClient); ok {
251+
defer v.Server.Close()
252+
laddr = v.Server.LocalAddr().String()
253+
}
254+
if v, ok := sc.(*SimpleStreamClient); ok {
255+
defer v.Server.Close()
256+
laddr = v.Server.LocalAddr().String()
257+
}
258+
a, address, port, err := socks5.ParseAddress(laddr)
259+
if err != nil {
260+
return ErrorReply(r, c, err)
261+
}
262+
rp := socks5.NewReply(socks5.RepSuccess, a, address, port)
263+
if _, err := rp.WriteTo(c); err != nil {
264+
return err
265+
}
266+
if err := sc.Exchange(c); err != nil {
267+
return nil
268+
}
269+
return nil
270+
}
271+
if r.Cmd == socks5.CmdUDP {
272+
_, err := r.UDP(c, x.s5.ServerAddr)
273+
if err != nil {
274+
return err
275+
}
276+
return nil
277+
}
278+
return socks5.ErrUnsupportCmd
279+
}
280+
281+
func (x *BrookLink) UDPHandle(s *socks5.Server, addr *net.UDPAddr, d *socks5.Datagram) error {
282+
dstb := append(append([]byte{d.Atyp}, d.DstAddr...), d.DstPort...)
283+
conn, err := x.pcf.Handle(addr, dstb, d.Data, func(b []byte) (int, error) {
284+
d.Data = b
285+
return s.UDPConn.WriteToUDP(d.Bytes(), addr)
286+
}, x.ut)
287+
if err != nil {
288+
return err
289+
}
290+
if conn == nil {
291+
return nil
292+
}
293+
defer conn.Close()
294+
sc, err := x.CreateExchanger("udp", addr.String(), dstb, x.tt, x.ut)
295+
if err != nil {
296+
return err
297+
}
298+
defer sc.Clean()
299+
if v, ok := sc.(*PacketClient); ok {
300+
defer v.Server.Close()
301+
}
302+
if v, ok := sc.(*StreamClient); ok {
303+
defer v.Server.Close()
304+
}
305+
if v, ok := sc.(*SimplePacketClient); ok {
306+
defer v.Server.Close()
307+
}
308+
if v, ok := sc.(*SimpleStreamClient); ok {
309+
defer v.Server.Close()
310+
}
311+
if err := sc.Exchange(conn); err != nil {
312+
return nil
313+
}
314+
return nil
315+
}
316+
317+
func (x *BrookLink) Shutdown() error {
318+
return x.s5.Shutdown()
319+
}

0 commit comments

Comments
 (0)