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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
	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{
 | 
			
		||||
		Timeout:   time.Second * 60,
 | 
			
		||||
		DualStack: true,
 | 
			
		||||
		LocalAddr: resolveSrcAddr(dest.Network, src),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	Dial(network string, address string) (net.Conn, error)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue