Fix: some UDP issues (#265)
This commit is contained in:
@ -30,7 +30,7 @@ func (d *Direct) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
addr, err := resolveUDPAddr("udp", net.JoinHostPort(metadata.String(), metadata.DstPort))
|
||||
addr, err := resolveUDPAddr("udp", metadata.RemoteAddress())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (h *Http) shakeHand(metadata *C.Metadata, rw io.ReadWriter) error {
|
||||
var buf bytes.Buffer
|
||||
var err error
|
||||
|
||||
addr := net.JoinHostPort(metadata.String(), metadata.DstPort)
|
||||
addr := metadata.RemoteAddress()
|
||||
buf.WriteString("CONNECT " + addr + " HTTP/1.1\r\n")
|
||||
buf.WriteString("Host: " + metadata.String() + "\r\n")
|
||||
buf.WriteString("Proxy-Connection: Keep-Alive\r\n")
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/Dreamacro/clash/common/pool"
|
||||
"github.com/Dreamacro/clash/common/structure"
|
||||
obfs "github.com/Dreamacro/clash/component/simple-obfs"
|
||||
"github.com/Dreamacro/clash/component/socks5"
|
||||
@ -93,9 +92,9 @@ func (ss *ShadowSocks) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, er
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
targetAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(metadata.String(), metadata.DstPort))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
targetAddr := socks5.ParseAddr(metadata.RemoteAddress())
|
||||
if targetAddr == nil {
|
||||
return nil, nil, fmt.Errorf("parse address error: %v:%v", metadata.String(), metadata.DstPort)
|
||||
}
|
||||
|
||||
pc = ss.cipher.PacketConn(pc)
|
||||
@ -189,16 +188,15 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
|
||||
type ssUDPConn struct {
|
||||
net.PacketConn
|
||||
rAddr net.Addr
|
||||
rAddr socks5.Addr
|
||||
}
|
||||
|
||||
func (uc *ssUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
buf := pool.BufPool.Get().([]byte)
|
||||
defer pool.BufPool.Put(buf[:cap(buf)])
|
||||
rAddr := socks5.ParseAddr(uc.rAddr.String())
|
||||
copy(buf[len(rAddr):], b)
|
||||
copy(buf, rAddr)
|
||||
return uc.PacketConn.WriteTo(buf[:len(rAddr)+len(b)], addr)
|
||||
func (uc *ssUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
packet, err := socks5.EncodeUDPPacket(uc.rAddr, b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return uc.PacketConn.WriteTo(packet[3:], addr)
|
||||
}
|
||||
|
||||
func (uc *ssUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
|
@ -98,9 +98,9 @@ func (ss *Socks5) DialUDP(metadata *C.Metadata) (_ C.PacketConn, _ net.Addr, err
|
||||
return
|
||||
}
|
||||
|
||||
targetAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(metadata.String(), metadata.DstPort))
|
||||
if err != nil {
|
||||
return
|
||||
targetAddr := socks5.ParseAddr(metadata.RemoteAddress())
|
||||
if targetAddr == nil {
|
||||
return nil, nil, fmt.Errorf("parse address error: %v:%v", metadata.String(), metadata.DstPort)
|
||||
}
|
||||
|
||||
pc, err := net.ListenPacket("udp", "")
|
||||
@ -146,12 +146,12 @@ func NewSocks5(option Socks5Option) *Socks5 {
|
||||
|
||||
type socksUDPConn struct {
|
||||
net.PacketConn
|
||||
rAddr net.Addr
|
||||
rAddr socks5.Addr
|
||||
tcpConn net.Conn
|
||||
}
|
||||
|
||||
func (uc *socksUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
packet, err := socks5.EncodeUDPPacket(uc.rAddr.String(), b)
|
||||
packet, err := socks5.EncodeUDPPacket(uc.rAddr, b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -160,12 +160,17 @@ func (uc *socksUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
|
||||
func (uc *socksUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
n, a, e := uc.PacketConn.ReadFrom(b)
|
||||
if e != nil {
|
||||
return 0, nil, e
|
||||
}
|
||||
addr, payload, err := socks5.DecodeUDPPacket(b)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
// due to DecodeUDPPacket is mutable, record addr length
|
||||
addrLength := len(addr)
|
||||
copy(b, payload)
|
||||
return n - len(addr) - 3, a, e
|
||||
return n - addrLength - 3, a, nil
|
||||
}
|
||||
|
||||
func (uc *socksUDPConn) Close() error {
|
||||
|
@ -86,19 +86,6 @@ func serializesSocksAddr(metadata *C.Metadata) []byte {
|
||||
return bytes.Join(buf, nil)
|
||||
}
|
||||
|
||||
type fakeUDPConn struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (fuc *fakeUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
return fuc.Conn.Write(b)
|
||||
}
|
||||
|
||||
func (fuc *fakeUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
n, err := fuc.Conn.Read(b)
|
||||
return n, fuc.RemoteAddr(), err
|
||||
}
|
||||
|
||||
func dialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
|
@ -51,7 +51,7 @@ func (v *Vmess) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("new vmess client error: %v", err)
|
||||
}
|
||||
return newPacketConn(&fakeUDPConn{Conn: c}, v), c.RemoteAddr(), nil
|
||||
return newPacketConn(&vmessUDPConn{Conn: c}, v), c.RemoteAddr(), nil
|
||||
}
|
||||
|
||||
func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
@ -111,3 +111,16 @@ func parseVmessAddr(metadata *C.Metadata) *vmess.DstAddr {
|
||||
Port: uint(port),
|
||||
}
|
||||
}
|
||||
|
||||
type vmessUDPConn struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (uc *vmessUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
return uc.Conn.Write(b)
|
||||
}
|
||||
|
||||
func (uc *vmessUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
n, err := uc.Conn.Read(b)
|
||||
return n, uc.RemoteAddr(), err
|
||||
}
|
||||
|
Reference in New Issue
Block a user