github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/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  	if strings.HasPrefix(dest, "tcp:") {
    36  		d.Network = Network_TCP
    37  		dest = dest[4:]
    38  	} else if strings.HasPrefix(dest, "udp:") {
    39  		d.Network = Network_UDP
    40  		dest = dest[4:]
    41  	} else if strings.HasPrefix(dest, "unix:") {
    42  		d = UnixDestination(DomainAddress(dest[5:]))
    43  		return d, nil
    44  	}
    45  
    46  	hstr, pstr, err := SplitHostPort(dest)
    47  	if err != nil {
    48  		return d, err
    49  	}
    50  	if len(hstr) > 0 {
    51  		d.Address = ParseAddress(hstr)
    52  	}
    53  	if len(pstr) > 0 {
    54  		port, err := PortFromString(pstr)
    55  		if err != nil {
    56  			return d, err
    57  		}
    58  		d.Port = port
    59  	}
    60  	return d, nil
    61  }
    62  
    63  // TCPDestination creates a TCP destination with given address
    64  func TCPDestination(address Address, port Port) Destination {
    65  	return Destination{
    66  		Network: Network_TCP,
    67  		Address: address,
    68  		Port:    port,
    69  	}
    70  }
    71  
    72  // UDPDestination creates a UDP destination with given address
    73  func UDPDestination(address Address, port Port) Destination {
    74  	return Destination{
    75  		Network: Network_UDP,
    76  		Address: address,
    77  		Port:    port,
    78  	}
    79  }
    80  
    81  // UnixDestination creates a Unix destination with given address
    82  func UnixDestination(address Address) Destination {
    83  	return Destination{
    84  		Network: Network_UNIX,
    85  		Address: address,
    86  	}
    87  }
    88  
    89  // NetAddr returns the network address in this Destination in string form.
    90  func (d Destination) NetAddr() string {
    91  	addr := ""
    92  	if d.Network == Network_TCP || d.Network == Network_UDP {
    93  		addr = d.Address.String() + ":" + d.Port.String()
    94  	} else if d.Network == Network_UNIX {
    95  		addr = d.Address.String()
    96  	}
    97  	return addr
    98  }
    99  
   100  // RawNetAddr converts a net.Addr from its Destination presentation.
   101  func (d Destination) RawNetAddr() net.Addr {
   102  	var addr net.Addr
   103  	switch d.Network {
   104  	case Network_TCP:
   105  		if d.Address.Family().IsIP() {
   106  			addr = &net.TCPAddr{
   107  				IP:   d.Address.IP(),
   108  				Port: int(d.Port),
   109  			}
   110  		}
   111  	case Network_UDP:
   112  		if d.Address.Family().IsIP() {
   113  			addr = &net.UDPAddr{
   114  				IP:   d.Address.IP(),
   115  				Port: int(d.Port),
   116  			}
   117  		}
   118  	case Network_UNIX:
   119  		if d.Address.Family().IsDomain() {
   120  			addr = &net.UnixAddr{
   121  				Name: d.Address.String(),
   122  				Net:  d.Network.SystemString(),
   123  			}
   124  		}
   125  	}
   126  	return addr
   127  }
   128  
   129  // String returns the strings form of this Destination.
   130  func (d Destination) String() string {
   131  	prefix := "unknown:"
   132  	switch d.Network {
   133  	case Network_TCP:
   134  		prefix = "tcp:"
   135  	case Network_UDP:
   136  		prefix = "udp:"
   137  	case Network_UNIX:
   138  		prefix = "unix:"
   139  	}
   140  	return prefix + d.NetAddr()
   141  }
   142  
   143  // IsValid returns true if this Destination is valid.
   144  func (d Destination) IsValid() bool {
   145  	return d.Network != Network_Unknown
   146  }
   147  
   148  // AsDestination converts current Endpoint into Destination.
   149  func (p *Endpoint) AsDestination() Destination {
   150  	return Destination{
   151  		Network: p.Network,
   152  		Address: p.Address.AsAddress(),
   153  		Port:    Port(p.Port),
   154  	}
   155  }