mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 09:25:41 +08:00
pool: added bufio.Reader pool
This commit is contained in:
parent
c15c55fe05
commit
417ac556f7
44
README.md
44
README.md
@ -44,28 +44,28 @@ we can set up local listeners as proxy servers, and forward requests to internet
|
|||||||
<summary>click to see details</summary>
|
<summary>click to see details</summary>
|
||||||
|
|
||||||
|Protocol | Listen/TCP | Listen/UDP | Forward/TCP | Forward/UDP | Description
|
|Protocol | Listen/TCP | Listen/UDP | Forward/TCP | Forward/UDP | Description
|
||||||
|:-: |:-:|:-:|:-:|:-:|:-
|
|:- |:-:|:-:|:-:|:-:|:-
|
||||||
|mixed |√|√| | |http+socks5 server
|
|Mixed |√|√| | |http+socks5 server
|
||||||
|http |√| |√| |client & server
|
|HTTP |√| |√| |client & server
|
||||||
|socks5 |√|√|√|√|client & server
|
|SOCKS5 |√|√|√|√|client & server
|
||||||
|ss |√|√|√|√|client & server
|
|SS |√|√|√|√|client & server
|
||||||
|trojan |√|√|√|√|client & server
|
|Trojan |√|√|√|√|client & server
|
||||||
|trojanc |√|√|√|√|trojan cleartext(without tls)
|
|Trojanc |√|√|√|√|trojan cleartext(without tls)
|
||||||
|vless |√|√|√|√|client & server
|
|VLESS |√|√|√|√|client & server
|
||||||
|vmess | | |√| |client only
|
|VMess | | |√| |client only
|
||||||
|ssr | | |√| |client only
|
|SSR | | |√| |client only
|
||||||
|ssh | | |√| |client only
|
|SSH | | |√| |client only
|
||||||
|socks4 | | |√| |client only
|
|SOCKS4 | | |√| |client only
|
||||||
|tls |√| |√| |transport client & server
|
|TLS |√| |√| |transport client & server
|
||||||
|kcp | |√|√| |transport client & server
|
|KCP | |√|√| |transport client & server
|
||||||
|unix |√| |√| |transport client & server
|
|Unix |√| |√| |transport client & server
|
||||||
|websocket |√| |√| |transport client & server
|
|Websocket |√| |√| |transport client & server
|
||||||
|simple-obfs | | |√| |transport client only
|
|Simple-Obfs | | |√| |transport client only
|
||||||
|tcptun |√| | | |transport server only
|
|TCPTun |√| | | |transport server only
|
||||||
|udptun | |√| | |transport server only
|
|UDPTun | |√| | |transport server only
|
||||||
|redir |√| | | |linux only
|
|Redir |√| | | |linux only
|
||||||
|redir6 |√| | | |linux only(ipv6)
|
|Redir6 |√| | | |linux only(ipv6)
|
||||||
|reject | | |√|√|reject all requests
|
|Reject | | |√|√|reject all requests
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -278,8 +278,8 @@ func (c *Client) AddRecord(record string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wb := pool.GetWriteBuffer()
|
wb := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(wb)
|
defer pool.PutBytesBuffer(wb)
|
||||||
|
|
||||||
_, err = m.MarshalTo(wb)
|
_, err = m.MarshalTo(wb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
6
go.mod
6
go.mod
@ -14,9 +14,9 @@ require (
|
|||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/xtaci/kcp-go/v5 v5.6.1
|
github.com/xtaci/kcp-go/v5 v5.6.1
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||||
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c // indirect
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect
|
||||||
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 // indirect
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 // indirect
|
||||||
golang.org/x/tools v0.0.0-20201029135353-690a3c245f28 // indirect
|
golang.org/x/tools v0.0.0-20201102212025-f46e4245211d // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
12
go.sum
12
go.sum
@ -97,8 +97,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c h1:rpcgRPA7OvNEOdprt2Wx8/Re2cBTd8NPo/lvo3AyMqk=
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
|
||||||
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -116,8 +116,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM=
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||||
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -125,8 +125,8 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201029135353-690a3c245f28 h1:KmEPH4S/AVTMSlbgNWC4xKvfsqvw/dNDUo/bGDqbDdo=
|
golang.org/x/tools v0.0.0-20201102212025-f46e4245211d h1:qbdJV2Z36oENmeAcKxD4qJx1FRdKoCzNewsdABS63dY=
|
||||||
golang.org/x/tools v0.0.0-20201029135353-690a3c245f28/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201102212025-f46e4245211d/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
24
pool/bufreader.go
Normal file
24
pool/bufreader.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var bufReaderPool sync.Pool
|
||||||
|
|
||||||
|
// GetBufReader returns a *bufio.Reader from pool.
|
||||||
|
func GetBufReader(r io.Reader) *bufio.Reader {
|
||||||
|
if v := bufReaderPool.Get(); v != nil {
|
||||||
|
br := v.(*bufio.Reader)
|
||||||
|
br.Reset(r)
|
||||||
|
return br
|
||||||
|
}
|
||||||
|
return bufio.NewReader(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutBufReader puts a *bufio.Reader into pool.
|
||||||
|
func PutBufReader(br *bufio.Reader) {
|
||||||
|
bufReaderPool.Put(br)
|
||||||
|
}
|
25
pool/bytesbuffer.go
Normal file
25
pool/bytesbuffer.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var bytesBufPool = sync.Pool{
|
||||||
|
New: func() interface{} { return &bytes.Buffer{} },
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBytesBuffer returns a bytes.buffer from pool.
|
||||||
|
func GetBytesBuffer() *bytes.Buffer {
|
||||||
|
return bytesBufPool.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutBytesBuffer puts a bytes.buffer into pool.
|
||||||
|
func PutBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
if buf.Cap() > 64<<10 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
bytesBufPool.Put(buf)
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
package pool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var writeBufPool = sync.Pool{
|
|
||||||
New: func() interface{} { return &bytes.Buffer{} },
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetWriteBuffer returns a bytes.buffer from pool.
|
|
||||||
func GetWriteBuffer() *bytes.Buffer {
|
|
||||||
return writeBufPool.Get().(*bytes.Buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutWriteBuffer puts a bytes.buffer into pool.
|
|
||||||
func PutWriteBuffer(buf *bytes.Buffer) {
|
|
||||||
if buf.Cap() > 64<<10 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.Reset()
|
|
||||||
writeBufPool.Put(buf)
|
|
||||||
}
|
|
@ -32,7 +32,7 @@ func NewConn(c net.Conn) *Conn {
|
|||||||
if conn, ok := c.(*Conn); ok {
|
if conn, ok := c.(*Conn); ok {
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
return &Conn{bufio.NewReader(c), c}
|
return &Conn{pool.GetBufReader(c), c}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader returns the internal bufio.Reader.
|
// Reader returns the internal bufio.Reader.
|
||||||
@ -73,6 +73,11 @@ func Relay(left, right net.Conn) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Close() error {
|
||||||
|
pool.PutBufReader(c.r)
|
||||||
|
return c.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
// Copy copies from src to dst.
|
// Copy copies from src to dst.
|
||||||
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
|
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||||
dst = underlyingWriter(dst)
|
dst = underlyingWriter(dst)
|
||||||
|
@ -32,7 +32,7 @@ func (s *HTTP) Dial(network, addr string) (net.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
buf.WriteString("CONNECT " + addr + " HTTP/1.1\r\n")
|
buf.WriteString("CONNECT " + addr + " HTTP/1.1\r\n")
|
||||||
buf.WriteString("Host: " + addr + "\r\n")
|
buf.WriteString("Host: " + addr + "\r\n")
|
||||||
buf.WriteString("Proxy-Connection: Keep-Alive\r\n")
|
buf.WriteString("Proxy-Connection: Keep-Alive\r\n")
|
||||||
@ -45,7 +45,7 @@ func (s *HTTP) Dial(network, addr string) (net.Conn, error) {
|
|||||||
// header ended
|
// header ended
|
||||||
buf.WriteString("\r\n")
|
buf.WriteString("\r\n")
|
||||||
_, err = rc.Write(buf.Bytes())
|
_, err = rc.Write(buf.Bytes())
|
||||||
pool.PutWriteBuffer(buf)
|
pool.PutBytesBuffer(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -114,8 +113,8 @@ func (s *HTTP) servHTTP(req *request, c *proxy.Conn) {
|
|||||||
}
|
}
|
||||||
defer rc.Close()
|
defer rc.Close()
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
// send request to remote server
|
// send request to remote server
|
||||||
req.WriteBuf(buf)
|
req.WriteBuf(buf)
|
||||||
@ -133,7 +132,9 @@ func (s *HTTP) servHTTP(req *request, c *proxy.Conn) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
r := bufio.NewReader(rc)
|
r := pool.GetBufReader(rc)
|
||||||
|
defer pool.PutBufReader(r)
|
||||||
|
|
||||||
tpr := textproto.NewReader(r)
|
tpr := textproto.NewReader(r)
|
||||||
line, err := tpr.ReadLine()
|
line, err := tpr.ReadLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,8 +43,8 @@ func (p *HTTPObfs) NewConn(c net.Conn) (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HTTPObfsConn) writeHeader() (int, error) {
|
func (c *HTTPObfsConn) writeHeader() (int, error) {
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.WriteString("GET " + c.obfsURI + " HTTP/1.1\r\n")
|
buf.WriteString("GET " + c.obfsURI + " HTTP/1.1\r\n")
|
||||||
buf.WriteString("Host: " + c.obfsHost + "\r\n")
|
buf.WriteString("Host: " + c.obfsHost + "\r\n")
|
||||||
|
@ -42,18 +42,13 @@ type TLSObfsConn struct {
|
|||||||
net.Conn
|
net.Conn
|
||||||
reqSent bool
|
reqSent bool
|
||||||
reader *bufio.Reader
|
reader *bufio.Reader
|
||||||
buf []byte
|
buf [lenSize]byte
|
||||||
leftBytes int
|
leftBytes int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConn returns a new obfs connection
|
// NewConn returns a new obfs connection
|
||||||
func (p *TLSObfs) NewConn(c net.Conn) (net.Conn, error) {
|
func (p *TLSObfs) NewConn(c net.Conn) (net.Conn, error) {
|
||||||
cc := &TLSObfsConn{
|
cc := &TLSObfsConn{Conn: c, TLSObfs: p}
|
||||||
Conn: c,
|
|
||||||
TLSObfs: p,
|
|
||||||
buf: make([]byte, lenSize),
|
|
||||||
}
|
|
||||||
|
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +58,8 @@ func (c *TLSObfsConn) Write(b []byte) (int, error) {
|
|||||||
return c.handshake(b)
|
return c.handshake(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
n := len(b)
|
n := len(b)
|
||||||
for i := 0; i < n; i += chunkSize {
|
for i := 0; i < n; i += chunkSize {
|
||||||
@ -128,10 +123,18 @@ func (c *TLSObfsConn) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *TLSObfsConn) handshake(b []byte) (int, error) {
|
func (c *TLSObfsConn) handshake(b []byte) (int, error) {
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
|
bufExt := pool.GetBytesBuffer()
|
||||||
|
defer pool.PutBytesBuffer(bufExt)
|
||||||
|
|
||||||
|
bufHello := pool.GetBytesBuffer()
|
||||||
|
defer pool.PutBytesBuffer(bufHello)
|
||||||
|
|
||||||
// prepare extension & clientHello content
|
// prepare extension & clientHello content
|
||||||
bufExt, bufHello := extension(b, c.obfsHost), clientHello()
|
extension(b, c.obfsHost, bufExt)
|
||||||
|
clientHello(bufHello)
|
||||||
|
|
||||||
// prepare lengths
|
// prepare lengths
|
||||||
extLen := bufExt.Len()
|
extLen := bufExt.Len()
|
||||||
@ -166,7 +169,7 @@ func (c *TLSObfsConn) handshake(b []byte) (int, error) {
|
|||||||
buf.Write(bufExt.Bytes())
|
buf.Write(bufExt.Bytes())
|
||||||
|
|
||||||
_, err := c.Conn.Write(buf.Bytes())
|
_, err := c.Conn.Write(buf.Bytes())
|
||||||
pool.PutWriteBuffer(buf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -174,9 +177,7 @@ func (c *TLSObfsConn) handshake(b []byte) (int, error) {
|
|||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func clientHello() *bytes.Buffer {
|
func clientHello(buf *bytes.Buffer) {
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
// Version: TLS 1.2 (0x0303)
|
// Version: TLS 1.2 (0x0303)
|
||||||
buf.Write([]byte{0x03, 0x03})
|
buf.Write([]byte{0x03, 0x03})
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ func clientHello() *bytes.Buffer {
|
|||||||
// clients do not send current time, and server do not check it,
|
// clients do not send current time, and server do not check it,
|
||||||
// golang tls client and chrome browser send random bytes instead.
|
// golang tls client and chrome browser send random bytes instead.
|
||||||
//
|
//
|
||||||
binary.Write(&buf, binary.BigEndian, uint32(time.Now().Unix()))
|
binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
|
||||||
random := make([]byte, 28)
|
random := make([]byte, 28)
|
||||||
// The above 2 lines of codes was added to make it compatible with some server implementation,
|
// The above 2 lines of codes was added to make it compatible with some server implementation,
|
||||||
// if we don't need the compatibility, just use the following code instead.
|
// if we don't need the compatibility, just use the following code instead.
|
||||||
@ -205,7 +206,7 @@ func clientHello() *bytes.Buffer {
|
|||||||
|
|
||||||
// https://github.com/shadowsocks/simple-obfs/blob/7659eeccf473aa41eb294e92c32f8f60a8747325/src/obfs_tls.c#L57
|
// https://github.com/shadowsocks/simple-obfs/blob/7659eeccf473aa41eb294e92c32f8f60a8747325/src/obfs_tls.c#L57
|
||||||
// Cipher Suites Length: 56
|
// Cipher Suites Length: 56
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(56))
|
binary.Write(buf, binary.BigEndian, uint16(56))
|
||||||
// Cipher Suites (28 suites)
|
// Cipher Suites (28 suites)
|
||||||
buf.Write([]byte{
|
buf.Write([]byte{
|
||||||
0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f,
|
0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f,
|
||||||
@ -218,56 +219,50 @@ func clientHello() *bytes.Buffer {
|
|||||||
buf.WriteByte(0x01)
|
buf.WriteByte(0x01)
|
||||||
// Compression Methods (1 method)
|
// Compression Methods (1 method)
|
||||||
buf.WriteByte(0x00)
|
buf.WriteByte(0x00)
|
||||||
|
|
||||||
return &buf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func extension(b []byte, server string) *bytes.Buffer {
|
func extension(b []byte, server string, buf *bytes.Buffer) {
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
// Extension: SessionTicket TLS
|
// Extension: SessionTicket TLS
|
||||||
buf.Write([]byte{0x00, 0x23}) // type
|
buf.Write([]byte{0x00, 0x23}) // type
|
||||||
// NOTE: send some data in sessionticket, the server will treat it as data too
|
// NOTE: send some data in sessionticket, the server will treat it as data too
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(len(b))) // length
|
binary.Write(buf, binary.BigEndian, uint16(len(b))) // length
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
||||||
// Extension: server_name
|
// Extension: server_name
|
||||||
buf.Write([]byte{0x00, 0x00}) // type
|
buf.Write([]byte{0x00, 0x00}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(len(server)+5)) // length
|
binary.Write(buf, binary.BigEndian, uint16(len(server)+5)) // length
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(len(server)+3)) // Server Name list length
|
binary.Write(buf, binary.BigEndian, uint16(len(server)+3)) // Server Name list length
|
||||||
buf.WriteByte(0x00) // Server Name Type: host_name (0)
|
buf.WriteByte(0x00) // Server Name Type: host_name (0)
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(len(server))) // Server Name length
|
binary.Write(buf, binary.BigEndian, uint16(len(server))) // Server Name length
|
||||||
buf.WriteString(server)
|
buf.WriteString(server)
|
||||||
|
|
||||||
// https://github.com/shadowsocks/simple-obfs/blob/7659eeccf473aa41eb294e92c32f8f60a8747325/src/obfs_tls.c#L88
|
// https://github.com/shadowsocks/simple-obfs/blob/7659eeccf473aa41eb294e92c32f8f60a8747325/src/obfs_tls.c#L88
|
||||||
// Extension: ec_point_formats (len=4)
|
// Extension: ec_point_formats (len=4)
|
||||||
buf.Write([]byte{0x00, 0x0b}) // type
|
buf.Write([]byte{0x00, 0x0b}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(4)) // length
|
binary.Write(buf, binary.BigEndian, uint16(4)) // length
|
||||||
buf.WriteByte(0x03) // format length
|
buf.WriteByte(0x03) // format length
|
||||||
buf.Write([]byte{0x01, 0x00, 0x02})
|
buf.Write([]byte{0x01, 0x00, 0x02})
|
||||||
|
|
||||||
// Extension: supported_groups (len=10)
|
// Extension: supported_groups (len=10)
|
||||||
buf.Write([]byte{0x00, 0x0a}) // type
|
buf.Write([]byte{0x00, 0x0a}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(10)) // length
|
binary.Write(buf, binary.BigEndian, uint16(10)) // length
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(8)) // Supported Groups List Length: 8
|
binary.Write(buf, binary.BigEndian, uint16(8)) // Supported Groups List Length: 8
|
||||||
buf.Write([]byte{0x00, 0x1d, 0x00, 0x17, 0x00, 0x19, 0x00, 0x18})
|
buf.Write([]byte{0x00, 0x1d, 0x00, 0x17, 0x00, 0x19, 0x00, 0x18})
|
||||||
|
|
||||||
// Extension: signature_algorithms (len=32)
|
// Extension: signature_algorithms (len=32)
|
||||||
buf.Write([]byte{0x00, 0x0d}) // type
|
buf.Write([]byte{0x00, 0x0d}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(32)) // length
|
binary.Write(buf, binary.BigEndian, uint16(32)) // length
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(30)) // Signature Hash Algorithms Length: 30
|
binary.Write(buf, binary.BigEndian, uint16(30)) // Signature Hash Algorithms Length: 30
|
||||||
buf.Write([]byte{
|
buf.Write([]byte{
|
||||||
0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02,
|
0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02,
|
||||||
0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
|
0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Extension: encrypt_then_mac (len=0)
|
// Extension: encrypt_then_mac (len=0)
|
||||||
buf.Write([]byte{0x00, 0x16}) // type
|
buf.Write([]byte{0x00, 0x16}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(0)) // length
|
binary.Write(buf, binary.BigEndian, uint16(0)) // length
|
||||||
|
|
||||||
// Extension: extended_master_secret (len=0)
|
// Extension: extended_master_secret (len=0)
|
||||||
buf.Write([]byte{0x00, 0x17}) // type
|
buf.Write([]byte{0x00, 0x17}) // type
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(0)) // length
|
binary.Write(buf, binary.BigEndian, uint16(0)) // length
|
||||||
|
|
||||||
return &buf
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server interface
|
// Server interface.
|
||||||
type Server interface {
|
type Server interface {
|
||||||
// ListenAndServe sets up a listener and serve on it
|
// ListenAndServe sets up a listener and serve on it
|
||||||
ListenAndServe()
|
ListenAndServe()
|
||||||
@ -15,20 +15,20 @@ type Server interface {
|
|||||||
Serve(c net.Conn)
|
Serve(c net.Conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerCreator is a function to create proxy servers
|
// ServerCreator is a function to create proxy servers.
|
||||||
type ServerCreator func(s string, proxy Proxy) (Server, error)
|
type ServerCreator func(s string, proxy Proxy) (Server, error)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serverCreators = make(map[string]ServerCreator)
|
serverCreators = make(map[string]ServerCreator)
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterServer is used to register a proxy server
|
// RegisterServer is used to register a proxy server.
|
||||||
func RegisterServer(name string, c ServerCreator) {
|
func RegisterServer(name string, c ServerCreator) {
|
||||||
serverCreators[strings.ToLower(name)] = c
|
serverCreators[strings.ToLower(name)] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerFromURL calls the registered creator to create proxy servers
|
// ServerFromURL calls the registered creator to create proxy servers.
|
||||||
// dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function
|
// dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function.
|
||||||
func ServerFromURL(s string, p Proxy) (Server, error) {
|
func ServerFromURL(s string, p Proxy) (Server, error) {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return nil, errors.New("ServerFromURL: dialer cannot be nil")
|
return nil, errors.New("ServerFromURL: dialer cannot be nil")
|
||||||
|
@ -97,8 +97,8 @@ func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
|||||||
return pc.PacketConn.WriteTo(b, addr)
|
return pc.PacketConn.WriteTo(b, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.Write([]byte{0, 0, 0})
|
buf.Write([]byte{0, 0, 0})
|
||||||
tgtLen, _ := buf.Write(pc.tgtAddr)
|
tgtLen, _ := buf.Write(pc.tgtAddr)
|
||||||
|
@ -67,8 +67,8 @@ func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
|||||||
return pc.PacketConn.WriteTo(b, addr)
|
return pc.PacketConn.WriteTo(b, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
tgtLen, _ := buf.Write(pc.tgtAddr)
|
tgtLen, _ := buf.Write(pc.tgtAddr)
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
@ -44,16 +44,16 @@ func NewSSTCPConn(c net.Conn, cipher *cipher.StreamCipher) *SSTCPConn {
|
|||||||
Conn: c,
|
Conn: c,
|
||||||
StreamCipher: cipher,
|
StreamCipher: cipher,
|
||||||
readBuf: pool.GetBuffer(bufSize),
|
readBuf: pool.GetBuffer(bufSize),
|
||||||
decryptedBuf: pool.GetWriteBuffer(),
|
decryptedBuf: pool.GetBytesBuffer(),
|
||||||
underPostdecryptBuf: pool.GetWriteBuffer(),
|
underPostdecryptBuf: pool.GetBytesBuffer(),
|
||||||
writeBuf: pool.GetBuffer(bufSize),
|
writeBuf: pool.GetBuffer(bufSize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SSTCPConn) Close() error {
|
func (c *SSTCPConn) Close() error {
|
||||||
pool.PutBuffer(c.readBuf)
|
pool.PutBuffer(c.readBuf)
|
||||||
pool.PutWriteBuffer(c.decryptedBuf)
|
pool.PutBytesBuffer(c.decryptedBuf)
|
||||||
pool.PutWriteBuffer(c.underPostdecryptBuf)
|
pool.PutBytesBuffer(c.underPostdecryptBuf)
|
||||||
pool.PutBuffer(c.writeBuf)
|
pool.PutBuffer(c.writeBuf)
|
||||||
return c.Conn.Close()
|
return c.Conn.Close()
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/nadoo/glider/log"
|
"github.com/nadoo/glider/log"
|
||||||
"github.com/nadoo/glider/proxy"
|
"github.com/nadoo/glider/proxy"
|
||||||
"github.com/nadoo/glider/proxy/socks"
|
"github.com/nadoo/glider/proxy/socks"
|
||||||
|
|
||||||
"github.com/nadoo/glider/proxy/ssr/internal"
|
"github.com/nadoo/glider/proxy/ssr/internal"
|
||||||
"github.com/nadoo/glider/proxy/ssr/internal/cipher"
|
"github.com/nadoo/glider/proxy/ssr/internal/cipher"
|
||||||
"github.com/nadoo/glider/proxy/ssr/internal/obfs"
|
"github.com/nadoo/glider/proxy/ssr/internal/obfs"
|
||||||
|
@ -33,7 +33,7 @@ func init() {
|
|||||||
proxy.RegisterServer("tls", NewTLSServer)
|
proxy.RegisterServer("tls", NewTLSServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTLS returns a tls proxy struct.
|
// NewTLS returns a tls struct.
|
||||||
func NewTLS(s string, d proxy.Dialer, p proxy.Proxy) (*TLS, error) {
|
func NewTLS(s string, d proxy.Dialer, p proxy.Proxy) (*TLS, error) {
|
||||||
u, err := url.Parse(s)
|
u, err := url.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -64,7 +64,7 @@ func NewTLS(s string, d proxy.Dialer, p proxy.Proxy) (*TLS, error) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTLSDialer returns a tls proxy dialer.
|
// NewTLSDialer returns a tls dialer.
|
||||||
func NewTLSDialer(s string, d proxy.Dialer) (proxy.Dialer, error) {
|
func NewTLSDialer(s string, d proxy.Dialer) (proxy.Dialer, error) {
|
||||||
p, err := NewTLS(s, d, nil)
|
p, err := NewTLS(s, d, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -69,8 +69,8 @@ func (s *Trojan) dial(network, addr string) (net.Conn, error) {
|
|||||||
rc = tlsConn
|
rc = tlsConn
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.Write(s.pass[:])
|
buf.Write(s.pass[:])
|
||||||
buf.WriteString("\r\n")
|
buf.WriteString("\r\n")
|
||||||
|
@ -67,8 +67,8 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
|||||||
|
|
||||||
// WriteTo implements the necessary function of net.PacketConn.
|
// WriteTo implements the necessary function of net.PacketConn.
|
||||||
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
tgtLen, _ := buf.Write(pc.tgtAddr)
|
tgtLen, _ := buf.Write(pc.tgtAddr)
|
||||||
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
||||||
|
@ -93,8 +93,8 @@ func (s *Trojan) Serve(c net.Conn) {
|
|||||||
c = tlsConn
|
c = tlsConn
|
||||||
}
|
}
|
||||||
|
|
||||||
headBuf := pool.GetWriteBuffer()
|
headBuf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(headBuf)
|
defer pool.PutBytesBuffer(headBuf)
|
||||||
|
|
||||||
cmd, target, err := s.readHeader(io.TeeReader(c, headBuf))
|
cmd, target, err := s.readHeader(io.TeeReader(c, headBuf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -59,12 +59,12 @@ func NewClientConn(c net.Conn, uuid [16]byte, network, target string) (*ClientCo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.WriteByte(Version) // ver
|
buf.WriteByte(Version) // ver
|
||||||
buf.Write(uuid[:]) // uuid
|
buf.Write(uuid[:]) // uuid
|
||||||
buf.WriteByte(0) // addLen
|
buf.WriteByte(0) // addonLen
|
||||||
|
|
||||||
cmd := CmdTCP
|
cmd := CmdTCP
|
||||||
if network == "udp" {
|
if network == "udp" {
|
||||||
|
@ -39,8 +39,8 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
|||||||
|
|
||||||
// WriteTo implements the necessary function of net.PacketConn.
|
// WriteTo implements the necessary function of net.PacketConn.
|
||||||
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
@ -48,8 +48,8 @@ func (s *VLess) Serve(c net.Conn) {
|
|||||||
c.SetKeepAlive(true)
|
c.SetKeepAlive(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
headBuf := pool.GetWriteBuffer()
|
headBuf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(headBuf)
|
defer pool.PutBytesBuffer(headBuf)
|
||||||
|
|
||||||
cmd, target, err := s.readHeader(io.TeeReader(c, headBuf))
|
cmd, target, err := s.readHeader(io.TeeReader(c, headBuf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -116,35 +116,25 @@ func (s *VLess) serveFallback(c net.Conn, tgt string, headBuf *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *VLess) readHeader(r io.Reader) (CmdType, string, error) {
|
func (s *VLess) readHeader(r io.Reader) (CmdType, string, error) {
|
||||||
buf := pool.GetBuffer(16)
|
// ver: 1, uuid: 16, addonLen: 1
|
||||||
|
buf := pool.GetBuffer(18)
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
|
|
||||||
// ver
|
if _, err := io.ReadFull(r, buf[:18]); err != nil {
|
||||||
if _, err := io.ReadFull(r, buf[:1]); err != nil {
|
return CmdErr, "", fmt.Errorf("read header error: %v", err)
|
||||||
return CmdErr, "", fmt.Errorf("get version error: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if buf[0] != Version {
|
if buf[0] != Version {
|
||||||
return CmdErr, "", fmt.Errorf("version %d not supported", buf[0])
|
return CmdErr, "", fmt.Errorf("version %d not supported", buf[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
// uuid
|
if !bytes.Equal(s.uuid[:], buf[1:17]) {
|
||||||
if _, err := io.ReadFull(r, buf[:16]); err != nil {
|
|
||||||
return CmdErr, "", fmt.Errorf("get uuid error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(s.uuid[:], buf) {
|
|
||||||
return CmdErr, "", fmt.Errorf("auth failed, client id: %02x", buf[:16])
|
return CmdErr, "", fmt.Errorf("auth failed, client id: %02x", buf[:16])
|
||||||
}
|
}
|
||||||
|
|
||||||
// addLen
|
|
||||||
if _, err := io.ReadFull(r, buf[:1]); err != nil {
|
|
||||||
return CmdErr, "", fmt.Errorf("get addon length error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore addons
|
// ignore addons
|
||||||
if addLen := int64(buf[0]); addLen > 0 {
|
if addonLen := int64(buf[17]); addonLen > 0 {
|
||||||
proxy.CopyN(ioutil.Discard, r, addLen)
|
proxy.CopyN(ioutil.Discard, r, addonLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmd
|
// cmd
|
||||||
@ -154,7 +144,6 @@ func (s *VLess) readHeader(r io.Reader) (CmdType, string, error) {
|
|||||||
|
|
||||||
// target
|
// target
|
||||||
target, err := ReadAddrString(r)
|
target, err := ReadAddrString(r)
|
||||||
|
|
||||||
return CmdType(buf[0]), target, err
|
return CmdType(buf[0]), target, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ func (c *Conn) Auth() error {
|
|||||||
|
|
||||||
// Request sends request to server.
|
// Request sends request to server.
|
||||||
func (c *Conn) Request() error {
|
func (c *Conn) Request() error {
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
// Request
|
// Request
|
||||||
buf.WriteByte(1) // Ver
|
buf.WriteByte(1) // Ver
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -60,8 +59,8 @@ func (s *WS) NewClientConn(rc net.Conn) (*ClientConn, error) {
|
|||||||
func (c *ClientConn) Handshake(host, path string) error {
|
func (c *ClientConn) Handshake(host, path string) error {
|
||||||
clientKey := generateClientKey()
|
clientKey := generateClientKey()
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.WriteString("GET " + path + " HTTP/1.1\r\n")
|
buf.WriteString("GET " + path + " HTTP/1.1\r\n")
|
||||||
buf.WriteString("Host: " + host + "\r\n")
|
buf.WriteString("Host: " + host + "\r\n")
|
||||||
@ -77,7 +76,10 @@ func (c *ClientConn) Handshake(host, path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tpr := textproto.NewReader(bufio.NewReader(c.Conn))
|
br := pool.GetBufReader(c.Conn)
|
||||||
|
defer pool.PutBufReader(br)
|
||||||
|
|
||||||
|
tpr := textproto.NewReader(br)
|
||||||
line, err := tpr.ReadLine()
|
line, err := tpr.ReadLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -93,7 +92,10 @@ func (s *WS) NewServerConn(rc net.Conn) (*ServerConn, error) {
|
|||||||
|
|
||||||
// Handshake handshakes with the client.
|
// Handshake handshakes with the client.
|
||||||
func (c *ServerConn) Handshake(host, path string) error {
|
func (c *ServerConn) Handshake(host, path string) error {
|
||||||
tpr := textproto.NewReader(bufio.NewReader(c.Conn))
|
br := pool.GetBufReader(c.Conn)
|
||||||
|
defer pool.PutBufReader(br)
|
||||||
|
|
||||||
|
tpr := textproto.NewReader(br)
|
||||||
line, err := tpr.ReadLine()
|
line, err := tpr.ReadLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -117,8 +119,8 @@ func (c *ServerConn) Handshake(host, path string) error {
|
|||||||
clientKey := reqHeader.Get("Sec-WebSocket-Key")
|
clientKey := reqHeader.Get("Sec-WebSocket-Key")
|
||||||
serverKey := computeServerKey(clientKey)
|
serverKey := computeServerKey(clientKey)
|
||||||
|
|
||||||
buf := pool.GetWriteBuffer()
|
buf := pool.GetBytesBuffer()
|
||||||
defer pool.PutWriteBuffer(buf)
|
defer pool.PutBytesBuffer(buf)
|
||||||
|
|
||||||
buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n")
|
buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n")
|
||||||
buf.WriteString("Upgrade: websocket\r\n")
|
buf.WriteString("Upgrade: websocket\r\n")
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// Package ws implements a simple websocket client.
|
|
||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -7,10 +7,12 @@ Type=simple
|
|||||||
User=nobody
|
User=nobody
|
||||||
Restart=always
|
Restart=always
|
||||||
LimitNOFILE=102400
|
LimitNOFILE=102400
|
||||||
|
Environment="GODEBUG=madvdontneed=1"
|
||||||
|
|
||||||
# NOTE: change to your glider path
|
# NOTE: CHANGE to your glider path
|
||||||
ExecStart=/usr/bin/glider -config /etc/glider/%i.conf
|
ExecStart=/usr/bin/glider -config /etc/glider/%i.conf
|
||||||
|
|
||||||
|
# NOTE:
|
||||||
# work with systemd v229 or later, so glider can listen on port below 1024 with none-root user
|
# work with systemd v229 or later, so glider can listen on port below 1024 with none-root user
|
||||||
# CAP_NET_ADMIN: ipset
|
# CAP_NET_ADMIN: ipset
|
||||||
# CAP_NET_BIND_SERVICE: bind ports under 1024
|
# CAP_NET_BIND_SERVICE: bind ports under 1024
|
||||||
|
Loading…
Reference in New Issue
Block a user