f038dae646
From-SVN: r204466
83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
// 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
|
|
}
|