`SSL_shutdown` and it is not desired for such calls to affect the whole
connection.
-**TBD:** Should we allow `SSL_shutdown_ex` on a QUIC stream SSL object to act as
-`SSL_stream_conclude`? Should we require this behaviour to be explicitly
-enabled?
-
The `args->quic_error_code` and `args->reason` fields allow the application
error code and reason string for the closure of a QUIC connection to be
specified. If `args` or `args->reason` is `NULL`, a zero-length string is used
to provide the basis for future work.
The following outlines an illustrative set of functions that will initially be
-provided. A number of `TODO(QUIC)` comments are inserted to explain how we
-might expand the API over time:
+provided. A number of `TODO(QUIC TESTING)` comments are inserted to explain how
+we might expand the API over time:
```` C
/* Type to represent the Fault Injector */
int ossl_quic_fault_resize_handshake(OSSL_QUIC_FAULT *fault, size_t newlen);
/*
- * TODO(QUIC): Add listeners for specific types of frame here. E.g. we might
- * expect to see an "ACK" frame listener which will be passed pre-parsed ack
- * data that can be modified as required.
+ * TODO(QUIC TESTING): Add listeners for specific types of frame here. E.g.
+ * we might expect to see an "ACK" frame listener which will be passed
+ * pre-parsed ack data that can be modified as required.
*/
/*
* Handshake message specific listeners. Unlike the general handshake message
* listener these messages are pre-parsed and supplied with message specific
- * data and exclude the handshake header
+ * data and exclude the handshake header.
*/
typedef int (*ossl_quic_fault_on_enc_ext_cb)(OSSL_QUIC_FAULT *fault,
OSSL_QF_ENCRYPTED_EXTENSIONS *ee,
ossl_quic_fault_on_enc_ext_cb encextcb,
void *encextcbarg);
-/* TODO(QUIC): Add listeners for other types of handshake message here */
+/* TODO(QUIC TESTING): Add listeners for other types of handshake message here */
/*
size_t *extlen);
/*
- * TODO(QUIC): Add additional helper functions for querying extensions here (e.g.
- * finding or adding them). We could also provide a "listener" API for listening
- * for specific extension types
+ * TODO(QUIC TESTING): Add additional helper functions for querying extensions
+ * here (e.g. finding or adding them). We could also provide a "listener" API
+ * for listening for specific extension types.
*/
/*
if (!TEST_int_eq(SSL_get_error(cssl, ret), SSL_ERROR_SSL))
goto err;
-#if 0
- /*
- * TODO(QUIC): We should expect an error on the queue after this - but we
- * don't have it yet.
- * Note, just raising the error in the obvious place causes SSL_tick() to
- * succeed, but leave a spurious error on the stack. We need to either
- * allow SSL_tick() to fail, or somehow delay the raising of the error
- * until the SSL_read() call.
- */
if (!TEST_int_eq(ERR_GET_REASON(ERR_peek_error()),
SSL_R_UNKNOWN_FRAME_TYPE_RECEIVED))
goto err;
-#endif
if (!TEST_true(qtest_check_server_protocol_err(qtserv)))
goto err;
Depending on whether default stream functionality is being used, it may be
necessary to explicitly configure the incoming stream policy before streams can
-be accepted; see L<SSL_set_incoming_stream_policy(3)>.
+be accepted; see L<SSL_set_incoming_stream_policy(3)>. See also
+L<openssl-quic(7)/MODES OF OPERATION>.
=begin comment
=head1 SEE ALSO
-L<SSL_new_stream(3)>, L<SSL_set_blocking_mode(3)>, L<SSL_free(3)>
+L<openssl-quic(7)/MODES OF OPERATION>, L<SSL_new_stream(3)>,
+L<SSL_set_blocking_mode(3)>, L<SSL_free(3)>
=head1 HISTORY
=head1 DESCRIPTION
-SSL_client_version() returns the numeric protocol version advertised by the
-client in the legacy_version field of the ClientHello when initiating the
-connection. Note that, for TLS, this value will never indicate a version greater
-than TLSv1.2 even if TLSv1.3 is subsequently negotiated. SSL_get_version()
-returns the name of the protocol used for the connection. SSL_version() returns
-the numeric protocol version used for the connection. They should only be called
-after the initial handshake has been completed. Prior to that the results
-returned from these functions may be unreliable.
+For SSL, TLS and DTLS protocols SSL_client_version() returns the numeric
+protocol version advertised by the client in the legacy_version field of the
+ClientHello when initiating the connection. Note that, for TLS, this value
+will never indicate a version greater than TLSv1.2 even if TLSv1.3 is
+subsequently negotiated. For QUIC connections it returns OSSL_QUIC1_VERSION.
+
+SSL_get_version() returns the name of the protocol used for the connection.
+SSL_version() returns the numeric protocol version used for the connection.
+They should only be called after the initial handshake has been completed.
+Prior to that the results returned from these functions may be unreliable.
SSL_is_dtls() returns 1 if the connection is using DTLS or 0 if not.
=item OSSL_QUIC1_VERSION
-The connection uses the QUICv1 protocol (never returned for
-SSL_client_version()).
+The connection uses the QUICv1 protocol.
=back
one call to the SSL object is blocking, no such call is needed. However,
SSL_handle_events() may optionally be used on a QUIC connection object if desired.
-=begin comment
-
-TODO(QUIC): Update the above paragraph once we support thread assisted mode.
-
-=end comment
+With the thread-assisted mode of operation L<OSSL_QUIC_client_thread_method(3)>
+it is unnecessary to call SSL_handle_events() as the assist thread handles the QUIC
+connection events.
=back
SSL object, the arguments are ignored and the call functions identically to
SSL_shutdown().
-=begin comment
-
-TODO(QUIC): Once streams are implemented, revise this text
-
-=end comment
-
When used with a QUIC connection SSL object, SSL_shutdown_ex() initiates a QUIC
immediate close. The I<quic_error_code> field can be used to specify a 62-bit
application error code to be signalled via QUIC. The value specified must be in
It can also occur when not all data was read using SSL_read().
+This value is also returned when called on QUIC stream SSL objects.
+
=back
=head1 SEE ALSO
=head1 DESCRIPTION
SSL_stream_conclude() signals the normal end-of-stream condition for the send
-part of a QUIC stream. If called on a QUIC connection SSL object, it signals the
-end of the single stream to the peer.
+part of a QUIC stream. If called on a QUIC connection SSL object with an
+associated default stream, it signals the end of the single stream to the peer.
Any data already queued for transmission via a call to SSL_write() will still be
written in a reliable manner before the end-of-stream is signalled, assuming the
Only the first call to this function has any effect for a given stream;
subsequent calls are no-ops. This is considered a success case.
-=begin comment
-
-TODO(QUIC): Once streams are implemented, revise this text
-
-=end comment
-
-This function is not supported on non-QUIC SSL objects.
+This function is not supported on an object other than a QUIC stream SSL object.
=head1 RETURN VALUES
Returns 1 on success and 0 on failure.
-Returns 0 if called on a non-QUIC SSL object.
+Returns 0 if called on an SSL object not representing a QUIC stream.
=head1 SEE ALSO
-L<ssl(7)>, L<SSL_shutdown_ex(3)>
+L<openssl-quic(7)>, L<ssl(7)>, L<SSL_shutdown_ex(3)>
=head1 HISTORY
* reasonably certain no benefit would be gained by sending
* STOP_SENDING.]
*
- * TODO(QUIC): Implement the latter case (currently we just
- * always do STOP_SENDING).
+ * TODO(QUIC FUTURE): Implement the latter case (currently we
+ just always do STOP_SENDING).
*
* and;
*
#define MIN_MAX_INIT_WND_SIZE 14720 /* RFC 9002 s. 7.2 */
-/* TODO(QUIC): Pacing support. */
+/* TODO(QUIC FUTURE): Pacing support. */
static void newreno_set_max_dgram_size(OSSL_CC_NEWRENO *nr,
size_t max_dgram_size);
static int ackm_in_persistent_congestion(OSSL_ACKM *ackm,
const OSSL_ACKM_TX_PKT *lpkt)
{
- /* TODO(QUIC): Persistent congestion not currently implemented. */
+ /* TODO(QUIC FUTURE): Persistent congestion not currently implemented. */
return 0;
}
static void ackm_queue_probe(OSSL_ACKM *ackm, int pkt_space)
{
/*
- * TODO(QUIC): We are allowed to send either one or two probe packets here.
+ * TODO(QUIC FUTURE): We are allowed to send either one or two probe
+ * packets here.
* Determine a strategy for when we should send two probe packets.
*/
++ackm->pending_probe.pto[pkt_space];
* not suitable for network use. In particular, it does not implement address
* validation, anti-amplification or retry logic.
*
- * TODO(QUIC): Implement address validation and anti-amplification
- * TODO(QUIC): Implement retry logic
+ * TODO(QUIC SERVER): Implement address validation and anti-amplification
+ * TODO(QUIC SERVER): Implement retry logic
*/
#define INIT_DCID_LEN 8
case QUIC_TPARAM_PREFERRED_ADDR:
{
- /* TODO(QUIC): Handle preferred address. */
+ /* TODO(QUIC FUTURE): Handle preferred address. */
QUIC_PREFERRED_ADDR pfa;
/*
* again because packets that were not previously processable and
* were deferred might now be processable.
*
- * TODO(QUIC): Consider handling this in the yield_secret callback.
+ * TODO(QUIC FUTURE): Consider handling this in the yield_secret callback.
*/
} while (ch->have_new_rx_secret);
}
return;
/*
- * TODO(QUIC): Theoretically this should probably be in the QRX.
+ * TODO(QUIC FUTURE): Theoretically this should probably be in the QRX.
* However because validation is dependent on context (namely the
* client's initial DCID) we can't do this cleanly. In the future we
* should probably add a callback to the QRX to let it call us (via
return;
/*
- * TODO(QUIC): Implement 0-RTT on the server side. We currently do
- * not need to implement this as a client can only do 0-RTT if we
+ * TODO(QUIC 0RTT): Implement 0-RTT on the server side. We currently
+ * do not need to implement this as a client can only do 0-RTT if we
* have given it permission to in a previous session.
*/
break;
case QUIC_VERSION_NONE:
default:
/* Unknown version or proactive version negotiation request, bail. */
- /* TODO(QUIC): Handle version negotiation on server side */
+ /* TODO(QUIC SERVER): Handle version negotiation on server side */
goto undesirable;
}
= (ssl_base->method == OSSL_QUIC_client_thread_method());
#endif
- qc->as_server = 0; /* TODO(QUIC): server support */
+ qc->as_server = 0; /* TODO(QUIC SERVER): add server support */
qc->as_server_state = qc->as_server;
qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
if (!expect_quic(s, &ctx))
return 0;
- /* TODO(QUIC): Currently a no-op. */
+ /* TODO(QUIC FUTURE): Currently a no-op. */
return 1;
}
return -1;
if (ctx.is_stream)
- /* TODO(QUIC): Semantics currently undefined for QSSOs */
return -1;
quic_lock(ctx.qc);
}
if (qc->as_server != qc->as_server_state) {
- /* TODO(QUIC): Must match the method used to create the QCSO */
QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL);
return -1; /* Non-protocol error */
}
/*
* Try and send.
*
- * TODO(QUIC): It is probably inefficient to try and do this immediately,
- * plus we should eventually consider Nagle's algorithm.
+ * TODO(QUIC FUTURE): It is probably inefficient to try and do this
+ * immediately, plus we should eventually consider Nagle's algorithm.
*/
if (do_tick)
ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(xso->conn->ch), 0);
ossl_quic_free, \
ossl_quic_reset, \
ossl_quic_init, \
- ossl_quic_clear, \
+ NULL /* clear */, \
ossl_quic_deinit, \
q_accept, \
q_connect, \
* things again. If poll_two_fds returns 0, this is some other
* non-timeout failure and we should stop here.
*
- * TODO(QUIC): In the future we could avoid unnecessary syscalls by
- * not retrying network I/O that isn't ready based on the result of
- * the poll call. However this might be difficult because it
- * requires we do the call to poll(2) or equivalent syscall
- * ourselves, whereas in the general case the application does the
- * polling and just calls SSL_handle_events(). Implementing this
- * optimisation in the future will probably therefore require API
- * changes.
+ * TODO(QUIC FUTURE): In the future we could avoid unnecessary
+ * syscalls by not retrying network I/O that isn't ready based
+ * on the result of the poll call. However this might be difficult
+ * because it requires we do the call to poll(2) or equivalent
+ * syscall ourselves, whereas in the general case the application
+ * does the polling and just calls SSL_handle_events().
+ * Implementing this optimisation in the future will probably
+ * therefore require API changes.
*/
return 0;
}
int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size)
{
- /* TODO(QUIC): Do we need to distinguish different error conditions ? */
if (ossl_sframe_list_is_head_locked(&qrs->fl))
return 0;
return 0;
}
- /* TODO(QUIC): ADD CODE to send |token| to the session manager */
+ /* TODO(QUIC FUTURE): ADD CODE to send |token| to the session manager */
return 1;
}
* currently non-conformant and for internal testing use; simply handle it
* as a no-op in this case.
*
- * TODO(QUIC): Revise and implement correctly for server support.
+ * TODO(QUIC SERVER): Revise and implement correctly for server support.
*/
if (!ch->is_server) {
ossl_quic_channel_raise_protocol_error(ch,
return 0;
}
- /* TODO(QUIC): ADD CODE to send |frame_data| to the ch manager */
+ /* TODO(QUIC MULTIPATH): ADD CODE to send |frame_data| to the ch manager */
return 1;
}
/* Initialize |ackm_data| (and reinitialize |ok|)*/
memset(&ackm_data, 0, sizeof(ackm_data));
/*
- * TODO(QUIC): ASSUMPTION: All packets that aren't special case have a
- * packet number
+ * ASSUMPTION: All packets that aren't special case have a
+ * packet number.
*/
ackm_data.pkt_num = qpacket->pn;
ackm_data.time = qpacket->time;
ok = 1;
end:
/*
- * TODO(QUIC): ASSUMPTION: If this function is called at all, |qpacket| is
+ * ASSUMPTION: If this function is called at all, |qpacket| is
* a legitimate packet, even if its contents aren't.
* Therefore, we call ossl_ackm_on_rx_packet() unconditionally, as long as
* |ackm_data| has at least been initialized.
static int qsm_ready_for_gc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs)
{
- int recv_stream_fully_drained = 0; /* TODO(QUIC): Optimisation */
+ int recv_stream_fully_drained = 0; /* TODO(QUIC FUTURE): Optimisation */
/*
* If sstream has no FIN, we auto-reset it at marked-for-deletion time, so
return 0;
/* Decode the packet header */
/*
- * TODO(QUIC): We need to query the short connection id len here,
- * e.g. via some API SSL_get_short_conn_id_len()
+ * TODO(QUIC SERVER): We need to query the short connection id len
+ * here, e.g. via some API SSL_get_short_conn_id_len()
*/
if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 1, &hdr, NULL) != 1)
return 0;
* This is not a major concern for clients, since if a client has a 1-RTT EL
* provisioned the server is guaranteed to also have a 1-RTT EL provisioned.
*
- * TODO(QUIC): Revisit this when server support is added.
+ * TODO(QUIC SERVER): Revisit this when server support is added.
*/
if (*conn_close_enc_level > enc_level
&& *conn_close_enc_level != QUIC_ENC_LEVEL_1RTT)
/* Determine how many bytes we should use for the encoded PN. */
static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp)
{
- return 4; /* TODO(QUIC) */
+ return 4; /* TODO(QUIC FUTURE) */
}
/* Determine plaintext packet payload length from payload length. */
return 0;
/* Create and initialise cipher context. */
- /* TODO(QUIC): Cipher fetch caching. */
+ /* TODO(QUIC FUTURE): Cipher fetch caching. */
if ((cipher = EVP_CIPHER_fetch(libctx, "AES-128-GCM", propq)) == NULL)
goto err;
ossl_statem_clear(sc);
- /* TODO(QUIC): Version handling not yet clear */
sc->version = s->method->version;
sc->client_version = sc->version;
sc->rwstate = SSL_NOTHING;
int SSL_copy_session_id(SSL *t, const SSL *f)
{
int i;
- /* TODO(QUIC): Not allowed for QUIC currently. */
+ /* TODO(QUIC FUTURE): Not allowed for QUIC currently. */
SSL_CONNECTION *tsc = SSL_CONNECTION_FROM_SSL_ONLY(t);
const SSL_CONNECTION *fsc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(f);
uint32_t partialwrite;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
+ /* TODO(QUIC 0RTT): This will need special handling for QUIC */
if (sc == NULL)
return 0;
long l;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- /* TODO(QUIC): Special handling for some ctrls will be needed */
+ /* TODO(QUIC FUTURE): Special handling for some ctrls will be needed */
if (sc == NULL)
return 0;
{
SSL *ret;
int i;
- /* TODO(QUIC): Add a SSL_METHOD function for duplication */
+ /* TODO(QUIC FUTURE): Add a SSL_METHOD function for duplication */
SSL_CONNECTION *retsc;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
return OSSL_QUIC1_VERSION;
#endif
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
if (sc == NULL)
return 0;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
+#ifndef OPENSSL_NO_QUIC
+ /* We only support QUICv1 - so if its QUIC its QUICv1 */
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return OSSL_QUIC1_VERSION;
+#endif
if (sc == NULL)
return 0;
CERT *new_cert;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
- /* TODO(QUIC): Do we need this for QUIC support? */
+ /* TODO(QUIC FUTURE): Add support for QUIC */
if (sc == NULL)
return NULL;