Sfoglia il codice sorgente

Don't log when fail to send responses due to tunnel I/O failure

Rod Hynes 7 anni fa
parent
commit
f9abb7eaa2
3 ha cambiato i file con 48 aggiunte e 5 eliminazioni
  1. 12 4
      psiphon/server/tunnelServer.go
  2. 3 1
      psiphon/server/udp.go
  3. 33 0
      psiphon/server/utils.go

+ 12 - 4
psiphon/server/tunnelServer.go

@@ -1405,7 +1405,9 @@ func (sshClient *sshClient) runTunnel(
 				err = request.Reply(false, nil)
 			}
 			if err != nil {
-				log.WithContextFields(LogFields{"error": err}).Warning("response failed")
+				if !isExpectedTunnelIOError(err) {
+					log.WithContextFields(LogFields{"error": err}).Warning("response failed")
+				}
 			}
 
 		}
@@ -1592,7 +1594,9 @@ func (sshClient *sshClient) runTunnel(
 
 			packetTunnelChannel, requests, err := newChannel.Accept()
 			if err != nil {
-				log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+				if !isExpectedTunnelIOError(err) {
+					log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+				}
 				continue
 			}
 			go ssh.DiscardRequests(requests)
@@ -1841,7 +1845,9 @@ func (sshClient *sshClient) runOSLSender() {
 			if err == nil {
 				break
 			}
-			log.WithContextFields(LogFields{"error": err}).Warning("sendOSLRequest failed")
+			if !isExpectedTunnelIOError(err) {
+				log.WithContextFields(LogFields{"error": err}).Warning("sendOSLRequest failed")
+			}
 
 			// If the request failed, retry after a delay (with exponential backoff)
 			// or when signaled that there are additional SLOKs to send
@@ -2656,7 +2662,9 @@ func (sshClient *sshClient) handleTCPChannel(
 
 	fwdChannel, requests, err := newChannel.Accept()
 	if err != nil {
-		log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+		if !isExpectedTunnelIOError(err) {
+			log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+		}
 		return
 	}
 	go ssh.DiscardRequests(requests)

+ 3 - 1
psiphon/server/udp.go

@@ -49,7 +49,9 @@ func (sshClient *sshClient) handleUDPChannel(newChannel ssh.NewChannel) {
 
 	sshChannel, requests, err := newChannel.Accept()
 	if err != nil {
-		log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+		if !isExpectedTunnelIOError(err) {
+			log.WithContextFields(LogFields{"error": err}).Warning("accept new channel failed")
+		}
 		return
 	}
 	go ssh.DiscardRequests(requests)

+ 33 - 0
psiphon/server/utils.go

@@ -22,6 +22,7 @@ package server
 import (
 	"fmt"
 	"io"
+	"strings"
 	"sync/atomic"
 )
 
@@ -85,3 +86,35 @@ func greaterThanSwapInt64(addr *int64, new int64) bool {
 	}
 	return false
 }
+
+var expectedTunnelIOErrorSubstrings = []string{
+	"EOF",
+	"use of closed network connection",
+	"connection reset by peer",
+	"connection has closed",
+	"broken pipe",
+	"i/o timeout",
+	"deadline exceeded",
+	"NetworkIdleTimeout",
+	"PeerGoingAway",
+}
+
+// isExpectedTunnelIOError checks if the error indicates failure due to tunnel
+// I/O timing out, use of a closed tunnel, etc. This is used to avoid logging
+// noise in cases where sending messages through the tunnel fail due regular,
+// expected tunnel failure conditions.
+//
+// Limitations introduced by error type wrapping and lack of common error
+// types across all network protcol layers means this function uses
+// heuristical error text substring matching and may fall out of sync with new
+// protocols/error messages. As such, this function should only be used for
+// the intended log noise purpose.
+func isExpectedTunnelIOError(err error) bool {
+	errString := err.Error()
+	for _, substring := range expectedTunnelIOErrorSubstrings {
+		if strings.Contains(errString, substring) {
+			return true
+		}
+	}
+	return false
+}