|
|
@@ -25,6 +25,7 @@ import (
|
|
|
"fmt"
|
|
|
"io"
|
|
|
"net"
|
|
|
+ "runtime/debug"
|
|
|
"sync"
|
|
|
"sync/atomic"
|
|
|
"time"
|
|
|
@@ -100,6 +101,17 @@ func (mux *udpPortForwardMultiplexer) run() {
|
|
|
// When the client disconnects or the server shuts down, the channel will close and
|
|
|
// readUdpgwMessage will exit with EOF.
|
|
|
|
|
|
+ // Recover from and log any unexpected panics caused by udpgw input handling bugs.
|
|
|
+ // Note: this covers the run() goroutine only and not relayDownstream() goroutines.
|
|
|
+ defer func() {
|
|
|
+ if e := recover(); e != nil {
|
|
|
+ err := common.ContextError(
|
|
|
+ fmt.Errorf(
|
|
|
+ "udpPortForwardMultiplexer panic: %s: %s", e, debug.Stack()))
|
|
|
+ log.WithContextFields(LogFields{"error": err}).Warning("run failed")
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
buffer := make([]byte, udpgwProtocolMaxMessageSize)
|
|
|
for {
|
|
|
// Note: message.packet points to the reusable memory in "buffer".
|
|
|
@@ -305,7 +317,7 @@ func (portForward *udpPortForward) relayDownstream() {
|
|
|
if err != nil {
|
|
|
if err != io.EOF {
|
|
|
// Debug since errors such as "use of closed network connection" occur during normal operation
|
|
|
- log.WithContextFields(LogFields{"error": err}).Warning("downstream UDP relay failed")
|
|
|
+ log.WithContextFields(LogFields{"error": err}).Debug("downstream UDP relay failed")
|
|
|
}
|
|
|
break
|
|
|
}
|