dae/component/outbound/dialer/direct.go

83 lines
1.8 KiB
Go
Raw Normal View History

2023-01-23 18:54:21 +07:00
package dialer
import (
"golang.org/x/net/proxy"
"net"
)
2023-01-27 01:10:27 +07:00
var SymmetricDirect = newDirect(false)
var FullconeDirect = newDirect(true)
2023-01-23 18:54:21 +07:00
2023-01-28 00:50:21 +07:00
func NewDirectDialer(option *GlobalOption, fullcone bool) *Dialer {
2023-01-27 01:10:27 +07:00
if fullcone {
return NewDialer(FullconeDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
2023-01-27 01:10:27 +07:00
} else {
return NewDialer(SymmetricDirect, option, InstanceOption{CheckEnabled: false}, "direct", "direct", "")
2023-01-27 01:10:27 +07:00
}
}
2023-01-23 18:54:21 +07:00
type direct struct {
proxy.Dialer
2023-01-28 00:50:21 +07:00
netDialer *net.Dialer
2023-01-23 18:54:21 +07:00
fullCone bool
}
2023-01-27 01:10:27 +07:00
func newDirect(fullCone bool) proxy.Dialer {
2023-01-23 18:54:21 +07:00
return &direct{
netDialer: &net.Dialer{},
fullCone: fullCone,
2023-01-23 18:54:21 +07:00
}
}
func (d *direct) Dial(network, addr string) (c net.Conn, err error) {
switch network {
case "tcp":
conn, err := d.netDialer.Dial(network, addr)
return conn, err
2023-01-23 18:54:21 +07:00
case "udp":
if d.fullCone {
conn, err := net.ListenUDP(network, nil)
2023-01-30 14:50:55 +07:00
if err != nil {
return nil, err
}
2023-01-23 18:54:21 +07:00
return &directUDPConn{UDPConn: conn, FullCone: true}, nil
} else {
conn, err := d.netDialer.Dial(network, addr)
if err != nil {
return nil, err
}
return &directUDPConn{UDPConn: conn.(*net.UDPConn), FullCone: false}, nil
}
default:
return nil, net.UnknownNetworkError(network)
}
}
type directUDPConn struct {
*net.UDPConn
FullCone bool
}
func (c *directUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
if !c.FullCone {
// FIXME: check the addr
return c.Write(b)
}
return c.UDPConn.WriteTo(b, addr)
}
func (c *directUDPConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) {
if !c.FullCone {
n, err = c.Write(b)
return n, 0, err
}
return c.UDPConn.WriteMsgUDP(b, oob, addr)
}
func (c *directUDPConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
if !c.FullCone {
return c.Write(b)
}
return c.UDPConn.WriteToUDP(b, addr)
}