Feature: socks5 udp associate

This commit is contained in:
Dreamacro
2019-04-23 23:29:36 +08:00
parent 49f8902961
commit c92cda6980
25 changed files with 339 additions and 85 deletions

View File

@ -8,6 +8,8 @@ import (
"math/rand"
"net"
"net/http"
"github.com/Dreamacro/clash/common/pool"
)
// HTTPObfs is shadowsocks http simple-obfs implementation
@ -32,15 +34,15 @@ func (ho *HTTPObfs) Read(b []byte) (int, error) {
}
if ho.firstResponse {
buf := bufPool.Get().([]byte)
buf := pool.BufPool.Get().([]byte)
n, err := ho.Conn.Read(buf)
if err != nil {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
return 0, err
}
idx := bytes.Index(buf[:n], []byte("\r\n\r\n"))
if idx == -1 {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
return 0, io.EOF
}
ho.firstResponse = false
@ -50,7 +52,7 @@ func (ho *HTTPObfs) Read(b []byte) (int, error) {
ho.buf = buf[:idx+4+length]
ho.offset = idx + 4 + n
} else {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
}
return n, nil
}

View File

@ -6,8 +6,9 @@ import (
"io"
"math/rand"
"net"
"sync"
"time"
"github.com/Dreamacro/clash/common/pool"
)
func init() {
@ -18,8 +19,6 @@ const (
chunkSize = 1 << 14 // 2 ** 14 == 16 * 1024
)
var bufPool = sync.Pool{New: func() interface{} { return make([]byte, 2048) }}
// TLSObfs is shadowsocks tls simple-obfs implementation
type TLSObfs struct {
net.Conn
@ -30,12 +29,12 @@ type TLSObfs struct {
}
func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
buf := bufPool.Get().([]byte)
buf := pool.BufPool.Get().([]byte)
_, err := io.ReadFull(to.Conn, buf[:discardN])
if err != nil {
return 0, err
}
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
sizeBuf := make([]byte, 2)
_, err = io.ReadFull(to.Conn, sizeBuf)
@ -103,7 +102,7 @@ func (to *TLSObfs) write(b []byte) (int, error) {
return len(b), err
}
size := bufPool.Get().([]byte)
size := pool.BufPool.Get().([]byte)
binary.BigEndian.PutUint16(size[:2], uint16(len(b)))
buf := &bytes.Buffer{}
@ -111,7 +110,7 @@ func (to *TLSObfs) write(b []byte) (int, error) {
buf.Write(size[:2])
buf.Write(b)
_, err := to.Conn.Write(buf.Bytes())
bufPool.Put(size[:cap(size)])
pool.BufPool.Put(size[:cap(size)])
return len(b), err
}

View File

@ -5,6 +5,8 @@ import (
"encoding/binary"
"errors"
"io"
"github.com/Dreamacro/clash/common/pool"
)
type aeadWriter struct {
@ -20,8 +22,8 @@ func newAEADWriter(w io.Writer, aead cipher.AEAD, iv []byte) *aeadWriter {
}
func (w *aeadWriter) Write(b []byte) (n int, err error) {
buf := bufPool.Get().([]byte)
defer bufPool.Put(buf[:cap(buf)])
buf := pool.BufPool.Get().([]byte)
defer pool.BufPool.Put(buf[:cap(buf)])
length := len(b)
for {
if length == 0 {
@ -71,7 +73,7 @@ func (r *aeadReader) Read(b []byte) (int, error) {
n := copy(b, r.buf[r.offset:])
r.offset += n
if r.offset == len(r.buf) {
bufPool.Put(r.buf[:cap(r.buf)])
pool.BufPool.Put(r.buf[:cap(r.buf)])
r.buf = nil
}
return n, nil
@ -87,10 +89,10 @@ func (r *aeadReader) Read(b []byte) (int, error) {
return 0, errors.New("Buffer is larger than standard")
}
buf := bufPool.Get().([]byte)
buf := pool.BufPool.Get().([]byte)
_, err = io.ReadFull(r.Reader, buf[:size])
if err != nil {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
return 0, err
}
@ -105,7 +107,7 @@ func (r *aeadReader) Read(b []byte) (int, error) {
realLen := size - r.Overhead()
n := copy(b, buf[:realLen])
if len(b) >= realLen {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
return n, nil
}

View File

@ -4,7 +4,8 @@ import (
"encoding/binary"
"errors"
"io"
"sync"
"github.com/Dreamacro/clash/common/pool"
)
const (
@ -13,8 +14,6 @@ const (
maxSize = 17 * 1024 // 2 + chunkSize + aead.Overhead()
)
var bufPool = sync.Pool{New: func() interface{} { return make([]byte, maxSize) }}
type chunkReader struct {
io.Reader
buf []byte
@ -35,7 +34,7 @@ func (cr *chunkReader) Read(b []byte) (int, error) {
n := copy(b, cr.buf[cr.offset:])
cr.offset += n
if cr.offset == len(cr.buf) {
bufPool.Put(cr.buf[:cap(cr.buf)])
pool.BufPool.Put(cr.buf[:cap(cr.buf)])
cr.buf = nil
}
return n, nil
@ -60,10 +59,10 @@ func (cr *chunkReader) Read(b []byte) (int, error) {
return size, nil
}
buf := bufPool.Get().([]byte)
buf := pool.BufPool.Get().([]byte)
_, err = io.ReadFull(cr.Reader, buf[:size])
if err != nil {
bufPool.Put(buf[:cap(buf)])
pool.BufPool.Put(buf[:cap(buf)])
return 0, err
}
n := copy(b, cr.buf[:])
@ -77,8 +76,8 @@ type chunkWriter struct {
}
func (cw *chunkWriter) Write(b []byte) (n int, err error) {
buf := bufPool.Get().([]byte)
defer bufPool.Put(buf[:cap(buf)])
buf := pool.BufPool.Get().([]byte)
defer pool.BufPool.Put(buf[:cap(buf)])
length := len(b)
for {
if length == 0 {