mirror of https://github.com/v2ray/v2ray-core
use ListenPacket in Dial UDP connection
parent
4e77570f36
commit
a1b552f948
|
@ -21,10 +21,51 @@ type DefaultSystemDialer struct {
|
||||||
controllers []controller
|
controllers []controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveSrcAddr(network net.Network, src net.Address) net.Addr {
|
||||||
|
if src == nil || src == net.AnyIP {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if network == net.Network_TCP {
|
||||||
|
return &net.TCPAddr{
|
||||||
|
IP: src.IP(),
|
||||||
|
Port: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &net.UDPAddr{
|
||||||
|
IP: src.IP(),
|
||||||
|
Port: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {
|
func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {
|
||||||
|
if dest.Network == net.Network_UDP {
|
||||||
|
srcAddr := resolveSrcAddr(net.Network_UDP, src)
|
||||||
|
if srcAddr == nil {
|
||||||
|
srcAddr = &net.UDPAddr{
|
||||||
|
IP: []byte{0, 0, 0, 0},
|
||||||
|
Port: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packetConn, err := ListenSystemPacket(ctx, srcAddr, sockopt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
destAddr, err := net.ResolveUDPAddr("udp", dest.NetAddr())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &packetConnWrapper{
|
||||||
|
conn: packetConn,
|
||||||
|
dest: destAddr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
dialer := &net.Dialer{
|
dialer := &net.Dialer{
|
||||||
Timeout: time.Second * 60,
|
Timeout: time.Second * 60,
|
||||||
DualStack: true,
|
DualStack: true,
|
||||||
|
LocalAddr: resolveSrcAddr(dest.Network, src),
|
||||||
}
|
}
|
||||||
|
|
||||||
if sockopt != nil || len(d.controllers) > 0 {
|
if sockopt != nil || len(d.controllers) > 0 {
|
||||||
|
@ -50,24 +91,47 @@ func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest ne
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if src != nil && src != net.AnyIP {
|
|
||||||
var addr net.Addr
|
|
||||||
if dest.Network == net.Network_TCP {
|
|
||||||
addr = &net.TCPAddr{
|
|
||||||
IP: src.IP(),
|
|
||||||
Port: 0,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addr = &net.UDPAddr{
|
|
||||||
IP: src.IP(),
|
|
||||||
Port: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dialer.LocalAddr = addr
|
|
||||||
}
|
|
||||||
return dialer.DialContext(ctx, dest.Network.SystemString(), dest.NetAddr())
|
return dialer.DialContext(ctx, dest.Network.SystemString(), dest.NetAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type packetConnWrapper struct {
|
||||||
|
conn net.PacketConn
|
||||||
|
dest net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) Close() error {
|
||||||
|
return c.conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) LocalAddr() net.Addr {
|
||||||
|
return c.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) RemoteAddr() net.Addr {
|
||||||
|
return c.dest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) Write(p []byte) (int, error) {
|
||||||
|
return c.conn.WriteTo(p, c.dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) Read(p []byte) (int, error) {
|
||||||
|
n, _, err := c.conn.ReadFrom(p)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) SetDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) SetReadDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *packetConnWrapper) SetWriteDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetWriteDeadline(t)
|
||||||
|
}
|
||||||
|
|
||||||
type SystemDialerAdapter interface {
|
type SystemDialerAdapter interface {
|
||||||
Dial(network string, address string) (net.Conn, error)
|
Dial(network string, address string) (net.Conn, error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue