mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/ishidawataru/sctp"
|
|
)
|
|
|
|
// SCTPProxy is a proxy for SCTP connections. It implements the Proxy interface to
|
|
// handle SCTP traffic forwarding between the frontend and backend addresses.
|
|
type SCTPProxy struct {
|
|
listener *sctp.SCTPListener
|
|
frontendAddr *sctp.SCTPAddr
|
|
backendAddr *sctp.SCTPAddr
|
|
}
|
|
|
|
// NewSCTPProxy creates a new SCTPProxy.
|
|
func NewSCTPProxy(listener *sctp.SCTPListener, backendAddr *sctp.SCTPAddr) (*SCTPProxy, error) {
|
|
return &SCTPProxy{
|
|
listener: listener,
|
|
frontendAddr: listener.Addr().(*sctp.SCTPAddr),
|
|
backendAddr: backendAddr,
|
|
}, nil
|
|
}
|
|
|
|
func (proxy *SCTPProxy) clientLoop(client *sctp.SCTPConn, quit chan bool) {
|
|
backend, err := sctp.DialSCTP("sctp", nil, proxy.backendAddr)
|
|
if err != nil {
|
|
log.Printf("Can't forward traffic to backend sctp/%v: %s\n", proxy.backendAddr, err)
|
|
client.Close()
|
|
return
|
|
}
|
|
clientC := sctp.NewSCTPSndRcvInfoWrappedConn(client)
|
|
backendC := sctp.NewSCTPSndRcvInfoWrappedConn(backend)
|
|
|
|
var wg sync.WaitGroup
|
|
broker := func(to, from net.Conn) {
|
|
io.Copy(to, from)
|
|
from.Close()
|
|
to.Close()
|
|
wg.Done()
|
|
}
|
|
|
|
wg.Add(2)
|
|
go broker(clientC, backendC)
|
|
go broker(backendC, clientC)
|
|
|
|
finish := make(chan struct{})
|
|
go func() {
|
|
wg.Wait()
|
|
close(finish)
|
|
}()
|
|
|
|
select {
|
|
case <-quit:
|
|
case <-finish:
|
|
}
|
|
clientC.Close()
|
|
backendC.Close()
|
|
<-finish
|
|
}
|
|
|
|
// Run starts forwarding the traffic using SCTP.
|
|
func (proxy *SCTPProxy) Run() {
|
|
quit := make(chan bool)
|
|
defer close(quit)
|
|
for {
|
|
client, err := proxy.listener.Accept()
|
|
if err != nil {
|
|
log.Printf("Stopping proxy on sctp/%v for sctp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err)
|
|
return
|
|
}
|
|
go proxy.clientLoop(client.(*sctp.SCTPConn), quit)
|
|
}
|
|
}
|
|
|
|
// Close stops forwarding the traffic.
|
|
func (proxy *SCTPProxy) Close() { proxy.listener.Close() }
|