glider/proxy/socks5/packet.go

124 lines
2.5 KiB
Go
Raw Normal View History

2018-06-28 09:49:23 +08:00
package socks5
import (
"errors"
2018-06-28 09:49:23 +08:00
"net"
"github.com/nadoo/glider/pool"
"github.com/nadoo/glider/proxy/socks"
2018-06-28 09:49:23 +08:00
)
// PktConn .
type PktConn struct {
net.PacketConn
writeAddr net.Addr // write to and read from addr
tgtAddr socks.Addr
tgtHeader bool
ctrlConn net.Conn // tcp control conn
}
// NewPktConn returns a PktConn.
2018-06-28 09:49:23 +08:00
func NewPktConn(c net.PacketConn, writeAddr net.Addr, tgtAddr socks.Addr, tgtHeader bool, ctrlConn net.Conn) *PktConn {
pc := &PktConn{
PacketConn: c,
writeAddr: writeAddr,
tgtAddr: tgtAddr,
tgtHeader: tgtHeader,
2020-10-08 18:48:23 +08:00
ctrlConn: ctrlConn,
}
2018-06-28 09:49:23 +08:00
if ctrlConn != nil {
go func() {
2020-04-22 19:37:10 +08:00
buf := pool.GetBuffer(1)
defer pool.PutBuffer(buf)
2018-06-28 09:49:23 +08:00
for {
_, err := ctrlConn.Read(buf)
if err, ok := err.(net.Error); ok && err.Timeout() {
continue
}
// log.F("[socks5] dialudp udp associate end")
2018-06-28 09:49:23 +08:00
return
}
}()
}
return pc
}
// ReadFrom overrides the original function from net.PacketConn.
2018-06-28 09:49:23 +08:00
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
if !pc.tgtHeader {
return pc.PacketConn.ReadFrom(b)
}
2020-04-22 19:37:10 +08:00
buf := pool.GetBuffer(len(b))
defer pool.PutBuffer(buf)
2018-06-28 09:49:23 +08:00
n, raddr, err := pc.PacketConn.ReadFrom(buf)
if err != nil {
return n, raddr, err
}
2020-04-12 15:27:20 +08:00
if n < 3 {
return n, raddr, errors.New("not enough size to get addr")
}
2018-06-28 09:49:23 +08:00
// https://tools.ietf.org/html/rfc1928#section-7
// +----+------+------+----------+----------+----------+
// |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
// +----+------+------+----------+----------+----------+
// | 2 | 1 | 1 | Variable | 2 | Variable |
// +----+------+------+----------+----------+----------+
tgtAddr := socks.SplitAddr(buf[3:n])
if tgtAddr == nil {
return n, raddr, errors.New("can not get addr")
}
n = copy(b, buf[3+len(tgtAddr):n])
2018-06-28 09:49:23 +08:00
//test
if pc.writeAddr == nil {
pc.writeAddr = raddr
}
if pc.tgtAddr == nil {
2020-11-30 20:28:09 +08:00
pc.tgtAddr = make([]byte, len(tgtAddr))
copy(pc.tgtAddr, tgtAddr)
2018-06-28 09:49:23 +08:00
}
return n, raddr, err
2018-06-28 09:49:23 +08:00
}
// WriteTo overrides the original function from net.PacketConn.
2018-06-28 09:49:23 +08:00
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
if !pc.tgtHeader {
return pc.PacketConn.WriteTo(b, addr)
}
2020-11-03 22:52:50 +08:00
buf := pool.GetBytesBuffer()
defer pool.PutBytesBuffer(buf)
buf.Write([]byte{0, 0, 0})
tgtLen, _ := buf.Write(pc.tgtAddr)
buf.Write(b)
2020-04-22 19:37:10 +08:00
n, err := pc.PacketConn.WriteTo(buf.Bytes(), pc.writeAddr)
if n > tgtLen+3 {
return n - tgtLen - 3, err
}
2020-04-22 19:37:10 +08:00
return 0, err
2018-06-28 09:49:23 +08:00
}
// Close .
func (pc *PktConn) Close() error {
if pc.ctrlConn != nil {
pc.ctrlConn.Close()
}
return pc.PacketConn.Close()
}