comparison src/event/quic/ngx_event_quic.c @ 8746:0c628de2e2b7 quic

QUIC: separate function for connection ids initialization. The function correctly cleans up resources in case of failure to create initial server id: it removes previously created udp node for odcid from listening rbtree.
author Vladimir Homutov <vl@nginx.com>
date Fri, 09 Apr 2021 11:33:10 +0300
parents 0b94e2df6389
children c8bda5e1e662
comparison
equal deleted inserted replaced
8745:0b94e2df6389 8746:0c628de2e2b7
67 67
68 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c, 68 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c,
69 ngx_quic_tp_t *ctp); 69 ngx_quic_tp_t *ctp);
70 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, 70 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
71 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 71 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
72 static ngx_int_t ngx_quic_setup_connection_ids(ngx_connection_t *c,
73 ngx_quic_connection_t *qc, ngx_quic_header_t *pkt);
72 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c, 74 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c,
73 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 75 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
74 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, 76 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid,
75 u_char *secret, u_char *token); 77 u_char *secret, u_char *token);
76 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, 78 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c,
921 ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf, 923 ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
922 ngx_quic_header_t *pkt) 924 ngx_quic_header_t *pkt)
923 { 925 {
924 ngx_uint_t i; 926 ngx_uint_t i;
925 ngx_quic_tp_t *ctp; 927 ngx_quic_tp_t *ctp;
926 ngx_quic_server_id_t *sid;
927 ngx_quic_client_id_t *cid;
928 ngx_quic_connection_t *qc; 928 ngx_quic_connection_t *qc;
929 929
930 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); 930 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t));
931 if (qc == NULL) { 931 if (qc == NULL) {
932 return NULL; 932 return NULL;
958 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { 958 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
959 ngx_queue_init(&qc->crypto[i].frames); 959 ngx_queue_init(&qc->crypto[i].frames);
960 } 960 }
961 961
962 ngx_queue_init(&qc->free_frames); 962 ngx_queue_init(&qc->free_frames);
963 ngx_queue_init(&qc->client_ids);
964 ngx_queue_init(&qc->server_ids);
965 ngx_queue_init(&qc->free_client_ids);
966 ngx_queue_init(&qc->free_server_ids);
967 963
968 qc->avg_rtt = NGX_QUIC_INITIAL_RTT; 964 qc->avg_rtt = NGX_QUIC_INITIAL_RTT;
969 qc->rttvar = NGX_QUIC_INITIAL_RTT / 2; 965 qc->rttvar = NGX_QUIC_INITIAL_RTT / 2;
970 qc->min_rtt = NGX_TIMER_INFINITE; 966 qc->min_rtt = NGX_TIMER_INFINITE;
971 967
972 /* 968 /*
973 * qc->latest_rtt = 0 969 * qc->latest_rtt = 0
974 * qc->nclient_ids = 0
975 * qc->nserver_ids = 0
976 * qc->max_retired_seqnum = 0
977 */ 970 */
978 971
979 qc->received = pkt->raw->last - pkt->raw->start; 972 qc->received = pkt->raw->last - pkt->raw->start;
980 973
981 qc->pto.log = c->log; 974 qc->pto.log = c->log;
1018 ngx_max(2 * qc->tp.max_udp_payload_size, 1011 ngx_max(2 * qc->tp.max_udp_payload_size,
1019 14720)); 1012 14720));
1020 qc->congestion.ssthresh = (size_t) -1; 1013 qc->congestion.ssthresh = (size_t) -1;
1021 qc->congestion.recovery_start = ngx_current_msec; 1014 qc->congestion.recovery_start = ngx_current_msec;
1022 1015
1023 qc->odcid.len = pkt->odcid.len;
1024 qc->odcid.data = ngx_pstrdup(c->pool, &pkt->odcid);
1025 if (qc->odcid.data == NULL) {
1026 return NULL;
1027 }
1028
1029 qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
1030 qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len);
1031 if (qc->dcid.data == NULL) {
1032 return NULL;
1033 }
1034
1035 if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
1036 return NULL;
1037 }
1038
1039 qc->tp.original_dcid = qc->odcid;
1040 qc->tp.initial_scid = qc->dcid;
1041
1042 if (pkt->validated && pkt->retried) { 1016 if (pkt->validated && pkt->retried) {
1043 qc->tp.retry_scid.len = pkt->dcid.len; 1017 qc->tp.retry_scid.len = pkt->dcid.len;
1044 qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid); 1018 qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid);
1045 if (qc->tp.retry_scid.data == NULL) { 1019 if (qc->tp.retry_scid.data == NULL) {
1046 return NULL; 1020 return NULL;
1047 } 1021 }
1048 } 1022 }
1049 1023
1050 qc->scid.len = pkt->scid.len;
1051 qc->scid.data = ngx_pstrdup(c->pool, &pkt->scid);
1052 if (qc->scid.data == NULL) {
1053 return NULL;
1054 }
1055
1056 cid = ngx_quic_alloc_client_id(c, qc);
1057 if (cid == NULL) {
1058 return NULL;
1059 }
1060
1061 cid->seqnum = 0;
1062 cid->len = pkt->scid.len;
1063 ngx_memcpy(cid->id, pkt->scid.data, pkt->scid.len);
1064
1065 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
1066 qc->nclient_ids++;
1067 qc->client_seqnum = 0;
1068
1069 qc->server_seqnum = NGX_QUIC_UNSET_PN;
1070
1071 if (ngx_quic_keys_set_initial_secret(c->pool, qc->keys, &pkt->dcid, 1024 if (ngx_quic_keys_set_initial_secret(c->pool, qc->keys, &pkt->dcid,
1072 qc->version) 1025 qc->version)
1073 != NGX_OK) 1026 != NGX_OK)
1074 { 1027 {
1075 return NULL; 1028 return NULL;
1076 } 1029 }
1077 1030
1078 if (ngx_quic_insert_server_id(c, qc, &qc->odcid) == NULL) { 1031 qc->validated = pkt->validated;
1032
1033 if (ngx_quic_setup_connection_ids(c, qc, pkt) != NGX_OK) {
1079 return NULL; 1034 return NULL;
1035 }
1036
1037 return qc;
1038 }
1039
1040
1041 static ngx_int_t
1042 ngx_quic_setup_connection_ids(ngx_connection_t *c, ngx_quic_connection_t *qc,
1043 ngx_quic_header_t *pkt)
1044 {
1045 ngx_quic_server_id_t *sid, *osid;
1046 ngx_quic_client_id_t *cid;
1047
1048 /*
1049 * qc->nclient_ids = 0
1050 * qc->nserver_ids = 0
1051 * qc->max_retired_seqnum = 0
1052 */
1053
1054 ngx_queue_init(&qc->client_ids);
1055 ngx_queue_init(&qc->server_ids);
1056 ngx_queue_init(&qc->free_client_ids);
1057 ngx_queue_init(&qc->free_server_ids);
1058
1059 qc->odcid.len = pkt->odcid.len;
1060 qc->odcid.data = ngx_pstrdup(c->pool, &pkt->odcid);
1061 if (qc->odcid.data == NULL) {
1062 return NGX_ERROR;
1063 }
1064
1065 qc->tp.original_dcid = qc->odcid;
1066
1067 qc->scid.len = pkt->scid.len;
1068 qc->scid.data = ngx_pstrdup(c->pool, &pkt->scid);
1069 if (qc->scid.data == NULL) {
1070 return NGX_ERROR;
1071 }
1072
1073 qc->dcid.len = NGX_QUIC_SERVER_CID_LEN;
1074 qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len);
1075 if (qc->dcid.data == NULL) {
1076 return NGX_ERROR;
1077 }
1078
1079 if (ngx_quic_create_server_id(c, qc->dcid.data) != NGX_OK) {
1080 return NGX_ERROR;
1081 }
1082
1083 qc->tp.initial_scid = qc->dcid;
1084
1085 cid = ngx_quic_alloc_client_id(c, qc);
1086 if (cid == NULL) {
1087 return NGX_ERROR;
1088 }
1089
1090 cid->seqnum = 0;
1091 cid->len = pkt->scid.len;
1092 ngx_memcpy(cid->id, pkt->scid.data, pkt->scid.len);
1093
1094 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
1095 qc->nclient_ids++;
1096 qc->client_seqnum = 0;
1097
1098 qc->server_seqnum = NGX_QUIC_UNSET_PN;
1099
1100 osid = ngx_quic_insert_server_id(c, qc, &qc->odcid);
1101 if (osid == NULL) {
1102 return NGX_ERROR;
1080 } 1103 }
1081 1104
1082 qc->server_seqnum = 0; 1105 qc->server_seqnum = 0;
1083 1106
1084 sid = ngx_quic_insert_server_id(c, qc, &qc->dcid); 1107 sid = ngx_quic_insert_server_id(c, qc, &qc->dcid);
1085 if (sid == NULL) { 1108 if (sid == NULL) {
1086 return NULL; 1109 ngx_rbtree_delete(&c->listening->rbtree, &osid->udp.node);
1110 return NGX_ERROR;
1087 } 1111 }
1088 1112
1089 c->udp = &sid->udp; 1113 c->udp = &sid->udp;
1090 1114
1091 qc->validated = pkt->validated; 1115 return NGX_OK;
1092
1093 return qc;
1094 } 1116 }
1095 1117
1096 1118
1097 static ngx_int_t 1119 static ngx_int_t
1098 ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf, 1120 ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,