liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
// +build !js,!plan9,!windows
 
package net
 
import (
   "context"
   "math/rand"
   "runtime"
   "sync"
   "syscall"
   "testing"
   "time"
)
 
// See golang.org/issue/14548.
func TestTCPSpuriousConnSetupCompletion(t *testing.T) {
   if testing.Short() {
       t.Skip("skipping in short mode")
   }
 
   ln, err := newLocalListener("tcp")
   if err != nil {
       t.Fatal(err)
   }
   var wg sync.WaitGroup
   wg.Add(1)
   go func(ln Listener) {
       defer wg.Done()
       for {
           c, err := ln.Accept()
           if err != nil {
               return
           }
           wg.Add(1)
           go func(c Conn) {
               var b [1]byte
               c.Read(b[:])
               c.Close()
               wg.Done()
           }(c)
       }
   }(ln)
 
   attempts := int(1e4) // larger is better
   wg.Add(attempts)
   throttle := make(chan struct{}, runtime.GOMAXPROCS(-1)*2)
   for i := 0; i < attempts; i++ {
       throttle <- struct{}{}
       go func(i int) {
           defer func() {
               <-throttle
               wg.Done()
           }()
           d := Dialer{Timeout: 50 * time.Millisecond}
           c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
           if err != nil {
               if perr := parseDialError(err); perr != nil {
                   t.Errorf("#%d: %v (original error: %v)", i, perr, err)
               }
               return
           }
           var b [1]byte
           if _, err := c.Write(b[:]); err != nil {
               if perr := parseWriteError(err); perr != nil {
                   t.Errorf("#%d: %v", i, err)
               }
               if samePlatformError(err, syscall.ENOTCONN) {
                   t.Errorf("#%d: %v", i, err)
               }
           }
           c.Close()
       }(i)
   }
 
   ln.Close()
   wg.Wait()
}
 
// Issue 19289.
// Test that a canceled Dial does not cause a subsequent Dial to succeed.
func TestTCPSpuriousConnSetupCompletionWithCancel(t *testing.T) {
   mustHaveExternalNetwork(t)
 
   defer dnsWaitGroup.Wait()
   t.Parallel()
   const tries = 10000
   var wg sync.WaitGroup
   wg.Add(tries * 2)
   sem := make(chan bool, 5)
   for i := 0; i < tries; i++ {
       sem <- true
       ctx, cancel := context.WithCancel(context.Background())
       go func() {
           defer wg.Done()
           time.Sleep(time.Duration(rand.Int63n(int64(5 * time.Millisecond))))
           cancel()
       }()
       go func(i int) {
           defer wg.Done()
           var dialer Dialer
           // Try to connect to a real host on a port
           // that it is not listening on.
           _, err := dialer.DialContext(ctx, "tcp", "golang.org:3")
           if err == nil {
               t.Errorf("Dial to unbound port succeeded on attempt %d", i)
           }
           <-sem
       }(i)
   }
   wg.Wait()
}