2020-04-12 15:27:20 +08:00
|
|
|
package trojan
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"net"
|
|
|
|
|
2022-01-08 15:05:55 +08:00
|
|
|
"github.com/nadoo/glider/pkg/pool"
|
|
|
|
"github.com/nadoo/glider/pkg/socks"
|
2020-04-12 15:27:20 +08:00
|
|
|
)
|
|
|
|
|
2020-10-03 20:51:27 +08:00
|
|
|
// PktConn is a udp Packet.Conn.
|
2020-04-12 15:27:20 +08:00
|
|
|
type PktConn struct {
|
|
|
|
net.Conn
|
|
|
|
tgtAddr socks.Addr
|
|
|
|
}
|
|
|
|
|
2020-04-13 00:55:11 +08:00
|
|
|
// NewPktConn returns a PktConn.
|
2020-04-12 15:27:20 +08:00
|
|
|
func NewPktConn(c net.Conn, tgtAddr socks.Addr) *PktConn {
|
|
|
|
pc := &PktConn{
|
|
|
|
Conn: c,
|
|
|
|
tgtAddr: tgtAddr,
|
|
|
|
}
|
|
|
|
return pc
|
|
|
|
}
|
|
|
|
|
2020-04-13 00:55:11 +08:00
|
|
|
// ReadFrom implements the necessary function of net.PacketConn.
|
2021-07-24 23:45:53 +08:00
|
|
|
// NOTE: the underlying connection is not udp, we returned the target address here,
|
|
|
|
// it's not the vless server's address, do not WriteTo it.
|
2020-04-12 15:27:20 +08:00
|
|
|
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
|
|
|
// ATYP, DST.ADDR, DST.PORT
|
|
|
|
_, err := socks.ReadAddr(pc.Conn)
|
|
|
|
if err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
|
2021-07-24 23:45:53 +08:00
|
|
|
// TODO: we know that we use it in proxy.RelayUDP and the length of b is enough, check it later.
|
2020-10-15 00:19:05 +08:00
|
|
|
if len(b) < 2 {
|
|
|
|
return 0, nil, errors.New("buf size is not enough")
|
|
|
|
}
|
|
|
|
|
2020-04-12 15:27:20 +08:00
|
|
|
// Length
|
|
|
|
if _, err = io.ReadFull(pc.Conn, b[:2]); err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
length := int(binary.BigEndian.Uint16(b[:2]))
|
2020-10-15 00:19:05 +08:00
|
|
|
|
|
|
|
if len(b) < length {
|
|
|
|
return 0, nil, errors.New("buf size is not enough")
|
2020-04-12 15:27:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// CRLF
|
|
|
|
if _, err = io.ReadFull(pc.Conn, b[:2]); err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Payload
|
|
|
|
n, err := io.ReadFull(pc.Conn, b[:length])
|
|
|
|
if err != nil {
|
2020-10-03 20:51:27 +08:00
|
|
|
return n, nil, err
|
2020-04-12 15:27:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check the addr in return value, it's a fake packetConn so the addr is not valid
|
2021-07-24 23:45:53 +08:00
|
|
|
return n, pc.tgtAddr, err
|
2020-04-12 15:27:20 +08:00
|
|
|
}
|
|
|
|
|
2020-04-13 12:26:21 +08:00
|
|
|
// WriteTo implements the necessary function of net.PacketConn.
|
2020-04-12 15:27:20 +08:00
|
|
|
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
2020-11-03 22:52:50 +08:00
|
|
|
buf := pool.GetBytesBuffer()
|
|
|
|
defer pool.PutBytesBuffer(buf)
|
2020-04-19 23:20:15 +08:00
|
|
|
|
2020-10-15 00:19:05 +08:00
|
|
|
tgtLen, _ := buf.Write(pc.tgtAddr)
|
2020-04-19 23:20:15 +08:00
|
|
|
binary.Write(buf, binary.BigEndian, uint16(len(b)))
|
2020-04-12 15:27:20 +08:00
|
|
|
buf.WriteString("\r\n")
|
|
|
|
buf.Write(b)
|
2020-10-02 19:09:12 +08:00
|
|
|
|
2020-10-15 00:19:05 +08:00
|
|
|
n, err := pc.Write(buf.Bytes())
|
|
|
|
if n > tgtLen+4 {
|
|
|
|
return n - tgtLen - 4, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0, err
|
2020-04-12 15:27:20 +08:00
|
|
|
}
|