server_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. // Copyright 2009 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. "flag"
  7. "io"
  8. "os"
  9. "runtime"
  10. "testing"
  11. "time"
  12. )
  13. func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxOnly bool) bool {
  14. switch runtime.GOOS {
  15. case "linux":
  16. case "nacl", "plan9", "windows":
  17. // "unix" sockets are not supported on Windows and Plan 9.
  18. if net == unixsotype {
  19. return true
  20. }
  21. default:
  22. if net == unixsotype && linuxOnly {
  23. return true
  24. }
  25. }
  26. switch addr {
  27. case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
  28. if testing.Short() || !*testExternal {
  29. return true
  30. }
  31. }
  32. if ipv6 && !supportsIPv6 {
  33. return true
  34. }
  35. if ipv4map && !supportsIPv4map {
  36. return true
  37. }
  38. return false
  39. }
  40. var streamConnServerTests = []struct {
  41. snet string // server side
  42. saddr string
  43. cnet string // client side
  44. caddr string
  45. ipv6 bool // test with underlying AF_INET6 socket
  46. ipv4map bool // test with IPv6 IPv4-mapping functionality
  47. empty bool // test with empty data
  48. linuxOnly bool // test with abstract unix domain socket, a Linux-ism
  49. }{
  50. {snet: "tcp", saddr: "", cnet: "tcp", caddr: "127.0.0.1"},
  51. {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "127.0.0.1"},
  52. {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "127.0.0.1"},
  53. {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "[::1]", ipv6: true},
  54. {snet: "tcp", saddr: "", cnet: "tcp", caddr: "[::1]", ipv4map: true},
  55. {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp", caddr: "[::1]", ipv4map: true},
  56. {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp", caddr: "[::1]", ipv4map: true},
  57. {snet: "tcp", saddr: "[::]", cnet: "tcp", caddr: "127.0.0.1", ipv4map: true},
  58. {snet: "tcp", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
  59. {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
  60. {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
  61. {snet: "tcp", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
  62. {snet: "tcp", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
  63. {snet: "tcp", saddr: "0.0.0.0", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
  64. {snet: "tcp", saddr: "[::ffff:0.0.0.0]", cnet: "tcp6", caddr: "[::1]", ipv4map: true},
  65. {snet: "tcp", saddr: "[::]", cnet: "tcp4", caddr: "127.0.0.1", ipv4map: true},
  66. {snet: "tcp", saddr: "127.0.0.1", cnet: "tcp", caddr: "127.0.0.1"},
  67. {snet: "tcp", saddr: "[::ffff:127.0.0.1]", cnet: "tcp", caddr: "127.0.0.1"},
  68. {snet: "tcp", saddr: "[::1]", cnet: "tcp", caddr: "[::1]", ipv6: true},
  69. {snet: "tcp4", saddr: "", cnet: "tcp4", caddr: "127.0.0.1"},
  70. {snet: "tcp4", saddr: "0.0.0.0", cnet: "tcp4", caddr: "127.0.0.1"},
  71. {snet: "tcp4", saddr: "[::ffff:0.0.0.0]", cnet: "tcp4", caddr: "127.0.0.1"},
  72. {snet: "tcp4", saddr: "127.0.0.1", cnet: "tcp4", caddr: "127.0.0.1"},
  73. {snet: "tcp6", saddr: "", cnet: "tcp6", caddr: "[::1]", ipv6: true},
  74. {snet: "tcp6", saddr: "[::]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
  75. {snet: "tcp6", saddr: "[::1]", cnet: "tcp6", caddr: "[::1]", ipv6: true},
  76. {snet: "unix", saddr: testUnixAddr(), cnet: "unix", caddr: testUnixAddr()},
  77. {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local", linuxOnly: true},
  78. }
  79. func TestStreamConnServer(t *testing.T) {
  80. for _, tt := range streamConnServerTests {
  81. if skipServerTest(tt.snet, "unix", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) {
  82. continue
  83. }
  84. listening := make(chan string)
  85. done := make(chan int)
  86. switch tt.snet {
  87. case "tcp", "tcp4", "tcp6":
  88. tt.saddr += ":0"
  89. case "unix":
  90. os.Remove(tt.saddr)
  91. os.Remove(tt.caddr)
  92. }
  93. go runStreamConnServer(t, tt.snet, tt.saddr, listening, done)
  94. taddr := <-listening // wait for server to start
  95. switch tt.cnet {
  96. case "tcp", "tcp4", "tcp6":
  97. _, port, err := SplitHostPort(taddr)
  98. if err != nil {
  99. t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
  100. }
  101. taddr = tt.caddr + ":" + port
  102. }
  103. runStreamConnClient(t, tt.cnet, taddr, tt.empty)
  104. <-done // make sure server stopped
  105. switch tt.snet {
  106. case "unix":
  107. os.Remove(tt.saddr)
  108. os.Remove(tt.caddr)
  109. }
  110. }
  111. }
  112. var seqpacketConnServerTests = []struct {
  113. net string
  114. saddr string // server address
  115. caddr string // client address
  116. empty bool // test with empty data
  117. linuxOnly bool // test with abstract unix domain socket, a Linux-ism
  118. }{
  119. {net: "unixpacket", saddr: testUnixAddr(), caddr: testUnixAddr()},
  120. {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local", linuxOnly: true},
  121. }
  122. func TestSeqpacketConnServer(t *testing.T) {
  123. switch runtime.GOOS {
  124. case "darwin", "nacl", "openbsd", "plan9", "windows":
  125. fallthrough
  126. case "freebsd": // FreeBSD 8 doesn't support unixpacket
  127. t.Skipf("skipping test on %q", runtime.GOOS)
  128. }
  129. for _, tt := range seqpacketConnServerTests {
  130. if runtime.GOOS != "linux" && tt.linuxOnly {
  131. continue
  132. }
  133. listening := make(chan string)
  134. done := make(chan int)
  135. switch tt.net {
  136. case "unixpacket":
  137. os.Remove(tt.saddr)
  138. os.Remove(tt.caddr)
  139. }
  140. go runStreamConnServer(t, tt.net, tt.saddr, listening, done)
  141. taddr := <-listening // wait for server to start
  142. runStreamConnClient(t, tt.net, taddr, tt.empty)
  143. <-done // make sure server stopped
  144. switch tt.net {
  145. case "unixpacket":
  146. os.Remove(tt.saddr)
  147. os.Remove(tt.caddr)
  148. }
  149. }
  150. }
  151. func runStreamConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
  152. defer close(done)
  153. l, err := Listen(net, laddr)
  154. if err != nil {
  155. t.Errorf("Listen(%q, %q) failed: %v", net, laddr, err)
  156. listening <- "<nil>"
  157. return
  158. }
  159. defer l.Close()
  160. listening <- l.Addr().String()
  161. echo := func(rw io.ReadWriter, done chan<- int) {
  162. buf := make([]byte, 1024)
  163. for {
  164. n, err := rw.Read(buf[0:])
  165. if err != nil || n == 0 || string(buf[:n]) == "END" {
  166. break
  167. }
  168. rw.Write(buf[0:n])
  169. }
  170. close(done)
  171. }
  172. run:
  173. for {
  174. c, err := l.Accept()
  175. if err != nil {
  176. t.Logf("Accept failed: %v", err)
  177. continue run
  178. }
  179. echodone := make(chan int)
  180. go echo(c, echodone)
  181. <-echodone // make sure echo stopped
  182. c.Close()
  183. break run
  184. }
  185. }
  186. func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) {
  187. c, err := Dial(net, taddr)
  188. if err != nil {
  189. t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err)
  190. }
  191. defer c.Close()
  192. c.SetReadDeadline(time.Now().Add(1 * time.Second))
  193. var wb []byte
  194. if !isEmpty {
  195. wb = []byte("StreamConnClient by Dial\n")
  196. }
  197. if n, err := c.Write(wb); err != nil || n != len(wb) {
  198. t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
  199. }
  200. rb := make([]byte, 1024)
  201. if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
  202. t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
  203. }
  204. // Send explicit ending for unixpacket.
  205. // Older Linux kernels do not stop reads on close.
  206. switch net {
  207. case "unixpacket":
  208. c.Write([]byte("END"))
  209. }
  210. }
  211. // Do not test empty datagrams by default.
  212. // It causes unexplained timeouts on some systems,
  213. // including Snow Leopard. I think that the kernel
  214. // doesn't quite expect them.
  215. var testDatagram = flag.Bool("datagram", false, "whether to test udp and unixgram")
  216. var datagramPacketConnServerTests = []struct {
  217. snet string // server side
  218. saddr string
  219. cnet string // client side
  220. caddr string
  221. ipv6 bool // test with underlying AF_INET6 socket
  222. ipv4map bool // test with IPv6 IPv4-mapping functionality
  223. dial bool // test with Dial or DialUnix
  224. empty bool // test with empty data
  225. linuxOnly bool // test with abstract unix domain socket, a Linux-ism
  226. }{
  227. {snet: "udp", saddr: "", cnet: "udp", caddr: "127.0.0.1"},
  228. {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "127.0.0.1"},
  229. {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "127.0.0.1"},
  230. {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "[::1]", ipv6: true},
  231. {snet: "udp", saddr: "", cnet: "udp", caddr: "[::1]", ipv4map: true},
  232. {snet: "udp", saddr: "0.0.0.0", cnet: "udp", caddr: "[::1]", ipv4map: true},
  233. {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp", caddr: "[::1]", ipv4map: true},
  234. {snet: "udp", saddr: "[::]", cnet: "udp", caddr: "127.0.0.1", ipv4map: true},
  235. {snet: "udp", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
  236. {snet: "udp", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
  237. {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
  238. {snet: "udp", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
  239. {snet: "udp", saddr: "", cnet: "udp6", caddr: "[::1]", ipv4map: true},
  240. {snet: "udp", saddr: "0.0.0.0", cnet: "udp6", caddr: "[::1]", ipv4map: true},
  241. {snet: "udp", saddr: "[::ffff:0.0.0.0]", cnet: "udp6", caddr: "[::1]", ipv4map: true},
  242. {snet: "udp", saddr: "[::]", cnet: "udp4", caddr: "127.0.0.1", ipv4map: true},
  243. {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1"},
  244. {snet: "udp", saddr: "[::ffff:127.0.0.1]", cnet: "udp", caddr: "127.0.0.1"},
  245. {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true},
  246. {snet: "udp4", saddr: "", cnet: "udp4", caddr: "127.0.0.1"},
  247. {snet: "udp4", saddr: "0.0.0.0", cnet: "udp4", caddr: "127.0.0.1"},
  248. {snet: "udp4", saddr: "[::ffff:0.0.0.0]", cnet: "udp4", caddr: "127.0.0.1"},
  249. {snet: "udp4", saddr: "127.0.0.1", cnet: "udp4", caddr: "127.0.0.1"},
  250. {snet: "udp6", saddr: "", cnet: "udp6", caddr: "[::1]", ipv6: true},
  251. {snet: "udp6", saddr: "[::]", cnet: "udp6", caddr: "[::1]", ipv6: true},
  252. {snet: "udp6", saddr: "[::1]", cnet: "udp6", caddr: "[::1]", ipv6: true},
  253. {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true},
  254. {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", empty: true},
  255. {snet: "udp", saddr: "127.0.0.1", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true},
  256. {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true},
  257. {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, empty: true},
  258. {snet: "udp", saddr: "[::1]", cnet: "udp", caddr: "[::1]", ipv6: true, dial: true, empty: true},
  259. {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr()},
  260. {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true},
  261. {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), empty: true},
  262. {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true, empty: true},
  263. {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local", linuxOnly: true},
  264. }
  265. func TestDatagramPacketConnServer(t *testing.T) {
  266. if !*testDatagram {
  267. return
  268. }
  269. for _, tt := range datagramPacketConnServerTests {
  270. if skipServerTest(tt.snet, "unixgram", tt.saddr, tt.ipv6, tt.ipv4map, tt.linuxOnly) {
  271. continue
  272. }
  273. listening := make(chan string)
  274. done := make(chan int)
  275. switch tt.snet {
  276. case "udp", "udp4", "udp6":
  277. tt.saddr += ":0"
  278. case "unixgram":
  279. os.Remove(tt.saddr)
  280. os.Remove(tt.caddr)
  281. }
  282. go runDatagramPacketConnServer(t, tt.snet, tt.saddr, listening, done)
  283. taddr := <-listening // wait for server to start
  284. switch tt.cnet {
  285. case "udp", "udp4", "udp6":
  286. _, port, err := SplitHostPort(taddr)
  287. if err != nil {
  288. t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err)
  289. }
  290. taddr = tt.caddr + ":" + port
  291. tt.caddr += ":0"
  292. }
  293. if tt.dial {
  294. runDatagramConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
  295. } else {
  296. runDatagramPacketConnClient(t, tt.cnet, tt.caddr, taddr, tt.empty)
  297. }
  298. <-done // tell server to stop
  299. <-done // make sure server stopped
  300. switch tt.snet {
  301. case "unixgram":
  302. os.Remove(tt.saddr)
  303. os.Remove(tt.caddr)
  304. }
  305. }
  306. }
  307. func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) {
  308. c, err := ListenPacket(net, laddr)
  309. if err != nil {
  310. t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err)
  311. listening <- "<nil>"
  312. done <- 1
  313. return
  314. }
  315. defer c.Close()
  316. listening <- c.LocalAddr().String()
  317. buf := make([]byte, 1024)
  318. run:
  319. for {
  320. c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
  321. n, ra, err := c.ReadFrom(buf[0:])
  322. if nerr, ok := err.(Error); ok && nerr.Timeout() {
  323. select {
  324. case done <- 1:
  325. break run
  326. default:
  327. continue run
  328. }
  329. }
  330. if err != nil {
  331. break run
  332. }
  333. if _, err = c.WriteTo(buf[0:n], ra); err != nil {
  334. t.Errorf("WriteTo(%v) failed: %v", ra, err)
  335. break run
  336. }
  337. }
  338. done <- 1
  339. }
  340. func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
  341. var c Conn
  342. var err error
  343. switch net {
  344. case "udp", "udp4", "udp6":
  345. c, err = Dial(net, taddr)
  346. if err != nil {
  347. t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err)
  348. }
  349. case "unixgram":
  350. c, err = DialUnix(net, &UnixAddr{Name: laddr, Net: net}, &UnixAddr{Name: taddr, Net: net})
  351. if err != nil {
  352. t.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err)
  353. }
  354. }
  355. defer c.Close()
  356. c.SetReadDeadline(time.Now().Add(1 * time.Second))
  357. var wb []byte
  358. if !isEmpty {
  359. wb = []byte("DatagramConnClient by Dial\n")
  360. }
  361. if n, err := c.Write(wb[0:]); err != nil || n != len(wb) {
  362. t.Fatalf("Write failed: %v, %v; want %v, <nil>", n, err, len(wb))
  363. }
  364. rb := make([]byte, 1024)
  365. if n, err := c.Read(rb[0:]); err != nil || n != len(wb) {
  366. t.Fatalf("Read failed: %v, %v; want %v, <nil>", n, err, len(wb))
  367. }
  368. }
  369. func runDatagramPacketConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) {
  370. var ra Addr
  371. var err error
  372. switch net {
  373. case "udp", "udp4", "udp6":
  374. ra, err = ResolveUDPAddr(net, taddr)
  375. if err != nil {
  376. t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, taddr, err)
  377. }
  378. case "unixgram":
  379. ra, err = ResolveUnixAddr(net, taddr)
  380. if err != nil {
  381. t.Fatalf("ResolveUxixAddr(%q, %q) failed: %v", net, taddr, err)
  382. }
  383. }
  384. c, err := ListenPacket(net, laddr)
  385. if err != nil {
  386. t.Fatalf("ListenPacket(%q, %q) faild: %v", net, laddr, err)
  387. }
  388. defer c.Close()
  389. c.SetReadDeadline(time.Now().Add(1 * time.Second))
  390. var wb []byte
  391. if !isEmpty {
  392. wb = []byte("DatagramPacketConnClient by ListenPacket\n")
  393. }
  394. if n, err := c.WriteTo(wb[0:], ra); err != nil || n != len(wb) {
  395. t.Fatalf("WriteTo(%v) failed: %v, %v; want %v, <nil>", ra, n, err, len(wb))
  396. }
  397. rb := make([]byte, 1024)
  398. if n, _, err := c.ReadFrom(rb[0:]); err != nil || n != len(wb) {
  399. t.Fatalf("ReadFrom failed: %v, %v; want %v, <nil>", n, err, len(wb))
  400. }
  401. }