From 904757052d6e85fd882d95bd2cb40956e919872b Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Wed, 21 Oct 2020 20:00:43 +0800 Subject: [PATCH] conn: change TCPBufSize to 32K as the golang standard lib did --- go.mod | 6 +++--- go.sum | 12 ++++++------ proxy/conn.go | 21 +++------------------ proxy/ws/client.go | 2 +- proxy/ws/frame.go | 29 ++++++++++++----------------- proxy/ws/server.go | 10 +++++----- proxy/ws/ws.go | 3 +-- 7 files changed, 31 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index 57f25f9..aa23020 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/xtaci/kcp-go/v5 v5.6.1 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 - golang.org/x/net v0.0.0-20201020065357-d65d470038a5 // indirect - golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 // indirect - golang.org/x/tools v0.0.0-20201019175715-b894a3290fff // indirect + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a // indirect + golang.org/x/tools v0.0.0-20201021000207-d49c4edd7d96 // indirect gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect ) diff --git a/go.sum b/go.sum index 39af401..93a5ba0 100644 --- a/go.sum +++ b/go.sum @@ -141,8 +141,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgN golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201020065357-d65d470038a5 h1:KrxvpY64uUzANd9wKWr6ZAsufiii93XnvXaeikyCJ2g= -golang.org/x/net v0.0.0-20201020065357-d65d470038a5/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -167,8 +167,8 @@ golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 h1:5jaG59Zhd+8ZXe8C+lgiAGqkOaZBruqrWclLkgAww34= -golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a h1:e3IU37lwO4aq3uoRKINC7JikojFmE5gO7xhfxs8VC34= +golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -177,8 +177,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU= 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-20201019175715-b894a3290fff h1:HiwHyqQ9ttqCHuTa++R4wNxOg6MY1hduSDT8j2aXoMM= -golang.org/x/tools v0.0.0-20201019175715-b894a3290fff/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201021000207-d49c4edd7d96 h1:K+nJoPcImWk+ZGPHOKkDocKcQPACCz8usiCiVQYfXsk= +golang.org/x/tools v0.0.0-20201021000207-d49c4edd7d96/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= 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-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/proxy/conn.go b/proxy/conn.go index 6a7a34e..7069f90 100644 --- a/proxy/conn.go +++ b/proxy/conn.go @@ -14,7 +14,7 @@ import ( const ( // TCPBufSize is the size of tcp buffer. - TCPBufSize = 16 << 10 + TCPBufSize = 32 << 10 // UDPBufSize is the size of udp buffer. UDPBufSize = 64 << 10 @@ -65,7 +65,7 @@ func Relay(left, right net.Conn) error { left.SetReadDeadline(time.Now().Add(wait)) // unblock read on left wg.Wait() - if err1 != nil && !errors.Is(err1, os.ErrDeadlineExceeded) { // requires Go 1.15+ + if err1 != nil && !errors.Is(err1, os.ErrDeadlineExceeded) { return err1 } @@ -78,9 +78,7 @@ func Relay(left, right net.Conn) error { func worthReadFrom(src io.Reader) bool { switch v := src.(type) { - case *net.TCPConn: - return true - case *net.UnixConn: + case *net.TCPConn, *net.UnixConn: return true case *os.File: fi, err := v.Stat() @@ -102,11 +100,9 @@ func Copy(dst io.Writer, src io.Reader) (written int64, err error) { if wt, ok := src.(io.WriterTo); ok { return wt.WriteTo(dst) } - if rt, ok := dst.(io.ReaderFrom); ok && worthReadFrom(src) { return rt.ReadFrom(src) } - return CopyBuffer(dst, src) } @@ -181,14 +177,3 @@ func RelayUDP(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout t } } } - -// OutboundIP returns preferred outbound ip of this machine. -func OutboundIP() string { - conn, err := net.Dial("udp", "8.8.8.8:80") - if err != nil { - return "" - } - defer conn.Close() - - return conn.LocalAddr().(*net.UDPAddr).IP.String() -} diff --git a/proxy/ws/client.go b/proxy/ws/client.go index 7a107f9..e17248f 100644 --- a/proxy/ws/client.go +++ b/proxy/ws/client.go @@ -85,7 +85,7 @@ func (c *ClientConn) Handshake(host, path string) error { _, code, _, ok := parseFirstLine(line) if !ok || code != "101" { - return errors.New("[ws] error in ws handshake parseFirstLine") + return errors.New("[ws] error in ws handshake parseFirstLine: " + line) } respHeader, err := tpr.ReadMIMEHeader() diff --git a/proxy/ws/frame.go b/proxy/ws/frame.go index 165a7e1..7c85f9e 100644 --- a/proxy/ws/frame.go +++ b/proxy/ws/frame.go @@ -31,8 +31,7 @@ import ( ) const ( - defaultFrameSize = 4096 - maxHeaderSize = 2 + 8 + 4 // Fixed header + length + mask + hdrSize = 2 + 8 // Fixed header + length // byte 0 finalBit byte = 1 << 7 @@ -44,10 +43,9 @@ const ( type frameWriter struct { io.Writer - header [maxHeaderSize]byte - server bool - maskKey [4]byte - maskOffset int + header [hdrSize]byte + server bool + maskKey [4]byte } // FrameWriter returns a frame writer. @@ -67,22 +65,22 @@ func (w *frameWriter) Write(b []byte) (int, error) { hdr[1] = maskBit } - nPayload, lenFieldLen := len(b), 0 + nPayload, nLenField := len(b), 0 switch { case nPayload <= 125: hdr[1] |= byte(nPayload) case nPayload < 65536: hdr[1] |= 126 - lenFieldLen = 2 - binary.BigEndian.PutUint16(hdr[2:2+lenFieldLen], uint16(nPayload)) + nLenField = 2 + binary.BigEndian.PutUint16(hdr[2:2+nLenField], uint16(nPayload)) default: hdr[1] |= 127 - lenFieldLen = 8 - binary.BigEndian.PutUint64(hdr[2:2+lenFieldLen], uint64(nPayload)) + nLenField = 8 + binary.BigEndian.PutUint64(hdr[2:2+nLenField], uint64(nPayload)) } // header and length - _, err := w.Writer.Write(hdr[:2+lenFieldLen]) + _, err := w.Writer.Write(hdr[:2+nLenField]) if err != nil { return 0, err } @@ -94,12 +92,13 @@ func (w *frameWriter) Write(b []byte) (int, error) { buf := pool.GetBuffer(nPayload) pool.PutBuffer(buf) + // mask _, err = w.Writer.Write(w.maskKey[:]) if err != nil { return 0, err } - // payload mask + // payload with mask for i := 0; i < nPayload; i++ { buf[i] = b[i] ^ w.maskKey[i%4] } @@ -129,10 +128,6 @@ func (r *frameReader) Read(b []byte) (int, error) { return 0, err } - // final := r.buf[0]&finalBit == finalBit - // frameType := int(r.buf[0] & 0xf) - // r.mask = r.buf[1]&maskBit == maskBit - r.left = int64(r.buf[1] & 0x7f) switch r.left { case 126: diff --git a/proxy/ws/server.go b/proxy/ws/server.go index 4a370b6..1acce82 100644 --- a/proxy/ws/server.go +++ b/proxy/ws/server.go @@ -3,7 +3,6 @@ package ws import ( "bufio" "errors" - "fmt" "io" "net" "net/textproto" @@ -102,7 +101,7 @@ func (c *ServerConn) Handshake(host, path string) error { _, path, _, ok := parseFirstLine(line) if !ok || path != path { - return errors.New("[ws] error in ws handshake parseFirstLine") + return errors.New("[ws] error in ws handshake parseFirstLine: " + line) } reqHeader, err := tpr.ReadMIMEHeader() @@ -110,9 +109,10 @@ func (c *ServerConn) Handshake(host, path string) error { return err } - if reqHeader.Get("Host") != host { - return fmt.Errorf("[ws] got wrong host: %s, expected: %s", reqHeader.Get("Host"), host) - } + // NOTE: in server mode, we do not validate the request Host now, check it. + // if reqHeader.Get("Host") != host { + // return fmt.Errorf("[ws] got wrong host: %s, expected: %s", reqHeader.Get("Host"), host) + // } clientKey := reqHeader.Get("Sec-WebSocket-Key") serverKey := computeServerKey(clientKey) diff --git a/proxy/ws/ws.go b/proxy/ws/ws.go index 34b00f8..236feb3 100644 --- a/proxy/ws/ws.go +++ b/proxy/ws/ws.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "crypto/sha1" "encoding/base64" - "net" "net/url" "strings" @@ -51,7 +50,7 @@ func NewWS(s string, d proxy.Dialer, p proxy.Proxy) (*WS, error) { } if w.host == "" { - w.host, _, _ = net.SplitHostPort(addr) + w.host = addr } if w.path == "" {