Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic.c @ 8294:ba9e34c03968 quic
QUIC: added check of client transport parameters.
Parameters sent by client are verified and defaults are set for parameters
omitted by client.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 15 Feb 2021 14:05:46 +0300 |
parents | 9ed95726b99b |
children | d4e02b3b734f |
comparison
equal
deleted
inserted
replaced
8293:75603531064a | 8294:ba9e34c03968 |
---|---|
223 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); | 223 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); |
224 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, | 224 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, |
225 enum ssl_encryption_level_t level, uint8_t alert); | 225 enum ssl_encryption_level_t level, uint8_t alert); |
226 | 226 |
227 | 227 |
228 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c, | |
229 ngx_quic_tp_t *ctp); | |
228 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, | 230 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, |
229 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); | 231 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); |
230 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c, | 232 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c, |
231 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); | 233 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); |
232 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, | 234 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, |
830 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) | 832 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) |
831 { | 833 { |
832 u_char *p, *end; | 834 u_char *p, *end; |
833 size_t client_params_len; | 835 size_t client_params_len; |
834 const uint8_t *client_params; | 836 const uint8_t *client_params; |
837 ngx_quic_tp_t ctp; | |
835 ngx_quic_frame_t *frame; | 838 ngx_quic_frame_t *frame; |
836 ngx_connection_t *c; | 839 ngx_connection_t *c; |
837 ngx_quic_connection_t *qc; | 840 ngx_quic_connection_t *qc; |
838 ngx_quic_frames_stream_t *fs; | 841 ngx_quic_frames_stream_t *fs; |
839 | 842 |
886 } | 889 } |
887 | 890 |
888 p = (u_char *) client_params; | 891 p = (u_char *) client_params; |
889 end = p + client_params_len; | 892 end = p + client_params_len; |
890 | 893 |
891 if (ngx_quic_parse_transport_params(p, end, &qc->ctp, c->log) | 894 /* defaults for parameters not sent by client */ |
895 ngx_memcpy(&ctp, &qc->ctp, sizeof(ngx_quic_tp_t)); | |
896 | |
897 if (ngx_quic_parse_transport_params(p, end, &ctp, c->log) | |
892 != NGX_OK) | 898 != NGX_OK) |
893 { | 899 { |
894 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | 900 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; |
895 qc->error_reason = "failed to process transport parameters"; | 901 qc->error_reason = "failed to process transport parameters"; |
896 | 902 |
897 return 0; | 903 return 0; |
898 } | 904 } |
899 | 905 |
900 if (qc->ctp.max_idle_timeout > 0 | 906 if (ngx_quic_apply_transport_params(c, &ctp) != NGX_OK) { |
901 && qc->ctp.max_idle_timeout < qc->tp.max_idle_timeout) | |
902 { | |
903 qc->tp.max_idle_timeout = qc->ctp.max_idle_timeout; | |
904 } | |
905 | |
906 if (qc->ctp.max_udp_payload_size < NGX_QUIC_MIN_INITIAL_SIZE | |
907 || qc->ctp.max_udp_payload_size > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) | |
908 { | |
909 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
910 qc->error_reason = "invalid maximum packet size"; | |
911 | |
912 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
913 "quic maximum packet size is invalid"); | |
914 return 0; | 907 return 0; |
915 } | 908 } |
916 | |
917 if (qc->ctp.max_udp_payload_size > ngx_quic_max_udp_payload(c)) { | |
918 qc->ctp.max_udp_payload_size = ngx_quic_max_udp_payload(c); | |
919 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
920 "quic client maximum packet size truncated"); | |
921 } | |
922 | |
923 #if (NGX_QUIC_DRAFT_VERSION >= 28) | |
924 if (qc->scid.len != qc->ctp.initial_scid.len | |
925 || ngx_memcmp(qc->scid.data, qc->ctp.initial_scid.data, | |
926 qc->scid.len) != 0) | |
927 { | |
928 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
929 "quic client initial_source_connection_id " | |
930 "mismatch"); | |
931 return 0; | |
932 } | |
933 #endif | |
934 | |
935 qc->streams.server_max_streams_bidi = qc->ctp.initial_max_streams_bidi; | |
936 qc->streams.server_max_streams_uni = qc->ctp.initial_max_streams_uni; | |
937 | 909 |
938 qc->client_tp_done = 1; | 910 qc->client_tp_done = 1; |
939 } | 911 } |
940 | 912 |
941 fs = &qc->crypto[level]; | 913 fs = &qc->crypto[level]; |
1005 if (ngx_quic_send_cc(c) != NGX_OK) { | 977 if (ngx_quic_send_cc(c) != NGX_OK) { |
1006 return 0; | 978 return 0; |
1007 } | 979 } |
1008 | 980 |
1009 return 1; | 981 return 1; |
982 } | |
983 | |
984 | |
985 static ngx_int_t | |
986 ngx_quic_apply_transport_params(ngx_connection_t *c, ngx_quic_tp_t *ctp) | |
987 { | |
988 ngx_quic_connection_t *qc; | |
989 | |
990 qc = ngx_quic_get_connection(c); | |
991 | |
992 #if (NGX_QUIC_DRAFT_VERSION >= 28) | |
993 if (qc->scid.len != ctp->initial_scid.len | |
994 || ngx_memcmp(qc->scid.data, ctp->initial_scid.data, qc->scid.len) != 0) | |
995 { | |
996 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
997 "quic client initial_source_connection_id mismatch"); | |
998 return NGX_ERROR; | |
999 } | |
1000 #endif | |
1001 | |
1002 if (ctp->max_udp_payload_size < NGX_QUIC_MIN_INITIAL_SIZE | |
1003 || ctp->max_udp_payload_size > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) | |
1004 { | |
1005 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
1006 qc->error_reason = "invalid maximum packet size"; | |
1007 | |
1008 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1009 "quic maximum packet size is invalid"); | |
1010 return NGX_ERROR; | |
1011 | |
1012 } else if (ctp->max_udp_payload_size > ngx_quic_max_udp_payload(c)) { | |
1013 ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c); | |
1014 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1015 "quic client maximum packet size truncated"); | |
1016 } | |
1017 | |
1018 if (ctp->active_connection_id_limit < 2) { | |
1019 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
1020 qc->error_reason = "invalid active_connection_id_limit"; | |
1021 | |
1022 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1023 "quic active_connection_id_limit is invalid"); | |
1024 return NGX_ERROR; | |
1025 } | |
1026 | |
1027 if (ctp->ack_delay_exponent > 20) { | |
1028 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
1029 qc->error_reason = "invalid ack_delay_exponent"; | |
1030 | |
1031 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1032 "quic ack_delay_exponent is invalid"); | |
1033 return NGX_ERROR; | |
1034 } | |
1035 | |
1036 if (ctp->max_ack_delay > 16384) { | |
1037 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
1038 qc->error_reason = "invalid max_ack_delay"; | |
1039 | |
1040 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1041 "quic max_ack_delay is invalid"); | |
1042 return NGX_ERROR; | |
1043 } | |
1044 | |
1045 if (ctp->max_idle_timeout > 0 | |
1046 && ctp->max_idle_timeout < qc->tp.max_idle_timeout) | |
1047 { | |
1048 qc->tp.max_idle_timeout = ctp->max_idle_timeout; | |
1049 } | |
1050 | |
1051 qc->streams.server_max_streams_bidi = ctp->initial_max_streams_bidi; | |
1052 qc->streams.server_max_streams_uni = ctp->initial_max_streams_uni; | |
1053 | |
1054 ngx_memcpy(&qc->ctp, ctp, sizeof(ngx_quic_tp_t)); | |
1055 | |
1056 return NGX_OK; | |
1010 } | 1057 } |
1011 | 1058 |
1012 | 1059 |
1013 void | 1060 void |
1014 ngx_quic_run(ngx_connection_t *c, ngx_quic_conf_t *conf) | 1061 ngx_quic_run(ngx_connection_t *c, ngx_quic_conf_t *conf) |
1122 ngx_memcpy(qc->sockaddr, c->sockaddr, c->socklen); | 1169 ngx_memcpy(qc->sockaddr, c->sockaddr, c->socklen); |
1123 qc->socklen = c->socklen; | 1170 qc->socklen = c->socklen; |
1124 } | 1171 } |
1125 | 1172 |
1126 ctp = &qc->ctp; | 1173 ctp = &qc->ctp; |
1174 | |
1175 /* defaults to be used before actual client parameters are received */ | |
1127 ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c); | 1176 ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c); |
1128 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; | 1177 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; |
1129 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; | 1178 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; |
1179 ctp->active_connection_id_limit = 2; | |
1130 | 1180 |
1131 qc->streams.recv_max_data = qc->tp.initial_max_data; | 1181 qc->streams.recv_max_data = qc->tp.initial_max_data; |
1132 | 1182 |
1133 qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni; | 1183 qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni; |
1134 qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi; | 1184 qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi; |