dns: use pool buffer if possible

This commit is contained in:
nadoo 2020-04-22 19:37:10 +08:00
parent 45f4240f73
commit 76fddcc29c
8 changed files with 63 additions and 35 deletions

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/proxy"
)
@ -59,7 +60,8 @@ func (s *Server) ListenAndServeUDP(wg *sync.WaitGroup) {
log.F("[dns] listening UDP on %s", s.addr)
for {
reqBytes := make([]byte, 2+UDPMaxLen)
reqBytes := pool.GetBuffer(2 + UDPMaxLen)
n, caddr, err := c.ReadFrom(reqBytes[2:])
if err != nil {
log.F("[dns] local read error: %v", err)
@ -75,6 +77,8 @@ func (s *Server) ListenAndServeUDP(wg *sync.WaitGroup) {
go func() {
respBytes, err := s.Client.Exchange(reqBytes[:2+n], caddr.String(), false)
defer pool.PutBuffer(reqBytes)
if err != nil {
log.F("[dns] error in exchange: %s", err)
return
@ -125,7 +129,9 @@ func (s *Server) ServeTCP(c net.Conn) {
return
}
reqBytes := make([]byte, reqLen+2)
reqBytes := pool.GetBuffer(int(reqLen) + 2)
defer pool.PutBuffer(reqBytes)
_, err := io.ReadFull(c, reqBytes[2:])
if err != nil {
log.F("[dns-tcp] error in read reqBytes %s", err)
@ -140,7 +146,7 @@ func (s *Server) ServeTCP(c net.Conn) {
return
}
if err := binary.Write(c, binary.BigEndian, respBytes); err != nil {
if _, err := c.Write(respBytes); err != nil {
log.F("[dns-tcp] error in local write respBytes: %s", err)
return
}

4
go.mod
View File

@ -10,8 +10,8 @@ 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-20200420104511-884d27f42877
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd // indirect
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f // indirect
)

8
go.sum
View File

@ -58,13 +58,13 @@ 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-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04=
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a h1:y6sBfNd1b9Wy08a6K1Z1DZc4aXABUN5TKjkYhz7UKmo=
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a/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=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd h1:QPwSajcTUrFriMF1nJ3XzgoqakqQEsnZf9LdXdi2nkI=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -12,6 +12,7 @@ import (
"strconv"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/proxy"
)
@ -66,12 +67,12 @@ func (s *SOCKS4) Dial(network, addr string) (net.Conn, error) {
switch network {
case "tcp", "tcp4":
default:
return nil, errors.New("[socks4]: no support for connection type " + network)
return nil, errors.New("[socks4] no support for connection type " + network)
}
c, err := s.dialer.Dial(network, s.addr)
if err != nil {
log.F("[socks4]: dial to %s error: %s", s.addr, err)
log.F("[socks4] dial to %s error: %s", s.addr, err)
return nil, err
}
@ -85,7 +86,7 @@ func (s *SOCKS4) Dial(network, addr string) (net.Conn, error) {
// DialUDP connects to the given address via the proxy.
func (s *SOCKS4) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return nil, nil, errors.New("DialUDP are not supported by Socks4")
return nil, nil, errors.New("[socks4] DialUDP are not supported by Socks4")
}
func (s *SOCKS4) lookupIP(host string) (ip net.IP, err error) {
@ -94,12 +95,12 @@ func (s *SOCKS4) lookupIP(host string) (ip net.IP, err error) {
return
}
if len(ips) == 0 {
err = errors.New("Cannot resolve host: " + host)
err = errors.New("[socks4] Cannot resolve host: " + host)
return
}
ip = ips[0].To4()
if len(ip) != net.IPv4len {
err = errors.New("IPv6 is not supported by socks4")
err = errors.New("[socks4] IPv6 is not supported by socks4")
return
}
return
@ -116,10 +117,10 @@ func (s *SOCKS4) connect(conn net.Conn, target string) error {
port, err := strconv.Atoi(portStr)
if err != nil {
return errors.New("proxy: failed to parse port number: " + portStr)
return errors.New("[socks4] failed to parse port number: " + portStr)
}
if port < 1 || port > 0xffff {
return errors.New("proxy: port number out of range: " + portStr)
return errors.New("[socks4] port number out of range: " + portStr)
}
ip, err := s.lookupIP(host)
@ -137,27 +138,28 @@ func (s *SOCKS4) connect(conn net.Conn, target string) error {
0, // user id
}
resp := make([]byte, 8)
resp := pool.GetBuffer(8)
defer pool.PutBuffer(resp)
if _, err := conn.Write(buf); err != nil {
return errors.New("proxy: failed to write greeting to socks4 proxy at " + s.addr + ": " + err.Error())
return errors.New("[socks4] failed to write greeting to socks4 proxy at " + s.addr + ": " + err.Error())
}
if _, err := io.ReadFull(conn, resp); err != nil {
return errors.New("proxy: failed to read greeting from socks4 proxy at " + s.addr + ": " + err.Error())
return errors.New("[socks4] failed to read greeting from socks4 proxy at " + s.addr + ": " + err.Error())
}
switch resp[1] {
case 0x5a:
// request granted
case 0x5b:
err = errors.New("Socks connection request rejected or failed")
err = errors.New("[socks4] connection request rejected or failed")
case 0x5c:
err = errors.New("Socks connection request request failed because client is not running identd (or not reachable from the server)")
err = errors.New("[socks4] connection request request failed because client is not running identd (or not reachable from the server)")
case 0x5d:
err = errors.New("Socks connection request request failed because client's identd could not confirm the user ID in the request")
err = errors.New("[socks4] connection request request failed because client's identd could not confirm the user ID in the request")
default:
err = errors.New("Socks connection request failed, unknown error")
err = errors.New("[socks4] connection request failed, unknown error")
}
return err

View File

@ -5,6 +5,7 @@ import (
"net"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/common/socks"
)
@ -31,7 +32,8 @@ func NewPktConn(c net.PacketConn, writeAddr net.Addr, tgtAddr socks.Addr, tgtHea
if ctrlConn != nil {
go func() {
buf := make([]byte, 1)
buf := pool.GetBuffer(1)
defer pool.PutBuffer(buf)
for {
_, err := ctrlConn.Read(buf)
if err, ok := err.(net.Error); ok && err.Timeout() {
@ -52,7 +54,9 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
return pc.PacketConn.ReadFrom(b)
}
buf := make([]byte, len(b))
buf := pool.GetBuffer(len(b))
defer pool.PutBuffer(buf)
n, raddr, err := pc.PacketConn.ReadFrom(buf)
if err != nil {
return n, raddr, err
@ -92,8 +96,13 @@ func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
return pc.PacketConn.WriteTo(b, addr)
}
buf := append([]byte{0, 0, 0}, pc.tgtAddr...)
buf = append(buf, b[:]...)
buf := pool.GetBuffer(3 + len(pc.tgtAddr) + len(b))
defer pool.PutBuffer(buf)
copy(buf, []byte{0, 0, 0})
copy(buf[3:], pc.tgtAddr)
copy(buf[3+len(pc.tgtAddr):], b)
return pc.PacketConn.WriteTo(buf, pc.writeAddr)
}

View File

@ -20,6 +20,7 @@ import (
"github.com/nadoo/glider/common/conn"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/common/socks"
"github.com/nadoo/glider/proxy"
)
@ -114,7 +115,8 @@ func (s *Socks5) Serve(c net.Conn) {
if err != nil {
// UDP: keep the connection until disconnect then free the UDP socket
if err == socks.Errors[9] {
buf := make([]byte, 1)
buf := pool.GetBuffer(1)
defer pool.PutBuffer(buf)
// block here
for {
_, err := c.Read(buf)
@ -252,7 +254,9 @@ func (s *Socks5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.A
// send VER, NMETHODS, METHODS
c.Write([]byte{Version, 1, 0})
buf := make([]byte, socks.MaxAddrLen)
buf := pool.GetBuffer(socks.MaxAddrLen)
defer pool.PutBuffer(buf)
// read VER METHOD
if _, err := io.ReadFull(c, buf[:2]); err != nil {
return nil, nil, err

View File

@ -4,6 +4,7 @@ import (
"errors"
"net"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/common/socks"
)
@ -33,7 +34,9 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
return pc.PacketConn.ReadFrom(b)
}
buf := make([]byte, len(b))
buf := pool.GetBuffer(len(b))
defer pool.PutBuffer(buf)
n, raddr, err := pc.PacketConn.ReadFrom(buf)
if err != nil {
return n, raddr, err
@ -63,7 +66,9 @@ func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
return pc.PacketConn.WriteTo(b, addr)
}
buf := make([]byte, len(pc.tgtAddr)+len(b))
buf := pool.GetBuffer(len(pc.tgtAddr) + len(b))
pool.PutBuffer(buf)
copy(buf, pc.tgtAddr)
copy(buf[len(pc.tgtAddr):], b)

View File

@ -12,6 +12,7 @@ import (
"github.com/nadoo/glider/common/conn"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/common/pool"
"github.com/nadoo/glider/common/socks"
"github.com/nadoo/glider/proxy"
)
@ -121,17 +122,18 @@ func (s *SS) Serve(c net.Conn) {
}
defer rc.Close()
req := make([]byte, conn.UDPBufSize)
n, err := c.Read(req)
buf := pool.GetBuffer(conn.UDPBufSize)
defer pool.PutBuffer(buf)
n, err := c.Read(buf)
if err != nil {
log.F("[ss-uottun] error in ioutil.ReadAll: %s\n", err)
return
}
tgtAddr, _ := net.ResolveUDPAddr("udp", tgt.String())
rc.WriteTo(req[:n], tgtAddr)
rc.WriteTo(buf[:n], tgtAddr)
buf := make([]byte, conn.UDPBufSize)
n, _, err = rc.ReadFrom(buf)
if err != nil {
log.F("[ss-uottun] read error: %v", err)