udpsock_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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. //go:build !js
  5. package net
  6. import (
  7. "errors"
  8. "internal/testenv"
  9. "os"
  10. "reflect"
  11. "runtime"
  12. "testing"
  13. "time"
  14. )
  15. func BenchmarkUDP6LinkLocalUnicast(b *testing.B) {
  16. testHookUninstaller.Do(uninstallTestHooks)
  17. if !supportsIPv6() {
  18. b.Skip("IPv6 is not supported")
  19. }
  20. ifi := loopbackInterface()
  21. if ifi == nil {
  22. b.Skip("loopback interface not found")
  23. }
  24. lla := ipv6LinkLocalUnicastAddr(ifi)
  25. if lla == "" {
  26. b.Skip("IPv6 link-local unicast address not found")
  27. }
  28. c1, err := ListenPacket("udp6", JoinHostPort(lla+"%"+ifi.Name, "0"))
  29. if err != nil {
  30. b.Fatal(err)
  31. }
  32. defer c1.Close()
  33. c2, err := ListenPacket("udp6", JoinHostPort(lla+"%"+ifi.Name, "0"))
  34. if err != nil {
  35. b.Fatal(err)
  36. }
  37. defer c2.Close()
  38. var buf [1]byte
  39. for i := 0; i < b.N; i++ {
  40. if _, err := c1.WriteTo(buf[:], c2.LocalAddr()); err != nil {
  41. b.Fatal(err)
  42. }
  43. if _, _, err := c2.ReadFrom(buf[:]); err != nil {
  44. b.Fatal(err)
  45. }
  46. }
  47. }
  48. type resolveUDPAddrTest struct {
  49. network string
  50. litAddrOrName string
  51. addr *UDPAddr
  52. err error
  53. }
  54. var resolveUDPAddrTests = []resolveUDPAddrTest{
  55. {"udp", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
  56. {"udp4", "127.0.0.1:65535", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
  57. {"udp", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil},
  58. {"udp6", "[::1]:65535", &UDPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
  59. {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
  60. {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
  61. {"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
  62. {"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior
  63. {"udp", ":12345", &UDPAddr{Port: 12345}, nil},
  64. {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
  65. {"udp", "127.0.0.1:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil},
  66. {"udp", "[::ffff:127.0.0.1]:domain", &UDPAddr{IP: ParseIP("::ffff:127.0.0.1"), Port: 53}, nil},
  67. {"udp", "[2001:db8::1]:domain", &UDPAddr{IP: ParseIP("2001:db8::1"), Port: 53}, nil},
  68. {"udp4", "127.0.0.1:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil},
  69. {"udp4", "[::ffff:127.0.0.1]:domain", &UDPAddr{IP: ParseIP("127.0.0.1"), Port: 53}, nil},
  70. {"udp6", "[2001:db8::1]:domain", &UDPAddr{IP: ParseIP("2001:db8::1"), Port: 53}, nil},
  71. {"udp4", "[2001:db8::1]:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "2001:db8::1"}},
  72. {"udp6", "127.0.0.1:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "127.0.0.1"}},
  73. {"udp6", "[::ffff:127.0.0.1]:domain", nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: "::ffff:127.0.0.1"}},
  74. }
  75. func TestResolveUDPAddr(t *testing.T) {
  76. origTestHookLookupIP := testHookLookupIP
  77. defer func() { testHookLookupIP = origTestHookLookupIP }()
  78. testHookLookupIP = lookupLocalhost
  79. for _, tt := range resolveUDPAddrTests {
  80. addr, err := ResolveUDPAddr(tt.network, tt.litAddrOrName)
  81. if !reflect.DeepEqual(addr, tt.addr) || !reflect.DeepEqual(err, tt.err) {
  82. t.Errorf("ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr, err, tt.addr, tt.err)
  83. continue
  84. }
  85. if err == nil {
  86. addr2, err := ResolveUDPAddr(addr.Network(), addr.String())
  87. if !reflect.DeepEqual(addr2, tt.addr) || err != tt.err {
  88. t.Errorf("(%q, %q): ResolveUDPAddr(%q, %q) = %#v, %v, want %#v, %v", tt.network, tt.litAddrOrName, addr.Network(), addr.String(), addr2, err, tt.addr, tt.err)
  89. }
  90. }
  91. }
  92. }
  93. func TestWriteToUDP(t *testing.T) {
  94. switch runtime.GOOS {
  95. case "plan9":
  96. t.Skipf("not supported on %s", runtime.GOOS)
  97. }
  98. c, err := ListenPacket("udp", "127.0.0.1:0")
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. defer c.Close()
  103. testWriteToConn(t, c.LocalAddr().String())
  104. testWriteToPacketConn(t, c.LocalAddr().String())
  105. }
  106. func testWriteToConn(t *testing.T, raddr string) {
  107. c, err := Dial("udp", raddr)
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. defer c.Close()
  112. ra, err := ResolveUDPAddr("udp", raddr)
  113. if err != nil {
  114. t.Fatal(err)
  115. }
  116. b := []byte("CONNECTED-MODE SOCKET")
  117. _, err = c.(*UDPConn).WriteToUDP(b, ra)
  118. if err == nil {
  119. t.Fatal("should fail")
  120. }
  121. if err != nil && err.(*OpError).Err != ErrWriteToConnected {
  122. t.Fatalf("should fail as ErrWriteToConnected: %v", err)
  123. }
  124. _, err = c.(*UDPConn).WriteTo(b, ra)
  125. if err == nil {
  126. t.Fatal("should fail")
  127. }
  128. if err != nil && err.(*OpError).Err != ErrWriteToConnected {
  129. t.Fatalf("should fail as ErrWriteToConnected: %v", err)
  130. }
  131. _, err = c.Write(b)
  132. if err != nil {
  133. t.Fatal(err)
  134. }
  135. _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
  136. if err == nil {
  137. t.Fatal("should fail")
  138. }
  139. if err != nil && err.(*OpError).Err != ErrWriteToConnected {
  140. t.Fatalf("should fail as ErrWriteToConnected: %v", err)
  141. }
  142. _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
  143. if err != nil {
  144. t.Fatal(err)
  145. }
  146. }
  147. func testWriteToPacketConn(t *testing.T, raddr string) {
  148. c, err := ListenPacket("udp", "127.0.0.1:0")
  149. if err != nil {
  150. t.Fatal(err)
  151. }
  152. defer c.Close()
  153. ra, err := ResolveUDPAddr("udp", raddr)
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. b := []byte("UNCONNECTED-MODE SOCKET")
  158. _, err = c.(*UDPConn).WriteToUDP(b, ra)
  159. if err != nil {
  160. t.Fatal(err)
  161. }
  162. _, err = c.WriteTo(b, ra)
  163. if err != nil {
  164. t.Fatal(err)
  165. }
  166. _, err = c.(*UDPConn).Write(b)
  167. if err == nil {
  168. t.Fatal("should fail")
  169. }
  170. _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil)
  171. if err == nil {
  172. t.Fatal("should fail")
  173. }
  174. if err != nil && err.(*OpError).Err != errMissingAddress {
  175. t.Fatalf("should fail as errMissingAddress: %v", err)
  176. }
  177. _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra)
  178. if err != nil {
  179. t.Fatal(err)
  180. }
  181. }
  182. var udpConnLocalNameTests = []struct {
  183. net string
  184. laddr *UDPAddr
  185. }{
  186. {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
  187. {"udp4", &UDPAddr{}},
  188. {"udp4", nil},
  189. }
  190. func TestUDPConnLocalName(t *testing.T) {
  191. testenv.MustHaveExternalNetwork(t)
  192. for _, tt := range udpConnLocalNameTests {
  193. c, err := ListenUDP(tt.net, tt.laddr)
  194. if err != nil {
  195. t.Fatal(err)
  196. }
  197. defer c.Close()
  198. la := c.LocalAddr()
  199. if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
  200. t.Fatalf("got %v; expected a proper address with non-zero port number", la)
  201. }
  202. }
  203. }
  204. func TestUDPConnLocalAndRemoteNames(t *testing.T) {
  205. for _, laddr := range []string{"", "127.0.0.1:0"} {
  206. c1, err := ListenPacket("udp", "127.0.0.1:0")
  207. if err != nil {
  208. t.Fatal(err)
  209. }
  210. defer c1.Close()
  211. var la *UDPAddr
  212. if laddr != "" {
  213. var err error
  214. if la, err = ResolveUDPAddr("udp", laddr); err != nil {
  215. t.Fatal(err)
  216. }
  217. }
  218. c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
  219. if err != nil {
  220. t.Fatal(err)
  221. }
  222. defer c2.Close()
  223. var connAddrs = [4]struct {
  224. got Addr
  225. ok bool
  226. }{
  227. {c1.LocalAddr(), true},
  228. {c1.(*UDPConn).RemoteAddr(), false},
  229. {c2.LocalAddr(), true},
  230. {c2.RemoteAddr(), true},
  231. }
  232. for _, ca := range connAddrs {
  233. if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
  234. t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
  235. }
  236. }
  237. }
  238. }
  239. func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
  240. testenv.MustHaveExternalNetwork(t)
  241. if !supportsIPv6() {
  242. t.Skip("IPv6 is not supported")
  243. }
  244. for i, tt := range ipv6LinkLocalUnicastUDPTests {
  245. c1, err := ListenPacket(tt.network, tt.address)
  246. if err != nil {
  247. // It might return "LookupHost returned no
  248. // suitable address" error on some platforms.
  249. t.Log(err)
  250. continue
  251. }
  252. ls := (&packetListener{PacketConn: c1}).newLocalServer()
  253. defer ls.teardown()
  254. ch := make(chan error, 1)
  255. handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, ch) }
  256. if err := ls.buildup(handler); err != nil {
  257. t.Fatal(err)
  258. }
  259. if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  260. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  261. }
  262. c2, err := Dial(tt.network, ls.PacketConn.LocalAddr().String())
  263. if err != nil {
  264. t.Fatal(err)
  265. }
  266. defer c2.Close()
  267. if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  268. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  269. }
  270. if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
  271. t.Fatalf("got %v; expected a proper address with zone identifier", ra)
  272. }
  273. if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
  274. t.Fatal(err)
  275. }
  276. b := make([]byte, 32)
  277. if _, err := c2.Read(b); err != nil {
  278. t.Fatal(err)
  279. }
  280. for err := range ch {
  281. t.Errorf("#%d: %v", i, err)
  282. }
  283. }
  284. }
  285. func TestUDPZeroBytePayload(t *testing.T) {
  286. switch runtime.GOOS {
  287. case "plan9":
  288. t.Skipf("not supported on %s", runtime.GOOS)
  289. case "darwin", "ios":
  290. testenv.SkipFlaky(t, 29225)
  291. }
  292. c := newLocalPacketListener(t, "udp")
  293. defer c.Close()
  294. for _, genericRead := range []bool{false, true} {
  295. n, err := c.WriteTo(nil, c.LocalAddr())
  296. if err != nil {
  297. t.Fatal(err)
  298. }
  299. if n != 0 {
  300. t.Errorf("got %d; want 0", n)
  301. }
  302. c.SetReadDeadline(time.Now().Add(30 * time.Second))
  303. var b [1]byte
  304. var name string
  305. if genericRead {
  306. _, err = c.(Conn).Read(b[:])
  307. name = "Read"
  308. } else {
  309. _, _, err = c.ReadFrom(b[:])
  310. name = "ReadFrom"
  311. }
  312. if err != nil {
  313. t.Errorf("%s of zero byte packet failed: %v", name, err)
  314. }
  315. }
  316. }
  317. func TestUDPZeroByteBuffer(t *testing.T) {
  318. switch runtime.GOOS {
  319. case "plan9":
  320. t.Skipf("not supported on %s", runtime.GOOS)
  321. }
  322. c := newLocalPacketListener(t, "udp")
  323. defer c.Close()
  324. b := []byte("UDP ZERO BYTE BUFFER TEST")
  325. for _, genericRead := range []bool{false, true} {
  326. n, err := c.WriteTo(b, c.LocalAddr())
  327. if err != nil {
  328. t.Fatal(err)
  329. }
  330. if n != len(b) {
  331. t.Errorf("got %d; want %d", n, len(b))
  332. }
  333. c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
  334. if genericRead {
  335. _, err = c.(Conn).Read(nil)
  336. } else {
  337. _, _, err = c.ReadFrom(nil)
  338. }
  339. switch err {
  340. case nil: // ReadFrom succeeds
  341. default: // Read may timeout, it depends on the platform
  342. if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE
  343. t.Fatal(err)
  344. }
  345. }
  346. }
  347. }
  348. func TestUDPReadSizeError(t *testing.T) {
  349. switch runtime.GOOS {
  350. case "plan9":
  351. t.Skipf("not supported on %s", runtime.GOOS)
  352. }
  353. c1 := newLocalPacketListener(t, "udp")
  354. defer c1.Close()
  355. c2, err := Dial("udp", c1.LocalAddr().String())
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. defer c2.Close()
  360. b1 := []byte("READ SIZE ERROR TEST")
  361. for _, genericRead := range []bool{false, true} {
  362. n, err := c2.Write(b1)
  363. if err != nil {
  364. t.Fatal(err)
  365. }
  366. if n != len(b1) {
  367. t.Errorf("got %d; want %d", n, len(b1))
  368. }
  369. b2 := make([]byte, len(b1)-1)
  370. if genericRead {
  371. n, err = c1.(Conn).Read(b2)
  372. } else {
  373. n, _, err = c1.ReadFrom(b2)
  374. }
  375. if err != nil && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE
  376. t.Fatal(err)
  377. }
  378. if n != len(b1)-1 {
  379. t.Fatalf("got %d; want %d", n, len(b1)-1)
  380. }
  381. }
  382. }
  383. // TestUDPReadTimeout verifies that ReadFromUDP with timeout returns an error
  384. // without data or an address.
  385. func TestUDPReadTimeout(t *testing.T) {
  386. la, err := ResolveUDPAddr("udp4", "127.0.0.1:0")
  387. if err != nil {
  388. t.Fatal(err)
  389. }
  390. c, err := ListenUDP("udp4", la)
  391. if err != nil {
  392. t.Fatal(err)
  393. }
  394. defer c.Close()
  395. c.SetDeadline(time.Now())
  396. b := make([]byte, 1)
  397. n, addr, err := c.ReadFromUDP(b)
  398. if !errors.Is(err, os.ErrDeadlineExceeded) {
  399. t.Errorf("ReadFromUDP got err %v want os.ErrDeadlineExceeded", err)
  400. }
  401. if n != 0 {
  402. t.Errorf("ReadFromUDP got n %d want 0", n)
  403. }
  404. if addr != nil {
  405. t.Errorf("ReadFromUDP got addr %+#v want nil", addr)
  406. }
  407. }
  408. func TestAllocs(t *testing.T) {
  409. switch runtime.GOOS {
  410. case "plan9":
  411. // Plan9 wasn't optimized.
  412. t.Skipf("skipping on %v", runtime.GOOS)
  413. }
  414. builder := os.Getenv("GO_BUILDER_NAME")
  415. switch builder {
  416. case "linux-amd64-noopt":
  417. // Optimizations are required to remove the allocs.
  418. t.Skipf("skipping on %v", builder)
  419. }
  420. conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
  421. if err != nil {
  422. t.Fatal(err)
  423. }
  424. defer conn.Close()
  425. addr := conn.LocalAddr()
  426. addrPort := addr.(*UDPAddr).AddrPort()
  427. buf := make([]byte, 8)
  428. allocs := testing.AllocsPerRun(1000, func() {
  429. _, _, err := conn.WriteMsgUDPAddrPort(buf, nil, addrPort)
  430. if err != nil {
  431. t.Fatal(err)
  432. }
  433. _, _, _, _, err = conn.ReadMsgUDPAddrPort(buf, nil)
  434. if err != nil {
  435. t.Fatal(err)
  436. }
  437. })
  438. if got := int(allocs); got != 0 {
  439. t.Errorf("WriteMsgUDPAddrPort/ReadMsgUDPAddrPort allocated %d objects", got)
  440. }
  441. allocs = testing.AllocsPerRun(1000, func() {
  442. _, err := conn.WriteToUDPAddrPort(buf, addrPort)
  443. if err != nil {
  444. t.Fatal(err)
  445. }
  446. _, _, err = conn.ReadFromUDPAddrPort(buf)
  447. if err != nil {
  448. t.Fatal(err)
  449. }
  450. })
  451. if got := int(allocs); got != 0 {
  452. t.Errorf("WriteToUDPAddrPort/ReadFromUDPAddrPort allocated %d objects", got)
  453. }
  454. allocs = testing.AllocsPerRun(1000, func() {
  455. _, err := conn.WriteTo(buf, addr)
  456. if err != nil {
  457. t.Fatal(err)
  458. }
  459. _, _, err = conn.ReadFromUDP(buf)
  460. if err != nil {
  461. t.Fatal(err)
  462. }
  463. })
  464. if got := int(allocs); got != 1 {
  465. if runtime.Compiler != "gccgo" {
  466. t.Errorf("WriteTo/ReadFromUDP allocated %d objects", got)
  467. }
  468. }
  469. }
  470. func BenchmarkReadWriteMsgUDPAddrPort(b *testing.B) {
  471. conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
  472. if err != nil {
  473. b.Fatal(err)
  474. }
  475. defer conn.Close()
  476. addr := conn.LocalAddr().(*UDPAddr).AddrPort()
  477. buf := make([]byte, 8)
  478. b.ResetTimer()
  479. b.ReportAllocs()
  480. for i := 0; i < b.N; i++ {
  481. _, _, err := conn.WriteMsgUDPAddrPort(buf, nil, addr)
  482. if err != nil {
  483. b.Fatal(err)
  484. }
  485. _, _, _, _, err = conn.ReadMsgUDPAddrPort(buf, nil)
  486. if err != nil {
  487. b.Fatal(err)
  488. }
  489. }
  490. }
  491. func BenchmarkWriteToReadFromUDP(b *testing.B) {
  492. conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
  493. if err != nil {
  494. b.Fatal(err)
  495. }
  496. defer conn.Close()
  497. addr := conn.LocalAddr()
  498. buf := make([]byte, 8)
  499. b.ResetTimer()
  500. b.ReportAllocs()
  501. for i := 0; i < b.N; i++ {
  502. _, err := conn.WriteTo(buf, addr)
  503. if err != nil {
  504. b.Fatal(err)
  505. }
  506. _, _, err = conn.ReadFromUDP(buf)
  507. if err != nil {
  508. b.Fatal(err)
  509. }
  510. }
  511. }
  512. func BenchmarkWriteToReadFromUDPAddrPort(b *testing.B) {
  513. conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
  514. if err != nil {
  515. b.Fatal(err)
  516. }
  517. defer conn.Close()
  518. addr := conn.LocalAddr().(*UDPAddr).AddrPort()
  519. buf := make([]byte, 8)
  520. b.ResetTimer()
  521. b.ReportAllocs()
  522. for i := 0; i < b.N; i++ {
  523. _, err := conn.WriteToUDPAddrPort(buf, addr)
  524. if err != nil {
  525. b.Fatal(err)
  526. }
  527. _, _, err = conn.ReadFromUDPAddrPort(buf)
  528. if err != nil {
  529. b.Fatal(err)
  530. }
  531. }
  532. }
  533. func TestUDPIPVersionReadMsg(t *testing.T) {
  534. switch runtime.GOOS {
  535. case "plan9":
  536. t.Skipf("skipping on %v", runtime.GOOS)
  537. }
  538. conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
  539. if err != nil {
  540. t.Fatal(err)
  541. }
  542. defer conn.Close()
  543. daddr := conn.LocalAddr().(*UDPAddr).AddrPort()
  544. buf := make([]byte, 8)
  545. _, err = conn.WriteToUDPAddrPort(buf, daddr)
  546. if err != nil {
  547. t.Fatal(err)
  548. }
  549. _, _, _, saddr, err := conn.ReadMsgUDPAddrPort(buf, nil)
  550. if err != nil {
  551. t.Fatal(err)
  552. }
  553. if !saddr.Addr().Is4() {
  554. t.Error("returned AddrPort is not IPv4")
  555. }
  556. _, err = conn.WriteToUDPAddrPort(buf, daddr)
  557. if err != nil {
  558. t.Fatal(err)
  559. }
  560. _, _, _, soldaddr, err := conn.ReadMsgUDP(buf, nil)
  561. if err != nil {
  562. t.Fatal(err)
  563. }
  564. if len(soldaddr.IP) != 4 {
  565. t.Error("returned UDPAddr is not IPv4")
  566. }
  567. }