예제 #1
0
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()
}
예제 #2
0
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)

}
예제 #3
0
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()
}