stack.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package nettest provides utilities for network testing.
  5. package nettest // import "golang.org/x/net/internal/nettest"
  6. import (
  7. "fmt"
  8. "io/ioutil"
  9. "net"
  10. "os"
  11. "runtime"
  12. )
  13. var (
  14. supportsIPv4 bool
  15. supportsIPv6 bool
  16. )
  17. func init() {
  18. if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
  19. ln.Close()
  20. supportsIPv4 = true
  21. }
  22. if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
  23. ln.Close()
  24. supportsIPv6 = true
  25. }
  26. }
  27. // SupportsIPv4 reports whether the platform supports IPv4 networking
  28. // functionality.
  29. func SupportsIPv4() bool { return supportsIPv4 }
  30. // SupportsIPv6 reports whether the platform supports IPv6 networking
  31. // functionality.
  32. func SupportsIPv6() bool { return supportsIPv6 }
  33. // SupportsRawIPSocket reports whether the platform supports raw IP
  34. // sockets.
  35. func SupportsRawIPSocket() (string, bool) {
  36. return supportsRawIPSocket()
  37. }
  38. // SupportsIPv6MulticastDeliveryOnLoopback reports whether the
  39. // platform supports IPv6 multicast packet delivery on software
  40. // loopback interface.
  41. func SupportsIPv6MulticastDeliveryOnLoopback() bool {
  42. return supportsIPv6MulticastDeliveryOnLoopback()
  43. }
  44. // ProtocolNotSupported reports whether err is a protocol not
  45. // supported error.
  46. func ProtocolNotSupported(err error) bool {
  47. return protocolNotSupported(err)
  48. }
  49. // TestableNetwork reports whether network is testable on the current
  50. // platform configuration.
  51. func TestableNetwork(network string) bool {
  52. // This is based on logic from standard library's
  53. // net/platform_test.go.
  54. switch network {
  55. case "unix", "unixgram":
  56. switch runtime.GOOS {
  57. case "android", "nacl", "plan9", "windows":
  58. return false
  59. }
  60. if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
  61. return false
  62. }
  63. case "unixpacket":
  64. switch runtime.GOOS {
  65. case "android", "darwin", "freebsd", "nacl", "plan9", "windows":
  66. return false
  67. }
  68. }
  69. return true
  70. }
  71. // NewLocalListener returns a listener which listens to a loopback IP
  72. // address or local file system path.
  73. // Network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
  74. func NewLocalListener(network string) (net.Listener, error) {
  75. switch network {
  76. case "tcp":
  77. if supportsIPv4 {
  78. if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
  79. return ln, nil
  80. }
  81. }
  82. if supportsIPv6 {
  83. return net.Listen("tcp6", "[::1]:0")
  84. }
  85. case "tcp4":
  86. if supportsIPv4 {
  87. return net.Listen("tcp4", "127.0.0.1:0")
  88. }
  89. case "tcp6":
  90. if supportsIPv6 {
  91. return net.Listen("tcp6", "[::1]:0")
  92. }
  93. case "unix", "unixpacket":
  94. return net.Listen(network, localPath())
  95. }
  96. return nil, fmt.Errorf("%s is not supported", network)
  97. }
  98. // NewLocalPacketListener returns a packet listener which listens to a
  99. // loopback IP address or local file system path.
  100. // Network must be "udp", "udp4", "udp6" or "unixgram".
  101. func NewLocalPacketListener(network string) (net.PacketConn, error) {
  102. switch network {
  103. case "udp":
  104. if supportsIPv4 {
  105. if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
  106. return c, nil
  107. }
  108. }
  109. if supportsIPv6 {
  110. return net.ListenPacket("udp6", "[::1]:0")
  111. }
  112. case "udp4":
  113. if supportsIPv4 {
  114. return net.ListenPacket("udp4", "127.0.0.1:0")
  115. }
  116. case "udp6":
  117. if supportsIPv6 {
  118. return net.ListenPacket("udp6", "[::1]:0")
  119. }
  120. case "unixgram":
  121. return net.ListenPacket(network, localPath())
  122. }
  123. return nil, fmt.Errorf("%s is not supported", network)
  124. }
  125. func localPath() string {
  126. f, err := ioutil.TempFile("", "nettest")
  127. if err != nil {
  128. panic(err)
  129. }
  130. path := f.Name()
  131. f.Close()
  132. os.Remove(path)
  133. return path
  134. }