Skip to content

Commit

Permalink
Improve TLS handshake error logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
wi1dcard committed Apr 16, 2024
1 parent 9d53f51 commit 09ccedb
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
14 changes: 11 additions & 3 deletions pkg/proxyserver/proxyserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ func (server *Server) serveConn(conn net.Conn) {
io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
}

if errors.Is(err, context.Canceled) ||
errors.Is(err, io.EOF) ||
errors.Is(err, syscall.ECONNRESET) {
if isNetworkOrClientError(err) {
server.vlogf("tls handshake failed (%s), client error: %s", conn.RemoteAddr(), err)
} else {
server.logf("tls handshake error (%s): %s", conn.RemoteAddr(), err)
Expand Down Expand Up @@ -312,3 +310,13 @@ func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
}
return false
}

func isNetworkOrClientError(err error) bool {
var netOpErr *net.OpError
return errors.Is(err, context.Canceled) ||
errors.Is(err, context.DeadlineExceeded) ||
errors.Is(err, io.EOF) ||
errors.Is(err, syscall.ECONNRESET) ||
// https://github.com/golang/go/blob/release-branch.go1.22/src/crypto/tls/conn.go#L724
(errors.As(err, &netOpErr) && netOpErr.Op == "remote error")
}
38 changes: 38 additions & 0 deletions pkg/proxyserver/proxyserver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package proxyserver

import (
"fmt"
"net"
"testing"
)

func TestIsNetworkOrClientError(t *testing.T) {
// https://github.com/golang/go/blob/release-branch.go1.22/src/crypto/tls/alert.go#L77
alert := fmt.Errorf("unknown certificate authority")
// https://github.com/golang/go/blob/release-branch.go1.22/src/crypto/tls/conn.go#L724
err := setErrorLocked(&net.OpError{Op: "remote error", Err: alert})
if isNetworkOrClientError(err) == false {
t.Error("expected tls alert record is client error, got false")
}

if isNetworkOrClientError(fmt.Errorf("some random error")) {
t.Error("expected random error is not client error, got true")
}
}

type permanentError struct {
err net.Error
}

func (e *permanentError) Error() string { return e.err.Error() }
func (e *permanentError) Unwrap() error { return e.err }
func (e *permanentError) Timeout() bool { return e.err.Timeout() }
func (e *permanentError) Temporary() bool { return false }

func setErrorLocked(err error) error {
if e, ok := err.(net.Error); ok {
return &permanentError{err: e}
} else {
return err
}
}

0 comments on commit 09ccedb

Please sign in to comment.