mirror of
https://github.com/nginx/nginx.git
synced 2025-06-21 13:20:47 +08:00
QUIC: updated specification references.
This includes updating citations and further clarification.
This commit is contained in:
parent
96e1db1c34
commit
ae58d87c01
@ -506,10 +506,11 @@ ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
|
|||||||
if (rc == NGX_DONE) {
|
if (rc == NGX_DONE) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 10.2. Idle Timeout
|
* RFC 9000, 10.1. Idle Timeout
|
||||||
*
|
*
|
||||||
* If the idle timeout is enabled by either peer, a connection is
|
* If a max_idle_timeout is specified by either endpoint in its
|
||||||
* silently closed and its state is discarded when it remains idle
|
* transport parameters (Section 18.2), the connection is silently
|
||||||
|
* closed and its state is discarded when it remains idle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
@ -519,7 +520,7 @@ ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 10.3. Immediate Close
|
* RFC 9000, 10.2. Immediate Close
|
||||||
*
|
*
|
||||||
* An endpoint sends a CONNECTION_CLOSE frame (Section 19.19)
|
* An endpoint sends a CONNECTION_CLOSE frame (Section 19.19)
|
||||||
* to terminate the connection immediately.
|
* to terminate the connection immediately.
|
||||||
@ -708,10 +709,10 @@ ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
|
|||||||
* Instead of queueing it, we ignore it and rely on the sender's
|
* Instead of queueing it, we ignore it and rely on the sender's
|
||||||
* retransmission:
|
* retransmission:
|
||||||
*
|
*
|
||||||
* 12.2. Coalescing Packets:
|
* RFC 9000, 12.2. Coalescing Packets
|
||||||
*
|
*
|
||||||
* For example, if decryption fails (because the keys are
|
* For example, if decryption fails (because the keys are
|
||||||
* not available or any other reason), the receiver MAY either
|
* not available or for any other reason), the receiver MAY either
|
||||||
* discard or buffer the packet for later processing and MUST
|
* discard or buffer the packet for later processing and MUST
|
||||||
* attempt to process the remaining packets.
|
* attempt to process the remaining packets.
|
||||||
*
|
*
|
||||||
@ -831,7 +832,7 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
|||||||
c->log->action = "processing initial packet";
|
c->log->action = "processing initial packet";
|
||||||
|
|
||||||
if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
|
if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
|
||||||
/* 7.2. Negotiating Connection IDs */
|
/* RFC 9000, 7.2. Negotiating Connection IDs */
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"quic too short dcid in initial"
|
"quic too short dcid in initial"
|
||||||
" packet: len:%i", pkt->dcid.len);
|
" packet: len:%i", pkt->dcid.len);
|
||||||
@ -944,7 +945,9 @@ ngx_quic_process_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
|||||||
|
|
||||||
if (pkt->level == ssl_encryption_handshake) {
|
if (pkt->level == ssl_encryption_handshake) {
|
||||||
/*
|
/*
|
||||||
* 4.10.1. The successful use of Handshake packets indicates
|
* RFC 9001, 4.9.1. Discarding Initial Keys
|
||||||
|
*
|
||||||
|
* The successful use of Handshake packets indicates
|
||||||
* that no more Initial packets need to be exchanged
|
* that no more Initial packets need to be exchanged
|
||||||
*/
|
*/
|
||||||
ngx_quic_discard_ctx(c, ssl_encryption_initial);
|
ngx_quic_discard_ctx(c, ssl_encryption_initial);
|
||||||
@ -957,12 +960,13 @@ ngx_quic_process_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
|||||||
|
|
||||||
if (qc->closing) {
|
if (qc->closing) {
|
||||||
/*
|
/*
|
||||||
* 10.1 Closing and Draining Connection States
|
* RFC 9000, 10.2. Immediate Close
|
||||||
|
*
|
||||||
* ... delayed or reordered packets are properly discarded.
|
* ... delayed or reordered packets are properly discarded.
|
||||||
*
|
*
|
||||||
* An endpoint retains only enough information to generate
|
* In the closing state, an endpoint retains only enough information
|
||||||
* a packet containing a CONNECTION_CLOSE frame and to identify
|
* to generate a packet containing a CONNECTION_CLOSE frame and to
|
||||||
* packets as belonging to the connection.
|
* identify packets as belonging to the connection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qc->error_level = pkt->level;
|
qc->error_level = pkt->level;
|
||||||
@ -1331,6 +1335,8 @@ ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
|||||||
|
|
||||||
if (qsock->path != qc->socket->path && nonprobing) {
|
if (qsock->path != qc->socket->path && nonprobing) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.2. Initiating Connection Migration
|
||||||
|
*
|
||||||
* An endpoint can migrate a connection to a new local
|
* An endpoint can migrate a connection to a new local
|
||||||
* address by sending packets containing non-probing frames
|
* address by sending packets containing non-probing frames
|
||||||
* from that address.
|
* from that address.
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
|
|
||||||
#define NGX_QUIC_MAX_ACK_GAP 2
|
#define NGX_QUIC_MAX_ACK_GAP 2
|
||||||
|
|
||||||
/* quic-recovery, section 6.1.1, Packet Threshold */
|
/* RFC 9002, 6.1.1. Packet Threshold: kPacketThreshold */
|
||||||
#define NGX_QUIC_PKT_THR 3 /* packets */
|
#define NGX_QUIC_PKT_THR 3 /* packets */
|
||||||
/* quic-recovery, section 6.1.2, Time Threshold */
|
/* RFC 9002, 6.1.2. Time Threshold: kTimeThreshold, kGranularity */
|
||||||
#define NGX_QUIC_TIME_THR 1.125
|
#define NGX_QUIC_TIME_THR 1.125
|
||||||
#define NGX_QUIC_TIME_GRANULARITY 1 /* ms */
|
#define NGX_QUIC_TIME_GRANULARITY 1 /* ms */
|
||||||
|
|
||||||
/* quic-recovery, section 7.6.1 Persistent congestion duration */
|
/* RFC 9002, 7.6.1. Duration: kPersistentCongestionThreshold */
|
||||||
#define NGX_QUIC_PERSISTENT_CONGESTION_THR 3
|
#define NGX_QUIC_PERSISTENT_CONGESTION_THR 3
|
||||||
|
|
||||||
#define ngx_quic_lost_threshold(qc) \
|
#define ngx_quic_lost_threshold(qc) \
|
||||||
@ -73,9 +73,10 @@ ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
|||||||
ack = &f->u.ack;
|
ack = &f->u.ack;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 19.3.1. ACK Ranges
|
||||||
|
*
|
||||||
* If any computed packet number is negative, an endpoint MUST
|
* If any computed packet number is negative, an endpoint MUST
|
||||||
* generate a connection error of type FRAME_ENCODING_ERROR.
|
* generate a connection error of type FRAME_ENCODING_ERROR.
|
||||||
* (19.3.1)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ack->first_range > ack->largest) {
|
if (ack->first_range > ack->largest) {
|
||||||
@ -97,13 +98,15 @@ ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 13.2.3. Receiver Tracking of ACK Frames */
|
/* RFC 9000, 13.2.4. Limiting Ranges by Tracking ACK Frames */
|
||||||
if (ctx->largest_ack < max || ctx->largest_ack == NGX_QUIC_UNSET_PN) {
|
if (ctx->largest_ack < max || ctx->largest_ack == NGX_QUIC_UNSET_PN) {
|
||||||
ctx->largest_ack = max;
|
ctx->largest_ack = max;
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
"quic updated largest received ack:%uL", max);
|
"quic updated largest received ack:%uL", max);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9002, 5.1. Generating RTT Samples
|
||||||
|
*
|
||||||
* An endpoint generates an RTT sample on receiving an
|
* An endpoint generates an RTT sample on receiving an
|
||||||
* ACK frame that meets the following two conditions:
|
* ACK frame that meets the following two conditions:
|
||||||
*
|
*
|
||||||
@ -470,7 +473,7 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Establishing Persistent Congestion (7.6.2) */
|
/* RFC 9002, 7.6.2. Establishing Persistent Congestion */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Once acknowledged, packets are no longer tracked. Thus no send time
|
* Once acknowledged, packets are no longer tracked. Thus no send time
|
||||||
@ -757,7 +760,7 @@ ngx_quic_pto(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
|
|||||||
|
|
||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
|
|
||||||
/* PTO calculation: quic-recovery, Appendix 8 */
|
/* RFC 9002, Appendix A.8. Setting the Loss Detection Timer */
|
||||||
duration = qc->avg_rtt;
|
duration = qc->avg_rtt;
|
||||||
|
|
||||||
duration += ngx_max(4 * qc->rttvar, NGX_QUIC_TIME_GRANULARITY);
|
duration += ngx_max(4 * qc->rttvar, NGX_QUIC_TIME_GRANULARITY);
|
||||||
|
@ -38,7 +38,7 @@ typedef struct ngx_quic_keys_s ngx_quic_keys_t;
|
|||||||
#include <ngx_event_quic_socket.h>
|
#include <ngx_event_quic_socket.h>
|
||||||
|
|
||||||
|
|
||||||
/* quic-recovery, section 6.2.2, kInitialRtt */
|
/* RFC 9002, 6.2.2. Handshakes and New Paths: kInitialRtt */
|
||||||
#define NGX_QUIC_INITIAL_RTT 333 /* ms */
|
#define NGX_QUIC_INITIAL_RTT 333 /* ms */
|
||||||
|
|
||||||
#define NGX_QUIC_UNSET_PN (uint64_t) -1
|
#define NGX_QUIC_UNSET_PN (uint64_t) -1
|
||||||
@ -143,13 +143,13 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 12.3. Packet Numbers
|
* RFC 9000, 12.3. Packet Numbers
|
||||||
*
|
*
|
||||||
* Conceptually, a packet number space is the context in which a packet
|
* Conceptually, a packet number space is the context in which a packet
|
||||||
* can be processed and acknowledged. Initial packets can only be sent
|
* can be processed and acknowledged. Initial packets can only be sent
|
||||||
* with Initial packet protection keys and acknowledged in packets which
|
* with Initial packet protection keys and acknowledged in packets that
|
||||||
* are also Initial packets.
|
* are also Initial packets.
|
||||||
*/
|
*/
|
||||||
struct ngx_quic_send_ctx_s {
|
struct ngx_quic_send_ctx_s {
|
||||||
enum ssl_encryption_level_t level;
|
enum ssl_encryption_level_t level;
|
||||||
|
|
||||||
|
@ -86,11 +86,13 @@ ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
|||||||
|
|
||||||
if (f->seqnum < qc->max_retired_seqnum) {
|
if (f->seqnum < qc->max_retired_seqnum) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 19.15. NEW_CONNECTION_ID Frame
|
||||||
|
*
|
||||||
* An endpoint that receives a NEW_CONNECTION_ID frame with
|
* An endpoint that receives a NEW_CONNECTION_ID frame with
|
||||||
* a sequence number smaller than the Retire Prior To field
|
* a sequence number smaller than the Retire Prior To field
|
||||||
* of a previously received NEW_CONNECTION_ID frame MUST send
|
* of a previously received NEW_CONNECTION_ID frame MUST send
|
||||||
* a corresponding RETIRE_CONNECTION_ID frame that retires
|
* a corresponding RETIRE_CONNECTION_ID frame that retires
|
||||||
* the newly received connection ID, unless it has already
|
* the newly received connection ID, unless it has already
|
||||||
* done so for that sequence number.
|
* done so for that sequence number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -117,8 +119,8 @@ ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
|||||||
|
|
||||||
if (cid) {
|
if (cid) {
|
||||||
/*
|
/*
|
||||||
* Transmission errors, timeouts and retransmissions might cause the
|
* Transmission errors, timeouts, and retransmissions might cause the
|
||||||
* same NEW_CONNECTION_ID frame to be received multiple times
|
* same NEW_CONNECTION_ID frame to be received multiple times.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cid->len != f->len
|
if (cid->len != f->len
|
||||||
@ -126,7 +128,7 @@ ngx_quic_handle_new_connection_id_frame(ngx_connection_t *c,
|
|||||||
|| ngx_strncmp(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN) != 0)
|
|| ngx_strncmp(cid->sr_token, f->srt, NGX_QUIC_SR_TOKEN_LEN) != 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* ..a sequence number is used for different connection IDs,
|
* ..if a sequence number is used for different connection IDs,
|
||||||
* the endpoint MAY treat that receipt as a connection error
|
* the endpoint MAY treat that receipt as a connection error
|
||||||
* of type PROTOCOL_VIOLATION.
|
* of type PROTOCOL_VIOLATION.
|
||||||
*/
|
*/
|
||||||
@ -190,6 +192,8 @@ done:
|
|||||||
|
|
||||||
if (qc->nclient_ids > qc->tp.active_connection_id_limit) {
|
if (qc->nclient_ids > qc->tp.active_connection_id_limit) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 5.1.1. Issuing Connection IDs
|
||||||
|
*
|
||||||
* After processing a NEW_CONNECTION_ID frame and
|
* After processing a NEW_CONNECTION_ID frame and
|
||||||
* adding and retiring active connection IDs, if the number of active
|
* adding and retiring active connection IDs, if the number of active
|
||||||
* connection IDs exceeds the value advertised in its
|
* connection IDs exceeds the value advertised in its
|
||||||
|
@ -38,15 +38,17 @@ ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
|
|||||||
frame.u.path_response = *f;
|
frame.u.path_response = *f;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 8.2.2. Path Validation Responses
|
||||||
|
*
|
||||||
* A PATH_RESPONSE frame MUST be sent on the network path where the
|
* A PATH_RESPONSE frame MUST be sent on the network path where the
|
||||||
* PATH_CHALLENGE was received.
|
* PATH_CHALLENGE frame was received.
|
||||||
*/
|
*/
|
||||||
qsock = ngx_quic_get_socket(c);
|
qsock = ngx_quic_get_socket(c);
|
||||||
path = qsock->path;
|
path = qsock->path;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An endpoint MUST NOT expand the datagram containing the PATH_RESPONSE
|
* An endpoint MUST NOT expand the datagram containing the PATH_RESPONSE
|
||||||
* if the resulting data exceeds the anti-amplification limit.
|
* if the resulting data exceeds the anti-amplification limit.
|
||||||
*/
|
*/
|
||||||
max = path->received * 3;
|
max = path->received * 3;
|
||||||
max = (path->sent >= max) ? 0 : max - path->sent;
|
max = (path->sent >= max) ? 0 : max - path->sent;
|
||||||
@ -61,6 +63,8 @@ ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
|
|||||||
|
|
||||||
if (qsock == qc->socket) {
|
if (qsock == qc->socket) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.3.3. Off-Path Packet Forwarding
|
||||||
|
*
|
||||||
* An endpoint that receives a PATH_CHALLENGE on an active path SHOULD
|
* An endpoint that receives a PATH_CHALLENGE on an active path SHOULD
|
||||||
* send a non-probing packet in response.
|
* send a non-probing packet in response.
|
||||||
*/
|
*/
|
||||||
@ -91,6 +95,8 @@ ngx_quic_handle_path_response_frame(ngx_connection_t *c,
|
|||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 8.2.3. Successful Path Validation
|
||||||
|
*
|
||||||
* A PATH_RESPONSE frame received on any network path validates the path
|
* A PATH_RESPONSE frame received on any network path validates the path
|
||||||
* on which the PATH_CHALLENGE was sent.
|
* on which the PATH_CHALLENGE was sent.
|
||||||
*/
|
*/
|
||||||
@ -120,11 +126,12 @@ ngx_quic_handle_path_response_frame(ngx_connection_t *c,
|
|||||||
valid:
|
valid:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.4. Loss Detection and Congestion Control
|
||||||
|
*
|
||||||
* On confirming a peer's ownership of its new address,
|
* On confirming a peer's ownership of its new address,
|
||||||
* an endpoint MUST immediately reset the congestion controller
|
* an endpoint MUST immediately reset the congestion controller
|
||||||
* and round-trip time estimator for the new path
|
* and round-trip time estimator for the new path to initial values
|
||||||
* to initial values
|
* unless the only change in the peer's address is its port number.
|
||||||
* ...unless the only change in the peer's address is its port number.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
prev = qc->backup->path;
|
prev = qc->backup->path;
|
||||||
@ -144,6 +151,8 @@ valid:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.3. Responding to Connection Migration
|
||||||
|
*
|
||||||
* After verifying a new client address, the server SHOULD
|
* After verifying a new client address, the server SHOULD
|
||||||
* send new address validation tokens (Section 8) to the client.
|
* send new address validation tokens (Section 8) to the client.
|
||||||
*/
|
*/
|
||||||
@ -474,6 +483,8 @@ ngx_quic_handle_migration(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
|||||||
ctx = ngx_quic_get_send_ctx(qc, pkt->level);
|
ctx = ngx_quic_get_send_ctx(qc, pkt->level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.3. Responding to Connection Migration
|
||||||
|
*
|
||||||
* An endpoint only changes the address to which it sends packets in
|
* An endpoint only changes the address to which it sends packets in
|
||||||
* response to the highest-numbered non-probing packet.
|
* response to the highest-numbered non-probing packet.
|
||||||
*/
|
*/
|
||||||
@ -486,6 +497,8 @@ ngx_quic_handle_migration(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
|||||||
ngx_quic_set_connection_path(c, next);
|
ngx_quic_set_connection_path(c, next);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.5. Privacy Implications of Connection Migration
|
||||||
|
*
|
||||||
* An endpoint MUST NOT reuse a connection ID when sending to
|
* An endpoint MUST NOT reuse a connection ID when sending to
|
||||||
* more than one destination address.
|
* more than one destination address.
|
||||||
*/
|
*/
|
||||||
@ -578,6 +591,8 @@ ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path)
|
|||||||
ngx_memcpy(frame.u.path_challenge.data, path->challenge1, 8);
|
ngx_memcpy(frame.u.path_challenge.data, path->challenge1, 8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 8.2.1. Initiating Path Validation
|
||||||
|
*
|
||||||
* An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
|
* An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame
|
||||||
* to at least the smallest allowed maximum datagram size of 1200 bytes,
|
* to at least the smallest allowed maximum datagram size of 1200 bytes,
|
||||||
* unless the anti-amplification limit for the path does not permit
|
* unless the anti-amplification limit for the path does not permit
|
||||||
@ -675,9 +690,11 @@ ngx_quic_path_validation_handler(ngx_event_t *ev)
|
|||||||
path->state = NGX_QUIC_PATH_NEW;
|
path->state = NGX_QUIC_PATH_NEW;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.4. Loss Detection and Congestion Control
|
||||||
|
*
|
||||||
* If the timer fires before the PATH_RESPONSE is received, the
|
* If the timer fires before the PATH_RESPONSE is received, the
|
||||||
* endpoint might send a new PATH_CHALLENGE, and restart the timer for
|
* endpoint might send a new PATH_CHALLENGE and restart the timer for
|
||||||
* a longer period of time. This timer SHOULD be set as described in
|
* a longer period of time. This timer SHOULD be set as described in
|
||||||
* Section 6.2.1 of [QUIC-RECOVERY] and MUST NOT be more aggressive.
|
* Section 6.2.1 of [QUIC-RECOVERY] and MUST NOT be more aggressive.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -708,9 +725,13 @@ ngx_quic_path_restore(ngx_connection_t *c)
|
|||||||
|
|
||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
|
|
||||||
/* Failure to validate a path does not cause the connection to end */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 9.1. Probing a New Path
|
||||||
|
*
|
||||||
|
* Failure to validate a path does not cause the connection to end
|
||||||
|
*
|
||||||
|
* RFC 9000, 9.3.2. On-Path Address Spoofing
|
||||||
|
*
|
||||||
* To protect the connection from failing due to such a spurious
|
* To protect the connection from failing due to such a spurious
|
||||||
* migration, an endpoint MUST revert to using the last validated
|
* migration, an endpoint MUST revert to using the last validated
|
||||||
* peer address when validation of a new peer address fails.
|
* peer address when validation of a new peer address fails.
|
||||||
|
@ -23,9 +23,11 @@
|
|||||||
/* 1 flags + 4 version + 3 x (1 + 20) s/o/dcid + itag + token(64) */
|
/* 1 flags + 4 version + 3 x (1 + 20) s/o/dcid + itag + token(64) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 10.3. Stateless Reset
|
||||||
|
*
|
||||||
* Endpoints MUST discard packets that are too small to be valid QUIC
|
* Endpoints MUST discard packets that are too small to be valid QUIC
|
||||||
* packets. With the set of AEAD functions defined in [QUIC-TLS],
|
* packets. With the set of AEAD functions defined in [QUIC-TLS],
|
||||||
* packets that are smaller than 21 bytes are never valid.
|
* short header packets that are smaller than 21 bytes are never valid.
|
||||||
*/
|
*/
|
||||||
#define NGX_QUIC_MIN_PKT_LEN 21
|
#define NGX_QUIC_MIN_PKT_LEN 21
|
||||||
|
|
||||||
@ -170,11 +172,11 @@ ngx_quic_get_padding_level(ngx_connection_t *c)
|
|||||||
ngx_quic_connection_t *qc;
|
ngx_quic_connection_t *qc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 14.1. Initial Datagram Size
|
* RFC 9000, 14.1. Initial Datagram Size
|
||||||
*
|
*
|
||||||
* Similarly, a server MUST expand the payload of all UDP datagrams
|
* Similarly, a server MUST expand the payload of all UDP datagrams
|
||||||
* carrying ack-eliciting Initial packets to at least the smallest
|
* carrying ack-eliciting Initial packets to at least the smallest
|
||||||
* allowed maximum datagram size of 1200 bytes
|
* allowed maximum datagram size of 1200 bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
@ -345,6 +347,8 @@ ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
|
|||||||
+ ngx_quic_create_header(&pkt, NULL, out.len, NULL);
|
+ ngx_quic_create_header(&pkt, NULL, out.len, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 8.2.1. Initiating Path Validation
|
||||||
|
*
|
||||||
* An endpoint MUST expand datagrams that contain a
|
* An endpoint MUST expand datagrams that contain a
|
||||||
* PATH_CHALLENGE frame to at least the smallest allowed
|
* PATH_CHALLENGE frame to at least the smallest allowed
|
||||||
* maximum datagram size of 1200 bytes, unless the
|
* maximum datagram size of 1200 bytes, unless the
|
||||||
@ -777,7 +781,9 @@ ngx_quic_send_retry(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
|||||||
"quic retry packet sent to %xV", &pkt.dcid);
|
"quic retry packet sent to %xV", &pkt.dcid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* quic-transport 17.2.5.1: A server MUST NOT send more than one Retry
|
* RFC 9000, 17.2.5.1. Sending a Retry Packet
|
||||||
|
*
|
||||||
|
* A server MUST NOT send more than one Retry
|
||||||
* packet in response to a single UDP datagram.
|
* packet in response to a single UDP datagram.
|
||||||
* NGX_DONE will stop quic_input() from processing further
|
* NGX_DONE will stop quic_input() from processing further
|
||||||
*/
|
*/
|
||||||
|
@ -160,7 +160,12 @@ ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
|
|||||||
client = &keys->secrets[ssl_encryption_initial].client;
|
client = &keys->secrets[ssl_encryption_initial].client;
|
||||||
server = &keys->secrets[ssl_encryption_initial].server;
|
server = &keys->secrets[ssl_encryption_initial].server;
|
||||||
|
|
||||||
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
|
/*
|
||||||
|
* RFC 9001, section 5. Packet Protection
|
||||||
|
*
|
||||||
|
* Initial packets use AEAD_AES_128_GCM. The hash function
|
||||||
|
* for HKDF when deriving initial secrets and keys is SHA-256.
|
||||||
|
*/
|
||||||
|
|
||||||
cipher = EVP_aes_128_gcm();
|
cipher = EVP_aes_128_gcm();
|
||||||
digest = EVP_sha256();
|
digest = EVP_sha256();
|
||||||
@ -187,7 +192,6 @@ ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
|
|||||||
"quic initial secret len:%uz %*xs", is_len, is_len, is);
|
"quic initial secret len:%uz %*xs", is_len, is_len, is);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* draft-ietf-quic-tls-23#section-5.2 */
|
|
||||||
client->secret.len = SHA256_DIGEST_LENGTH;
|
client->secret.len = SHA256_DIGEST_LENGTH;
|
||||||
server->secret.len = SHA256_DIGEST_LENGTH;
|
server->secret.len = SHA256_DIGEST_LENGTH;
|
||||||
|
|
||||||
@ -206,7 +210,7 @@ ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
|
|||||||
ngx_str_t *prk;
|
ngx_str_t *prk;
|
||||||
} seq[] = {
|
} seq[] = {
|
||||||
|
|
||||||
/* draft-ietf-quic-tls-23#section-5.2 */
|
/* labels per RFC 9001, 5.1. Packet Protection Keys */
|
||||||
{ ngx_string("tls13 client in"), &client->secret, &iss },
|
{ ngx_string("tls13 client in"), &client->secret, &iss },
|
||||||
{
|
{
|
||||||
ngx_string("tls13 quic key"),
|
ngx_string("tls13 quic key"),
|
||||||
@ -219,14 +223,12 @@ ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
|
|||||||
&client->secret,
|
&client->secret,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
|
|
||||||
ngx_string("tls13 quic hp"),
|
ngx_string("tls13 quic hp"),
|
||||||
&client->hp,
|
&client->hp,
|
||||||
&client->secret,
|
&client->secret,
|
||||||
},
|
},
|
||||||
{ ngx_string("tls13 server in"), &server->secret, &iss },
|
{ ngx_string("tls13 server in"), &server->secret, &iss },
|
||||||
{
|
{
|
||||||
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
|
|
||||||
ngx_string("tls13 quic key"),
|
ngx_string("tls13 quic key"),
|
||||||
&server->key,
|
&server->key,
|
||||||
&server->secret,
|
&server->secret,
|
||||||
@ -237,7 +239,6 @@ ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
|
|||||||
&server->secret,
|
&server->secret,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
|
|
||||||
ngx_string("tls13 quic hp"),
|
ngx_string("tls13 quic hp"),
|
||||||
&server->hp,
|
&server->hp,
|
||||||
&server->secret,
|
&server->secret,
|
||||||
@ -894,7 +895,7 @@ ngx_quic_create_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quic-tls: 5.4.1. Header Protection Application */
|
/* RFC 9001, 5.4.1. Header Protection Application */
|
||||||
ad.data[0] ^= mask[0] & ngx_quic_pkt_hp_mask(pkt->flags);
|
ad.data[0] ^= mask[0] & ngx_quic_pkt_hp_mask(pkt->flags);
|
||||||
|
|
||||||
for (i = 0; i < pkt->num_len; i++) {
|
for (i = 0; i < pkt->num_len; i++) {
|
||||||
@ -1095,10 +1096,13 @@ ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
|
|||||||
p = pkt->raw->pos;
|
p = pkt->raw->pos;
|
||||||
len = pkt->data + pkt->len - p;
|
len = pkt->data + pkt->len - p;
|
||||||
|
|
||||||
/* draft-ietf-quic-tls-23#section-5.4.2:
|
/*
|
||||||
|
* RFC 9001, 5.4.2. Header Protection Sample
|
||||||
|
* 5.4.3. AES-Based Header Protection
|
||||||
|
* 5.4.4. ChaCha20-Based Header Protection
|
||||||
|
*
|
||||||
* the Packet Number field is assumed to be 4 bytes long
|
* the Packet Number field is assumed to be 4 bytes long
|
||||||
* draft-ietf-quic-tls-23#section-5.4.[34]:
|
* AES and ChaCha20 algorithms sample 16 bytes
|
||||||
* AES-Based and ChaCha20-Based header protections sample 16 bytes
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (len < EVP_GCM_TLS_TAG_LEN + 4) {
|
if (len < EVP_GCM_TLS_TAG_LEN + 4) {
|
||||||
@ -1172,6 +1176,8 @@ ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
|
|||||||
|
|
||||||
if (pkt->payload.len == 0) {
|
if (pkt->payload.len == 0) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, 12.4. Frames and Frame Types
|
||||||
|
*
|
||||||
* An endpoint MUST treat receipt of a packet containing no
|
* An endpoint MUST treat receipt of a packet containing no
|
||||||
* frames as a connection error of type PROTOCOL_VIOLATION.
|
* frames as a connection error of type PROTOCOL_VIOLATION.
|
||||||
*/
|
*/
|
||||||
@ -1182,6 +1188,8 @@ ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
|
|||||||
|
|
||||||
if (pkt->flags & ngx_quic_pkt_rb_mask(pkt->flags)) {
|
if (pkt->flags & ngx_quic_pkt_rb_mask(pkt->flags)) {
|
||||||
/*
|
/*
|
||||||
|
* RFC 9000, Reserved Bits
|
||||||
|
*
|
||||||
* An endpoint MUST treat receipt of a packet that has
|
* An endpoint MUST treat receipt of a packet that has
|
||||||
* a non-zero value for these bits, after removing both
|
* a non-zero value for these bits, after removing both
|
||||||
* packet and header protection, as a connection error
|
* packet and header protection, as a connection error
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 7.4. Cryptographic Message Buffering
|
* RFC 9000, 7.5. Cryptographic Message Buffering
|
||||||
* Implementations MUST support buffering at least 4096 bytes of data
|
*
|
||||||
|
* Implementations MUST support buffering at least 4096 bytes of data
|
||||||
*/
|
*/
|
||||||
#define NGX_QUIC_MAX_BUFFERED 65535
|
#define NGX_QUIC_MAX_BUFFERED 65535
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
|
|||||||
" params_len:%ui", client_params_len);
|
" params_len:%ui", client_params_len);
|
||||||
|
|
||||||
if (client_params_len == 0) {
|
if (client_params_len == 0) {
|
||||||
/* quic-tls 8.2 */
|
/* RFC 9001, 8.2. QUIC Transport Parameters Extension */
|
||||||
qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_MISSING_EXTENSION);
|
qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_MISSING_EXTENSION);
|
||||||
qc->error_reason = "missing transport parameters";
|
qc->error_reason = "missing transport parameters";
|
||||||
|
|
||||||
@ -428,7 +429,6 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 12.4 Frames and frame types, figure 8 */
|
|
||||||
frame->level = ssl_encryption_application;
|
frame->level = ssl_encryption_application;
|
||||||
frame->type = NGX_QUIC_FT_HANDSHAKE_DONE;
|
frame->type = NGX_QUIC_FT_HANDSHAKE_DONE;
|
||||||
ngx_quic_queue_frame(qc, frame);
|
ngx_quic_queue_frame(qc, frame);
|
||||||
@ -440,8 +440,9 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* RFC 9001, 9.5. Header Protection Timing Side Channels
|
||||||
|
*
|
||||||
* Generating next keys before a key update is received.
|
* Generating next keys before a key update is received.
|
||||||
* See quic-tls 9.4 Header Protection Timing Side-Channels.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ngx_quic_keys_update(c, qc->keys) != NGX_OK) {
|
if (ngx_quic_keys_update(c, qc->keys) != NGX_OK) {
|
||||||
@ -449,8 +450,10 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4.10.2 An endpoint MUST discard its handshake keys
|
* RFC 9001, 4.9.2. Discarding Handshake Keys
|
||||||
* when the TLS handshake is confirmed
|
*
|
||||||
|
* An endpoint MUST discard its Handshake keys
|
||||||
|
* when the TLS handshake is confirmed.
|
||||||
*/
|
*/
|
||||||
ngx_quic_discard_ctx(c, ssl_encryption_handshake);
|
ngx_quic_discard_ctx(c, ssl_encryption_handshake);
|
||||||
|
|
||||||
|
@ -296,12 +296,11 @@ ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.1. Stream Types and Identifiers
|
* RFC 9000, 2.1. Stream Types and Identifiers
|
||||||
*
|
*
|
||||||
* Within each type, streams are created with numerically increasing
|
* successive streams of each type are created with numerically increasing
|
||||||
* stream IDs. A stream ID that is used out of order results in all
|
* stream IDs. A stream ID that is used out of order results in all
|
||||||
* streams of that type with lower-numbered stream IDs also being
|
* streams of that type with lower-numbered stream IDs also being opened.
|
||||||
* opened.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for ( /* void */ ; min_id < id; min_id += 0x04) {
|
for ( /* void */ ; min_id < id; min_id += 0x04) {
|
||||||
|
@ -1127,7 +1127,11 @@ ngx_quic_frame_allowed(ngx_quic_header_t *pkt, ngx_uint_t frame_type)
|
|||||||
{
|
{
|
||||||
uint8_t ptype;
|
uint8_t ptype;
|
||||||
|
|
||||||
/* frame permissions per packet: 4 bits: IH01: 12.4, Table 3 */
|
/*
|
||||||
|
* RFC 9000, 12.4. Frames and Frame Types: Table 3
|
||||||
|
*
|
||||||
|
* Frame permissions per packet: 4 bits: IH01
|
||||||
|
*/
|
||||||
static uint8_t ngx_quic_frame_masks[] = {
|
static uint8_t ngx_quic_frame_masks[] = {
|
||||||
/* PADDING */ 0xF,
|
/* PADDING */ 0xF,
|
||||||
/* PING */ 0xF,
|
/* PING */ 0xF,
|
||||||
@ -1242,9 +1246,9 @@ ssize_t
|
|||||||
ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* QUIC-recovery, section 2:
|
* RFC 9002, 2. Conventions and Definitions
|
||||||
*
|
*
|
||||||
* Ack-eliciting Frames: All frames other than ACK, PADDING, and
|
* Ack-eliciting frames: All frames other than ACK, PADDING, and
|
||||||
* CONNECTION_CLOSE are considered ack-eliciting.
|
* CONNECTION_CLOSE are considered ack-eliciting.
|
||||||
*/
|
*/
|
||||||
f->need_ack = 1;
|
f->need_ack = 1;
|
||||||
|
@ -12,8 +12,12 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
/* QUIC flags in first byte, see quic-transport 17.2 and 17.3 */
|
/*
|
||||||
|
* RFC 9000, 17.2. Long Header Packets
|
||||||
|
* 17.3. Short Header Packets
|
||||||
|
*
|
||||||
|
* QUIC flags in first byte
|
||||||
|
*/
|
||||||
#define NGX_QUIC_PKT_LONG 0x80 /* header form */
|
#define NGX_QUIC_PKT_LONG 0x80 /* header form */
|
||||||
#define NGX_QUIC_PKT_FIXED_BIT 0x40
|
#define NGX_QUIC_PKT_FIXED_BIT 0x40
|
||||||
#define NGX_QUIC_PKT_TYPE 0x30 /* in long packet */
|
#define NGX_QUIC_PKT_TYPE 0x30 /* in long packet */
|
||||||
@ -85,7 +89,7 @@
|
|||||||
|
|
||||||
#define NGX_QUIC_FT_LAST NGX_QUIC_FT_HANDSHAKE_DONE
|
#define NGX_QUIC_FT_LAST NGX_QUIC_FT_HANDSHAKE_DONE
|
||||||
|
|
||||||
/* 22.4. QUIC Transport Error Codes Registry */
|
/* 22.5. QUIC Transport Error Codes Registry */
|
||||||
/* Keep in sync with ngx_quic_errors[] */
|
/* Keep in sync with ngx_quic_errors[] */
|
||||||
#define NGX_QUIC_ERR_NO_ERROR 0x00
|
#define NGX_QUIC_ERR_NO_ERROR 0x00
|
||||||
#define NGX_QUIC_ERR_INTERNAL_ERROR 0x01
|
#define NGX_QUIC_ERR_INTERNAL_ERROR 0x01
|
||||||
@ -111,7 +115,7 @@
|
|||||||
#define NGX_QUIC_ERR_CRYPTO(e) (NGX_QUIC_ERR_CRYPTO_ERROR + (e))
|
#define NGX_QUIC_ERR_CRYPTO(e) (NGX_QUIC_ERR_CRYPTO_ERROR + (e))
|
||||||
|
|
||||||
|
|
||||||
/* Transport parameters */
|
/* 22.3. QUIC Transport Parameters Registry */
|
||||||
#define NGX_QUIC_TP_ORIGINAL_DCID 0x00
|
#define NGX_QUIC_TP_ORIGINAL_DCID 0x00
|
||||||
#define NGX_QUIC_TP_MAX_IDLE_TIMEOUT 0x01
|
#define NGX_QUIC_TP_MAX_IDLE_TIMEOUT 0x01
|
||||||
#define NGX_QUIC_TP_SR_TOKEN 0x02
|
#define NGX_QUIC_TP_SR_TOKEN 0x02
|
||||||
|
Loading…
Reference in New Issue
Block a user