package tls_interceptor import ( "net" "sync" ) var ( bufferPool = sync.Pool{ New: func() interface{} { return make([]byte, 1024) }, } ) func chanFromConn(conn net.Conn) chan []byte { c := make(chan []byte) go func() { b := bufferPool.Get().([]byte) for { n, err := conn.Read(b) if n > 0 { res := bufferPool.Get().([]byte) // Copy the buffer so it doesn't get changed while read by the recipient. copy(res, b[:n]) c <- res[:n] } if err != nil { c <- nil break } } }() return c } func Pipe(conn1 net.Conn, conn2 net.Conn) { chan1 := chanFromConn(conn1) chan2 := chanFromConn(conn2) for { select { case b1 := <-chan1: if b1 == nil { return } else { conn2.Write(b1) } case b2 := <-chan2: if b2 == nil { return } else { conn1.Write(b2) } } } }