1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-10 18:00:43 +00:00

use ListenPacket in Dial UDP connection

This commit is contained in:
Darien Raymond 2019-01-06 09:39:37 +01:00
parent 4e77570f36
commit a1b552f948
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169

View File

@ -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)
}