dial_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. // Copyright 2011 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. "bufio"
  8. "context"
  9. "internal/testenv"
  10. "io"
  11. "os"
  12. "runtime"
  13. "strings"
  14. "sync"
  15. "testing"
  16. "time"
  17. )
  18. var prohibitionaryDialArgTests = []struct {
  19. network string
  20. address string
  21. }{
  22. {"tcp6", "127.0.0.1"},
  23. {"tcp6", "::ffff:127.0.0.1"},
  24. }
  25. func TestProhibitionaryDialArg(t *testing.T) {
  26. testenv.MustHaveExternalNetwork(t)
  27. switch runtime.GOOS {
  28. case "plan9":
  29. t.Skipf("not supported on %s", runtime.GOOS)
  30. }
  31. if !supportsIPv4map() {
  32. t.Skip("mapping ipv4 address inside ipv6 address not supported")
  33. }
  34. ln, err := Listen("tcp", "[::]:0")
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. defer ln.Close()
  39. _, port, err := SplitHostPort(ln.Addr().String())
  40. if err != nil {
  41. t.Fatal(err)
  42. }
  43. for i, tt := range prohibitionaryDialArgTests {
  44. c, err := Dial(tt.network, JoinHostPort(tt.address, port))
  45. if err == nil {
  46. c.Close()
  47. t.Errorf("#%d: %v", i, err)
  48. }
  49. }
  50. }
  51. func TestDialLocal(t *testing.T) {
  52. ln := newLocalListener(t, "tcp")
  53. defer ln.Close()
  54. _, port, err := SplitHostPort(ln.Addr().String())
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. c, err := Dial("tcp", JoinHostPort("", port))
  59. if err != nil {
  60. t.Fatal(err)
  61. }
  62. c.Close()
  63. }
  64. func TestDialerDualStackFDLeak(t *testing.T) {
  65. switch runtime.GOOS {
  66. case "plan9":
  67. t.Skipf("%s does not have full support of socktest", runtime.GOOS)
  68. case "windows":
  69. t.Skipf("not implemented a way to cancel dial racers in TCP SYN-SENT state on %s", runtime.GOOS)
  70. case "openbsd":
  71. testenv.SkipFlaky(t, 15157)
  72. }
  73. if !supportsIPv4() || !supportsIPv6() {
  74. t.Skip("both IPv4 and IPv6 are required")
  75. }
  76. before := sw.Sockets()
  77. origTestHookLookupIP := testHookLookupIP
  78. defer func() { testHookLookupIP = origTestHookLookupIP }()
  79. testHookLookupIP = lookupLocalhost
  80. handler := func(dss *dualStackServer, ln Listener) {
  81. for {
  82. c, err := ln.Accept()
  83. if err != nil {
  84. return
  85. }
  86. c.Close()
  87. }
  88. }
  89. dss, err := newDualStackServer()
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. if err := dss.buildup(handler); err != nil {
  94. dss.teardown()
  95. t.Fatal(err)
  96. }
  97. const N = 10
  98. var wg sync.WaitGroup
  99. wg.Add(N)
  100. d := &Dialer{DualStack: true, Timeout: 5 * time.Second}
  101. for i := 0; i < N; i++ {
  102. go func() {
  103. defer wg.Done()
  104. c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
  105. if err != nil {
  106. t.Error(err)
  107. return
  108. }
  109. c.Close()
  110. }()
  111. }
  112. wg.Wait()
  113. dss.teardown()
  114. after := sw.Sockets()
  115. if len(after) != len(before) {
  116. t.Errorf("got %d; want %d", len(after), len(before))
  117. }
  118. }
  119. // Define a pair of blackholed (IPv4, IPv6) addresses, for which dialTCP is
  120. // expected to hang until the timeout elapses. These addresses are reserved
  121. // for benchmarking by RFC 6890.
  122. const (
  123. slowDst4 = "198.18.0.254"
  124. slowDst6 = "2001:2::254"
  125. )
  126. // In some environments, the slow IPs may be explicitly unreachable, and fail
  127. // more quickly than expected. This test hook prevents dialTCP from returning
  128. // before the deadline.
  129. func slowDialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
  130. sd := &sysDialer{network: network, address: raddr.String()}
  131. c, err := sd.doDialTCP(ctx, laddr, raddr)
  132. if ParseIP(slowDst4).Equal(raddr.IP) || ParseIP(slowDst6).Equal(raddr.IP) {
  133. // Wait for the deadline, or indefinitely if none exists.
  134. <-ctx.Done()
  135. }
  136. return c, err
  137. }
  138. func dialClosedPort(t *testing.T) (dialLatency time.Duration) {
  139. // On most platforms, dialing a closed port should be nearly instantaneous —
  140. // less than a few hundred milliseconds. However, on some platforms it may be
  141. // much slower: on Windows and OpenBSD, it has been observed to take up to a
  142. // few seconds.
  143. l, err := Listen("tcp", "127.0.0.1:0")
  144. if err != nil {
  145. t.Fatalf("dialClosedPort: Listen failed: %v", err)
  146. }
  147. addr := l.Addr().String()
  148. l.Close()
  149. startTime := time.Now()
  150. c, err := Dial("tcp", addr)
  151. if err == nil {
  152. c.Close()
  153. }
  154. elapsed := time.Now().Sub(startTime)
  155. t.Logf("dialClosedPort: measured delay %v", elapsed)
  156. return elapsed
  157. }
  158. func TestDialParallel(t *testing.T) {
  159. testenv.MustHaveExternalNetwork(t)
  160. if !supportsIPv4() || !supportsIPv6() {
  161. t.Skip("both IPv4 and IPv6 are required")
  162. }
  163. closedPortDelay := dialClosedPort(t)
  164. const instant time.Duration = 0
  165. const fallbackDelay = 200 * time.Millisecond
  166. // Some cases will run quickly when "connection refused" is fast,
  167. // or trigger the fallbackDelay on Windows. This value holds the
  168. // lesser of the two delays.
  169. var closedPortOrFallbackDelay time.Duration
  170. if closedPortDelay < fallbackDelay {
  171. closedPortOrFallbackDelay = closedPortDelay
  172. } else {
  173. closedPortOrFallbackDelay = fallbackDelay
  174. }
  175. origTestHookDialTCP := testHookDialTCP
  176. defer func() { testHookDialTCP = origTestHookDialTCP }()
  177. testHookDialTCP = slowDialTCP
  178. nCopies := func(s string, n int) []string {
  179. out := make([]string, n)
  180. for i := 0; i < n; i++ {
  181. out[i] = s
  182. }
  183. return out
  184. }
  185. var testCases = []struct {
  186. primaries []string
  187. fallbacks []string
  188. teardownNetwork string
  189. expectOk bool
  190. expectElapsed time.Duration
  191. }{
  192. // These should just work on the first try.
  193. {[]string{"127.0.0.1"}, []string{}, "", true, instant},
  194. {[]string{"::1"}, []string{}, "", true, instant},
  195. {[]string{"127.0.0.1", "::1"}, []string{slowDst6}, "tcp6", true, instant},
  196. {[]string{"::1", "127.0.0.1"}, []string{slowDst4}, "tcp4", true, instant},
  197. // Primary is slow; fallback should kick in.
  198. {[]string{slowDst4}, []string{"::1"}, "", true, fallbackDelay},
  199. // Skip a "connection refused" in the primary thread.
  200. {[]string{"127.0.0.1", "::1"}, []string{}, "tcp4", true, closedPortDelay},
  201. {[]string{"::1", "127.0.0.1"}, []string{}, "tcp6", true, closedPortDelay},
  202. // Skip a "connection refused" in the fallback thread.
  203. {[]string{slowDst4, slowDst6}, []string{"::1", "127.0.0.1"}, "tcp6", true, fallbackDelay + closedPortDelay},
  204. // Primary refused, fallback without delay.
  205. {[]string{"127.0.0.1"}, []string{"::1"}, "tcp4", true, closedPortOrFallbackDelay},
  206. {[]string{"::1"}, []string{"127.0.0.1"}, "tcp6", true, closedPortOrFallbackDelay},
  207. // Everything is refused.
  208. {[]string{"127.0.0.1"}, []string{}, "tcp4", false, closedPortDelay},
  209. // Nothing to do; fail instantly.
  210. {[]string{}, []string{}, "", false, instant},
  211. // Connecting to tons of addresses should not trip the deadline.
  212. {nCopies("::1", 1000), []string{}, "", true, instant},
  213. }
  214. handler := func(dss *dualStackServer, ln Listener) {
  215. for {
  216. c, err := ln.Accept()
  217. if err != nil {
  218. return
  219. }
  220. c.Close()
  221. }
  222. }
  223. // Convert a list of IP strings into TCPAddrs.
  224. makeAddrs := func(ips []string, port string) addrList {
  225. var out addrList
  226. for _, ip := range ips {
  227. addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, port))
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. out = append(out, addr)
  232. }
  233. return out
  234. }
  235. for i, tt := range testCases {
  236. dss, err := newDualStackServer()
  237. if err != nil {
  238. t.Fatal(err)
  239. }
  240. defer dss.teardown()
  241. if err := dss.buildup(handler); err != nil {
  242. t.Fatal(err)
  243. }
  244. if tt.teardownNetwork != "" {
  245. // Destroy one of the listening sockets, creating an unreachable port.
  246. dss.teardownNetwork(tt.teardownNetwork)
  247. }
  248. primaries := makeAddrs(tt.primaries, dss.port)
  249. fallbacks := makeAddrs(tt.fallbacks, dss.port)
  250. d := Dialer{
  251. FallbackDelay: fallbackDelay,
  252. }
  253. startTime := time.Now()
  254. sd := &sysDialer{
  255. Dialer: d,
  256. network: "tcp",
  257. address: "?",
  258. }
  259. c, err := sd.dialParallel(context.Background(), primaries, fallbacks)
  260. elapsed := time.Since(startTime)
  261. if c != nil {
  262. c.Close()
  263. }
  264. if tt.expectOk && err != nil {
  265. t.Errorf("#%d: got %v; want nil", i, err)
  266. } else if !tt.expectOk && err == nil {
  267. t.Errorf("#%d: got nil; want non-nil", i)
  268. }
  269. // We used to always use 95 milliseconds as the slop,
  270. // but that was flaky on Windows. See issue 35616.
  271. slop := 95 * time.Millisecond
  272. if fifth := tt.expectElapsed / 5; fifth > slop {
  273. slop = fifth
  274. }
  275. expectElapsedMin := tt.expectElapsed - slop
  276. expectElapsedMax := tt.expectElapsed + slop
  277. if elapsed < expectElapsedMin {
  278. t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin)
  279. } else if elapsed > expectElapsedMax {
  280. t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectElapsedMax)
  281. }
  282. // Repeat each case, ensuring that it can be canceled quickly.
  283. ctx, cancel := context.WithCancel(context.Background())
  284. var wg sync.WaitGroup
  285. wg.Add(1)
  286. go func() {
  287. time.Sleep(5 * time.Millisecond)
  288. cancel()
  289. wg.Done()
  290. }()
  291. startTime = time.Now()
  292. c, err = sd.dialParallel(ctx, primaries, fallbacks)
  293. if c != nil {
  294. c.Close()
  295. }
  296. elapsed = time.Now().Sub(startTime)
  297. if elapsed > 100*time.Millisecond {
  298. t.Errorf("#%d (cancel): got %v; want <= 100ms", i, elapsed)
  299. }
  300. wg.Wait()
  301. }
  302. }
  303. func lookupSlowFast(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
  304. switch host {
  305. case "slow6loopback4":
  306. // Returns a slow IPv6 address, and a local IPv4 address.
  307. return []IPAddr{
  308. {IP: ParseIP(slowDst6)},
  309. {IP: ParseIP("127.0.0.1")},
  310. }, nil
  311. default:
  312. return fn(ctx, network, host)
  313. }
  314. }
  315. func TestDialerFallbackDelay(t *testing.T) {
  316. testenv.MustHaveExternalNetwork(t)
  317. if !supportsIPv4() || !supportsIPv6() {
  318. t.Skip("both IPv4 and IPv6 are required")
  319. }
  320. origTestHookLookupIP := testHookLookupIP
  321. defer func() { testHookLookupIP = origTestHookLookupIP }()
  322. testHookLookupIP = lookupSlowFast
  323. origTestHookDialTCP := testHookDialTCP
  324. defer func() { testHookDialTCP = origTestHookDialTCP }()
  325. testHookDialTCP = slowDialTCP
  326. var testCases = []struct {
  327. dualstack bool
  328. delay time.Duration
  329. expectElapsed time.Duration
  330. }{
  331. // Use a very brief delay, which should fallback immediately.
  332. {true, 1 * time.Nanosecond, 0},
  333. // Use a 200ms explicit timeout.
  334. {true, 200 * time.Millisecond, 200 * time.Millisecond},
  335. // The default is 300ms.
  336. {true, 0, 300 * time.Millisecond},
  337. }
  338. handler := func(dss *dualStackServer, ln Listener) {
  339. for {
  340. c, err := ln.Accept()
  341. if err != nil {
  342. return
  343. }
  344. c.Close()
  345. }
  346. }
  347. dss, err := newDualStackServer()
  348. if err != nil {
  349. t.Fatal(err)
  350. }
  351. defer dss.teardown()
  352. if err := dss.buildup(handler); err != nil {
  353. t.Fatal(err)
  354. }
  355. for i, tt := range testCases {
  356. d := &Dialer{DualStack: tt.dualstack, FallbackDelay: tt.delay}
  357. startTime := time.Now()
  358. c, err := d.Dial("tcp", JoinHostPort("slow6loopback4", dss.port))
  359. elapsed := time.Now().Sub(startTime)
  360. if err == nil {
  361. c.Close()
  362. } else if tt.dualstack {
  363. t.Error(err)
  364. }
  365. expectMin := tt.expectElapsed - 1*time.Millisecond
  366. expectMax := tt.expectElapsed + 95*time.Millisecond
  367. if elapsed < expectMin {
  368. t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectMin)
  369. }
  370. if elapsed > expectMax {
  371. t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectMax)
  372. }
  373. }
  374. }
  375. func TestDialParallelSpuriousConnection(t *testing.T) {
  376. if !supportsIPv4() || !supportsIPv6() {
  377. t.Skip("both IPv4 and IPv6 are required")
  378. }
  379. var readDeadline time.Time
  380. if td, ok := t.Deadline(); ok {
  381. const arbitraryCleanupMargin = 1 * time.Second
  382. readDeadline = td.Add(-arbitraryCleanupMargin)
  383. } else {
  384. readDeadline = time.Now().Add(5 * time.Second)
  385. }
  386. var closed sync.WaitGroup
  387. closed.Add(2)
  388. handler := func(dss *dualStackServer, ln Listener) {
  389. // Accept one connection per address.
  390. c, err := ln.Accept()
  391. if err != nil {
  392. t.Fatal(err)
  393. }
  394. // The client should close itself, without sending data.
  395. c.SetReadDeadline(readDeadline)
  396. var b [1]byte
  397. if _, err := c.Read(b[:]); err != io.EOF {
  398. t.Errorf("got %v; want %v", err, io.EOF)
  399. }
  400. c.Close()
  401. closed.Done()
  402. }
  403. dss, err := newDualStackServer()
  404. if err != nil {
  405. t.Fatal(err)
  406. }
  407. defer dss.teardown()
  408. if err := dss.buildup(handler); err != nil {
  409. t.Fatal(err)
  410. }
  411. const fallbackDelay = 100 * time.Millisecond
  412. var dialing sync.WaitGroup
  413. dialing.Add(2)
  414. origTestHookDialTCP := testHookDialTCP
  415. defer func() { testHookDialTCP = origTestHookDialTCP }()
  416. testHookDialTCP = func(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
  417. // Wait until Happy Eyeballs kicks in and both connections are dialing,
  418. // and inhibit cancellation.
  419. // This forces dialParallel to juggle two successful connections.
  420. dialing.Done()
  421. dialing.Wait()
  422. // Now ignore the provided context (which will be canceled) and use a
  423. // different one to make sure this completes with a valid connection,
  424. // which we hope to be closed below:
  425. sd := &sysDialer{network: net, address: raddr.String()}
  426. return sd.doDialTCP(context.Background(), laddr, raddr)
  427. }
  428. d := Dialer{
  429. FallbackDelay: fallbackDelay,
  430. }
  431. sd := &sysDialer{
  432. Dialer: d,
  433. network: "tcp",
  434. address: "?",
  435. }
  436. makeAddr := func(ip string) addrList {
  437. addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, dss.port))
  438. if err != nil {
  439. t.Fatal(err)
  440. }
  441. return addrList{addr}
  442. }
  443. // dialParallel returns one connection (and closes the other.)
  444. c, err := sd.dialParallel(context.Background(), makeAddr("127.0.0.1"), makeAddr("::1"))
  445. if err != nil {
  446. t.Fatal(err)
  447. }
  448. c.Close()
  449. // The server should've seen both connections.
  450. closed.Wait()
  451. }
  452. func TestDialerPartialDeadline(t *testing.T) {
  453. now := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
  454. var testCases = []struct {
  455. now time.Time
  456. deadline time.Time
  457. addrs int
  458. expectDeadline time.Time
  459. expectErr error
  460. }{
  461. // Regular division.
  462. {now, now.Add(12 * time.Second), 1, now.Add(12 * time.Second), nil},
  463. {now, now.Add(12 * time.Second), 2, now.Add(6 * time.Second), nil},
  464. {now, now.Add(12 * time.Second), 3, now.Add(4 * time.Second), nil},
  465. // Bump against the 2-second sane minimum.
  466. {now, now.Add(12 * time.Second), 999, now.Add(2 * time.Second), nil},
  467. // Total available is now below the sane minimum.
  468. {now, now.Add(1900 * time.Millisecond), 999, now.Add(1900 * time.Millisecond), nil},
  469. // Null deadline.
  470. {now, noDeadline, 1, noDeadline, nil},
  471. // Step the clock forward and cross the deadline.
  472. {now.Add(-1 * time.Millisecond), now, 1, now, nil},
  473. {now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout},
  474. {now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout},
  475. }
  476. for i, tt := range testCases {
  477. deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs)
  478. if err != tt.expectErr {
  479. t.Errorf("#%d: got %v; want %v", i, err, tt.expectErr)
  480. }
  481. if !deadline.Equal(tt.expectDeadline) {
  482. t.Errorf("#%d: got %v; want %v", i, deadline, tt.expectDeadline)
  483. }
  484. }
  485. }
  486. // isEADDRINUSE reports whether err is syscall.EADDRINUSE.
  487. var isEADDRINUSE = func(err error) bool { return false }
  488. func TestDialerLocalAddr(t *testing.T) {
  489. if !supportsIPv4() || !supportsIPv6() {
  490. t.Skip("both IPv4 and IPv6 are required")
  491. }
  492. type test struct {
  493. network, raddr string
  494. laddr Addr
  495. error
  496. }
  497. var tests = []test{
  498. {"tcp4", "127.0.0.1", nil, nil},
  499. {"tcp4", "127.0.0.1", &TCPAddr{}, nil},
  500. {"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
  501. {"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
  502. {"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"}},
  503. {"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
  504. {"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
  505. {"tcp4", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
  506. {"tcp4", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
  507. {"tcp4", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
  508. {"tcp6", "::1", nil, nil},
  509. {"tcp6", "::1", &TCPAddr{}, nil},
  510. {"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
  511. {"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
  512. {"tcp6", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
  513. {"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
  514. {"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
  515. {"tcp6", "::1", &TCPAddr{IP: IPv6loopback}, nil},
  516. {"tcp6", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
  517. {"tcp6", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
  518. {"tcp", "127.0.0.1", nil, nil},
  519. {"tcp", "127.0.0.1", &TCPAddr{}, nil},
  520. {"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
  521. {"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
  522. {"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
  523. {"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
  524. {"tcp", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
  525. {"tcp", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
  526. {"tcp", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
  527. {"tcp", "::1", nil, nil},
  528. {"tcp", "::1", &TCPAddr{}, nil},
  529. {"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
  530. {"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
  531. {"tcp", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
  532. {"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
  533. {"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
  534. {"tcp", "::1", &TCPAddr{IP: IPv6loopback}, nil},
  535. {"tcp", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
  536. {"tcp", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
  537. }
  538. issue34264Index := -1
  539. if supportsIPv4map() {
  540. issue34264Index = len(tests)
  541. tests = append(tests, test{
  542. "tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, nil,
  543. })
  544. } else {
  545. tests = append(tests, test{
  546. "tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"},
  547. })
  548. }
  549. origTestHookLookupIP := testHookLookupIP
  550. defer func() { testHookLookupIP = origTestHookLookupIP }()
  551. testHookLookupIP = lookupLocalhost
  552. handler := func(ls *localServer, ln Listener) {
  553. for {
  554. c, err := ln.Accept()
  555. if err != nil {
  556. return
  557. }
  558. c.Close()
  559. }
  560. }
  561. var lss [2]*localServer
  562. for i, network := range []string{"tcp4", "tcp6"} {
  563. lss[i] = newLocalServer(t, network)
  564. defer lss[i].teardown()
  565. if err := lss[i].buildup(handler); err != nil {
  566. t.Fatal(err)
  567. }
  568. }
  569. for i, tt := range tests {
  570. d := &Dialer{LocalAddr: tt.laddr}
  571. var addr string
  572. ip := ParseIP(tt.raddr)
  573. if ip.To4() != nil {
  574. addr = lss[0].Listener.Addr().String()
  575. }
  576. if ip.To16() != nil && ip.To4() == nil {
  577. addr = lss[1].Listener.Addr().String()
  578. }
  579. c, err := d.Dial(tt.network, addr)
  580. if err == nil && tt.error != nil || err != nil && tt.error == nil {
  581. if i == issue34264Index && runtime.GOOS == "freebsd" && isEADDRINUSE(err) {
  582. // https://golang.org/issue/34264: FreeBSD through at least version 12.2
  583. // has been observed to fail with EADDRINUSE when dialing from an IPv6
  584. // local address to an IPv4 remote address.
  585. t.Logf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
  586. t.Logf("(spurious EADDRINUSE ignored on freebsd: see https://golang.org/issue/34264)")
  587. } else {
  588. t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
  589. }
  590. }
  591. if err != nil {
  592. if perr := parseDialError(err); perr != nil {
  593. t.Error(perr)
  594. }
  595. continue
  596. }
  597. c.Close()
  598. }
  599. }
  600. func TestDialerDualStack(t *testing.T) {
  601. testenv.SkipFlaky(t, 13324)
  602. if !supportsIPv4() || !supportsIPv6() {
  603. t.Skip("both IPv4 and IPv6 are required")
  604. }
  605. closedPortDelay := dialClosedPort(t)
  606. origTestHookLookupIP := testHookLookupIP
  607. defer func() { testHookLookupIP = origTestHookLookupIP }()
  608. testHookLookupIP = lookupLocalhost
  609. handler := func(dss *dualStackServer, ln Listener) {
  610. for {
  611. c, err := ln.Accept()
  612. if err != nil {
  613. return
  614. }
  615. c.Close()
  616. }
  617. }
  618. var timeout = 150*time.Millisecond + closedPortDelay
  619. for _, dualstack := range []bool{false, true} {
  620. dss, err := newDualStackServer()
  621. if err != nil {
  622. t.Fatal(err)
  623. }
  624. defer dss.teardown()
  625. if err := dss.buildup(handler); err != nil {
  626. t.Fatal(err)
  627. }
  628. d := &Dialer{DualStack: dualstack, Timeout: timeout}
  629. for range dss.lns {
  630. c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
  631. if err != nil {
  632. t.Error(err)
  633. continue
  634. }
  635. switch addr := c.LocalAddr().(*TCPAddr); {
  636. case addr.IP.To4() != nil:
  637. dss.teardownNetwork("tcp4")
  638. case addr.IP.To16() != nil && addr.IP.To4() == nil:
  639. dss.teardownNetwork("tcp6")
  640. }
  641. c.Close()
  642. }
  643. }
  644. }
  645. func TestDialerKeepAlive(t *testing.T) {
  646. handler := func(ls *localServer, ln Listener) {
  647. for {
  648. c, err := ln.Accept()
  649. if err != nil {
  650. return
  651. }
  652. c.Close()
  653. }
  654. }
  655. ls := newLocalServer(t, "tcp")
  656. defer ls.teardown()
  657. if err := ls.buildup(handler); err != nil {
  658. t.Fatal(err)
  659. }
  660. defer func() { testHookSetKeepAlive = func(time.Duration) {} }()
  661. tests := []struct {
  662. ka time.Duration
  663. expected time.Duration
  664. }{
  665. {-1, -1},
  666. {0, 15 * time.Second},
  667. {5 * time.Second, 5 * time.Second},
  668. {30 * time.Second, 30 * time.Second},
  669. }
  670. for _, test := range tests {
  671. var got time.Duration = -1
  672. testHookSetKeepAlive = func(d time.Duration) { got = d }
  673. d := Dialer{KeepAlive: test.ka}
  674. c, err := d.Dial("tcp", ls.Listener.Addr().String())
  675. if err != nil {
  676. t.Fatal(err)
  677. }
  678. c.Close()
  679. if got != test.expected {
  680. t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive set to %v, want %v", d.KeepAlive, got, test.expected)
  681. }
  682. }
  683. }
  684. func TestDialCancel(t *testing.T) {
  685. mustHaveExternalNetwork(t)
  686. blackholeIPPort := JoinHostPort(slowDst4, "1234")
  687. if !supportsIPv4() {
  688. blackholeIPPort = JoinHostPort(slowDst6, "1234")
  689. }
  690. ticker := time.NewTicker(10 * time.Millisecond)
  691. defer ticker.Stop()
  692. const cancelTick = 5 // the timer tick we cancel the dial at
  693. const timeoutTick = 100
  694. var d Dialer
  695. cancel := make(chan struct{})
  696. d.Cancel = cancel
  697. errc := make(chan error, 1)
  698. connc := make(chan Conn, 1)
  699. go func() {
  700. if c, err := d.Dial("tcp", blackholeIPPort); err != nil {
  701. errc <- err
  702. } else {
  703. connc <- c
  704. }
  705. }()
  706. ticks := 0
  707. for {
  708. select {
  709. case <-ticker.C:
  710. ticks++
  711. if ticks == cancelTick {
  712. close(cancel)
  713. }
  714. if ticks == timeoutTick {
  715. t.Fatal("timeout waiting for dial to fail")
  716. }
  717. case c := <-connc:
  718. c.Close()
  719. t.Fatal("unexpected successful connection")
  720. case err := <-errc:
  721. if perr := parseDialError(err); perr != nil {
  722. t.Error(perr)
  723. }
  724. if ticks < cancelTick {
  725. // Using strings.Contains is ugly but
  726. // may work on plan9 and windows.
  727. if strings.Contains(err.Error(), "connection refused") {
  728. t.Skipf("connection to %v failed fast with %v", blackholeIPPort, err)
  729. }
  730. t.Fatalf("dial error after %d ticks (%d before cancel sent): %v",
  731. ticks, cancelTick-ticks, err)
  732. }
  733. if oe, ok := err.(*OpError); !ok || oe.Err != errCanceled {
  734. t.Fatalf("dial error = %v (%T); want OpError with Err == errCanceled", err, err)
  735. }
  736. return // success.
  737. }
  738. }
  739. }
  740. func TestCancelAfterDial(t *testing.T) {
  741. if testing.Short() {
  742. t.Skip("avoiding time.Sleep")
  743. }
  744. ln := newLocalListener(t, "tcp")
  745. var wg sync.WaitGroup
  746. wg.Add(1)
  747. defer func() {
  748. ln.Close()
  749. wg.Wait()
  750. }()
  751. // Echo back the first line of each incoming connection.
  752. go func() {
  753. for {
  754. c, err := ln.Accept()
  755. if err != nil {
  756. break
  757. }
  758. rb := bufio.NewReader(c)
  759. line, err := rb.ReadString('\n')
  760. if err != nil {
  761. t.Error(err)
  762. c.Close()
  763. continue
  764. }
  765. if _, err := c.Write([]byte(line)); err != nil {
  766. t.Error(err)
  767. }
  768. c.Close()
  769. }
  770. wg.Done()
  771. }()
  772. try := func() {
  773. cancel := make(chan struct{})
  774. d := &Dialer{Cancel: cancel}
  775. c, err := d.Dial("tcp", ln.Addr().String())
  776. // Immediately after dialing, request cancellation and sleep.
  777. // Before Issue 15078 was fixed, this would cause subsequent operations
  778. // to fail with an i/o timeout roughly 50% of the time.
  779. close(cancel)
  780. time.Sleep(10 * time.Millisecond)
  781. if err != nil {
  782. t.Fatal(err)
  783. }
  784. defer c.Close()
  785. // Send some data to confirm that the connection is still alive.
  786. const message = "echo!\n"
  787. if _, err := c.Write([]byte(message)); err != nil {
  788. t.Fatal(err)
  789. }
  790. // The server should echo the line, and close the connection.
  791. rb := bufio.NewReader(c)
  792. line, err := rb.ReadString('\n')
  793. if err != nil {
  794. t.Fatal(err)
  795. }
  796. if line != message {
  797. t.Errorf("got %q; want %q", line, message)
  798. }
  799. if _, err := rb.ReadByte(); err != io.EOF {
  800. t.Errorf("got %v; want %v", err, io.EOF)
  801. }
  802. }
  803. // This bug manifested about 50% of the time, so try it a few times.
  804. for i := 0; i < 10; i++ {
  805. try()
  806. }
  807. }
  808. // Issue 18806: it should always be possible to net.Dial a
  809. // net.Listener().Addr().String when the listen address was ":n", even
  810. // if the machine has halfway configured IPv6 such that it can bind on
  811. // "::" not connect back to that same address.
  812. func TestDialListenerAddr(t *testing.T) {
  813. mustHaveExternalNetwork(t)
  814. ln, err := Listen("tcp", ":0")
  815. if err != nil {
  816. t.Fatal(err)
  817. }
  818. defer ln.Close()
  819. addr := ln.Addr().String()
  820. c, err := Dial("tcp", addr)
  821. if err != nil {
  822. t.Fatalf("for addr %q, dial error: %v", addr, err)
  823. }
  824. c.Close()
  825. }
  826. func TestDialerControl(t *testing.T) {
  827. switch runtime.GOOS {
  828. case "plan9":
  829. t.Skipf("not supported on %s", runtime.GOOS)
  830. }
  831. t.Run("StreamDial", func(t *testing.T) {
  832. for _, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
  833. if !testableNetwork(network) {
  834. continue
  835. }
  836. ln := newLocalListener(t, network)
  837. defer ln.Close()
  838. d := Dialer{Control: controlOnConnSetup}
  839. c, err := d.Dial(network, ln.Addr().String())
  840. if err != nil {
  841. t.Error(err)
  842. continue
  843. }
  844. c.Close()
  845. }
  846. })
  847. t.Run("PacketDial", func(t *testing.T) {
  848. for _, network := range []string{"udp", "udp4", "udp6", "unixgram"} {
  849. if !testableNetwork(network) {
  850. continue
  851. }
  852. c1 := newLocalPacketListener(t, network)
  853. if network == "unixgram" {
  854. defer os.Remove(c1.LocalAddr().String())
  855. }
  856. defer c1.Close()
  857. d := Dialer{Control: controlOnConnSetup}
  858. c2, err := d.Dial(network, c1.LocalAddr().String())
  859. if err != nil {
  860. t.Error(err)
  861. continue
  862. }
  863. c2.Close()
  864. }
  865. })
  866. }
  867. // mustHaveExternalNetwork is like testenv.MustHaveExternalNetwork
  868. // except that it won't skip testing on non-mobile builders.
  869. func mustHaveExternalNetwork(t *testing.T) {
  870. t.Helper()
  871. mobile := runtime.GOOS == "android" || runtime.GOOS == "ios"
  872. if testenv.Builder() == "" || mobile {
  873. testenv.MustHaveExternalNetwork(t)
  874. }
  875. }
  876. type contextWithNonZeroDeadline struct {
  877. context.Context
  878. }
  879. func (contextWithNonZeroDeadline) Deadline() (time.Time, bool) {
  880. // Return non-zero time.Time value with false indicating that no deadline is set.
  881. return time.Unix(0, 0), false
  882. }
  883. func TestDialWithNonZeroDeadline(t *testing.T) {
  884. ln := newLocalListener(t, "tcp")
  885. defer ln.Close()
  886. _, port, err := SplitHostPort(ln.Addr().String())
  887. if err != nil {
  888. t.Fatal(err)
  889. }
  890. ctx := contextWithNonZeroDeadline{Context: context.Background()}
  891. var dialer Dialer
  892. c, err := dialer.DialContext(ctx, "tcp", JoinHostPort("", port))
  893. if err != nil {
  894. t.Fatal(err)
  895. }
  896. c.Close()
  897. }