github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/net/destination.go (about)

     1  package net
     2  
     3  import (
     4  	"net"
     5  	"strings"
     6  )
     7  
     8  // Destination represents a network destination including address and protocol (tcp / udp).
     9  type Destination struct {
    10  	Address Address
    11  	Port    Port
    12  	Network Network
    13  }
    14  
    15  // DestinationFromAddr generates a Destination from a net address.
    16  func DestinationFromAddr(addr net.Addr) Destination {
    17  	switch addr := addr.(type) {
    18  	case *net.TCPAddr:
    19  		return TCPDestination(IPAddress(addr.IP), Port(addr.Port))
    20  	case *net.UDPAddr:
    21  		return UDPDestination(IPAddress(addr.IP), Port(addr.Port))
    22  	case *net.UnixAddr:
    23  		return UnixDestination(DomainAddress(addr.Name))
    24  	default:
    25  		panic("Net: Unknown address type.")
    26  	}
    27  }
    28  
    29  // ParseDestination converts a destination from its string presentation.
    30  func ParseDestination(dest string) (Destination, error) {
    31  	d := Destination{
    32  		Address: AnyIP,
    33  		Port:    Port(0),
    34  	}
    35  
    36  	switch {
    37  	case strings.HasPrefix(dest, "tcp:"):
    38  		d.Network = Network_TCP
    39  		dest = dest[4:]
    40  	case strings.HasPrefix(dest, "udp:"):
    41  		d.Network = Network_UDP
    42  		dest = dest[4:]
    43  	case strings.HasPrefix(dest, "unix:"):
    44  		d = UnixDestination(DomainAddress(dest[5:]))
    45  		return d, nil
    46  	}
    47  
    48  	hstr, pstr, err := SplitHostPort(dest)
    49  	if err != nil {
    50  		return d, err
    51  	}
    52  	if len(hstr) > 0 {
    53  		d.Address = ParseAddress(hstr)
    54  	}
    55  	if len(pstr) > 0 {
    56  		port, err := PortFromString(pstr)
    57  		if err != nil {
    58  			return d, err
    59  		}
    60  		d.Port = port
    61  	}
    62  	return d, nil
    63  }
    64  
    65  // TCPDestination creates a TCP destination with given address
    66  func TCPDestination(address Address, port Port) Destination {
    67  	return Destination{
    68  		Network: Network_TCP,
    69  		Address: address,
    70  		Port:    port,
    71  	}
    72  }
    73  
    74  // UDPDestination creates a UDP destination with given address
    75  func UDPDestination(address Address, port Port) Destination {
    76  	return Destination{
    77  		Network: Network_UDP,
    78  		Address: address,
    79  		Port:    port,
    80  	}
    81  }
    82  
    83  // UnixDestination creates a Unix destination with given address
    84  func UnixDestination(address Address) Destination {
    85  	return Destination{
    86  		Network: Network_UNIX,
    87  		Address: address,
    88  	}
    89  }
    90  
    91  // NetAddr returns the network address in this Destination in string form.
    92  func (d Destination) NetAddr() string {
    93  	addr := ""
    94  	if d.Network == Network_TCP || d.Network == Network_UDP {
    95  		addr = d.Address.String() + ":" + d.Port.String()
    96  	} else if d.Network == Network_UNIX {
    97  		addr = d.Address.String()
    98  	}
    99  	return addr
   100  }
   101  
   102  // String returns the strings form of this Destination.
   103  func (d Destination) String() string {
   104  	prefix := "unknown:"
   105  	switch d.Network {
   106  	case Network_TCP:
   107  		prefix = "tcp:"
   108  	case Network_UDP:
   109  		prefix = "udp:"
   110  	case Network_UNIX:
   111  		prefix = "unix:"
   112  	}
   113  	return prefix + d.NetAddr()
   114  }
   115  
   116  // IsValid returns true if this Destination is valid.
   117  func (d Destination) IsValid() bool {
   118  	return d.Network != Network_Unknown
   119  }
   120  
   121  // AsDestination converts current Endpoint into Destination.
   122  func (p *Endpoint) AsDestination() Destination {
   123  	return Destination{
   124  		Network: p.Network,
   125  		Address: p.Address.AsAddress(),
   126  		Port:    Port(p.Port),
   127  	}
   128  }