github.com/eagleql/xray-core@v1.4.4/transport/internet/dialer.go (about)

     1  package internet
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/eagleql/xray-core/common/net"
     7  	"github.com/eagleql/xray-core/common/session"
     8  )
     9  
    10  // Dialer is the interface for dialing outbound connections.
    11  type Dialer interface {
    12  	// Dial dials a system connection to the given destination.
    13  	Dial(ctx context.Context, destination net.Destination) (Connection, error)
    14  
    15  	// Address returns the address used by this Dialer. Maybe nil if not known.
    16  	Address() net.Address
    17  }
    18  
    19  // dialFunc is an interface to dial network connection to a specific destination.
    20  type dialFunc func(ctx context.Context, dest net.Destination, streamSettings *MemoryStreamConfig) (Connection, error)
    21  
    22  var (
    23  	transportDialerCache = make(map[string]dialFunc)
    24  )
    25  
    26  // RegisterTransportDialer registers a Dialer with given name.
    27  func RegisterTransportDialer(protocol string, dialer dialFunc) error {
    28  	if _, found := transportDialerCache[protocol]; found {
    29  		return newError(protocol, " dialer already registered").AtError()
    30  	}
    31  	transportDialerCache[protocol] = dialer
    32  	return nil
    33  }
    34  
    35  // Dial dials a internet connection towards the given destination.
    36  func Dial(ctx context.Context, dest net.Destination, streamSettings *MemoryStreamConfig) (Connection, error) {
    37  	if dest.Network == net.Network_TCP {
    38  		if streamSettings == nil {
    39  			s, err := ToMemoryStreamConfig(nil)
    40  			if err != nil {
    41  				return nil, newError("failed to create default stream settings").Base(err)
    42  			}
    43  			streamSettings = s
    44  		}
    45  
    46  		protocol := streamSettings.ProtocolName
    47  		dialer := transportDialerCache[protocol]
    48  		if dialer == nil {
    49  			return nil, newError(protocol, " dialer not registered").AtError()
    50  		}
    51  		return dialer(ctx, dest, streamSettings)
    52  	}
    53  
    54  	if dest.Network == net.Network_UDP {
    55  		udpDialer := transportDialerCache["udp"]
    56  		if udpDialer == nil {
    57  			return nil, newError("UDP dialer not registered").AtError()
    58  		}
    59  		return udpDialer(ctx, dest, streamSettings)
    60  	}
    61  
    62  	return nil, newError("unknown network ", dest.Network)
    63  }
    64  
    65  // DialSystem calls system dialer to create a network connection.
    66  func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {
    67  	var src net.Address
    68  	if outbound := session.OutboundFromContext(ctx); outbound != nil {
    69  		src = outbound.Gateway
    70  	}
    71  	return effectiveSystemDialer.Dial(ctx, src, dest, sockopt)
    72  }