func (s *SimpleCopier) CopyBytes(in, out *net.TCPConn) { var wg sync.WaitGroup wg.Add(2) go s.copy(fmt.Sprintf("from backend: %v -> %v", in.RemoteAddr(), out.RemoteAddr()), in, out, &wg) go s.copy(fmt.Sprintf("to backend: %v -> %v", out.RemoteAddr(), in.RemoteAddr()), out, in, &wg) wg.Wait() }
func (s *SimpleCopier) copy(direction string, in, out *net.TCPConn, wg *sync.WaitGroup) { defer func() { in.Close(direction) out.Close(direction) if wg != nil { wg.Done() } }() n, err := io.CopyDesc(direction, in, out) if err != nil { if s.isClosedError(err) { log.Printf("ERROR [%v] closed connection: %v", err) } else { log.Printf("ERROR [%v] unexpected error %v", direction, err) } } log.Printf("[%v] Copied %d bytes", direction, n) }
func (s *Splicer) CopyBytes(in, out *net.TCPConn) { // Close the tcp connection given to us. defer func() { // TODO: Double close problems? out.Close() in.Close() }() // Invoking File() on the connection will duplicate the socket fd, setting // the original (socket fd) to block. inFile, err := in.File() if err != nil { log.Fatal(err) } inFD := int(inFile.Fd()) defer syscall.Close(inFD) outFile, err := out.File() if err != nil { log.Fatal(err) } outFD := int(outFile.Fd()) defer syscall.Close(outFD) var wg sync.WaitGroup wg.Add(2) go s.splice(fmt.Sprintf("from backend: %v -> %v", in.RemoteAddr(), out.RemoteAddr()), inFD, outFD, &wg) go s.splice(fmt.Sprintf("to backend: %v -> %v", out.RemoteAddr(), in.RemoteAddr()), outFD, inFD, &wg) wg.Wait() }