jpillora / go-tcp-proxy

A small TCP proxy written in Go
MIT License
745 stars 197 forks source link

Port Mirroring #23

Open stokito opened 2 years ago

stokito commented 2 years ago

I need a proxy to imitate a port mirroring (SPAN) that will be used for a logging. There is some NGINX module http://nginx.org/en/docs/http/ngx_http_mirror_module.html but it mirrors only requests. For my case I need responses from the remote too. Here I patched your proxy and hope this may be useful to add as a fature

stokito commented 2 years ago

Just an example of response listener using FastHttp library:

var ReadBufferSize = 30000
var readerPool sync.Pool

func startResponseLoggerServer() {
    l, err := net.Listen("tcp", "localhost:9092")
    if err != nil {
        fmt.Fprintf("Error listening: %s\n", err.Error())
    }

    for {
        in, err := l.Accept()
        if err != nil {
            continue
        }
        fmt.Fprintf("Incoming connection from %s\n", in.RemoteAddr())
        //handleClient(in)

        resp := fasthttp.AcquireResponse()
        br := acquireReader(in)
        err = resp.ReadLimitBody(br, ReadBufferSize)
        if err != nil {
            fmt.Fprintf("Failed to read body: %s\n", err)
        }
        releaseReader(br)
        fmt.Fprintf("Bid resp: %s\n", resp.Body())
        fasthttp.ReleaseResponse(resp)
    }
}

func handleClient(conn net.Conn) {
    var buf [512]byte
    for {
        n, err := conn.Read(buf[0:])
        if err != nil {
            return
        }
        fmt.Println(string(buf[0:n]))
    }
}

func acquireReader(conn net.Conn) *bufio.Reader {
    v := readerPool.Get()
    if v == nil {
        return bufio.NewReaderSize(conn, ReadBufferSize)
    }
    br := v.(*bufio.Reader)
    br.Reset(conn)
    return br
}

func releaseReader(br *bufio.Reader) {
    readerPool.Put(br)
}