Improve: use one bytes.Buffer pool
This commit is contained in:
parent
b17d8b661d
commit
0be9c2ae4a
10 changed files with 53 additions and 60 deletions
17
common/pool/buffer.go
Normal file
17
common/pool/buffer.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var bufferPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
||||||
|
|
||||||
|
func GetBuffer() *bytes.Buffer {
|
||||||
|
return bufferPool.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PutBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
bufferPool.Put(buf)
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ package gun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -17,6 +16,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +32,6 @@ var (
|
||||||
"content-type": []string{"application/grpc"},
|
"content-type": []string{"application/grpc"},
|
||||||
"user-agent": []string{"grpc-go/1.36.0"},
|
"user-agent": []string{"grpc-go/1.36.0"},
|
||||||
}
|
}
|
||||||
bufferPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DialFn = func(network, addr string) (net.Conn, error)
|
type DialFn = func(network, addr string) (net.Conn, error)
|
||||||
|
@ -127,9 +127,8 @@ func (g *Conn) Write(b []byte) (n int, err error) {
|
||||||
grpcPayloadLen := uint32(varuintSize + 1 + len(b))
|
grpcPayloadLen := uint32(varuintSize + 1 + len(b))
|
||||||
binary.BigEndian.PutUint32(grpcHeader[1:5], grpcPayloadLen)
|
binary.BigEndian.PutUint32(grpcHeader[1:5], grpcPayloadLen)
|
||||||
|
|
||||||
buf := bufferPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer bufferPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
buf.Write(grpcHeader)
|
buf.Write(grpcHeader)
|
||||||
buf.Write(protobufHeader[:varuintSize+1])
|
buf.Write(protobufHeader[:varuintSize+1])
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
|
@ -102,7 +102,8 @@ func (to *TLSObfs) write(b []byte) (int, error) {
|
||||||
return len(b), err
|
return len(b), err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := pool.GetBuffer()
|
||||||
|
defer pool.PutBuffer(buf)
|
||||||
buf.Write([]byte{0x17, 0x03, 0x03})
|
buf.Write([]byte{0x17, 0x03, 0x03})
|
||||||
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package snell
|
package snell
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
|
||||||
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
"github.com/Dreamacro/go-shadowsocks2/shadowaead"
|
"github.com/Dreamacro/go-shadowsocks2/shadowaead"
|
||||||
)
|
)
|
||||||
|
@ -31,8 +31,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bufferPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
endSignal = []byte{}
|
||||||
endSignal = []byte{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Snell struct {
|
type Snell struct {
|
||||||
|
@ -79,9 +78,8 @@ func (s *Snell) Read(b []byte) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteHeader(conn net.Conn, host string, port uint, version int) error {
|
func WriteHeader(conn net.Conn, host string, port uint, version int) error {
|
||||||
buf := bufferPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
buf.Reset()
|
defer pool.PutBuffer(buf)
|
||||||
defer bufferPool.Put(buf)
|
|
||||||
buf.WriteByte(Version)
|
buf.WriteByte(Version)
|
||||||
if version == Version2 {
|
if version == Version2 {
|
||||||
buf.WriteByte(CommandConnectV2)
|
buf.WriteByte(CommandConnectV2)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -102,9 +101,8 @@ func (c *httpConn) Write(b []byte) (int, error) {
|
||||||
hosts := strings.Split(host, ",")
|
hosts := strings.Split(host, ",")
|
||||||
host = hosts[rand.Intn(len(hosts))]
|
host = hosts[rand.Intn(len(hosts))]
|
||||||
|
|
||||||
buf := tools.BufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
if c.post {
|
if c.post {
|
||||||
buf.WriteString("POST /")
|
buf.WriteString("POST /")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -87,9 +87,8 @@ func (c *tls12TicketConn) Read(b []byte) (int, error) {
|
||||||
func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
length := len(b)
|
length := len(b)
|
||||||
if c.handshakeStatus == 8 {
|
if c.handshakeStatus == 8 {
|
||||||
buf := tools.BufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
for len(b) > 2048 {
|
for len(b) > 2048 {
|
||||||
size := rand.Intn(4096) + 100
|
size := rand.Intn(4096) + 100
|
||||||
if len(b) < size {
|
if len(b) < size {
|
||||||
|
@ -115,9 +114,8 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
if c.handshakeStatus == 0 {
|
if c.handshakeStatus == 0 {
|
||||||
c.handshakeStatus = 1
|
c.handshakeStatus = 1
|
||||||
|
|
||||||
data := tools.BufPool.Get().(*bytes.Buffer)
|
data := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(data)
|
defer pool.PutBuffer(data)
|
||||||
defer data.Reset()
|
|
||||||
|
|
||||||
data.Write([]byte{3, 3})
|
data.Write([]byte{3, 3})
|
||||||
c.packAuthData(data)
|
c.packAuthData(data)
|
||||||
|
@ -126,9 +124,8 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
data.Write([]byte{0x00, 0x1c, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x9c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0x0a})
|
data.Write([]byte{0x00, 0x1c, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x9c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0x0a})
|
||||||
data.Write([]byte{0x1, 0x0})
|
data.Write([]byte{0x1, 0x0})
|
||||||
|
|
||||||
ext := tools.BufPool.Get().(*bytes.Buffer)
|
ext := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(ext)
|
defer pool.PutBuffer(ext)
|
||||||
defer ext.Reset()
|
|
||||||
|
|
||||||
host := c.getHost()
|
host := c.getHost()
|
||||||
ext.Write([]byte{0xff, 0x01, 0x00, 0x01, 0x00})
|
ext.Write([]byte{0xff, 0x01, 0x00, 0x01, 0x00})
|
||||||
|
@ -145,9 +142,8 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
binary.Write(data, binary.BigEndian, uint16(ext.Len()))
|
binary.Write(data, binary.BigEndian, uint16(ext.Len()))
|
||||||
data.ReadFrom(ext)
|
data.ReadFrom(ext)
|
||||||
|
|
||||||
ret := tools.BufPool.Get().(*bytes.Buffer)
|
ret := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(ret)
|
defer pool.PutBuffer(ret)
|
||||||
defer ret.Reset()
|
|
||||||
|
|
||||||
ret.Write([]byte{0x16, 3, 1})
|
ret.Write([]byte{0x16, 3, 1})
|
||||||
binary.Write(ret, binary.BigEndian, uint16(data.Len()+4))
|
binary.Write(ret, binary.BigEndian, uint16(data.Len()+4))
|
||||||
|
@ -161,9 +157,8 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
}
|
}
|
||||||
return length, nil
|
return length, nil
|
||||||
} else if c.handshakeStatus == 1 && len(b) == 0 {
|
} else if c.handshakeStatus == 1 && len(b) == 0 {
|
||||||
buf := tools.BufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
|
|
||||||
buf.Write([]byte{0x14, 3, 3, 0, 1, 1, 0x16, 3, 3, 0, 0x20})
|
buf.Write([]byte{0x14, 3, 3, 0, 1, 1, 0x16, 3, 3, 0, 0x20})
|
||||||
tools.AppendRandBytes(buf, 22)
|
tools.AppendRandBytes(buf, 22)
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PacketConn struct {
|
type PacketConn struct {
|
||||||
|
@ -13,9 +12,8 @@ type PacketConn struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
func (c *PacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
buf := tools.BufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
err := c.EncodePacket(buf, b)
|
err := c.EncodePacket(buf, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
|
@ -37,9 +36,8 @@ func (c *Conn) Read(b []byte) (int, error) {
|
||||||
|
|
||||||
func (c *Conn) Write(b []byte) (int, error) {
|
func (c *Conn) Write(b []byte) (int, error) {
|
||||||
bLength := len(b)
|
bLength := len(b)
|
||||||
buf := tools.BufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer tools.BufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
err := c.Encode(buf, b)
|
err := c.Encode(buf, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -2,17 +2,10 @@ package tools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"math/rand"
|
"crypto/rand"
|
||||||
"sync"
|
"io"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var BufPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
|
||||||
|
|
||||||
func AppendRandBytes(b *bytes.Buffer, length int) {
|
func AppendRandBytes(b *bytes.Buffer, length int) {
|
||||||
randBytes := pool.Get(length)
|
b.ReadFrom(io.LimitReader(rand.Reader, int64(length)))
|
||||||
defer pool.Put(randBytes)
|
|
||||||
rand.Read(randBytes)
|
|
||||||
b.Write(randBytes)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package trojan
|
package trojan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
@ -11,6 +10,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/transport/socks5"
|
"github.com/Dreamacro/clash/transport/socks5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ const (
|
||||||
var (
|
var (
|
||||||
defaultALPN = []string{"h2", "http/1.1"}
|
defaultALPN = []string{"h2", "http/1.1"}
|
||||||
crlf = []byte{'\r', '\n'}
|
crlf = []byte{'\r', '\n'}
|
||||||
|
|
||||||
bufPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command = byte
|
type Command = byte
|
||||||
|
@ -67,9 +65,8 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error {
|
func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error {
|
||||||
buf := bufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer bufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
|
|
||||||
buf.Write(t.hexPassword)
|
buf.Write(t.hexPassword)
|
||||||
buf.Write(crlf)
|
buf.Write(crlf)
|
||||||
|
@ -89,9 +86,8 @@ func (t *Trojan) PacketConn(conn net.Conn) net.PacketConn {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writePacket(w io.Writer, socks5Addr, payload []byte) (int, error) {
|
func writePacket(w io.Writer, socks5Addr, payload []byte) (int, error) {
|
||||||
buf := bufPool.Get().(*bytes.Buffer)
|
buf := pool.GetBuffer()
|
||||||
defer bufPool.Put(buf)
|
defer pool.PutBuffer(buf)
|
||||||
defer buf.Reset()
|
|
||||||
|
|
||||||
buf.Write(socks5Addr)
|
buf.Write(socks5Addr)
|
||||||
binary.Write(buf, binary.BigEndian, uint16(len(payload)))
|
binary.Write(buf, binary.BigEndian, uint16(len(payload)))
|
||||||
|
|
Loading…
Reference in a new issue