udp_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Copyright 2012 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 net
  5. import (
  6. "reflect"
  7. "runtime"
  8. "strings"
  9. "testing"
  10. "time"
  11. )
  12. func TestResolveUDPAddr(t *testing.T) {
  13. for _, tt := range resolveTCPAddrTests {
  14. net := strings.Replace(tt.net, "tcp", "udp", -1)
  15. addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
  16. if err != tt.err {
  17. t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
  18. }
  19. if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
  20. t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
  21. }
  22. if err == nil {
  23. str := addr.String()
  24. addr1, err := ResolveUDPAddr(net, str)
  25. if err != nil {
  26. t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
  27. }
  28. if !reflect.DeepEqual(addr1, addr) {
  29. t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
  30. }
  31. }
  32. }
  33. }
  34. func TestReadFromUDP(t *testing.T) {
  35. switch runtime.GOOS {
  36. case "nacl", "plan9":
  37. t.Skipf("skipping test on %q, see issue 8916", runtime.GOOS)
  38. }
  39. ra, err := ResolveUDPAddr("udp", "127.0.0.1:7")
  40. if err != nil {
  41. t.Fatal(err)
  42. }
  43. la, err := ResolveUDPAddr("udp", "127.0.0.1:0")
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. c, err := ListenUDP("udp", la)
  48. if err != nil {
  49. t.Fatal(err)
  50. }
  51. defer c.Close()
  52. _, err = c.WriteToUDP([]byte("a"), ra)
  53. if err != nil {
  54. t.Fatal(err)
  55. }
  56. err = c.SetDeadline(time.Now().Add(100 * time.Millisecond))
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. b := make([]byte, 1)
  61. _, _, err = c.ReadFromUDP(b)
  62. if err == nil {
  63. t.Fatal("ReadFromUDP should fail")
  64. } else if !isTimeout(err) {
  65. t.Fatal(err)
  66. }
  67. }
  68. func TestWriteToUDP(t *testing.T) {
  69. switch runtime.GOOS {
  70. case "plan9":
  71. t.Skipf("skipping test on %q", runtime.GOOS)
  72. }
  73. l, err := ListenPacket("udp", "127.0.0.1:0")
  74. if err != nil {
  75. t.Fatalf("Listen failed: %v", err)
  76. }
  77. defer l.Close()
  78. testWriteToConn(t, l.LocalAddr().String())
  79. testWriteToPacketConn(t, l.LocalAddr().String())
  80. }
  81. func testWriteToConn(t *testing.T, raddr string) {
  82. c, err := Dial("udp", raddr)
  83. if err != nil {
  84. t.Fatalf("Dial failed: %v", err)
  85. }
  86. defer c.Close()
  87. ra, err := ResolveUDPAddr("udp", raddr)
  88. if err != nil {
  89. t.Fatalf("ResolveUDPAddr failed: %v", err)
  90. }
  91. _, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
  92. if err == nil {
  93. t.Fatal("WriteToUDP should fail")
  94. }
  95. if err != nil && err.(*OpError).Err != ErrWriteToConnected {
  96. t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
  97. }
  98. _, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
  99. if err == nil {
  100. t.Fatal("WriteTo should fail")
  101. }
  102. if err != nil && err.(*OpError).Err != ErrWriteToConnected {
  103. t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
  104. }
  105. _, err = c.Write([]byte("Connection-oriented mode socket"))
  106. if err != nil {
  107. t.Fatalf("Write failed: %v", err)
  108. }
  109. }
  110. func testWriteToPacketConn(t *testing.T, raddr string) {
  111. c, err := ListenPacket("udp", "127.0.0.1:0")
  112. if err != nil {
  113. t.Fatalf("ListenPacket failed: %v", err)
  114. }
  115. defer c.Close()
  116. ra, err := ResolveUDPAddr("udp", raddr)
  117. if err != nil {
  118. t.Fatalf("ResolveUDPAddr failed: %v", err)
  119. }
  120. _, err = c.(*UDPConn).WriteToUDP([]byte("Connection-less mode socket"), ra)
  121. if err != nil {
  122. t.Fatalf("WriteToUDP failed: %v", err)
  123. }
  124. _, err = c.WriteTo([]byte("Connection-less mode socket"), ra)
  125. if err != nil {
  126. t.Fatalf("WriteTo failed: %v", err)
  127. }
  128. _, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
  129. if err == nil {
  130. t.Fatal("Write should fail")
  131. }
  132. }
  133. var udpConnLocalNameTests = []struct {
  134. net string
  135. laddr *UDPAddr
  136. }{
  137. {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
  138. {"udp4", &UDPAddr{}},
  139. {"udp4", nil},
  140. }
  141. func TestUDPConnLocalName(t *testing.T) {
  142. if testing.Short() || !*testExternal {
  143. t.Skip("skipping test to avoid external network")
  144. }
  145. for _, tt := range udpConnLocalNameTests {
  146. c, err := ListenUDP(tt.net, tt.laddr)
  147. if err != nil {
  148. t.Fatalf("ListenUDP failed: %v", err)
  149. }
  150. defer c.Close()
  151. la := c.LocalAddr()
  152. if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
  153. t.Fatalf("got %v; expected a proper address with non-zero port number", la)
  154. }
  155. }
  156. }
  157. func TestUDPConnLocalAndRemoteNames(t *testing.T) {
  158. for _, laddr := range []string{"", "127.0.0.1:0"} {
  159. c1, err := ListenPacket("udp", "127.0.0.1:0")
  160. if err != nil {
  161. t.Fatalf("ListenUDP failed: %v", err)
  162. }
  163. defer c1.Close()
  164. var la *UDPAddr
  165. if laddr != "" {
  166. var err error
  167. if la, err = ResolveUDPAddr("udp", laddr); err != nil {
  168. t.Fatalf("ResolveUDPAddr failed: %v", err)
  169. }
  170. }
  171. c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
  172. if err != nil {
  173. t.Fatalf("DialUDP failed: %v", err)
  174. }
  175. defer c2.Close()
  176. var connAddrs = [4]struct {
  177. got Addr
  178. ok bool
  179. }{
  180. {c1.LocalAddr(), true},
  181. {c1.(*UDPConn).RemoteAddr(), false},
  182. {c2.LocalAddr(), true},
  183. {c2.RemoteAddr(), true},
  184. }
  185. for _, ca := range connAddrs {
  186. if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
  187. t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
  188. }
  189. }
  190. }
  191. }
  192. func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
  193. if testing.Short() || !*testExternal {
  194. t.Skip("skipping test to avoid external network")
  195. }
  196. if !supportsIPv6 {
  197. t.Skip("ipv6 is not supported")
  198. }
  199. ifi := loopbackInterface()
  200. if ifi == nil {
  201. t.Skip("loopback interface not found")
  202. }
  203. laddr := ipv6LinkLocalUnicastAddr(ifi)
  204. if laddr == "" {
  205. t.Skip("ipv6 unicast address on loopback not found")
  206. }
  207. type test struct {
  208. net, addr string
  209. nameLookup bool
  210. }
  211. var tests = []test{
  212. {"udp", "[" + laddr + "%" + ifi.Name + "]:0", false},
  213. {"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
  214. }
  215. // The first udp test fails on DragonFly - see issue 7473.
  216. if runtime.GOOS == "dragonfly" {
  217. tests = tests[1:]
  218. }
  219. switch runtime.GOOS {
  220. case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
  221. tests = append(tests, []test{
  222. {"udp", "[localhost%" + ifi.Name + "]:0", true},
  223. {"udp6", "[localhost%" + ifi.Name + "]:0", true},
  224. }...)
  225. case "linux":
  226. tests = append(tests, []test{
  227. {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
  228. {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
  229. }...)
  230. }
  231. for _, tt := range tests {
  232. c1, err := ListenPacket(tt.net, tt.addr)
  233. if err != nil {
  234. // It might return "LookupHost returned no
  235. // suitable address" error on some platforms.
  236. t.Logf("ListenPacket failed: %v", err)
  237. continue
  238. }
  239. defer c1.Close()
  240. if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  241. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  242. }
  243. c2, err := Dial(tt.net, c1.LocalAddr().String())
  244. if err != nil {
  245. t.Fatalf("Dial failed: %v", err)
  246. }
  247. defer c2.Close()
  248. if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  249. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  250. }
  251. if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
  252. t.Fatalf("got %v; expected a proper address with zone identifier", ra)
  253. }
  254. if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
  255. t.Fatalf("Conn.Write failed: %v", err)
  256. }
  257. b := make([]byte, 32)
  258. if _, from, err := c1.ReadFrom(b); err != nil {
  259. t.Fatalf("PacketConn.ReadFrom failed: %v", err)
  260. } else {
  261. if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
  262. t.Fatalf("got %v; expected a proper address with zone identifier", ra)
  263. }
  264. }
  265. }
  266. }