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