Introduced packet namespace in QUIC connection.

The structure contains all data that is related to the namespace:
packet number and output queue (next patch).
This commit is contained in:
Vladimir Homutov 2020-04-01 14:31:08 +03:00
parent 9595417396
commit d7eeb2e30b
4 changed files with 37 additions and 18 deletions

View File

@ -9,6 +9,20 @@
#include <ngx_event.h>
/* 0-RTT and 1-RTT data exist in the same packet number space,
* so we have 3 packet number spaces:
*
* 0 - Initial
* 1 - Handshake
* 2 - 0-RTT and 1-RTT
*/
#define ngx_quic_ns(level) \
((level) == ssl_encryption_initial) ? 0 \
: (((level) == ssl_encryption_handshake) ? 1 : 2)
#define NGX_QUIC_NAMESPACE_LAST (NGX_QUIC_ENCRYPTION_LAST - 1)
typedef enum {
NGX_QUIC_ST_INITIAL, /* connection just created */
NGX_QUIC_ST_HANDSHAKE, /* handshake started */
@ -26,6 +40,14 @@ typedef struct {
} ngx_quic_streams_t;
typedef struct {
ngx_quic_secret_t client_secret;
ngx_quic_secret_t server_secret;
ngx_uint_t pnum;
} ngx_quic_namespace_t;
struct ngx_quic_connection_s {
ngx_str_t scid;
ngx_str_t dcid;
@ -37,11 +59,7 @@ struct ngx_quic_connection_s {
ngx_quic_state_t state;
/* current packet numbers for each namespace */
ngx_uint_t initial_pn;
ngx_uint_t handshake_pn;
ngx_uint_t appdata_pn;
ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST];
ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
@ -1106,11 +1124,14 @@ ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
return NGX_ERROR;
}
ack_frame->level = pkt->level;
ack_frame->level = (pkt->level == ssl_encryption_early_data)
? ssl_encryption_application
: pkt->level;
ack_frame->type = NGX_QUIC_FT_ACK;
ack_frame->u.ack.pn = pkt->pn;
ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, pkt->level);
ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level);
ngx_quic_queue_frame(qc, ack_frame);
return ngx_quic_output(c);
@ -1454,6 +1475,7 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
ngx_quic_frame_t *f;
ngx_quic_header_t pkt;
ngx_quic_secrets_t *keys;
ngx_quic_namespace_t *ns;
ngx_quic_connection_t *qc;
static ngx_str_t initial_token = ngx_null_string;
static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
@ -1493,20 +1515,17 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
qc = c->quic;
keys = &c->quic->keys[start->level];
ns = &c->quic->ns[ngx_quic_ns(start->level)];
pkt.secret = &keys->server;
pkt.number = ns->pnum;
if (start->level == ssl_encryption_initial) {
pkt.number = &qc->initial_pn;
pkt.flags = NGX_QUIC_PKT_INITIAL;
pkt.token = initial_token;
} else if (start->level == ssl_encryption_handshake) {
pkt.number = &qc->handshake_pn;
pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
} else {
pkt.number = &qc->appdata_pn;
}
pkt.log = c->log;
@ -1525,7 +1544,7 @@ ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
c->send(c, res.data, res.len); // TODO: err handling
(*pkt.number)++;
ns->pnum++;
return NGX_OK;
}

View File

@ -673,7 +673,7 @@ ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
}
ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
pn = *pkt->number;
pn = pkt->number;
nonce[11] ^= pn;
ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);
@ -731,7 +731,7 @@ ngx_quic_create_short_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
if (pkt->level == ssl_encryption_handshake
|| pkt->level == ssl_encryption_application)
{
nonce[11] ^= *pkt->number;
nonce[11] ^= pkt->number;
}
ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);

View File

@ -366,7 +366,7 @@ ngx_quic_create_long_header(ngx_quic_header_t *pkt, u_char *out,
*pnp = p;
*p++ = (uint64_t) (*pkt->number);
*p++ = pkt->number; // XXX: uint64
return p - start;
}
@ -386,7 +386,7 @@ ngx_quic_create_short_header(ngx_quic_header_t *pkt, u_char *out,
*pnp = p;
*p++ = (*pkt->number);
*p++ = pkt->number; // XXX: uint64
return p - start;
}

View File

@ -232,7 +232,7 @@ typedef struct {
ngx_log_t *log;
struct ngx_quic_secret_s *secret;
ngx_uint_t *number;
uint64_t number;
uint8_t flags;
uint32_t version;
ngx_str_t token;