Improve: udp NAT type
This commit is contained in:
@ -30,8 +30,8 @@ func (b *Base) Type() C.AdapterType {
|
||||
return b.tp
|
||||
}
|
||||
|
||||
func (b *Base) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
return nil, nil, errors.New("no support")
|
||||
func (b *Base) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return nil, errors.New("no support")
|
||||
}
|
||||
|
||||
func (b *Base) SupportUDP() bool {
|
||||
|
@ -25,17 +25,12 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn,
|
||||
return newConn(c, d), nil
|
||||
}
|
||||
|
||||
func (d *Direct) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
func (d *Direct) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
pc, err := net.ListenPacket("udp", "")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := resolveUDPAddr("udp", metadata.RemoteAddress())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return newPacketConn(pc, d), addr, nil
|
||||
return newPacketConn(pc, d), nil
|
||||
}
|
||||
|
||||
func NewDirect() *Direct {
|
||||
|
@ -18,8 +18,8 @@ func (r *Reject) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn,
|
||||
return newConn(&NopConn{}, r), nil
|
||||
}
|
||||
|
||||
func (r *Reject) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
return nil, nil, errors.New("match reject rule")
|
||||
func (r *Reject) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return nil, errors.New("match reject rule")
|
||||
}
|
||||
|
||||
func NewReject() *Reject {
|
||||
|
@ -82,24 +82,19 @@ func (ss *ShadowSocks) DialContext(ctx context.Context, metadata *C.Metadata) (C
|
||||
return newConn(c, ss), err
|
||||
}
|
||||
|
||||
func (ss *ShadowSocks) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
func (ss *ShadowSocks) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
pc, err := net.ListenPacket("udp", "")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := resolveUDPAddr("udp", ss.server)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
targetAddr := socks5.ParseAddr(metadata.RemoteAddress())
|
||||
if targetAddr == nil {
|
||||
return nil, nil, fmt.Errorf("parse address %s error: %s", metadata.String(), metadata.DstPort)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pc = ss.cipher.PacketConn(pc)
|
||||
return newPacketConn(&ssUDPConn{PacketConn: pc, rAddr: targetAddr}, ss), addr, nil
|
||||
return newPacketConn(&ssUDPConn{PacketConn: pc, rAddr: addr}, ss), nil
|
||||
}
|
||||
|
||||
func (ss *ShadowSocks) MarshalJSON() ([]byte, error) {
|
||||
@ -189,15 +184,15 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
|
||||
type ssUDPConn struct {
|
||||
net.PacketConn
|
||||
rAddr socks5.Addr
|
||||
rAddr net.Addr
|
||||
}
|
||||
|
||||
func (uc *ssUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
packet, err := socks5.EncodeUDPPacket(uc.rAddr, b)
|
||||
packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return uc.PacketConn.WriteTo(packet[3:], addr)
|
||||
return uc.PacketConn.WriteTo(packet[3:], uc.rAddr)
|
||||
}
|
||||
|
||||
func (uc *ssUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
|
@ -60,7 +60,7 @@ func (ss *Socks5) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn
|
||||
return newConn(c, ss), nil
|
||||
}
|
||||
|
||||
func (ss *Socks5) DialUDP(metadata *C.Metadata) (_ C.PacketConn, _ net.Addr, err error) {
|
||||
func (ss *Socks5) DialUDP(metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), tcpTimeout)
|
||||
defer cancel()
|
||||
c, err := dialContext(ctx, "tcp", ss.addr)
|
||||
@ -96,16 +96,6 @@ func (ss *Socks5) DialUDP(metadata *C.Metadata) (_ C.PacketConn, _ net.Addr, err
|
||||
return
|
||||
}
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", bindAddr.String())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
targetAddr := socks5.ParseAddr(metadata.RemoteAddress())
|
||||
if targetAddr == nil {
|
||||
return nil, nil, fmt.Errorf("parse address %s error: %s", metadata.String(), metadata.DstPort)
|
||||
}
|
||||
|
||||
pc, err := net.ListenPacket("udp", "")
|
||||
if err != nil {
|
||||
return
|
||||
@ -119,7 +109,7 @@ func (ss *Socks5) DialUDP(metadata *C.Metadata) (_ C.PacketConn, _ net.Addr, err
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
return newPacketConn(&socksUDPConn{PacketConn: pc, rAddr: targetAddr, tcpConn: c}, ss), addr, nil
|
||||
return newPacketConn(&socksUDPConn{PacketConn: pc, rAddr: bindAddr.UDPAddr(), tcpConn: c}, ss), nil
|
||||
}
|
||||
|
||||
func NewSocks5(option Socks5Option) *Socks5 {
|
||||
@ -149,16 +139,16 @@ func NewSocks5(option Socks5Option) *Socks5 {
|
||||
|
||||
type socksUDPConn struct {
|
||||
net.PacketConn
|
||||
rAddr socks5.Addr
|
||||
rAddr net.Addr
|
||||
tcpConn net.Conn
|
||||
}
|
||||
|
||||
func (uc *socksUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
packet, err := socks5.EncodeUDPPacket(uc.rAddr, b)
|
||||
packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return uc.PacketConn.WriteTo(packet, addr)
|
||||
return uc.PacketConn.WriteTo(packet, uc.rAddr)
|
||||
}
|
||||
|
||||
func (uc *socksUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
|
@ -42,19 +42,19 @@ func (v *Vmess) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn,
|
||||
return newConn(c, v), err
|
||||
}
|
||||
|
||||
func (v *Vmess) DialUDP(metadata *C.Metadata) (C.PacketConn, net.Addr, error) {
|
||||
func (v *Vmess) DialUDP(metadata *C.Metadata) (C.PacketConn, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), tcpTimeout)
|
||||
defer cancel()
|
||||
c, err := dialContext(ctx, "tcp", v.server)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("%s connect error", v.server)
|
||||
return nil, fmt.Errorf("%s connect error", v.server)
|
||||
}
|
||||
tcpKeepAlive(c)
|
||||
c, err = v.client.New(c, parseVmessAddr(metadata))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("new vmess client error: %v", err)
|
||||
return nil, fmt.Errorf("new vmess client error: %v", err)
|
||||
}
|
||||
return newPacketConn(&vmessUDPConn{Conn: c}, v), c.RemoteAddr(), nil
|
||||
return newPacketConn(&vmessUDPConn{Conn: c}, v), nil
|
||||
}
|
||||
|
||||
func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
|
Reference in New Issue
Block a user