| 27 | } |
| 28 | |
| 29 | func (proxy *SCTPProxy) clientLoop(client *sctp.SCTPConn, quit chan bool) { |
| 30 | backend, err := sctp.DialSCTP("sctp", nil, proxy.backendAddr) |
| 31 | if err != nil { |
| 32 | log.Printf("Can't forward traffic to backend sctp/%v: %s\n", proxy.backendAddr, err) |
| 33 | client.Close() |
| 34 | return |
| 35 | } |
| 36 | clientC := sctp.NewSCTPSndRcvInfoWrappedConn(client) |
| 37 | backendC := sctp.NewSCTPSndRcvInfoWrappedConn(backend) |
| 38 | |
| 39 | var wg sync.WaitGroup |
| 40 | broker := func(to, from net.Conn) { |
| 41 | io.Copy(to, from) |
| 42 | from.Close() |
| 43 | to.Close() |
| 44 | wg.Done() |
| 45 | } |
| 46 | |
| 47 | wg.Add(2) |
| 48 | go broker(clientC, backendC) |
| 49 | go broker(backendC, clientC) |
| 50 | |
| 51 | finish := make(chan struct{}) |
| 52 | go func() { |
| 53 | wg.Wait() |
| 54 | close(finish) |
| 55 | }() |
| 56 | |
| 57 | select { |
| 58 | case <-quit: |
| 59 | case <-finish: |
| 60 | } |
| 61 | clientC.Close() |
| 62 | backendC.Close() |
| 63 | <-finish |
| 64 | } |
| 65 | |
| 66 | // Run starts forwarding the traffic using SCTP. |
| 67 | func (proxy *SCTPProxy) Run() { |