pool: added buffer pool for conn

This commit is contained in:
nadoo 2020-04-19 17:03:39 +08:00
parent 8ccafa8fbd
commit 5326c0a901
6 changed files with 131 additions and 43 deletions

View File

@ -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
</details>
## 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://
```
</details>

View File

@ -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)

50
common/pool/buffer.go Normal file
View File

@ -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
}
}
}

23
common/pool/writebuf.go Normal file
View File

@ -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)
}

4
go.mod
View File

@ -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

8
go.sum
View File

@ -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=