comparison src/event/ngx_event_quic.c @ 8339:aba84d9ab256 quic

Parsing of truncated packet numbers. For sample decoding algorithm, see quic-transport-27#appendix-A.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 16 Apr 2020 12:46:48 +0300
parents 0f9e9786b90d
children efc0a65424e8
comparison
equal deleted inserted replaced
8338:0f9e9786b90d 8339:aba84d9ab256
63 */ 63 */
64 typedef struct { 64 typedef struct {
65 ngx_quic_secret_t client_secret; 65 ngx_quic_secret_t client_secret;
66 ngx_quic_secret_t server_secret; 66 ngx_quic_secret_t server_secret;
67 67
68 uint64_t pnum; 68 uint64_t pnum; /* packet number to send */
69 uint64_t largest_ack; /* number received from peer */ 69 uint64_t largest_ack; /* number received from peer */
70 uint64_t largest_pn; /* number received from peer */
70 71
71 ngx_queue_t frames; 72 ngx_queue_t frames;
72 ngx_queue_t sent; 73 ngx_queue_t sent;
73 } ngx_quic_send_ctx_t; 74 } ngx_quic_send_ctx_t;
74 75
471 ngx_quic_header_t *pkt, ngx_connection_handler_pt handler) 472 ngx_quic_header_t *pkt, ngx_connection_handler_pt handler)
472 { 473 {
473 ngx_uint_t i; 474 ngx_uint_t i;
474 ngx_quic_tp_t *ctp; 475 ngx_quic_tp_t *ctp;
475 ngx_quic_secrets_t *keys; 476 ngx_quic_secrets_t *keys;
477 ngx_quic_send_ctx_t *ctx;
476 ngx_quic_connection_t *qc; 478 ngx_quic_connection_t *qc;
477 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 479 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
478 480
479 if (ngx_buf_size(pkt->raw) < 1200) { 481 if (ngx_buf_size(pkt->raw) < 1200) {
480 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram"); 482 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram");
508 ngx_quic_rbtree_insert_stream); 510 ngx_quic_rbtree_insert_stream);
509 511
510 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { 512 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
511 ngx_queue_init(&qc->send_ctx[i].frames); 513 ngx_queue_init(&qc->send_ctx[i].frames);
512 ngx_queue_init(&qc->send_ctx[i].sent); 514 ngx_queue_init(&qc->send_ctx[i].sent);
515 qc->send_ctx[i].largest_pn = (uint64_t) -1;
513 } 516 }
514 517
515 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { 518 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
516 ngx_queue_init(&qc->crypto[i].frames); 519 ngx_queue_init(&qc->crypto[i].frames);
517 } 520 }
572 575
573 pkt->secret = &keys->client; 576 pkt->secret = &keys->client;
574 pkt->level = ssl_encryption_initial; 577 pkt->level = ssl_encryption_initial;
575 pkt->plaintext = buf; 578 pkt->plaintext = buf;
576 579
577 if (ngx_quic_decrypt(pkt, NULL) != NGX_OK) { 580 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
581
582 if (ngx_quic_decrypt(pkt, NULL, &ctx->largest_pn) != NGX_OK) {
578 return NGX_ERROR; 583 return NGX_ERROR;
579 } 584 }
580 585
581 if (pkt->pn != 0) { 586 if (pkt->pn != 0) {
582 ngx_log_error(NGX_LOG_INFO, c->log, 0, 587 ngx_log_error(NGX_LOG_INFO, c->log, 0,
905 910
906 911
907 static ngx_int_t 912 static ngx_int_t
908 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 913 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
909 { 914 {
910 ngx_ssl_conn_t *ssl_conn; 915 ngx_ssl_conn_t *ssl_conn;
911 ngx_quic_secrets_t *keys; 916 ngx_quic_secrets_t *keys;
912 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 917 ngx_quic_send_ctx_t *ctx;
918 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
913 919
914 c->log->action = "processing initial quic packet"; 920 c->log->action = "processing initial quic packet";
915 921
916 ssl_conn = c->ssl->connection; 922 ssl_conn = c->ssl->connection;
917 923
927 933
928 pkt->secret = &keys->client; 934 pkt->secret = &keys->client;
929 pkt->level = ssl_encryption_initial; 935 pkt->level = ssl_encryption_initial;
930 pkt->plaintext = buf; 936 pkt->plaintext = buf;
931 937
932 if (ngx_quic_decrypt(pkt, ssl_conn) != NGX_OK) { 938 ctx = ngx_quic_get_send_ctx(c->quic, pkt->level);
939
940 if (ngx_quic_decrypt(pkt, ssl_conn, &ctx->largest_pn) != NGX_OK) {
933 return NGX_ERROR; 941 return NGX_ERROR;
934 } 942 }
935 943
936 return ngx_quic_payload_handler(c, pkt); 944 return ngx_quic_payload_handler(c, pkt);
937 } 945 }
939 947
940 static ngx_int_t 948 static ngx_int_t
941 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 949 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
942 { 950 {
943 ngx_quic_secrets_t *keys; 951 ngx_quic_secrets_t *keys;
952 ngx_quic_send_ctx_t *ctx;
944 ngx_quic_connection_t *qc; 953 ngx_quic_connection_t *qc;
945 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 954 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
946 955
947 c->log->action = "processing handshake quic packet"; 956 c->log->action = "processing handshake quic packet";
948 957
993 1002
994 pkt->secret = &keys->client; 1003 pkt->secret = &keys->client;
995 pkt->level = ssl_encryption_handshake; 1004 pkt->level = ssl_encryption_handshake;
996 pkt->plaintext = buf; 1005 pkt->plaintext = buf;
997 1006
998 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 1007 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1008
1009 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) {
999 return NGX_ERROR; 1010 return NGX_ERROR;
1000 } 1011 }
1001 1012
1002 return ngx_quic_payload_handler(c, pkt); 1013 return ngx_quic_payload_handler(c, pkt);
1003 } 1014 }
1005 1016
1006 static ngx_int_t 1017 static ngx_int_t
1007 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1018 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1008 { 1019 {
1009 ngx_quic_secrets_t *keys; 1020 ngx_quic_secrets_t *keys;
1021 ngx_quic_send_ctx_t *ctx;
1010 ngx_quic_connection_t *qc; 1022 ngx_quic_connection_t *qc;
1011 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 1023 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1012 1024
1013 c->log->action = "processing early data quic packet"; 1025 c->log->action = "processing early data quic packet";
1014 1026
1058 1070
1059 pkt->secret = &keys->client; 1071 pkt->secret = &keys->client;
1060 pkt->level = ssl_encryption_early_data; 1072 pkt->level = ssl_encryption_early_data;
1061 pkt->plaintext = buf; 1073 pkt->plaintext = buf;
1062 1074
1063 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 1075 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1076
1077 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) {
1064 return NGX_ERROR; 1078 return NGX_ERROR;
1065 } 1079 }
1066 1080
1067 return ngx_quic_payload_handler(c, pkt); 1081 return ngx_quic_payload_handler(c, pkt);
1068 } 1082 }
1071 static ngx_int_t 1085 static ngx_int_t
1072 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1086 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1073 { 1087 {
1074 ngx_int_t rc; 1088 ngx_int_t rc;
1075 ngx_quic_secrets_t *keys, *next, tmp; 1089 ngx_quic_secrets_t *keys, *next, tmp;
1090 ngx_quic_send_ctx_t *ctx;
1076 ngx_quic_connection_t *qc; 1091 ngx_quic_connection_t *qc;
1077 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 1092 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1078 1093
1079 c->log->action = "processing application data quic packet"; 1094 c->log->action = "processing application data quic packet";
1080 1095
1097 pkt->next = &next->client; 1112 pkt->next = &next->client;
1098 pkt->key_phase = c->quic->key_phase; 1113 pkt->key_phase = c->quic->key_phase;
1099 pkt->level = ssl_encryption_application; 1114 pkt->level = ssl_encryption_application;
1100 pkt->plaintext = buf; 1115 pkt->plaintext = buf;
1101 1116
1102 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 1117 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1118
1119 if (ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn) != NGX_OK) {
1103 return NGX_ERROR; 1120 return NGX_ERROR;
1104 } 1121 }
1105 1122
1106 /* switch keys on Key Phase change */ 1123 /* switch keys on Key Phase change */
1107 1124