diff --git a/internal/netxlite/dialer.go b/internal/netxlite/dialer.go index 7e78f61..d402f27 100644 --- a/internal/netxlite/dialer.go +++ b/internal/netxlite/dialer.go @@ -277,3 +277,23 @@ func (c *dialerErrWrapperConn) Close() error { } return nil } + +// ErrNoDialer indicates that no dialer is configured. +var ErrNoDialer = errors.New("no configured dialer") + +// NewNullDialer returns a dialer that always fails. +func NewNullDialer() Dialer { + return &nullDialer{} +} + +type nullDialer struct{} + +var _ Dialer = &nullDialer{} + +func (*nullDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + return nil, ErrNoDialer +} + +func (*nullDialer) CloseIdleConnections() { + // nothing to do +} diff --git a/internal/netxlite/dialer_test.go b/internal/netxlite/dialer_test.go index 20b5f96..93ccfa4 100644 --- a/internal/netxlite/dialer_test.go +++ b/internal/netxlite/dialer_test.go @@ -462,3 +462,15 @@ func TestDialerErrWrapperConn(t *testing.T) { }) }) } + +func TestNewNullDialer(t *testing.T) { + dialer := NewNullDialer() + conn, err := dialer.DialContext(context.Background(), "", "") + if !errors.Is(err, ErrNoDialer) { + t.Fatal("unexpected err", err) + } + if conn != nil { + t.Fatal("expected nil conn") + } + dialer.CloseIdleConnections() // does not crash +} diff --git a/internal/netxlite/tls.go b/internal/netxlite/tls.go index 253e7f3..296fb8b 100644 --- a/internal/netxlite/tls.go +++ b/internal/netxlite/tls.go @@ -342,3 +342,23 @@ func (h *tlsHandshakerErrWrapper) Handshake( } return tlsconn, state, nil } + +// ErrNoTLSDialer indicates that no TLS dialer is configured. +var ErrNoTLSDialer = errors.New("no configured TLS dialer") + +// NewNullTLSDialer returns a TLS dialer that always fails. +func NewNullTLSDialer() TLSDialer { + return &nullTLSDialer{} +} + +type nullTLSDialer struct{} + +var _ TLSDialer = &nullTLSDialer{} + +func (*nullTLSDialer) DialTLSContext(ctx context.Context, network, address string) (net.Conn, error) { + return nil, ErrNoTLSDialer +} + +func (*nullTLSDialer) CloseIdleConnections() { + // nothing to do +} diff --git a/internal/netxlite/tls_test.go b/internal/netxlite/tls_test.go index 9a85dbf..ae97c78 100644 --- a/internal/netxlite/tls_test.go +++ b/internal/netxlite/tls_test.go @@ -536,3 +536,15 @@ func TestTLSHandshakerErrWrapper(t *testing.T) { }) }) } + +func TestNewNullTLSDialer(t *testing.T) { + dialer := NewNullTLSDialer() + conn, err := dialer.DialTLSContext(context.Background(), "", "") + if !errors.Is(err, ErrNoTLSDialer) { + t.Fatal("unexpected err", err) + } + if conn != nil { + t.Fatal("expected nil conn") + } + dialer.CloseIdleConnections() // does not crash +}