diff --git a/proxy/bind_linux.go b/proxy/bind_linux.go new file mode 100644 index 0000000..dab7734 --- /dev/null +++ b/proxy/bind_linux.go @@ -0,0 +1,14 @@ +package proxy + +import ( + "net" + "syscall" +) + +func bind(dialer *net.Dialer, iface *net.Interface) { + dialer.Control = func(network, address string, c syscall.RawConn) error { + return c.Control(func(fd uintptr) { + syscall.BindToDevice(int(fd), iface.Name) + }) + } +} diff --git a/proxy/bind_others.go b/proxy/bind_others.go new file mode 100644 index 0000000..c77ec29 --- /dev/null +++ b/proxy/bind_others.go @@ -0,0 +1,8 @@ +//go:build !linux +// +build !linux + +package proxy + +import "net" + +func bind(dialer *net.Dialer, iface *net.Interface) {} diff --git a/proxy/direct.go b/proxy/direct.go index 3044ae7..1f97cce 100644 --- a/proxy/direct.go +++ b/proxy/direct.go @@ -33,9 +33,6 @@ func NewDirect(intface string, dialTimeout, relayTimeout time.Duration) (*Direct return nil, errors.New(err.Error() + ": " + intface) } d.iface = iface - if ips := d.IFaceIPs(); len(ips) > 0 { - d.ip = ips[0] - } } } @@ -88,6 +85,10 @@ func (d *Direct) dial(network, addr string, localIP net.IP) (net.Conn, error) { } dialer := &net.Dialer{LocalAddr: la, Timeout: d.dialTimeout} + if d.iface != nil { + bind(dialer, d.iface) + } + c, err := dialer.Dial(network, addr) if err != nil { return nil, err diff --git a/proxy/vmess/chunk.go b/proxy/vmess/chunk.go index 39c00d1..bfb3849 100644 --- a/proxy/vmess/chunk.go +++ b/proxy/vmess/chunk.go @@ -47,7 +47,7 @@ type chunkedReader struct { // ChunkedReader returns a chunked reader. func ChunkedReader(r io.Reader, chunkSizeDecoder ChunkSizeDecoder) io.Reader { - return &chunkedReader{Reader: r, chunkSizeDecoder: chunkSizeDecoder} + return &chunkedReader{Reader: r, chunkSizeDecoder: chunkSizeDecoder, buf: make([]byte, chunkSizeDecoder.SizeBytes())} } func (r *chunkedReader) Read(p []byte) (int, error) {