github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/mockserver_test.go (about) 1 // Copyright 2013 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 5 package net 6 7 import "sync" 8 9 type streamListener struct { 10 net, addr string 11 ln Listener 12 } 13 14 type dualStackServer struct { 15 lnmu sync.RWMutex 16 lns []streamListener 17 port string 18 19 cmu sync.RWMutex 20 cs []Conn // established connections at the passive open side 21 } 22 23 func (dss *dualStackServer) buildup(server func(*dualStackServer, Listener)) error { 24 for i := range dss.lns { 25 go server(dss, dss.lns[i].ln) 26 } 27 return nil 28 } 29 30 func (dss *dualStackServer) putConn(c Conn) error { 31 dss.cmu.Lock() 32 dss.cs = append(dss.cs, c) 33 dss.cmu.Unlock() 34 return nil 35 } 36 37 func (dss *dualStackServer) teardownNetwork(net string) error { 38 dss.lnmu.Lock() 39 for i := range dss.lns { 40 if net == dss.lns[i].net && dss.lns[i].ln != nil { 41 dss.lns[i].ln.Close() 42 dss.lns[i].ln = nil 43 } 44 } 45 dss.lnmu.Unlock() 46 return nil 47 } 48 49 func (dss *dualStackServer) teardown() error { 50 dss.lnmu.Lock() 51 for i := range dss.lns { 52 if dss.lns[i].ln != nil { 53 dss.lns[i].ln.Close() 54 } 55 } 56 dss.lnmu.Unlock() 57 dss.cmu.Lock() 58 for _, c := range dss.cs { 59 c.Close() 60 } 61 dss.cmu.Unlock() 62 return nil 63 } 64 65 func newDualStackServer(lns []streamListener) (*dualStackServer, error) { 66 dss := &dualStackServer{lns: lns, port: "0"} 67 for i := range dss.lns { 68 ln, err := Listen(dss.lns[i].net, dss.lns[i].addr+":"+dss.port) 69 if err != nil { 70 dss.teardown() 71 return nil, err 72 } 73 dss.lns[i].ln = ln 74 if dss.port == "0" { 75 if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil { 76 dss.teardown() 77 return nil, err 78 } 79 } 80 } 81 return dss, nil 82 }