Do not exit the server loop on obfs4 connection errors

obfs4Listener.Accept() returns an error when obfs4 handshake fails, which in
practice happens routinely when someone scans a machine that has an open
listening port.

Currently the accept loop in server.go exits on first such error, which makes
further connections to the same port impossible.

This change wraps obfs4 handshake errors into a custom error type that
satisfies net.Error and presents itself as temporary, which will prevent such
errors from aborting the server.
This commit is contained in:
Anton Tolchanov 2022-11-30 07:21:28 +00:00
parent b0bb26fc95
commit a9600f691e

14
obfs.go
View File

@ -20,9 +20,9 @@ import (
"github.com/go-log/log" "github.com/go-log/log"
pt "git.torproject.org/pluggable-transports/goptlib.git" pt "git.torproject.org/pluggable-transports/goptlib.git"
dissector "github.com/go-gost/tls-dissector"
"gitlab.com/yawning/obfs4.git/transports/base" "gitlab.com/yawning/obfs4.git/transports/base"
"gitlab.com/yawning/obfs4.git/transports/obfs4" "gitlab.com/yawning/obfs4.git/transports/obfs4"
dissector "github.com/go-gost/tls-dissector"
) )
const ( const (
@ -804,6 +804,16 @@ func Obfs4Listener(addr string) (Listener, error) {
return l, nil return l, nil
} }
// TempError satisfies the net.Error interface and presents itself
// as temporary to make sure that it gets retried by the Accept loop
// in server.go.
type TempError struct {
error
}
func (e TempError) Timeout() bool { return false }
func (e TempError) Temporary() bool { return true }
func (l *obfs4Listener) Accept() (net.Conn, error) { func (l *obfs4Listener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept() conn, err := l.Listener.Accept()
if err != nil { if err != nil {
@ -812,7 +822,7 @@ func (l *obfs4Listener) Accept() (net.Conn, error) {
cc, err := obfs4ServerConn(l.addr, conn) cc, err := obfs4ServerConn(l.addr, conn)
if err != nil { if err != nil {
conn.Close() conn.Close()
return nil, err return nil, TempError{err}
} }
return cc, nil return cc, nil
} }