mirror of
https://github.com/openssl/openssl.git
synced 2026-01-18 17:11:31 +01:00
QUIC listener may fail with SSL_POLL_EVENT_EL on windows.
recvfrom() may return WSAECONNRESET when the destination port used in a previous sendto() call is no longer available. This causes QUIC PORT to swich from running state. This behavior is not desired for QUIC protocol. The trick is to disable SIO_UDP_CONNRESET flag on UDP port used by QUIC. The issue was kindly reported and root caused by goforit22123-netizen@ Fixes: #29530 Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Norbert Pocs <norbertp@openssl.org> MergeDate: Mon Jan 12 10:27:25 2026 (Merged from https://github.com/openssl/openssl/pull/29538)
This commit is contained in:
@@ -899,6 +899,20 @@ that a call to L<SSL_handle_events(3)> is performed after the specified timeout
|
||||
|
||||
=back
|
||||
|
||||
=head1 WINDOWS APPLICATION NOTES
|
||||
|
||||
QUIC protocol uses UDP sockets. The recvfrom() function on Windows may fail
|
||||
with C<WSAECONNRESET> error causing OpenSSL QUIC stack to enter permanent
|
||||
error, which prevents further communication over QUIC protocol. Applications
|
||||
should disable SIO_UDP_CONNRESET and SIO_UDP_NETRESET error notification
|
||||
on UDP sockets they pass to OpenSSL QUIC stack. More details can be found here:
|
||||
https://learn.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls#sio_udp_connreset-opcode-setting-i-t3
|
||||
|
||||
OpenSSL attempts to always disable SIO_UDP_CONNRESET and SIO_UDP_NETRESET
|
||||
on UDP sockets it receives from application, but no error is reported back
|
||||
if the respective C<WSAIoctl()> calls fail. Robust application should set those
|
||||
options itself so it can handle error notifications from C<WSAIoctl()> properly.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<SSL_handle_events(3)>, L<SSL_get_event_timeout(3)>,
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
#include "internal/thread_arch.h"
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <mstcpip.h>
|
||||
#include <mswsock.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Core I/O Reactor Framework
|
||||
* ==========================
|
||||
@@ -69,6 +75,28 @@ void ossl_quic_reactor_cleanup(QUIC_REACTOR *rtor)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
/*
|
||||
* On Windows recvfrom() may return WSAECONNRESET when destination port
|
||||
* used in preceding call to sendto() is no longer reachable. The reset
|
||||
* error received from UDP socket takes the whole port down. This behavior
|
||||
* must be suppressed for QUIC protocol so QUIC applications may rely on
|
||||
* QUIC protocol itself to detect network failures.
|
||||
*/
|
||||
static void rtor_configure_winsock(BIO_POLL_DESCRIPTOR *bpd)
|
||||
{
|
||||
BOOL bNewBehavior = FALSE;
|
||||
DWORD dwBytesReturned = 0;
|
||||
|
||||
if (bpd->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
|
||||
WSAIoctl(bpd->value.fd, SIO_UDP_CONNRESET, &bNewBehavior,
|
||||
sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL);
|
||||
WSAIoctl(bpd->value.fd, SIO_UDP_NETRESET, &bNewBehavior,
|
||||
sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ossl_quic_reactor_set_poll_r(QUIC_REACTOR *rtor, const BIO_POLL_DESCRIPTOR *r)
|
||||
{
|
||||
if (r == NULL)
|
||||
@@ -76,6 +104,10 @@ void ossl_quic_reactor_set_poll_r(QUIC_REACTOR *rtor, const BIO_POLL_DESCRIPTOR
|
||||
else
|
||||
rtor->poll_r = *r;
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
rtor_configure_winsock(&rtor->poll_r);
|
||||
#endif
|
||||
|
||||
rtor->can_poll_r
|
||||
= ossl_quic_reactor_can_support_poll_descriptor(rtor, &rtor->poll_r);
|
||||
}
|
||||
@@ -87,6 +119,10 @@ void ossl_quic_reactor_set_poll_w(QUIC_REACTOR *rtor, const BIO_POLL_DESCRIPTOR
|
||||
else
|
||||
rtor->poll_w = *w;
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
rtor_configure_winsock(&rtor->poll_w);
|
||||
#endif
|
||||
|
||||
rtor->can_poll_w
|
||||
= ossl_quic_reactor_can_support_poll_descriptor(rtor, &rtor->poll_w);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user