comparison src/event/ngx_event_quic_transport.c @ 8260:f388c0ad3477 quic

Added processing of client transport parameters. note: + parameters are available in SSL connection since they are obtained by ssl stack quote: During connection establishment, both endpoints make authenticated declarations of their transport parameters. These declarations are made unilaterally by each endpoint. and really, we send our parameters before we read client's. no handling of incoming parameters is made by this patch.
author Vladimir Homutov <vl@nginx.com>
date Sat, 21 Mar 2020 20:51:59 +0300
parents 085fd6e68367
children 55a3a9c50af2
comparison
equal deleted inserted replaced
8259:9e9eab876964 8260:f388c0ad3477
54 static u_char *ngx_quic_parse_int(u_char *pos, u_char *end, uint64_t *out); 54 static u_char *ngx_quic_parse_int(u_char *pos, u_char *end, uint64_t *out);
55 static u_char *ngx_quic_parse_int_multi(u_char *pos, u_char *end, ...); 55 static u_char *ngx_quic_parse_int_multi(u_char *pos, u_char *end, ...);
56 static void ngx_quic_build_int(u_char **pos, uint64_t value); 56 static void ngx_quic_build_int(u_char **pos, uint64_t value);
57 57
58 static u_char *ngx_quic_read_uint8(u_char *pos, u_char *end, uint8_t *value); 58 static u_char *ngx_quic_read_uint8(u_char *pos, u_char *end, uint8_t *value);
59 /*static*/ u_char *ngx_quic_read_uint16(u_char *pos, u_char *end, uint16_t *value); // usage depends on quic_version
59 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value); 60 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value);
60 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, 61 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len,
61 u_char **out); 62 u_char **out);
62 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, 63 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len,
63 u_char *dst); 64 u_char *dst);
67 ngx_quic_crypto_frame_t *crypto); 68 ngx_quic_crypto_frame_t *crypto);
68 static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf); 69 static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf);
69 static size_t ngx_quic_create_max_streams(u_char *p, 70 static size_t ngx_quic_create_max_streams(u_char *p,
70 ngx_quic_max_streams_frame_t *ms); 71 ngx_quic_max_streams_frame_t *ms);
71 static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl); 72 static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl);
73
74 static ngx_int_t ngx_quic_parse_transport_param(u_char *p, u_char *end,
75 uint16_t id, ngx_quic_tp_t *dst);
72 76
73 77
74 /* literal errors indexed by corresponding value */ 78 /* literal errors indexed by corresponding value */
75 static char *ngx_quic_errors[] = { 79 static char *ngx_quic_errors[] = {
76 "NO_ERROR", 80 "NO_ERROR",
165 169
166 return pos + 1; 170 return pos + 1;
167 } 171 }
168 172
169 173
174 /*static*/ ngx_inline u_char *
175 ngx_quic_read_uint16(u_char *pos, u_char *end, uint16_t *value)
176 {
177 if ((size_t)(end - pos) < sizeof(uint16_t)) {
178 return NULL;
179 }
180
181 *value = ngx_quic_parse_uint16(pos);
182
183 return pos + sizeof(uint16_t);
184 }
185
186
170 static ngx_inline u_char * 187 static ngx_inline u_char *
171 ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value) 188 ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value)
172 { 189 {
173 if ((size_t)(end - pos) < sizeof(uint32_t)) { 190 if ((size_t)(end - pos) < sizeof(uint32_t)) {
174 return NULL; 191 return NULL;
1196 1213
1197 return p - start; 1214 return p - start;
1198 } 1215 }
1199 1216
1200 1217
1218 static ngx_int_t
1219 ngx_quic_parse_transport_param(u_char *p, u_char *end, uint16_t id,
1220 ngx_quic_tp_t *dst)
1221 {
1222 uint64_t varint;
1223
1224 switch (id) {
1225 case NGX_QUIC_TP_ORIGINAL_CONNECTION_ID:
1226 case NGX_QUIC_TP_STATELESS_RESET_TOKEN:
1227 case NGX_QUIC_TP_PREFERRED_ADDRESS:
1228 // TODO
1229 return NGX_ERROR;
1230 }
1231
1232 switch (id) {
1233
1234 case NGX_QUIC_TP_DISABLE_ACTIVE_MIGRATION:
1235 /* zero-length option */
1236 if (end - p != 0) {
1237 return NGX_ERROR;
1238 }
1239 dst->disable_active_migration = 1;
1240 return NGX_OK;
1241
1242 case NGX_QUIC_TP_MAX_IDLE_TIMEOUT:
1243 case NGX_QUIC_TP_MAX_PACKET_SIZE:
1244 case NGX_QUIC_TP_INITIAL_MAX_DATA:
1245 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:
1246 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:
1247 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_UNI:
1248 case NGX_QUIC_TP_INITIAL_MAX_STREAMS_BIDI:
1249 case NGX_QUIC_TP_INITIAL_MAX_STREAMS_UNI:
1250 case NGX_QUIC_TP_ACK_DELAY_EXPONENT:
1251 case NGX_QUIC_TP_MAX_ACK_DELAY:
1252 case NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT:
1253
1254 p = ngx_quic_parse_int(p, end, &varint);
1255 if (p == NULL) {
1256 return NGX_ERROR;
1257 }
1258 break;
1259
1260 default:
1261 return NGX_ERROR;
1262 }
1263
1264 switch (id) {
1265
1266 case NGX_QUIC_TP_MAX_IDLE_TIMEOUT:
1267 dst->max_idle_timeout = varint;
1268 break;
1269
1270 case NGX_QUIC_TP_MAX_PACKET_SIZE:
1271 dst->max_packet_size = varint;
1272 break;
1273
1274 case NGX_QUIC_TP_INITIAL_MAX_DATA:
1275 dst->initial_max_data = varint;
1276 break;
1277
1278 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:
1279 dst->initial_max_stream_data_bidi_local = varint;
1280 break;
1281
1282 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:
1283 dst->initial_max_stream_data_bidi_remote = varint;
1284 break;
1285
1286 case NGX_QUIC_TP_INITIAL_MAX_STREAM_DATA_UNI:
1287 dst->initial_max_stream_data_uni = varint;
1288 break;
1289
1290 case NGX_QUIC_TP_INITIAL_MAX_STREAMS_BIDI:
1291 dst->initial_max_streams_bidi = varint;
1292 break;
1293
1294 case NGX_QUIC_TP_INITIAL_MAX_STREAMS_UNI:
1295 dst->initial_max_streams_uni = varint;
1296 break;
1297
1298 case NGX_QUIC_TP_ACK_DELAY_EXPONENT:
1299 dst->ack_delay_exponent = varint;
1300 break;
1301
1302 case NGX_QUIC_TP_MAX_ACK_DELAY:
1303 dst->max_ack_delay = varint;
1304 break;
1305
1306 case NGX_QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT:
1307 dst->active_connection_id_limit = varint;
1308 break;
1309
1310 default:
1311 return NGX_ERROR;
1312 }
1313
1314 return NGX_OK;
1315 }
1316
1317
1318 ngx_int_t
1319 ngx_quic_parse_transport_params(u_char *p, u_char *end, ngx_quic_tp_t *tp,
1320 ngx_log_t *log)
1321 {
1322
1323 #if (quic_version < 0xff00001b)
1324
1325 uint16_t id, len, tp_len;
1326
1327 p = ngx_quic_read_uint16(p, end, &tp_len);
1328 if (p == NULL) {
1329 ngx_log_error(NGX_LOG_INFO, log, 0,
1330 "failed to parse total transport params length");
1331 return NGX_ERROR;
1332 }
1333
1334 while (p < end) {
1335
1336 p = ngx_quic_read_uint16(p, end, &id);
1337 if (p == NULL) {
1338 ngx_log_error(NGX_LOG_INFO, log, 0,
1339 "failed to parse transport param id");
1340 return NGX_ERROR;
1341 }
1342
1343 p = ngx_quic_read_uint16(p, end, &len);
1344 if (p == NULL) {
1345 ngx_log_error(NGX_LOG_INFO, log, 0,
1346 "failed to parse transport param id 0x%xi length", id);
1347 return NGX_ERROR;
1348 }
1349
1350 if (ngx_quic_parse_transport_param(p, p + len, id, tp) != NGX_OK) {
1351 ngx_log_error(NGX_LOG_INFO, log, 0,
1352 "failed to parse transport param id 0x%xi data", id);
1353 return NGX_ERROR;
1354 }
1355
1356 p += len;
1357 };
1358
1359 #else
1360
1361 uint64_t id, len;
1362
1363 while (p < end) {
1364 p = ngx_quic_parse_int(p, end, &id);
1365 if (p == NULL) {
1366 ngx_log_error(NGX_LOG_INFO, log, 0,
1367 "failed to parse transport param id");
1368 return NGX_ERROR;
1369 }
1370
1371 p = ngx_quic_parse_int(p, end, &len);
1372 if (p == NULL) {
1373 ngx_log_error(NGX_LOG_INFO, log, 0,
1374 "failed to parse transport param id 0x%xi length", id);
1375 return NGX_ERROR;
1376 }
1377
1378 if (ngx_quic_parse_transport_param(p, p + len, id, tp) != NGX_OK) {
1379 ngx_log_error(NGX_LOG_INFO, log, 0,
1380 "failed to parse transport param id 0x%xi data", id);
1381 return NGX_ERROR;
1382 }
1383
1384 p += len;
1385
1386 }
1387
1388 #endif
1389
1390 if (p != end) {
1391 ngx_log_error(NGX_LOG_INFO, log, 0,
1392 "trailing garbage in transport parameters: %ui bytes",
1393 end - p);
1394 return NGX_ERROR;
1395 }
1396
1397
1398 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
1399 "client transport parameters parsed successfully");
1400
1401 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
1402 "disable active migration: %ui",
1403 tp->disable_active_migration);
1404
1405 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "idle timeout: %ui",
1406 tp->max_idle_timeout);
1407
1408 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "max packet size: %ui",
1409 tp->max_packet_size);
1410
1411 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "max data: %ui",
1412 tp->initial_max_data);
1413
1414 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
1415 "max stream data bidi local: %ui",
1416 tp->initial_max_stream_data_bidi_local);
1417
1418 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
1419 "max stream data bidi remote: %ui",
1420 tp->initial_max_stream_data_bidi_remote);
1421
1422 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "max stream data uni: %ui",
1423 tp->initial_max_stream_data_uni);
1424
1425 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
1426 "initial max streams bidi: %ui",
1427 tp->initial_max_streams_bidi);
1428
1429 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "initial max streams uni: %ui",
1430 tp->initial_max_streams_uni);
1431
1432 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "ack delay exponent: %ui",
1433 tp->ack_delay_exponent);
1434
1435 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "max ack delay: %ui",
1436 tp->max_ack_delay);
1437
1438 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
1439 "active connection id limit: %ui",
1440 tp->active_connection_id_limit);
1441
1442 return NGX_OK;
1443 }
1444
1445
1201 ssize_t 1446 ssize_t
1202 ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp) 1447 ngx_quic_create_transport_params(u_char *pos, u_char *end, ngx_quic_tp_t *tp)
1203 { 1448 {
1204 u_char *p; 1449 u_char *p;
1205 size_t len; 1450 size_t len;