mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-02-26 16:57:08 +00:00
fix: vless packetaddr not working
This commit is contained in:
@@ -3,14 +3,10 @@ package outbound
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/common/convert"
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
@@ -30,11 +26,6 @@ import (
|
||||
M "github.com/metacubex/sing/common/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
// max packet length
|
||||
maxLength = 1024 << 3
|
||||
)
|
||||
|
||||
type Vless struct {
|
||||
*Base
|
||||
client *vless.Client
|
||||
@@ -188,9 +179,6 @@ func (v *Vless) streamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||
}
|
||||
}
|
||||
conn, err = v.client.StreamConn(c, parseVlessAddr(metadata, v.option.XUDP))
|
||||
if v.option.PacketAddr {
|
||||
conn = packetaddr.NewBindConn(conn)
|
||||
}
|
||||
} else {
|
||||
conn, err = v.client.StreamConn(c, parseVlessAddr(metadata, false))
|
||||
}
|
||||
@@ -352,12 +340,11 @@ func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metada
|
||||
), v), nil
|
||||
} else if v.option.PacketAddr {
|
||||
return newPacketConn(N.NewThreadSafePacketConn(
|
||||
packetaddr.NewConn(&vlessPacketConn{
|
||||
Conn: c, rAddr: metadata.UDPAddr(),
|
||||
}, M.SocksaddrFromNet(metadata.UDPAddr())),
|
||||
packetaddr.NewConn(v.client.PacketConn(c, metadata.UDPAddr()),
|
||||
M.SocksaddrFromNet(metadata.UDPAddr())),
|
||||
), v), nil
|
||||
}
|
||||
return newPacketConn(N.NewThreadSafePacketConn(&vlessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}), v), nil
|
||||
return newPacketConn(N.NewThreadSafePacketConn(v.client.PacketConn(c, metadata.UDPAddr())), v), nil
|
||||
}
|
||||
|
||||
// SupportUOT implements C.ProxyAdapter
|
||||
@@ -408,98 +395,6 @@ func parseVlessAddr(metadata *C.Metadata, xudp bool) *vless.DstAddr {
|
||||
}
|
||||
}
|
||||
|
||||
type vlessPacketConn struct {
|
||||
net.Conn
|
||||
rAddr net.Addr
|
||||
remain int
|
||||
mux sync.Mutex
|
||||
cache [2]byte
|
||||
}
|
||||
|
||||
func (c *vlessPacketConn) writePacket(payload []byte) (int, error) {
|
||||
binary.BigEndian.PutUint16(c.cache[:], uint16(len(payload)))
|
||||
|
||||
if _, err := c.Conn.Write(c.cache[:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return c.Conn.Write(payload)
|
||||
}
|
||||
|
||||
func (c *vlessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
total := len(b)
|
||||
if total == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if total <= maxLength {
|
||||
return c.writePacket(b)
|
||||
}
|
||||
|
||||
offset := 0
|
||||
|
||||
for offset < total {
|
||||
cursor := offset + maxLength
|
||||
if cursor > total {
|
||||
cursor = total
|
||||
}
|
||||
|
||||
n, err := c.writePacket(b[offset:cursor])
|
||||
if err != nil {
|
||||
return offset + n, err
|
||||
}
|
||||
|
||||
offset = cursor
|
||||
if offset == total {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (c *vlessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
if c.remain > 0 {
|
||||
length := len(b)
|
||||
if c.remain < length {
|
||||
length = c.remain
|
||||
}
|
||||
|
||||
n, err := c.Conn.Read(b[:length])
|
||||
if err != nil {
|
||||
return 0, c.rAddr, err
|
||||
}
|
||||
|
||||
c.remain -= n
|
||||
return n, c.rAddr, nil
|
||||
}
|
||||
|
||||
if _, err := c.Conn.Read(b[:2]); err != nil {
|
||||
return 0, c.rAddr, err
|
||||
}
|
||||
|
||||
total := int(binary.BigEndian.Uint16(b[:2]))
|
||||
if total == 0 {
|
||||
return 0, c.rAddr, nil
|
||||
}
|
||||
|
||||
length := len(b)
|
||||
if length > total {
|
||||
length = total
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(c.Conn, b[:length]); err != nil {
|
||||
return 0, c.rAddr, errors.New("read packet error")
|
||||
}
|
||||
|
||||
c.remain = total - length
|
||||
|
||||
return length, c.rAddr, nil
|
||||
}
|
||||
|
||||
func NewVless(option VlessOption) (*Vless, error) {
|
||||
var addons *vless.Addons
|
||||
if option.Network != "ws" && len(option.Flow) >= 16 {
|
||||
|
||||
Reference in New Issue
Block a user