not a listener object and which is not descended from a listener object (e.g. a
connection obtained using SSL_accept_connection()) or indirectly from a listener
object (e.g. a QUIC stream SSL object obtained using SSL_accept_stream() called
-on a connection obtained using SSL_accept_connection()) returns NULL.
+on a connection obtained using SSL_accept_connection()) returns NULL. Also note
+that pending SSL connections on a QUIC listeners accept queue have some caveats,
+see NOTES below.
The SSL_listen() function begins listening after a listener has been created.
Appropriate BIOs must have been configured before calling SSL_listen(), along
SSL_new_from_listener() returns a pointer to a new SSL object on success or NULL
on failure. On success, the caller assumes ownership of the reference.
+=head1 NOTES
+
+SSL_get0_listener() behaves somewhat differently in SSL callbacks for QUIC
+connections. As QUIC connections begin TLS handshake operations prior to them
+being accepted via SSL_accept_connection(), an application may receive callbacks
+for such pending connection prior to acceptance via SSL_accept_connection(). As
+listner association takes place during the accept process, prior to being
+returned from SSL_accept_connection(), calls to SSL_get0_listener() made from
+such SSL callbacks will return NULL. This can be used as an indicator within
+the callback that the referenced SSL object has not yet been accepted.
+
=head1 SEE ALSO
L<OSSL_QUIC_server_method(3)>, L<SSL_free(3)>, L<SSL_set_bio(3)>,
ossl_quic_channel_free(qc->ch);
qc->ch = NULL;
- if (qc->port != NULL && qc->listener == NULL) { /* TODO */
+ if (qc->port != NULL && qc->listener == NULL && qc->pending == 0) { /* TODO */
quic_unref_port_bios(qc->port);
ossl_quic_port_free(qc->port);
qc->port = NULL;
/* tsan doesn't like freeing locked mutexes */
ossl_crypto_mutex_unlock(qc->mutex);
- if (qc->listener == NULL)
+ if (qc->listener == NULL && qc->pending == 0)
ossl_crypto_mutex_free(&qc->mutex);
#endif
}
conn_ssl = SSL_CONNECTION_GET_USER_SSL(SSL_CONNECTION_FROM_SSL(conn_ssl));
qc = (QUIC_CONNECTION *)conn_ssl;
qc->accepted = 1;
-
+ qc->listener = ctx.ql;
+ qc->pending = 0;
if (!SSL_up_ref(&ctx.ql->obj.ssl)) {
SSL_free(conn_ssl);
SSL_free(ossl_quic_channel_get0_tls(new_ch));
ossl_quic_channel_get_peer_addr(ch, &qc->init_peer_addr); /* best effort */
qc->accepted = 0;
- qc->listener = ql;
+ qc->listener = NULL;
+ qc->pending = 1;
qc->engine = ql->engine;
qc->port = ql->port;
qc->ch = ch;
/* Flag to indicate if this connection has been accepted */
unsigned int accepted : 1;
+ /* Flag to indicate waiting on accept queue */
+ unsigned int pending : 1;
+
/* Default stream type. Defaults to SSL_DEFAULT_STREAM_MODE_AUTO_BIDI. */
uint32_t default_stream_mode;