in internal/proxy/proxy.go [937:1001]
func (c *Client) proxyConn(inst string, client, server net.Conn) {
// only allow the first side to give an error for terminating a connection
var o sync.Once
cleanup := func(errDesc string, isErr bool) {
o.Do(func() {
_ = client.Close()
_ = server.Close()
if isErr {
c.logger.Errorf(errDesc)
} else {
c.logger.Infof(errDesc)
}
})
}
// copy bytes from client to server
go func() {
buf := make([]byte, 8*1024) // 8kb
for {
n, cErr := client.Read(buf)
var sErr error
if n > 0 {
_, sErr = server.Write(buf[:n])
}
switch {
case cErr == io.EOF:
cleanup(fmt.Sprintf("[%s] client closed the connection", inst), false)
return
case cErr != nil:
cleanup(fmt.Sprintf("[%s] connection aborted - error reading from client: %v", inst, cErr), true)
return
case sErr == io.EOF:
cleanup(fmt.Sprintf("[%s] instance closed the connection", inst), false)
return
case sErr != nil:
cleanup(fmt.Sprintf("[%s] connection aborted - error writing to instance: %v", inst, sErr), true)
return
}
}
}()
// copy bytes from server to client
buf := make([]byte, 8*1024) // 8kb
for {
n, sErr := server.Read(buf)
var cErr error
if n > 0 {
_, cErr = client.Write(buf[:n])
}
switch {
case sErr == io.EOF:
cleanup(fmt.Sprintf("[%s] instance closed the connection", inst), false)
return
case sErr != nil:
cleanup(fmt.Sprintf("[%s] connection aborted - error reading from instance: %v", inst, sErr), true)
return
case cErr == io.EOF:
cleanup(fmt.Sprintf("[%s] client closed the connection", inst), false)
return
case cErr != nil:
cleanup(fmt.Sprintf("[%s] connection aborted - error writing to client: %v", inst, cErr), true)
return
}
}
}