1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // Copyright 2013 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.
- package net
- import "sync"
- type streamListener struct {
- net, addr string
- ln Listener
- }
- type dualStackServer struct {
- lnmu sync.RWMutex
- lns []streamListener
- port string
- cmu sync.RWMutex
- cs []Conn // established connections at the passive open side
- }
- func (dss *dualStackServer) buildup(server func(*dualStackServer, Listener)) error {
- for i := range dss.lns {
- go server(dss, dss.lns[i].ln)
- }
- return nil
- }
- func (dss *dualStackServer) putConn(c Conn) error {
- dss.cmu.Lock()
- dss.cs = append(dss.cs, c)
- dss.cmu.Unlock()
- return nil
- }
- func (dss *dualStackServer) teardownNetwork(net string) error {
- dss.lnmu.Lock()
- for i := range dss.lns {
- if net == dss.lns[i].net && dss.lns[i].ln != nil {
- dss.lns[i].ln.Close()
- dss.lns[i].ln = nil
- }
- }
- dss.lnmu.Unlock()
- return nil
- }
- func (dss *dualStackServer) teardown() error {
- dss.lnmu.Lock()
- for i := range dss.lns {
- if dss.lns[i].ln != nil {
- dss.lns[i].ln.Close()
- }
- }
- dss.lnmu.Unlock()
- dss.cmu.Lock()
- for _, c := range dss.cs {
- c.Close()
- }
- dss.cmu.Unlock()
- return nil
- }
- func newDualStackServer(lns []streamListener) (*dualStackServer, error) {
- dss := &dualStackServer{lns: lns, port: "0"}
- for i := range dss.lns {
- ln, err := Listen(dss.lns[i].net, dss.lns[i].addr+":"+dss.port)
- if err != nil {
- dss.teardown()
- return nil, err
- }
- dss.lns[i].ln = ln
- if dss.port == "0" {
- if _, dss.port, err = SplitHostPort(ln.Addr().String()); err != nil {
- dss.teardown()
- return nil, err
- }
- }
- }
- return dss, nil
- }
|