TUN-5836: Avoid websocket#Stream function from crashing cloudflared with unexpected memory access
This commit is contained in:
parent
5c6207debc
commit
9d9627f645
|
@ -12,6 +12,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/getsentry/raven-go"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
@ -72,13 +73,25 @@ func unidirectionalStream(dst io.Writer, src io.Reader, dir string, status *bidi
|
||||||
// close. In such case, if the other direction did not stop (due to application level stopping, e.g., if a
|
// close. In such case, if the other direction did not stop (due to application level stopping, e.g., if a
|
||||||
// server/origin listens forever until closure), it may read/write from the underlying ReadWriter (backed by
|
// server/origin listens forever until closure), it may read/write from the underlying ReadWriter (backed by
|
||||||
// the Edge<->cloudflared transport) in an unexpected state.
|
// the Edge<->cloudflared transport) in an unexpected state.
|
||||||
|
// Because of this, we set this recover() logic.
|
||||||
if status.isAnyDone() {
|
|
||||||
// Because of this, we set this recover() logic, which kicks-in *only* if any stream is known to have
|
|
||||||
// exited. In such case, we stop a possible panic from propagating upstream.
|
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
if status.isAnyDone() {
|
||||||
// We handle such unexpected errors only when we detect that one side of the streaming is done.
|
// We handle such unexpected errors only when we detect that one side of the streaming is done.
|
||||||
log.Debug().Msgf("Gracefully handled error %v in Streaming for %s, error %s", r, dir, debug.Stack())
|
log.Debug().Msgf("Gracefully handled error %v in Streaming for %s, error %s", r, dir, debug.Stack())
|
||||||
|
} else {
|
||||||
|
// Otherwise, this is unexpected, but we prevent the program from crashing anyway.
|
||||||
|
log.Warn().Msgf("Gracefully handled unexpected error %v in Streaming for %s, error %s", r, dir, debug.Stack())
|
||||||
|
|
||||||
|
tags := make(map[string]string)
|
||||||
|
tags["root"] = "websocket.stream"
|
||||||
|
tags["dir"] = dir
|
||||||
|
switch rval := r.(type) {
|
||||||
|
case error:
|
||||||
|
raven.CaptureError(rval, tags)
|
||||||
|
default:
|
||||||
|
rvalStr := fmt.Sprint(rval)
|
||||||
|
raven.CaptureMessage(rvalStr, tags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in New Issue