diff --git a/src/Npgsql/Internal/NpgsqlConnector.cs b/src/Npgsql/Internal/NpgsqlConnector.cs index 25262b323a..16a9298b16 100644 --- a/src/Npgsql/Internal/NpgsqlConnector.cs +++ b/src/Npgsql/Internal/NpgsqlConnector.cs @@ -378,7 +378,7 @@ internal NpgsqlConnector(NpgsqlDataSource dataSource, NpgsqlConnection conn) _isKeepAliveEnabled = Settings.KeepAlive > 0; if (_isKeepAliveEnabled) _keepAliveTimer = new Timer(PerformKeepAlive, null, Timeout.Infinite, Timeout.Infinite); - + DataReader = new NpgsqlDataReader(this); // TODO: Not just for automatic preparation anymore... @@ -659,7 +659,7 @@ internal async Task Open(NpgsqlTimeout timeout, bool async, CancellationToken ca reader.NextResult(); reader.Read(); } - + _isTransactionReadOnly = reader.GetString(0) != "off"; var databaseState = UpdateDatabaseState(); @@ -876,6 +876,18 @@ async Task RawOpen(SslMode sslMode, NpgsqlTimeout timeout, bool async, Cancellat certificateValidationCallback = SslVerifyFullValidation; } + var host = Host; + +#if !NET8_0_OR_GREATER + // If the host is a valid IP address - replace it with an empty string + // We do that because .NET uses targetHost argument to send SNI to the server + // RFC explicitly prohibits sending an IP address so some servers might fail + // This was already fixed for .NET 8 + // See #5543 for discussion + if (IPAddress.TryParse(host, out _)) + host = string.Empty; +#endif + timeout.CheckAndApply(this); try @@ -889,9 +901,9 @@ async Task RawOpen(SslMode sslMode, NpgsqlTimeout timeout, bool async, Cancellat #endif if (async) - await sslStream.AuthenticateAsClientAsync(Host, clientCertificates, sslProtocols, checkCertificateRevocation); + await sslStream.AuthenticateAsClientAsync(host, clientCertificates, sslProtocols, checkCertificateRevocation); else - sslStream.AuthenticateAsClient(Host, clientCertificates, sslProtocols, checkCertificateRevocation); + sslStream.AuthenticateAsClient(host, clientCertificates, sslProtocols, checkCertificateRevocation); _stream = sslStream; } @@ -2076,7 +2088,7 @@ internal Exception Break(Exception reason) Monitor.Exit(CleanupLock); } } - + void FullCleanup() { lock (CleanupLock)