diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index 78860e25d..6e95f84aa 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -7,6 +7,8 @@ import ( "github.com/v2ray/v2ray-core/app" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/common/retry" + "github.com/v2ray/v2ray-core/transport/dialer" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -15,8 +17,17 @@ type FreedomConnection struct { } func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error { - conn, err := net.Dial(firstPacket.Destination().Network(), firstPacket.Destination().NetAddr()) log.Info("Freedom: Opening connection to %s", firstPacket.Destination().String()) + + var conn net.Conn + err := retry.Timed(5, 100).On(func() error { + rawConn, err := dialer.Dial(firstPacket.Destination()) + if err != nil { + return err + } + conn = rawConn + return nil + }) if err != nil { close(ray.OutboundOutput()) log.Error("Freedom: Failed to open connection: %s : %v", firstPacket.Destination().String(), err) diff --git a/transport/dialer/dialer.go b/transport/dialer/dialer.go new file mode 100644 index 000000000..fdbf05e36 --- /dev/null +++ b/transport/dialer/dialer.go @@ -0,0 +1,44 @@ +package dialer + +import ( + "errors" + "math/rand" + "net" + + v2net "github.com/v2ray/v2ray-core/common/net" +) + +var ( + ErrInvalidHost = errors.New("Invalid Host.") +) + +func Dial(dest v2net.Destination) (net.Conn, error) { + var ip net.IP + if dest.Address().IsIPv4() || dest.Address().IsIPv6() { + ip = dest.Address().IP() + } else { + ips, err := net.LookupIP(dest.Address().Domain()) + if err != nil { + return nil, err + } + if len(ips) == 0 { + return nil, ErrInvalidHost + } + if len(ips) == 1 { + ip = ips[0] + } else { + ip = ips[rand.Intn(len(ips))] + } + } + if dest.IsTCP() { + return net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: ip, + Port: int(dest.Port()), + }) + } else { + return net.DialUDP("udp", nil, &net.UDPAddr{ + IP: ip, + Port: int(dest.Port()), + }) + } +}