From 5326c0a9017bba98415f993d7aa33998651b669f Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Sun, 19 Apr 2020 17:03:39 +0800 Subject: [PATCH] pool: added buffer pool for conn --- README.md | 62 ++++++++++++++++++++--------------------- common/conn/conn.go | 27 ++++++++++++++---- common/pool/buffer.go | 50 +++++++++++++++++++++++++++++++++ common/pool/writebuf.go | 23 +++++++++++++++ go.mod | 4 +-- go.sum | 8 +++--- 6 files changed, 131 insertions(+), 43 deletions(-) create mode 100644 common/pool/buffer.go create mode 100644 common/pool/writebuf.go diff --git a/README.md b/README.md index 4ea4138..0ee1f5c 100644 --- a/README.md +++ b/README.md @@ -23,16 +23,16 @@ we can set up local listeners as proxy servers, and forward requests to internet - lha: latency based high availability - dh: destination hashing - Rule & priority based forwarder choosing: [Config Examples](config/examples) -- DNS Forwarding Server: - - Dns over proxy - - Force upstream querying by tcp - - Association rules between dns and forwarder choosing - - Association rules between dns and ipset - - DNS cache support - - Custom dns record -- IPSet Management (Linux kernel version >= 2.6.32): - - Add ip/cidrs from rule files on startup - - Add resolved ips for domains from rule files by dns forwarding server +- DNS forwarding server: + - dns over proxy + - force upstream querying by tcp + - association rules between dns and forwarder choosing + - association rules between dns and ipset + - dns cache support + - custom dns record +- IPSet management (linux kernel version >= 2.6.32): + - add ip/cidrs from rule files on startup + - add resolved ips for domains from rule files by dns forwarding server - Serve http and socks5 on the same port - Periodical availability checking for forwarders - Send requests from specific local ip/interface @@ -43,30 +43,30 @@ we can set up local listeners as proxy servers, and forward requests to internet |Protocol | Listen/TCP | Listen/UDP | Forward/TCP | Forward/UDP | Description |:-: |:-:|:-:|:-:|:-:|:- -|ss |√|√|√|√|client & server -|ssr | | |√| |client only |http |√| |√| |client & server |socks4 | | |√| |client only |socks5 |√|√|√|√|client & server |mixed |√|√| | |http+socks5 server +|ss |√|√|√|√|client & server +|ssr | | |√| |client only |trojan | | |√|√|client only |vmess | | |√| |client only |redir |√| | | |linux only |tls |√| |√| |transport client & server |kcp | |√|√| |transport client & server |unix |√| |√| |transport client & server -|tcptun |√| | | |transport -|udptun | |√| | |transport -|uottun | |√| | |transport |websocket | | |√| |transport client only |simple-obfs | | |√| |transport client only +|tcptun |√| | | |transport server only +|udptun | |√| | |transport server only +|uottun | |√| | |transport server only |reject | | |√|√|reject all requests ## Install -Binary Download +Binary Download: - [https://github.com/nadoo/glider/releases](https://github.com/nadoo/glider/releases) Go Get (requires **Go 1.14+** ): @@ -336,33 +336,33 @@ glider -config CONFIGPATH -listen :8080 -verbose - Chain proxy servers: -```bash -forward=http://1.1.1.1:80,socks5://2.2.2.2:1080,ss://method:pass@3.3.3.3:8443@ -``` + ```bash + forward=http://1.1.1.1:80,socks5://2.2.2.2:1080,ss://method:pass@3.3.3.3:8443@ + ``` - Chain protocols: https proxy (http over tls) -```bash -forward=tls://1.1.1.1:443,http:// -``` + ```bash + forward=tls://1.1.1.1:443,http:// + ``` - Chain protocols: vmess over ws over tls -```bash -forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2 -``` + ```bash + forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2 + ``` - Chain protocols and servers: -``` bash -forward=socks5://1.1.1.1:1080,tls://2.2.2.2:443,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2 -``` + ``` bash + forward=socks5://1.1.1.1:1080,tls://2.2.2.2:443,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2 + ``` - Chain protocols in listener: https proxy server -``` bash -listen=tls://:443?cert=crtFilePath&key=keyFilePath,http:// -``` + ``` bash + listen=tls://:443?cert=crtFilePath&key=keyFilePath,http:// + ``` diff --git a/common/conn/conn.go b/common/conn/conn.go index aca363b..995b9a1 100644 --- a/common/conn/conn.go +++ b/common/conn/conn.go @@ -5,12 +5,19 @@ import ( "io" "net" "time" + + "github.com/nadoo/glider/common/pool" ) -// UDPBufSize is the size of udp buffer. -const UDPBufSize = 65536 +const ( + // TCPBufSize is the size of tcp buffer + TCPBufSize = 16 << 10 -// Conn is a base conn struct. + // UDPBufSize is the size of udp buffer + UDPBufSize = 64 << 10 +) + +// Conn is a base conn struct type Conn struct { r *bufio.Reader net.Conn @@ -44,13 +51,19 @@ func Relay(left, right net.Conn) (int64, int64, error) { ch := make(chan res) go func() { - n, err := io.Copy(right, left) + buf := pool.GetBuffer(TCPBufSize) + n, err := io.CopyBuffer(right, left, buf) + pool.PutBuffer(buf) + right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left ch <- res{n, err} }() - n, err := io.Copy(left, right) + buf := pool.GetBuffer(TCPBufSize) + n, err := io.CopyBuffer(left, right, buf) + pool.PutBuffer(buf) + right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left rs := <-ch @@ -63,7 +76,9 @@ func Relay(left, right net.Conn) (int64, int64, error) { // RelayUDP copys from src to dst at target with read timeout. func RelayUDP(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error { - buf := make([]byte, UDPBufSize) + buf := pool.GetBuffer(UDPBufSize) + defer pool.PutBuffer(buf) + for { src.SetReadDeadline(time.Now().Add(timeout)) n, _, err := src.ReadFrom(buf) diff --git a/common/pool/buffer.go b/common/pool/buffer.go new file mode 100644 index 0000000..7f0e90f --- /dev/null +++ b/common/pool/buffer.go @@ -0,0 +1,50 @@ +package pool + +import ( + "sync" +) + +var bufSizes = [...]int{ + 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, 1 << 9, + 1 << 10, 2 << 10, 4 << 10, 8 << 10, 16 << 10, 32 << 10, 64 << 10, +} + +var bufPools = [...]sync.Pool{ + {New: func() interface{} { return make([]byte, 1<<0) }}, + {New: func() interface{} { return make([]byte, 1<<1) }}, + {New: func() interface{} { return make([]byte, 1<<2) }}, + {New: func() interface{} { return make([]byte, 1<<3) }}, + {New: func() interface{} { return make([]byte, 1<<4) }}, + {New: func() interface{} { return make([]byte, 1<<5) }}, + {New: func() interface{} { return make([]byte, 1<<6) }}, + {New: func() interface{} { return make([]byte, 1<<7) }}, + {New: func() interface{} { return make([]byte, 1<<8) }}, + {New: func() interface{} { return make([]byte, 1<<9) }}, + {New: func() interface{} { return make([]byte, 1<<10) }}, + {New: func() interface{} { return make([]byte, 2<<10) }}, + {New: func() interface{} { return make([]byte, 4<<10) }}, + {New: func() interface{} { return make([]byte, 8<<10) }}, + {New: func() interface{} { return make([]byte, 16<<10) }}, + {New: func() interface{} { return make([]byte, 32<<10) }}, + {New: func() interface{} { return make([]byte, 64<<10) }}, +} + +func GetBuffer(size int64) []byte { + i := 0 + for ; i < len(bufSizes)-1; i++ { + if size <= int64(bufSizes[i]) { + break + } + } + return bufPools[i].Get().([]byte) +} + +func PutBuffer(p []byte) { + l := len(p) + for i, n := range bufSizes { + if l == n { + bufPools[i].Put(p) + return + } + } +} diff --git a/common/pool/writebuf.go b/common/pool/writebuf.go new file mode 100644 index 0000000..b84c495 --- /dev/null +++ b/common/pool/writebuf.go @@ -0,0 +1,23 @@ +package pool + +import ( + "bytes" + "sync" +) + +var writeBufPool = sync.Pool{ + New: func() interface{} { return &bytes.Buffer{} }, +} + +func GetWriteBuffer(size int64) *bytes.Buffer { + return writeBufPool.Get().(*bytes.Buffer) +} + +func PutWriteBuffer(buf *bytes.Buffer) { + if buf.Cap() > 64<<10 { + return + } + + buf.Reset() + writeBufPool.Put(buf) +} diff --git a/go.mod b/go.mod index 53b75a9..d1824c5 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/tjfoc/gmsm v1.3.0 // indirect github.com/xtaci/kcp-go/v5 v5.5.12 - golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 + golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect - golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa // indirect + golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect ) // Replace dependency modules with local developing copy diff --git a/go.sum b/go.sum index 783d8b0..117de00 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,8 @@ golang.org/x/crypto v0.0.0-20191010185427-af544f31c8ac/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y= -golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -73,8 +73,8 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU= -golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=