chore: udp always direct pass ip to remote without domain
This commit is contained in:
parent
aaf534427e
commit
cb0c9e5caf
4 changed files with 106 additions and 74 deletions
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/common/structure"
|
"github.com/Dreamacro/clash/common/structure"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
"github.com/Dreamacro/clash/component/proxydialer"
|
"github.com/Dreamacro/clash/component/proxydialer"
|
||||||
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/transport/restls"
|
"github.com/Dreamacro/clash/transport/restls"
|
||||||
obfs "github.com/Dreamacro/clash/transport/simple-obfs"
|
obfs "github.com/Dreamacro/clash/transport/simple-obfs"
|
||||||
|
@ -184,12 +185,7 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
destination := M.ParseSocksaddr(metadata.RemoteAddress())
|
return ss.ListenPacketOnStreamConn(ctx, tcpConn, metadata)
|
||||||
if ss.option.UDPOverTCPVersion == 1 {
|
|
||||||
return newPacketConn(uot.NewConn(tcpConn, uot.Request{Destination: destination}), ss), nil
|
|
||||||
} else {
|
|
||||||
return newPacketConn(uot.NewLazyConn(tcpConn, uot.Request{Destination: destination}), ss), nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ss.addr, ss.prefer)
|
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ss.addr, ss.prefer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -210,9 +206,18 @@ func (ss *ShadowSocks) SupportWithDialer() C.NetWork {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
||||||
func (ss *ShadowSocks) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
func (ss *ShadowSocks) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||||
if ss.option.UDPOverTCP {
|
if ss.option.UDPOverTCP {
|
||||||
destination := M.ParseSocksaddr(metadata.RemoteAddress())
|
// ss uot use stream-oriented udp with a special address, so we need a net.UDPAddr
|
||||||
|
if !metadata.Resolved() {
|
||||||
|
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("can't resolve ip")
|
||||||
|
}
|
||||||
|
metadata.DstIP = ip
|
||||||
|
}
|
||||||
|
|
||||||
|
destination := M.SocksaddrFromNet(metadata.UDPAddr())
|
||||||
if ss.option.UDPOverTCPVersion == uot.LegacyVersion {
|
if ss.option.UDPOverTCPVersion == uot.LegacyVersion {
|
||||||
return newPacketConn(uot.NewConn(c, uot.Request{Destination: destination}), ss), nil
|
return newPacketConn(uot.NewConn(c, uot.Request{Destination: destination}), ss), nil
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -169,7 +169,34 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.client.StreamConn(c, parseVlessAddr(metadata, v.option.XUDP))
|
return v.streamConn(c, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vless) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err error) {
|
||||||
|
metadata = &C.Metadata{ // a clear metadata only contains ip
|
||||||
|
NetWork: metadata.NetWork,
|
||||||
|
DstIP: metadata.DstIP,
|
||||||
|
DstPort: metadata.DstPort,
|
||||||
|
}
|
||||||
|
if metadata.NetWork == C.UDP {
|
||||||
|
if v.option.PacketAddr {
|
||||||
|
metadata = &C.Metadata{
|
||||||
|
NetWork: C.UDP,
|
||||||
|
Host: packetaddr.SeqPacketMagicAddress,
|
||||||
|
DstPort: "443",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
conn = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error) {
|
func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error) {
|
||||||
|
@ -271,7 +298,6 @@ func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
}
|
}
|
||||||
metadata.DstIP = ip
|
metadata.DstIP = ip
|
||||||
}
|
}
|
||||||
|
|
||||||
var c net.Conn
|
var c net.Conn
|
||||||
// gun transport
|
// gun transport
|
||||||
if v.transport != nil && len(opts) == 0 {
|
if v.transport != nil && len(opts) == 0 {
|
||||||
|
@ -283,21 +309,12 @@ func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
safeConnClose(c, err)
|
safeConnClose(c, err)
|
||||||
}(c)
|
}(c)
|
||||||
|
|
||||||
if v.option.PacketAddr {
|
c, err = v.streamConn(c, metadata)
|
||||||
packetAddrMetadata := *metadata // make a copy
|
|
||||||
packetAddrMetadata.Host = packetaddr.SeqPacketMagicAddress
|
|
||||||
packetAddrMetadata.DstPort = "443"
|
|
||||||
|
|
||||||
c, err = v.client.StreamConn(c, parseVlessAddr(&packetAddrMetadata, false))
|
|
||||||
} else {
|
|
||||||
c, err = v.client.StreamConn(c, parseVlessAddr(metadata, v.option.XUDP))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("new vless client error: %v", err)
|
return nil, fmt.Errorf("new vless client error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.ListenPacketOnStreamConn(c, metadata)
|
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||||
}
|
}
|
||||||
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
|
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
|
||||||
}
|
}
|
||||||
|
@ -310,6 +327,7 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vless use stream-oriented udp with a special address, so we need a net.UDPAddr
|
// vless use stream-oriented udp with a special address, so we need a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
||||||
|
@ -318,6 +336,7 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||||
}
|
}
|
||||||
metadata.DstIP = ip
|
metadata.DstIP = ip
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||||
|
@ -327,21 +346,12 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||||
safeConnClose(c, err)
|
safeConnClose(c, err)
|
||||||
}(c)
|
}(c)
|
||||||
|
|
||||||
if v.option.PacketAddr {
|
c, err = v.streamConn(c, metadata)
|
||||||
packetAddrMetadata := *metadata // make a copy
|
|
||||||
packetAddrMetadata.Host = packetaddr.SeqPacketMagicAddress
|
|
||||||
packetAddrMetadata.DstPort = "443"
|
|
||||||
|
|
||||||
c, err = v.StreamConn(c, &packetAddrMetadata)
|
|
||||||
} else {
|
|
||||||
c, err = v.StreamConn(c, metadata)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("new vless client error: %v", err)
|
return nil, fmt.Errorf("new vless client error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.ListenPacketOnStreamConn(c, metadata)
|
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SupportWithDialer implements C.ProxyAdapter
|
// SupportWithDialer implements C.ProxyAdapter
|
||||||
|
@ -350,7 +360,16 @@ func (v *Vless) SupportWithDialer() C.NetWork {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
||||||
func (v *Vless) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||||
|
// vless use stream-oriented udp with a special address, so we need a net.UDPAddr
|
||||||
|
if !metadata.Resolved() {
|
||||||
|
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("can't resolve ip")
|
||||||
|
}
|
||||||
|
metadata.DstIP = ip
|
||||||
|
}
|
||||||
|
|
||||||
if v.option.XUDP {
|
if v.option.XUDP {
|
||||||
return newPacketConn(&threadSafePacketConn{
|
return newPacketConn(&threadSafePacketConn{
|
||||||
PacketConn: vmessSing.NewXUDPConn(c, M.ParseSocksaddr(metadata.RemoteAddress())),
|
PacketConn: vmessSing.NewXUDPConn(c, M.ParseSocksaddr(metadata.RemoteAddress())),
|
||||||
|
@ -517,6 +536,9 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||||
option.XUDP = true
|
option.XUDP = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if option.XUDP {
|
||||||
|
option.PacketAddr = false
|
||||||
|
}
|
||||||
|
|
||||||
client, err := vless.NewClient(option.UUID, addons, option.FlowShow)
|
client, err := vless.NewClient(option.UUID, addons, option.FlowShow)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -217,27 +217,42 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return v.streamConn(c, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vmess) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err error) {
|
||||||
if metadata.NetWork == C.UDP {
|
if metadata.NetWork == C.UDP {
|
||||||
if v.option.XUDP {
|
if v.option.XUDP {
|
||||||
if N.NeedHandshake(c) {
|
if N.NeedHandshake(c) {
|
||||||
return v.client.DialEarlyXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())), nil
|
conn = v.client.DialEarlyXUDPPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
} else {
|
} else {
|
||||||
return v.client.DialXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
conn, err = v.client.DialXUDPPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
}
|
}
|
||||||
|
} else if v.option.PacketAddr {
|
||||||
|
if N.NeedHandshake(c) {
|
||||||
|
conn = v.client.DialEarlyPacketConn(c, M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
|
||||||
|
} else {
|
||||||
|
conn, err = v.client.DialPacketConn(c, M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
|
||||||
|
}
|
||||||
|
conn = packetaddr.NewBindConn(conn)
|
||||||
} else {
|
} else {
|
||||||
if N.NeedHandshake(c) {
|
if N.NeedHandshake(c) {
|
||||||
return v.client.DialEarlyPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress())), nil
|
conn = v.client.DialEarlyPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
} else {
|
} else {
|
||||||
return v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
conn, err = v.client.DialPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if N.NeedHandshake(c) {
|
if N.NeedHandshake(c) {
|
||||||
return v.client.DialEarlyConn(c, M.ParseSocksaddr(metadata.RemoteAddress())), nil
|
conn = v.client.DialEarlyConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
||||||
} else {
|
} else {
|
||||||
return v.client.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
conn, err = v.client.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
conn = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialContext implements C.ProxyAdapter
|
// DialContext implements C.ProxyAdapter
|
||||||
|
@ -293,14 +308,6 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
}
|
}
|
||||||
metadata.DstIP = ip
|
metadata.DstIP = ip
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.option.PacketAddr {
|
|
||||||
_metadata := *metadata // make a copy
|
|
||||||
metadata = &_metadata
|
|
||||||
metadata.Host = packetaddr.SeqPacketMagicAddress
|
|
||||||
metadata.DstPort = "443"
|
|
||||||
}
|
|
||||||
|
|
||||||
var c net.Conn
|
var c net.Conn
|
||||||
// gun transport
|
// gun transport
|
||||||
if v.transport != nil && len(opts) == 0 {
|
if v.transport != nil && len(opts) == 0 {
|
||||||
|
@ -312,24 +319,11 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
safeConnClose(c, err)
|
safeConnClose(c, err)
|
||||||
}(c)
|
}(c)
|
||||||
|
|
||||||
if v.option.XUDP {
|
c, err = v.streamConn(c, metadata)
|
||||||
if N.NeedHandshake(c) {
|
|
||||||
c = v.client.DialEarlyXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
|
||||||
} else {
|
|
||||||
c, err = v.client.DialXUDPPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if N.NeedHandshake(c) {
|
|
||||||
c = v.client.DialEarlyPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
|
||||||
} else {
|
|
||||||
c, err = v.client.DialPacketConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("new vmess client error: %v", err)
|
return nil, fmt.Errorf("new vmess client error: %v", err)
|
||||||
}
|
}
|
||||||
return v.ListenPacketOnStreamConn(c, metadata)
|
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||||
}
|
}
|
||||||
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
|
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.Base.DialOptions(opts...)...), metadata)
|
||||||
}
|
}
|
||||||
|
@ -342,6 +336,7 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vmess use stream-oriented udp with a special address, so we need a net.UDPAddr
|
// vmess use stream-oriented udp with a special address, so we need a net.UDPAddr
|
||||||
if !metadata.Resolved() {
|
if !metadata.Resolved() {
|
||||||
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
||||||
|
@ -364,7 +359,7 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("new vmess client error: %v", err)
|
return nil, fmt.Errorf("new vmess client error: %v", err)
|
||||||
}
|
}
|
||||||
return v.ListenPacketOnStreamConn(c, metadata)
|
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SupportWithDialer implements C.ProxyAdapter
|
// SupportWithDialer implements C.ProxyAdapter
|
||||||
|
@ -373,10 +368,17 @@ func (v *Vmess) SupportWithDialer() C.NetWork {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
||||||
func (v *Vmess) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
func (v *Vmess) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||||
if v.option.PacketAddr {
|
// vmess use stream-oriented udp with a special address, so we need a net.UDPAddr
|
||||||
return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindConn(c)}, v), nil
|
if !metadata.Resolved() {
|
||||||
} else if pc, ok := c.(net.PacketConn); ok {
|
ip, err := resolver.ResolveIP(ctx, metadata.Host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("can't resolve ip")
|
||||||
|
}
|
||||||
|
metadata.DstIP = ip
|
||||||
|
}
|
||||||
|
|
||||||
|
if pc, ok := c.(net.PacketConn); ok {
|
||||||
return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil
|
return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil
|
||||||
}
|
}
|
||||||
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
||||||
|
|
|
@ -2,6 +2,7 @@ package proxydialer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
@ -9,6 +10,7 @@ import (
|
||||||
|
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/tunnel"
|
"github.com/Dreamacro/clash/tunnel"
|
||||||
"github.com/Dreamacro/clash/tunnel/statistic"
|
"github.com/Dreamacro/clash/tunnel/statistic"
|
||||||
|
@ -38,17 +40,18 @@ func (p proxyDialer) DialContext(ctx context.Context, network, address string) (
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if strings.Contains(network, "udp") { // using in wireguard outbound
|
if strings.Contains(network, "udp") { // using in wireguard outbound
|
||||||
|
if !currentMeta.Resolved() {
|
||||||
|
ip, err := resolver.ResolveIP(ctx, currentMeta.Host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("can't resolve ip")
|
||||||
|
}
|
||||||
|
currentMeta.DstIP = ip
|
||||||
|
}
|
||||||
pc, err := p.listenPacket(ctx, currentMeta)
|
pc, err := p.listenPacket(ctx, currentMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var rAddr net.Addr
|
return N.NewBindPacketConn(pc, currentMeta.UDPAddr()), nil
|
||||||
if udpAddr := currentMeta.UDPAddr(); udpAddr != nil {
|
|
||||||
rAddr = udpAddr
|
|
||||||
} else { // the domain name was not resolved, will appear in not stream-oriented udp like Shadowsocks/Tuic
|
|
||||||
rAddr = N.NewCustomAddr("udp", currentMeta.RemoteAddress(), nil)
|
|
||||||
}
|
|
||||||
return N.NewBindPacketConn(pc, rAddr), nil
|
|
||||||
}
|
}
|
||||||
var conn C.Conn
|
var conn C.Conn
|
||||||
var err error
|
var err error
|
||||||
|
|
Loading…
Reference in a new issue