destination.go 3.5 KB

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