lsquic_mini_conn_ietf.c revision 92f6e17b
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * lsquic_mini_conn_ietf.c -- Mini connection used by the IETF QUIC 4 */ 5 6#include <assert.h> 7#include <errno.h> 8#include <inttypes.h> 9#include <stddef.h> 10#include <stdint.h> 11#include <string.h> 12#include <sys/queue.h> 13#include <stdlib.h> 14 15#include "lsquic.h" 16#include "lsquic_int_types.h" 17#include "lsquic_sizes.h" 18#include "lsquic_hash.h" 19#include "lsquic_conn.h" 20#include "lsquic_mm.h" 21#include "lsquic_malo.h" 22#include "lsquic_engine_public.h" 23#include "lsquic_packet_common.h" 24#include "lsquic_packet_in.h" 25#include "lsquic_packet_out.h" 26#include "lsquic_parse.h" 27#include "lsquic_rtt.h" 28#include "lsquic_util.h" 29#include "lsquic_enc_sess.h" 30#include "lsquic_mini_conn_ietf.h" 31#include "lsquic_ev_log.h" 32#include "lsquic_trans_params.h" 33#include "lsquic_ietf.h" 34#include "lsquic_packet_ietf.h" 35 36#define LSQUIC_LOGGER_MODULE LSQLM_MINI_CONN 37#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&conn->imc_conn) 38#include "lsquic_logger.h" 39 40#define MIN(a, b) ((a) < (b) ? (a) : (b)) 41#define MAX(a, b) ((a) > (b) ? (a) : (b)) 42 43static const struct conn_iface mini_conn_ietf_iface; 44 45static unsigned highest_bit_set (unsigned long long); 46 47 48static const enum header_type el2hety[] = 49{ 50 [ENC_LEV_INIT] = HETY_HANDSHAKE, 51 [ENC_LEV_CLEAR] = HETY_INITIAL, 52 [ENC_LEV_FORW] = HETY_NOT_SET, 53 [ENC_LEV_EARLY] = 0, /* Invalid */ 54}; 55 56 57static void 58imico_destroy_packet (struct ietf_mini_conn *conn, 59 struct lsquic_packet_out *packet_out) 60{ 61 lsquic_packet_out_destroy(packet_out, conn->imc_enpub, 62 conn->imc_path.np_peer_ctx); 63} 64 65 66int 67lsquic_mini_conn_ietf_ecn_ok (const struct ietf_mini_conn *conn) 68{ 69 packno_set_t acked; 70 71 /* First flight has only Initial and Handshake packets */ 72 acked = conn->imc_acked_packnos[PNS_INIT] 73 | conn->imc_acked_packnos[PNS_HSK] 74 ; 75 return 0 != (conn->imc_ecn_packnos & acked); 76} 77 78 79#define imico_ecn_ok lsquic_mini_conn_ietf_ecn_ok 80 81 82static enum ecn 83imico_get_ecn (struct ietf_mini_conn *conn) 84{ 85 if (!conn->imc_enpub->enp_settings.es_ecn) 86 return ECN_NOT_ECT; 87 else if (!conn->imc_sent_packnos /* We set ECT0 in first flight */ 88 || imico_ecn_ok(conn)) 89 return ECN_ECT0; 90 else 91 return ECN_NOT_ECT; 92} 93 94 95static struct lsquic_packet_out * 96imico_get_packet_out (struct ietf_mini_conn *conn, 97 enum header_type header_type, size_t need) 98{ 99 struct lsquic_packet_out *packet_out; 100 enum ecn ecn; 101 102 if (need) 103 TAILQ_FOREACH(packet_out, &conn->imc_packets_out, po_next) 104 if (!(packet_out->po_flags & PO_SENT) 105 && packet_out->po_header_type == header_type 106 && lsquic_packet_out_avail(packet_out) >= need) 107 return packet_out; 108 109 if (conn->imc_next_packno >= MAX_PACKETS) 110 { 111 LSQ_DEBUG("ran out of outgoing packet numbers, won't allocate packet"); 112 return NULL; 113 } 114 115 packet_out = lsquic_packet_out_new(&conn->imc_enpub->enp_mm, NULL, 1, 116 &conn->imc_conn, IQUIC_PACKNO_LEN_1, NULL, NULL, &conn->imc_path); 117 if (!packet_out) 118 { 119 LSQ_WARN("could not allocate packet: %s", strerror(errno)); 120 return NULL; 121 } 122 123 packet_out->po_header_type = header_type; 124 packet_out->po_packno = conn->imc_next_packno++; 125 packet_out->po_flags |= PO_MINI; 126 lsquic_packet_out_set_pns(packet_out, lsquic_hety2pns[header_type]); 127 ecn = imico_get_ecn(conn); 128 packet_out->po_lflags |= ecn << POECN_SHIFT; 129 TAILQ_INSERT_TAIL(&conn->imc_packets_out, packet_out, po_next); 130 packet_out->po_loss_chain = packet_out; 131 return packet_out; 132} 133 134 135static struct ietf_mini_conn * 136cryst_get_conn (const struct mini_crypto_stream *cryst) 137{ 138 return (void *) 139 ((unsigned char *) (cryst - cryst->mcs_enc_level) 140 - offsetof(struct ietf_mini_conn, imc_streams)); 141} 142 143 144struct msg_ctx 145{ 146 const unsigned char *buf; 147 const unsigned char *const end; 148}; 149 150 151static size_t 152read_from_msg_ctx (void *ctx, void *buf, size_t len) 153{ 154 struct msg_ctx *msg_ctx = ctx; 155 if (len > (uintptr_t) (msg_ctx->end - msg_ctx->buf)) 156 len = msg_ctx->end - msg_ctx->buf; 157 memcpy(buf, msg_ctx->buf, len); 158 msg_ctx->buf += len; 159 return len; 160} 161 162 163static ssize_t 164imico_stream_write (void *stream, const void *bufp, size_t bufsz) 165{ 166 struct mini_crypto_stream *const cryst = stream; 167 struct ietf_mini_conn *const conn = cryst_get_conn(cryst); 168 struct lsquic_conn *const lconn = &conn->imc_conn; 169 const struct parse_funcs *const pf = lconn->cn_pf; 170 struct msg_ctx msg_ctx = { bufp, (unsigned char *) bufp + bufsz, }; 171 struct lsquic_packet_out *packet_out; 172 size_t header_sz, need; 173 const unsigned char *p; 174 int len; 175 176 if (PNS_INIT == lsquic_enclev2pns[ cryst->mcs_enc_level ] 177 && (conn->imc_flags & IMC_IGNORE_INIT)) 178 { 179 LSQ_WARN("trying to write at the ignored Initial level"); 180 return bufsz; 181 } 182 183 while (msg_ctx.buf < msg_ctx.end) 184 { 185 header_sz = lconn->cn_pf->pf_calc_crypto_frame_header_sz( 186 cryst->mcs_write_off); 187 need = header_sz + 1; 188 packet_out = imico_get_packet_out(conn, 189 el2hety[ cryst->mcs_enc_level ], need); 190 if (!packet_out) 191 return -1; 192 193 p = msg_ctx.buf; 194 len = pf->pf_gen_crypto_frame(packet_out->po_data + packet_out->po_data_sz, 195 lsquic_packet_out_avail(packet_out), cryst->mcs_write_off, 196 msg_ctx.end - msg_ctx.buf, read_from_msg_ctx, &msg_ctx); 197 if (len < 0) 198 return len; 199 EV_LOG_GENERATED_CRYPTO_FRAME(LSQUIC_LOG_CONN_ID, pf, 200 packet_out->po_data + packet_out->po_data_sz, len); 201 packet_out->po_data_sz += len; 202 packet_out->po_frame_types |= 1 << QUIC_FRAME_CRYPTO; 203 packet_out->po_flags |= PO_HELLO; 204 cryst->mcs_write_off += msg_ctx.buf - p; 205 } 206 207 assert(msg_ctx.buf == msg_ctx.end); 208 return bufsz; 209} 210 211 212static int 213imico_stream_flush (void *stream) 214{ 215 return 0; 216} 217 218 219static ssize_t 220imico_stream_readf (void *stream, 221 size_t (*readf)(void *, const unsigned char *, size_t, int), void *ctx) 222{ 223 struct mini_crypto_stream *const cryst = stream; 224 struct ietf_mini_conn *const conn = cryst_get_conn(cryst); 225 struct stream_frame *frame = conn->imc_last_in.frame; 226 size_t nread; 227 228 if (cryst->mcs_enc_level == conn->imc_last_in.enc_level 229 && frame && cryst->mcs_read_off == DF_ROFF(frame)) 230 { 231 nread = readf(ctx, frame->data_frame.df_data 232 + frame->data_frame.df_read_off, DF_SIZE(frame) 233 - frame->data_frame.df_read_off, DF_FIN(frame)); 234 cryst->mcs_read_off += nread; 235 frame->data_frame.df_read_off += nread; 236 LSQ_DEBUG("read %zu bytes at offset %"PRIu64" on enc level %u", nread, 237 DF_ROFF(frame), cryst->mcs_enc_level); 238 return nread; 239 } 240 else 241 { 242 errno = EWOULDBLOCK; 243 return -1; 244 } 245} 246 247 248static int 249imico_stream_wantX (struct mini_crypto_stream *cryst, int bit, int is_want) 250{ 251 int old; 252 253 old = (cryst->mcs_flags & (1 << bit)) > 0; 254 cryst->mcs_flags &= ~(1 << bit); 255 cryst->mcs_flags |= !!is_want << bit; 256 return old; 257} 258 259 260static int 261imico_stream_wantwrite (void *stream, int is_want) 262{ 263 return imico_stream_wantX(stream, MCSBIT_WANTWRITE, is_want); 264} 265 266 267static int 268imico_stream_wantread (void *stream, int is_want) 269{ 270 return imico_stream_wantX(stream, MCSBIT_WANTREAD, is_want); 271} 272 273 274static enum enc_level 275imico_stream_enc_level (void *stream) 276{ 277 struct mini_crypto_stream *const cryst = stream; 278 return cryst->mcs_enc_level; 279} 280 281 282static const struct crypto_stream_if crypto_stream_if = 283{ 284 .csi_write = imico_stream_write, 285 .csi_flush = imico_stream_flush, 286 .csi_readf = imico_stream_readf, 287 .csi_wantwrite = imico_stream_wantwrite, 288 .csi_wantread = imico_stream_wantread, 289 .csi_enc_level = imico_stream_enc_level, 290}; 291 292 293static int 294is_first_packet_ok (const struct lsquic_packet_in *packet_in) 295{ 296 /* TODO: Move decryption of the first packet into this function? */ 297 return 1; /* TODO */ 298} 299 300 301struct lsquic_conn * 302lsquic_mini_conn_ietf_new (struct lsquic_engine_public *enpub, 303 const struct lsquic_packet_in *packet_in, 304 enum lsquic_version version, int is_ipv4, const lsquic_cid_t *odcid) 305{ 306 struct ietf_mini_conn *conn; 307 enc_session_t *enc_sess; 308 enum enc_level i; 309 const struct enc_session_funcs_iquic *esfi; 310 311 if (!is_first_packet_ok(packet_in)) 312 return NULL; 313 314 conn = lsquic_malo_get(enpub->enp_mm.malo.mini_conn_ietf); 315 if (!conn) 316 { 317 LSQ_LOG1(LSQ_LOG_WARN, "cannot allocate mini connection: %s", 318 strerror(errno)); 319 return NULL; 320 } 321 memset(conn, 0, sizeof(*conn)); 322 conn->imc_conn.cn_if = &mini_conn_ietf_iface; 323 conn->imc_conn.cn_cces = conn->imc_cces; 324 conn->imc_conn.cn_n_cces = sizeof(conn->imc_cces) 325 / sizeof(conn->imc_cces[0]); 326 conn->imc_cces[0].cce_cid = packet_in->pi_dcid; 327 conn->imc_cces[0].cce_flags = CCE_USED; 328 conn->imc_conn.cn_cces_mask = 1; 329 lsquic_scid_from_packet_in(packet_in, &conn->imc_path.np_dcid); 330 LSQ_DEBUGC("recv SCID from client %"CID_FMT, CID_BITS(&conn->imc_cces[0].cce_cid)); 331 LSQ_DEBUGC("recv DCID from client %"CID_FMT, CID_BITS(&conn->imc_path.np_dcid)); 332 333 /* Generate new SCID. Since is not the original SCID, it is given 334 * a sequence number (0) and therefore can be retired by the client. 335 */ 336 lsquic_generate_cid(&conn->imc_conn.cn_cces[1].cce_cid, 337 enpub->enp_settings.es_scid_len); 338 LSQ_DEBUGC("generated SCID %"CID_FMT" at index %u, switching to it", 339 CID_BITS(&conn->imc_conn.cn_cces[1].cce_cid), 1); 340 conn->imc_conn.cn_cces[1].cce_flags = CCE_SEQNO | CCE_USED; 341 conn->imc_conn.cn_cces_mask |= 1u << 1; 342 conn->imc_conn.cn_cur_cce_idx = 1; 343 344 conn->imc_conn.cn_flags = LSCONN_MINI|LSCONN_IETF|LSCONN_SERVER; 345 346 for (i = 0; i < N_ENC_LEVS; ++i) 347 { 348 conn->imc_streams[i].mcs_enc_level = i; 349 conn->imc_stream_ps[i] = &conn->imc_streams[i]; 350 } 351 352 esfi = select_esf_iquic_by_ver(version); 353 enc_sess = esfi->esfi_create_server(enpub, &conn->imc_conn, 354 &packet_in->pi_dcid, conn->imc_stream_ps, &crypto_stream_if, 355 odcid); 356 if (!enc_sess) 357 { 358 lsquic_malo_put(conn); 359 return NULL; 360 } 361 362 conn->imc_enpub = enpub; 363 conn->imc_created = packet_in->pi_received; 364 conn->imc_path.np_pack_size = is_ipv4 ? IQUIC_MAX_IPv4_PACKET_SZ 365 : IQUIC_MAX_IPv6_PACKET_SZ; 366#ifndef NDEBUG 367 if (getenv("LSQUIC_CN_PACK_SIZE")) 368 conn->imc_path.np_pack_size = atoi(getenv("LSQUIC_CN_PACK_SIZE")); 369#endif 370 conn->imc_conn.cn_version = version; 371 conn->imc_conn.cn_pf = select_pf_by_ver(version); 372 conn->imc_conn.cn_esf.i = esfi; 373 conn->imc_conn.cn_enc_session = enc_sess; 374 conn->imc_conn.cn_esf_c = select_esf_common_by_ver(version); 375 TAILQ_INIT(&conn->imc_packets_out); 376 TAILQ_INIT(&conn->imc_app_packets); 377 378 LSQ_DEBUG("created mini connection object %p; max packet size=%hu", 379 conn, conn->imc_path.np_pack_size); 380 return &conn->imc_conn; 381} 382 383 384static void 385ietf_mini_conn_ci_client_call_on_new (struct lsquic_conn *lconn) 386{ 387 assert(0); 388} 389 390 391static void 392ietf_mini_conn_ci_destroy (struct lsquic_conn *lconn) 393{ 394 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 395 struct lsquic_packet_out *packet_out; 396 struct lsquic_packet_in *packet_in; 397 398 while ((packet_out = TAILQ_FIRST(&conn->imc_packets_out))) 399 { 400 TAILQ_REMOVE(&conn->imc_packets_out, packet_out, po_next); 401 imico_destroy_packet(conn, packet_out); 402 } 403 while ((packet_in = TAILQ_FIRST(&conn->imc_app_packets))) 404 { 405 TAILQ_REMOVE(&conn->imc_app_packets, packet_in, pi_next); 406 lsquic_packet_in_put(&conn->imc_enpub->enp_mm, packet_in); 407 } 408 if (lconn->cn_enc_session) 409 lconn->cn_esf.i->esfi_destroy(lconn->cn_enc_session); 410 LSQ_DEBUG("ietf_mini_conn_ci_destroyed"); 411 lsquic_malo_put(conn); 412} 413 414 415static struct lsquic_engine * 416ietf_mini_conn_ci_get_engine (struct lsquic_conn *lconn) 417{ 418 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 419 return conn->imc_enpub->enp_engine; 420} 421 422 423static void 424ietf_mini_conn_ci_hsk_done (struct lsquic_conn *lconn, 425 enum lsquic_hsk_status status) 426{ 427 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 428 429 switch (status) 430 { 431 case LSQ_HSK_OK: 432 case LSQ_HSK_0RTT_OK: 433 conn->imc_flags |= IMC_HSK_OK; 434 conn->imc_conn.cn_flags |= LSCONN_HANDSHAKE_DONE; 435 LSQ_DEBUG("handshake OK"); 436 break; 437 default: 438 assert(0); 439 /* fall-through */ 440 case LSQ_HSK_FAIL: 441 conn->imc_flags |= IMC_HSK_FAILED|IMC_ERROR; 442 LSQ_INFO("handshake failed"); 443 break; 444 } 445} 446 447 448static void 449ietf_mini_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert) 450{ 451 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 452 LSQ_DEBUG("got TLS alert %"PRIu8, alert); 453 conn->imc_flags |= IMC_ERROR|IMC_TLS_ALERT; 454 conn->imc_tls_alert = alert; 455} 456 457 458static int 459ietf_mini_conn_ci_is_tickable (struct lsquic_conn *lconn) 460{ 461 /* A mini connection is never tickable: Either there are incoming 462 * packets, in which case, the connection is going to be ticked, or 463 * there is an alarm pending, in which case it will be handled via 464 * the attq. 465 */ 466 return 0; 467} 468 469 470static int 471imico_can_send (const struct ietf_mini_conn *conn, size_t size) 472{ 473 return (conn->imc_flags & IMC_ADDR_VALIDATED) 474 || conn->imc_bytes_in * 3 >= conn->imc_bytes_out + size 475 ; 476} 477 478 479static struct lsquic_packet_out * 480ietf_mini_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size) 481{ 482 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 483 struct lsquic_packet_out *packet_out; 484 size_t packet_size; 485 486 TAILQ_FOREACH(packet_out, &conn->imc_packets_out, po_next) 487 { 488 if (packet_out->po_flags & PO_SENT) 489 continue; 490 packet_size = lsquic_packet_out_total_sz(lconn, packet_out); 491 if (size == 0 || packet_size + size <= conn->imc_path.np_pack_size) 492 { 493 if (!imico_can_send(conn, packet_size + IQUIC_TAG_LEN)) 494 { 495 LSQ_DEBUG("cannot send packet %"PRIu64" of size %zu: client " 496 "address has not been validated", packet_out->po_packno, 497 packet_size + IQUIC_TAG_LEN); 498 return NULL; 499 } 500 packet_out->po_flags |= PO_SENT; 501 conn->imc_bytes_out += packet_size + IQUIC_TAG_LEN; 502 if (size == 0) 503 LSQ_DEBUG("packet_to_send: %"PRIu64, packet_out->po_packno); 504 else 505 LSQ_DEBUG("packet_to_send: %"PRIu64" (coalesced)", 506 packet_out->po_packno); 507 return packet_out; 508 } 509 else 510 return NULL; 511 } 512 513 return NULL; 514} 515 516 517static int 518imico_calc_retx_timeout (const struct ietf_mini_conn *conn) 519{ 520 lsquic_time_t to; 521 to = lsquic_rtt_stats_get_srtt(&conn->imc_rtt_stats); 522 if (to) 523 { 524 to += to / 2; 525 if (to < 10000) 526 to = 10000; 527 } 528 else 529 to = 300000; 530 return to << conn->imc_hsk_count; 531} 532 533 534static lsquic_time_t 535ietf_mini_conn_ci_next_tick_time (struct lsquic_conn *lconn) 536{ 537 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 538 const struct lsquic_packet_out *packet_out; 539 lsquic_time_t exp_time, retx_time; 540 541 exp_time = conn->imc_created + 542 conn->imc_enpub->enp_settings.es_handshake_to; 543 544 TAILQ_FOREACH(packet_out, &conn->imc_packets_out, po_next) 545 if (packet_out->po_flags & PO_SENT) 546 { 547 retx_time = packet_out->po_sent + imico_calc_retx_timeout(conn); 548 if (retx_time < exp_time) 549 return retx_time; 550 else 551 return exp_time; 552 } 553 554 return exp_time; 555} 556 557 558#define IMICO_PROC_FRAME_ARGS \ 559 struct ietf_mini_conn *conn, struct lsquic_packet_in *packet_in, \ 560 const unsigned char *p, size_t len 561 562 563static void 564imico_dispatch_stream_events (struct ietf_mini_conn *conn) 565{ 566 enum enc_level i; 567 568 for (i = 0; i < N_ENC_LEVS; ++i) 569 if ((conn->imc_streams[i].mcs_flags & (MCS_CREATED|MCS_WANTREAD)) 570 == (MCS_CREATED|MCS_WANTREAD)) 571 { 572 LSQ_DEBUG("dispatch read events on level #%u", i); 573 lsquic_mini_cry_sm_if.on_read((void *) &conn->imc_streams[i], 574 conn->imc_conn.cn_enc_session); 575 } 576 577 for (i = 0; i < N_ENC_LEVS; ++i) 578 if ((conn->imc_streams[i].mcs_flags & (MCS_CREATED|MCS_WANTWRITE)) 579 == (MCS_CREATED|MCS_WANTWRITE)) 580 { 581 LSQ_DEBUG("dispatch write events on level #%u", i); 582 lsquic_mini_cry_sm_if.on_write((void *) &conn->imc_streams[i], 583 conn->imc_conn.cn_enc_session); 584 } 585} 586 587 588static unsigned 589imico_process_stream_frame (IMICO_PROC_FRAME_ARGS) 590{ 591 LSQ_WARN("%s: TODO", __func__); 592 return 0; 593} 594 595 596static unsigned 597imico_process_crypto_frame (IMICO_PROC_FRAME_ARGS) 598{ 599 int parsed_len; 600 enum enc_level enc_level, i; 601 struct stream_frame stream_frame; 602 const struct transport_params *params; 603 604 parsed_len = conn->imc_conn.cn_pf->pf_parse_crypto_frame(p, len, 605 &stream_frame); 606 if (parsed_len < 0) 607 return 0; 608 609 enc_level = lsquic_packet_in_enc_level(packet_in); 610 EV_LOG_CRYPTO_FRAME_IN(LSQUIC_LOG_CONN_ID, &stream_frame, enc_level); 611 612 if (!(conn->imc_streams[enc_level].mcs_flags & MCS_CREATED) 613 || conn->imc_streams[enc_level].mcs_read_off < 614 stream_frame.data_frame.df_offset 615 + stream_frame.data_frame.df_size) 616 LSQ_DEBUG("Got CRYPTO frame for enc level #%u", enc_level); 617 else 618 { 619 LSQ_DEBUG("Got duplicate CRYPTO frame for enc level #%u -- ignore", 620 enc_level); 621 return parsed_len; 622 } 623 624 if (!(conn->imc_flags & IMC_ENC_SESS_INITED)) 625 { 626 if (0 != conn->imc_conn.cn_esf.i->esfi_init_server( 627 conn->imc_conn.cn_enc_session)) 628 return -1; 629 conn->imc_flags |= IMC_ENC_SESS_INITED; 630 } 631 632 if (!(conn->imc_streams[enc_level].mcs_flags & MCS_CREATED)) 633 { 634 LSQ_DEBUG("creating stream on level #%u", enc_level); 635 conn->imc_streams[enc_level].mcs_flags |= MCS_CREATED; 636 lsquic_mini_cry_sm_if.on_new_stream(conn->imc_conn.cn_enc_session, 637 (void *) &conn->imc_streams[enc_level]); 638 } 639 640 /* Assume that receiving a CRYPTO frame at a higher level means that we 641 * no longer want to read from a lower level. 642 */ 643 for (i = 0; i < enc_level; ++i) 644 conn->imc_streams[i].mcs_flags &= ~MCS_WANTREAD; 645 646 conn->imc_last_in.frame = &stream_frame; 647 conn->imc_last_in.enc_level = enc_level; 648 imico_dispatch_stream_events(conn); 649 conn->imc_last_in.frame = NULL; 650 651 652 if (enc_level == ENC_LEV_CLEAR && stream_frame.data_frame.df_offset == 0 653 /* Assume that we have ClientHello at offset zero and that it has 654 * transport parameters. 655 */ 656 && (conn->imc_flags & (IMC_ENC_SESS_INITED|IMC_HAVE_TP)) 657 == IMC_ENC_SESS_INITED) 658 { 659 params = conn->imc_conn.cn_esf.i->esfi_get_peer_transport_params( 660 conn->imc_conn.cn_enc_session); 661 if (params) 662 { 663 conn->imc_flags |= IMC_HAVE_TP; 664 conn->imc_ack_exp = params->tp_ack_delay_exponent; 665 } 666 else 667 { 668 conn->imc_flags |= IMC_BAD_TRANS_PARAMS; 669 return 0; 670 } 671 } 672 673 return parsed_len; 674} 675 676 677static ptrdiff_t 678imico_count_zero_bytes (const unsigned char *p, size_t len) 679{ 680 const unsigned char *const end = p + len; 681 while (p < end && 0 == *p) 682 ++p; 683 return len - (end - p); 684} 685 686 687static unsigned 688imico_process_padding_frame (IMICO_PROC_FRAME_ARGS) 689{ 690 len = (size_t) imico_count_zero_bytes(p, len); 691 EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len); 692 return len; 693} 694 695 696static void 697imico_take_rtt_sample (struct ietf_mini_conn *conn, 698 const struct lsquic_packet_out *packet_out, 699 lsquic_time_t now, lsquic_time_t lack_delta) 700{ 701 assert(packet_out->po_sent); 702 lsquic_time_t measured_rtt = now - packet_out->po_sent; 703 if (lack_delta < measured_rtt) 704 { 705 lsquic_rtt_stats_update(&conn->imc_rtt_stats, measured_rtt, lack_delta); 706 LSQ_DEBUG("srtt: %"PRIu64" usec, var: %"PRIu64, 707 lsquic_rtt_stats_get_srtt(&conn->imc_rtt_stats), 708 lsquic_rtt_stats_get_rttvar(&conn->imc_rtt_stats)); 709 } 710} 711 712 713static unsigned 714imico_process_ack_frame (IMICO_PROC_FRAME_ARGS) 715{ 716 int parsed_len; 717 unsigned n; 718 lsquic_packet_out_t *packet_out, *next; 719 struct ack_info *acki; 720 lsquic_packno_t packno; 721 lsquic_time_t warn_time; 722 packno_set_t acked; 723 enum packnum_space pns; 724 uint8_t ack_exp; 725 726 if (conn->imc_flags & IMC_HAVE_TP) 727 ack_exp = conn->imc_ack_exp; 728 else 729 ack_exp = TP_DEF_ACK_DELAY_EXP; /* Odd: no transport params yet? */ 730 acki = conn->imc_enpub->enp_mm.acki; 731 parsed_len = conn->imc_conn.cn_pf->pf_parse_ack_frame(p, len, acki, 732 ack_exp); 733 if (parsed_len < 0) 734 return 0; 735 736 pns = lsquic_hety2pns[ packet_in->pi_header_type ]; 737 acked = 0; 738 739 for (n = 0; n < acki->n_ranges; ++n) 740 { 741 if (acki->ranges[n].high <= MAX_PACKETS) 742 { 743 acked |= (1ULL << acki->ranges[n].high) 744 | ((1ULL << acki->ranges[n].high) - 1); 745 acked &= ~((1ULL << acki->ranges[n].low) - 1); 746 } 747 else 748 { 749 packno = acki->ranges[n].high; 750 goto err_never_sent; 751 } 752 } 753 if (acked & ~conn->imc_sent_packnos) 754 { 755 packno = highest_bit_set(acked & ~conn->imc_sent_packnos); 756 goto err_never_sent; 757 } 758 759 EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, acki); 760 for (packet_out = TAILQ_FIRST(&conn->imc_packets_out); packet_out; 761 packet_out = next) 762 { 763 next = TAILQ_NEXT(packet_out, po_next); 764 if ((1ULL << packet_out->po_packno) & acked) 765 { 766 assert(lsquic_packet_out_pns(packet_out) == pns); 767 LSQ_DEBUG("Got ACK for packet %"PRIu64, packet_out->po_packno); 768 if (packet_out->po_packno == largest_acked(acki)) 769 imico_take_rtt_sample(conn, packet_out, 770 packet_in->pi_received, acki->lack_delta); 771 TAILQ_REMOVE(&conn->imc_packets_out, packet_out, po_next); 772 imico_destroy_packet(conn, packet_out); 773 } 774 } 775 776 if (conn->imc_sent_packnos & ~conn->imc_acked_packnos[pns] & acked) 777 { 778 LSQ_DEBUG("Newly acked packets, reset handshake count"); 779 conn->imc_hsk_count = 0; 780 } 781 782 conn->imc_acked_packnos[pns] |= acked; 783 784 return parsed_len; 785 786 err_never_sent: 787 warn_time = lsquic_time_now(); 788 if (0 == conn->imc_enpub->enp_last_warning[WT_ACKPARSE_MINI] 789 || conn->imc_enpub->enp_last_warning[WT_ACKPARSE_MINI] 790 + WARNING_INTERVAL < warn_time) 791 { 792 conn->imc_enpub->enp_last_warning[WT_ACKPARSE_MINI] = warn_time; 793 LSQ_WARN("packet %"PRIu64" (pns: %u) was never sent", packno, pns); 794 } 795 else 796 LSQ_DEBUG("packet %"PRIu64" (pns: %u) was never sent", packno, pns); 797 return 0; 798} 799 800 801static unsigned 802imico_process_invalid_frame (IMICO_PROC_FRAME_ARGS) 803{ 804 LSQ_DEBUG("invalid frame %u (%s)", p[0], 805 frame_type_2_str[ conn->imc_conn.cn_pf->pf_parse_frame_type(p[0]) ]); 806 return 0; 807} 808 809 810static unsigned (*const imico_process_frames[N_QUIC_FRAMES]) 811 (IMICO_PROC_FRAME_ARGS) = 812{ 813 [QUIC_FRAME_PADDING] = imico_process_padding_frame, 814 [QUIC_FRAME_STREAM] = imico_process_stream_frame, 815 [QUIC_FRAME_CRYPTO] = imico_process_crypto_frame, 816 [QUIC_FRAME_ACK] = imico_process_ack_frame, 817 /* XXX: Some of them are invalid, while others are unexpected. We treat 818 * them the same: handshake cannot proceed. 819 */ 820 [QUIC_FRAME_RST_STREAM] = imico_process_invalid_frame, 821 [QUIC_FRAME_CONNECTION_CLOSE] = imico_process_invalid_frame, 822 [QUIC_FRAME_MAX_DATA] = imico_process_invalid_frame, 823 [QUIC_FRAME_MAX_STREAM_DATA] = imico_process_invalid_frame, 824 [QUIC_FRAME_MAX_STREAMS] = imico_process_invalid_frame, 825 [QUIC_FRAME_PING] = imico_process_invalid_frame, 826 [QUIC_FRAME_BLOCKED] = imico_process_invalid_frame, 827 [QUIC_FRAME_STREAM_BLOCKED] = imico_process_invalid_frame, 828 [QUIC_FRAME_STREAMS_BLOCKED] = imico_process_invalid_frame, 829 [QUIC_FRAME_NEW_CONNECTION_ID] = imico_process_invalid_frame, 830 [QUIC_FRAME_STOP_SENDING] = imico_process_invalid_frame, 831 [QUIC_FRAME_PATH_CHALLENGE] = imico_process_invalid_frame, 832 [QUIC_FRAME_PATH_RESPONSE] = imico_process_invalid_frame, 833}; 834 835 836static unsigned 837imico_process_packet_frame (struct ietf_mini_conn *conn, 838 struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len) 839{ 840 enum enc_level enc_level = lsquic_packet_in_enc_level(packet_in); 841 enum quic_frame_type type = conn->imc_conn.cn_pf->pf_parse_frame_type(p[0]); 842 if (lsquic_legal_frames_by_level[enc_level] & (1 << type)) 843 { 844 packet_in->pi_frame_types |= 1 << type; 845 return imico_process_frames[type](conn, packet_in, p, len); 846 } 847 else 848 { 849 LSQ_DEBUG("invalid frame %u at encryption level %s", type, 850 lsquic_enclev2str[enc_level]); 851 return 0; 852 } 853} 854 855 856static int 857imico_parse_regular_packet (struct ietf_mini_conn *conn, 858 struct lsquic_packet_in *packet_in) 859{ 860 const unsigned char *p, *pend; 861 unsigned len; 862 863 p = packet_in->pi_data + packet_in->pi_header_sz; 864 pend = packet_in->pi_data + packet_in->pi_data_sz; 865 866 while (p < pend) 867 { 868 len = imico_process_packet_frame(conn, packet_in, p, pend - p); 869 if (len > 0) 870 p += len; 871 else 872 return -1; 873 } 874 875 return 0; 876} 877 878 879static unsigned 880highest_bit_set (unsigned long long sz) 881{ 882#if __GNUC__ 883 unsigned clz = __builtin_clzll(sz); 884 return 63 - clz; 885#else 886 unsigned long y; 887 unsigned n; 888 n = 64; 889 y = sz >> 32; if (y) { n -= 32; sz = y; } 890 y = sz >> 16; if (y) { n -= 16; sz = y; } 891 y = sz >> 8; if (y) { n -= 8; sz = y; } 892 y = sz >> 4; if (y) { n -= 4; sz = y; } 893 y = sz >> 2; if (y) { n -= 2; sz = y; } 894 y = sz >> 1; if (y) return 63 - n + 2; 895 return 63 - n + sz; 896#endif 897} 898 899 900static void 901ignore_init (struct ietf_mini_conn *conn) 902{ 903 struct lsquic_packet_out *packet_out, *next; 904 unsigned count; 905 906 conn->imc_flags |= IMC_IGNORE_INIT; 907 conn->imc_flags &= ~(IMC_QUEUED_ACK_INIT << PNS_INIT); 908 909 count = 0; 910 for (packet_out = TAILQ_FIRST(&conn->imc_packets_out); packet_out; 911 packet_out = next) 912 { 913 next = TAILQ_NEXT(packet_out, po_next); 914 if (PNS_INIT == lsquic_packet_out_pns(packet_out)) 915 { 916 TAILQ_REMOVE(&conn->imc_packets_out, packet_out, po_next); 917 imico_destroy_packet(conn, packet_out); 918 ++count; 919 } 920 } 921 922 LSQ_DEBUG("henceforth, no Initial packets shall be sent or received; " 923 "destroyed %u packet%.*s", count, count != 1, "s"); 924} 925 926 927/* Only a single packet is supported */ 928static void 929ietf_mini_conn_ci_packet_in (struct lsquic_conn *lconn, 930 struct lsquic_packet_in *packet_in) 931{ 932 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 933 enum dec_packin dec_packin; 934 enum packnum_space pns; 935 936 if (conn->imc_flags & IMC_ERROR) 937 { 938 LSQ_DEBUG("ignore incoming packet: connection is in error state"); 939 return; 940 } 941 942 pns = lsquic_hety2pns[ packet_in->pi_header_type ]; 943 if (pns == PNS_INIT && (conn->imc_flags & IMC_IGNORE_INIT)) 944 { 945 LSQ_DEBUG("ignore init packet"); /* Don't bother decrypting */ 946 return; 947 } 948 949 dec_packin = lconn->cn_esf_c->esf_decrypt_packet(lconn->cn_enc_session, 950 conn->imc_enpub, lconn, packet_in); 951 if (dec_packin != DECPI_OK) 952 { 953 /* TODO: handle reordering perhaps? */ 954 LSQ_DEBUG("could not decrypt packet"); 955 return; 956 } 957 958 EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in); 959 conn->imc_bytes_in += packet_in->pi_data_sz + IQUIC_TAG_LEN; 960 961 if (pns == PNS_APP) 962 { 963 lsquic_packet_in_upref(packet_in); 964 TAILQ_INSERT_TAIL(&conn->imc_app_packets, packet_in, pi_next); 965 LSQ_DEBUG("delay processing of packet %"PRIu64" in pns %u", 966 packet_in->pi_packno, pns); 967 return; 968 } 969 else if (pns == PNS_HSK) 970 conn->imc_flags |= IMC_ADDR_VALIDATED; 971 972 if (((conn->imc_flags >> IMCBIT_PNS_BIT_SHIFT) & 3) < pns) 973 { 974 conn->imc_flags &= ~(3 << IMCBIT_PNS_BIT_SHIFT); 975 conn->imc_flags |= pns << IMCBIT_PNS_BIT_SHIFT; 976 } 977 978 if (pns == PNS_HSK && !(conn->imc_flags & IMC_IGNORE_INIT)) 979 ignore_init(conn); 980 981 if (conn->imc_recvd_packnos[pns] & (1ULL << packet_in->pi_packno)) 982 { 983 LSQ_DEBUG("duplicate packet %"PRIu64, packet_in->pi_packno); 984 return; 985 } 986 987 /* Update receive history before processing the packet: if there is an 988 * error, the connection is terminated and recording this packet number 989 * is helpful when it is printed along with other diagnostics in dtor. 990 */ 991 if (0 == conn->imc_recvd_packnos[pns] || 992 packet_in->pi_packno > highest_bit_set(conn->imc_recvd_packnos[pns])) 993 conn->imc_largest_recvd[pns] = packet_in->pi_received; 994 conn->imc_recvd_packnos[pns] |= 1ULL << packet_in->pi_packno; 995 996 if (0 != imico_parse_regular_packet(conn, packet_in)) 997 { 998 LSQ_DEBUG("connection is now in error state"); 999 conn->imc_flags |= IMC_ERROR; 1000 return; 1001 } 1002 1003 conn->imc_flags |= IMC_QUEUED_ACK_INIT << pns; 1004 ++conn->imc_ecn_counts_in[pns][ lsquic_packet_in_ecn(packet_in) ]; 1005 conn->imc_incoming_ecn <<= 1; 1006 conn->imc_incoming_ecn |= lsquic_packet_in_ecn(packet_in) != ECN_NOT_ECT; 1007} 1008 1009 1010static void 1011ietf_mini_conn_ci_packet_sent (struct lsquic_conn *lconn, 1012 struct lsquic_packet_out *packet_out) 1013{ 1014 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1015 conn->imc_sent_packnos |= 1ULL << packet_out->po_packno; 1016 conn->imc_ecn_packnos |= !!lsquic_packet_out_ecn(packet_out) 1017 << packet_out->po_packno; 1018#if 0 1019 if (packet_out->po_frame_types & (1 << QUIC_FRAME_ACK)) 1020 { 1021 assert(mc->mc_flags & MC_UNSENT_ACK); 1022 mc->mc_flags &= ~MC_UNSENT_ACK; 1023 } 1024#endif 1025 ++conn->imc_ecn_counts_out[ lsquic_packet_out_pns(packet_out) ] 1026 [ lsquic_packet_out_ecn(packet_out) ]; 1027 if (packet_out->po_header_type == HETY_HANDSHAKE) 1028 conn->imc_flags |= IMC_HSK_PACKET_SENT; 1029 LSQ_DEBUG("%s: packet %"PRIu64" sent", __func__, packet_out->po_packno); 1030} 1031 1032 1033static void 1034ietf_mini_conn_ci_packet_not_sent (struct lsquic_conn *lconn, 1035 struct lsquic_packet_out *packet_out) 1036{ 1037 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1038 size_t packet_size; 1039 1040 packet_out->po_flags &= ~PO_SENT; 1041 packet_size = lsquic_packet_out_total_sz(lconn, packet_out); 1042 conn->imc_bytes_out -= packet_size + IQUIC_TAG_LEN; 1043 LSQ_DEBUG("%s: packet %"PRIu64" not sent", __func__, packet_out->po_packno); 1044} 1045 1046 1047static void 1048imico_return_enc_data (struct ietf_mini_conn *conn, 1049 struct lsquic_packet_out *packet_out) 1050{ 1051 conn->imc_enpub->enp_pmi->pmi_return(conn->imc_enpub->enp_pmi_ctx, 1052 conn->imc_path.np_peer_ctx, packet_out->po_enc_data, 1053 lsquic_packet_out_ipv6(packet_out)); 1054 packet_out->po_flags &= ~PO_ENCRYPTED; 1055 packet_out->po_enc_data = NULL; 1056} 1057 1058 1059static int 1060imico_repackage_packet (struct ietf_mini_conn *conn, 1061 struct lsquic_packet_out *packet_out) 1062{ 1063 const lsquic_packno_t oldno = packet_out->po_packno; 1064 const lsquic_packno_t packno = conn->imc_next_packno++; 1065 if (packno > MAX_PACKETS) 1066 return -1; 1067 1068 LSQ_DEBUG("Packet %"PRIu64" repackaged for resending as packet %"PRIu64, 1069 oldno, packno); 1070 EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "packet %"PRIu64" repackaged for " 1071 "resending as packet %"PRIu64, oldno, packno); 1072 packet_out->po_packno = packno; 1073 packet_out->po_flags &= ~PO_SENT; 1074 lsquic_packet_out_set_ecn(packet_out, imico_get_ecn(conn)); 1075 if (packet_out->po_flags & PO_ENCRYPTED) 1076 imico_return_enc_data(conn, packet_out); 1077 TAILQ_INSERT_TAIL(&conn->imc_packets_out, packet_out, po_next); 1078 return 0; 1079} 1080 1081 1082static int 1083imico_handle_losses_and_have_unsent (struct ietf_mini_conn *conn, 1084 lsquic_time_t now) 1085{ 1086 TAILQ_HEAD(, lsquic_packet_out) lost_packets = 1087 TAILQ_HEAD_INITIALIZER(lost_packets); 1088 lsquic_packet_out_t *packet_out, *next; 1089 lsquic_time_t retx_to = 0; 1090 unsigned n_to_send = 0; 1091 1092 for (packet_out = TAILQ_FIRST(&conn->imc_packets_out); packet_out; 1093 packet_out = next) 1094 { 1095 next = TAILQ_NEXT(packet_out, po_next); 1096 if (packet_out->po_flags & PO_SENT) 1097 { 1098 if (0 == retx_to) 1099 retx_to = imico_calc_retx_timeout(conn); 1100 if (packet_out->po_sent + retx_to < now) 1101 { 1102 LSQ_DEBUG("packet %"PRIu64" has been lost (rto: %"PRIu64")", 1103 packet_out->po_packno, retx_to); 1104 TAILQ_REMOVE(&conn->imc_packets_out, packet_out, po_next); 1105 TAILQ_INSERT_TAIL(&lost_packets, packet_out, po_next); 1106 } 1107 } 1108 else 1109 ++n_to_send; 1110 } 1111 1112 conn->imc_hsk_count += !TAILQ_EMPTY(&lost_packets); 1113 1114 while ((packet_out = TAILQ_FIRST(&lost_packets))) 1115 { 1116 TAILQ_REMOVE(&lost_packets, packet_out, po_next); 1117 if ((packet_out->po_frame_types & IQUIC_FRAME_RETX_MASK) 1118 && 0 == imico_repackage_packet(conn, packet_out)) 1119 ++n_to_send; 1120 else 1121 imico_destroy_packet(conn, packet_out); 1122 } 1123 1124 return n_to_send > 0; 1125} 1126 1127 1128static int 1129imico_have_packets_to_send (struct ietf_mini_conn *conn, lsquic_time_t now) 1130{ 1131 return imico_handle_losses_and_have_unsent(conn, now); 1132} 1133 1134 1135struct ietf_mini_rechist 1136{ 1137 const struct ietf_mini_conn *conn; 1138 packno_set_t cur_set; 1139 struct lsquic_packno_range range; /* We return a pointer to this */ 1140 int cur_idx; 1141 enum packnum_space pns; 1142}; 1143 1144 1145static void 1146imico_rechist_init (struct ietf_mini_rechist *rechist, 1147 const struct ietf_mini_conn *conn, enum packnum_space pns) 1148{ 1149 rechist->conn = conn; 1150 rechist->pns = pns; 1151 rechist->cur_set = 0; 1152 rechist->cur_idx = 0; 1153} 1154 1155 1156static lsquic_time_t 1157imico_rechist_largest_recv (void *rechist_ctx) 1158{ 1159 struct ietf_mini_rechist *rechist = rechist_ctx; 1160 return rechist->conn->imc_largest_recvd[ rechist->pns ]; 1161} 1162 1163 1164static const struct lsquic_packno_range * 1165imico_rechist_next (void *rechist_ctx) 1166{ 1167 struct ietf_mini_rechist *rechist = rechist_ctx; 1168 const struct ietf_mini_conn *conn = rechist->conn; 1169 packno_set_t packnos; 1170 int i; 1171 1172 packnos = rechist->cur_set; 1173 if (0 == packnos) 1174 return NULL; 1175 1176 /* There may be a faster way to do this, but for now, we just want 1177 * correctness. 1178 */ 1179 for (i = rechist->cur_idx; i >= 0; --i) 1180 if (packnos & (1ULL << i)) 1181 { 1182 rechist->range.low = i; 1183 rechist->range.high = i; 1184 break; 1185 } 1186 assert(i >= 0); /* We must have hit at least one bit */ 1187 --i; 1188 for ( ; i >= 0 && (packnos & (1ULL << i)); --i) 1189 rechist->range.low = i; 1190 if (i >= 0) 1191 { 1192 rechist->cur_set = packnos & ((1ULL << i) - 1); 1193 rechist->cur_idx = i; 1194 } 1195 else 1196 rechist->cur_set = 0; 1197 LSQ_DEBUG("%s: return [%"PRIu64", %"PRIu64"]", __func__, 1198 rechist->range.low, rechist->range.high); 1199 return &rechist->range; 1200} 1201 1202 1203static const struct lsquic_packno_range * 1204imico_rechist_first (void *rechist_ctx) 1205{ 1206 struct ietf_mini_rechist *rechist = rechist_ctx; 1207 rechist->cur_set = rechist->conn->imc_recvd_packnos[ rechist->pns ]; 1208 rechist->cur_idx = highest_bit_set(rechist->cur_set); 1209 return imico_rechist_next(rechist_ctx); 1210} 1211 1212 1213static const enum header_type pns2hety[] = 1214{ 1215 [PNS_INIT] = HETY_INITIAL, 1216 [PNS_HSK] = HETY_HANDSHAKE, 1217 [PNS_APP] = HETY_NOT_SET, 1218}; 1219 1220 1221static int 1222imico_generate_ack (struct ietf_mini_conn *conn, enum packnum_space pns, 1223 lsquic_time_t now) 1224{ 1225 struct lsquic_packet_out *packet_out; 1226 enum header_type header_type; 1227 struct ietf_mini_rechist rechist; 1228 int not_used_has_missing, len; 1229 uint64_t ecn_counts_buf[4]; 1230 const uint64_t *ecn_counts; 1231 1232 header_type = pns2hety[pns]; 1233 1234 if (conn->imc_incoming_ecn) 1235 { 1236 ecn_counts_buf[0] = conn->imc_ecn_counts_in[pns][0]; 1237 ecn_counts_buf[1] = conn->imc_ecn_counts_in[pns][1]; 1238 ecn_counts_buf[2] = conn->imc_ecn_counts_in[pns][2]; 1239 ecn_counts_buf[3] = conn->imc_ecn_counts_in[pns][3]; 1240 ecn_counts = ecn_counts_buf; 1241 } 1242 else 1243 ecn_counts = NULL; 1244 1245 packet_out = imico_get_packet_out(conn, header_type, 0); 1246 if (!packet_out) 1247 return -1; 1248 1249 /* Generate ACK frame */ 1250 imico_rechist_init(&rechist, conn, pns); 1251 len = conn->imc_conn.cn_pf->pf_gen_ack_frame( 1252 packet_out->po_data + packet_out->po_data_sz, 1253 lsquic_packet_out_avail(packet_out), imico_rechist_first, 1254 imico_rechist_next, imico_rechist_largest_recv, &rechist, 1255 now, ¬_used_has_missing, &packet_out->po_ack2ed, ecn_counts); 1256 if (len < 0) 1257 { 1258 LSQ_WARN("could not generate ACK frame"); 1259 return -1; 1260 } 1261 EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, conn->imc_conn.cn_pf, 1262 packet_out->po_data + packet_out->po_data_sz, len); 1263 packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK; 1264 packet_out->po_data_sz += len; 1265 packet_out->po_regen_sz += len; 1266 conn->imc_flags &= ~(IMC_QUEUED_ACK_INIT << pns); 1267 LSQ_DEBUG("wrote ACK frame of size %d", len); 1268 return 0; 1269} 1270 1271 1272static int 1273imico_generate_acks (struct ietf_mini_conn *conn, lsquic_time_t now) 1274{ 1275 enum packnum_space pns; 1276 1277 for (pns = PNS_INIT; pns < N_PNS; ++pns) 1278 if (conn->imc_flags & (IMC_QUEUED_ACK_INIT << pns) 1279 && !(pns == PNS_INIT && (conn->imc_flags & IMC_IGNORE_INIT))) 1280 if (0 != imico_generate_ack(conn, pns, now)) 1281 return -1; 1282 1283 return 0; 1284} 1285 1286 1287static void 1288imico_generate_conn_close (struct ietf_mini_conn *conn) 1289{ 1290 struct lsquic_packet_out *packet_out; 1291 enum header_type header_type; 1292 enum packnum_space pns, pns_max; 1293 unsigned error_code; 1294 const char *reason; 1295 size_t need; 1296 int sz, rlen, is_app; 1297 char reason_buf[0x20]; 1298 1299 if (conn->imc_flags & IMC_ABORT_ERROR) 1300 { 1301 is_app = !!(conn->imc_flags & IMC_ABORT_ISAPP); 1302 error_code = conn->imc_error_code; 1303 reason = NULL; 1304 rlen = 0; 1305 } 1306 else if (conn->imc_flags & IMC_TLS_ALERT) 1307 { 1308 is_app = 0; 1309 error_code = 0x100 + conn->imc_tls_alert; 1310 if (ALERT_NO_APPLICATION_PROTOCOL == conn->imc_tls_alert) 1311 reason = "no suitable application protocol"; 1312 else 1313 { 1314 snprintf(reason_buf, sizeof(reason_buf), "TLS alert %"PRIu8, 1315 conn->imc_tls_alert); 1316 reason = reason_buf; 1317 } 1318 rlen = strlen(reason); 1319 } 1320 else if (conn->imc_flags & IMC_BAD_TRANS_PARAMS) 1321 { 1322 is_app = 0; 1323 error_code = TEC_NO_ERROR; 1324 reason = "bad transport parameters"; 1325 rlen = 24; 1326 } 1327 else if (conn->imc_flags & IMC_HSK_FAILED) 1328 { 1329 is_app = 0; 1330 error_code = TEC_NO_ERROR; 1331 reason = "handshake failed"; 1332 rlen = 16; 1333 } 1334 else 1335 { 1336 is_app = 0; 1337 error_code = TEC_INTERNAL_ERROR; 1338 reason = NULL; 1339 rlen = 0; 1340 } 1341 1342 1343/* [draft-ietf-quic-transport-23] Section 12.2: 1344 * 1345 " A client will always know whether the server has Handshake keys (see 1346 " Section 17.2.2.1), but it is possible that a server does not know 1347 " whether the client has Handshake keys. Under these circumstances, a 1348 " server SHOULD send a CONNECTION_CLOSE frame in both Handshake and 1349 " Initial packets to ensure that at least one of them is processable by 1350 " the client. 1351 */ 1352 1353 pns = (conn->imc_flags >> IMCBIT_PNS_BIT_SHIFT) & 3; 1354 switch ((!!(conn->imc_flags & IMC_HSK_PACKET_SENT) << 1) 1355 | (pns == PNS_HSK) /* Handshake packet received */) 1356 { 1357 case (0 << 1) | 0: 1358 pns = PNS_INIT; 1359 pns_max = PNS_INIT; 1360 break; 1361 case (1 << 1) | 0: 1362 pns = PNS_INIT; 1363 pns_max = PNS_HSK; 1364 break; 1365 default: 1366 pns = PNS_HSK; 1367 pns_max = PNS_HSK; 1368 break; 1369 } 1370 1371 LSQ_DEBUG("will generate %u CONNECTION_CLOSE frame%.*s", 1372 pns_max - pns + 1, pns_max > pns, "s"); 1373 do 1374 { 1375 header_type = pns2hety[pns]; 1376 need = 30; /* Guess */ /* TODO: calculate, don't guess */ 1377 packet_out = imico_get_packet_out(conn, header_type, need); 1378 if (!packet_out) 1379 return; 1380 sz = conn->imc_conn.cn_pf->pf_gen_connect_close_frame( 1381 packet_out->po_data + packet_out->po_data_sz, 1382 lsquic_packet_out_avail(packet_out), is_app, error_code, reason, 1383 rlen); 1384 if (sz >= 0) 1385 { 1386 packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE; 1387 packet_out->po_data_sz += sz; 1388 LSQ_DEBUG("generated CONNECTION_CLOSE frame"); 1389 } 1390 else 1391 LSQ_WARN("could not generate CONNECTION_CLOSE frame"); 1392 ++pns; 1393 } 1394 while (pns <= pns_max); 1395} 1396 1397 1398static enum tick_st 1399ietf_mini_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now) 1400{ 1401 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1402 enum tick_st tick; 1403 1404 if (conn->imc_created + conn->imc_enpub->enp_settings.es_handshake_to < now) 1405 { 1406 LSQ_DEBUG("connection expired: closing"); 1407 return TICK_CLOSE; 1408 } 1409 1410 if (conn->imc_flags & 1411 (IMC_QUEUED_ACK_INIT|IMC_QUEUED_ACK_HSK|IMC_QUEUED_ACK_APP)) 1412 { 1413 if (0 != imico_generate_acks(conn, now)) 1414 { 1415 conn->imc_flags |= IMC_ERROR; 1416 return TICK_CLOSE; 1417 } 1418 } 1419 1420 1421 tick = 0; 1422 1423 if (conn->imc_flags & IMC_ERROR) 1424 { 1425 imico_generate_conn_close(conn); 1426 tick |= TICK_CLOSE; 1427 } 1428 else if (conn->imc_flags & IMC_HSK_OK) 1429 tick |= TICK_PROMOTE; 1430 1431 if (imico_have_packets_to_send(conn, now)) 1432 tick |= TICK_SEND; 1433 else 1434 tick |= TICK_QUIET; 1435 1436 LSQ_DEBUG("Return TICK %d", tick); 1437 return tick; 1438} 1439 1440 1441static void 1442ietf_mini_conn_ci_internal_error (struct lsquic_conn *lconn, 1443 const char *format, ...) 1444{ 1445 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1446 LSQ_INFO("internal error reported"); 1447 conn->imc_flags |= IMC_ERROR; 1448} 1449 1450 1451static void 1452ietf_mini_conn_ci_abort_error (struct lsquic_conn *lconn, int is_app, 1453 unsigned error_code, const char *fmt, ...) 1454{ 1455 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1456 va_list ap; 1457 const char *err_str, *percent; 1458 char err_buf[0x100]; 1459 1460 percent = strchr(fmt, '%'); 1461 if (percent) 1462 { 1463 va_start(ap, fmt); 1464 vsnprintf(err_buf, sizeof(err_buf), fmt, ap); 1465 va_end(ap); 1466 err_str = err_buf; 1467 } 1468 else 1469 err_str = fmt; 1470 LSQ_INFO("abort error: is_app: %d; error code: %u; error str: %s", 1471 is_app, error_code, err_str); 1472 conn->imc_flags |= IMC_ERROR|IMC_ABORT_ERROR; 1473 if (is_app) 1474 conn->imc_flags |= IMC_ABORT_ISAPP; 1475 conn->imc_error_code = error_code; 1476} 1477 1478 1479static struct network_path * 1480ietf_mini_conn_ci_get_path (struct lsquic_conn *lconn, 1481 const struct sockaddr *sa) 1482{ 1483 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1484 1485 return &conn->imc_path; 1486} 1487 1488 1489static const lsquic_cid_t * 1490ietf_mini_conn_ci_get_log_cid (const struct lsquic_conn *lconn) 1491{ 1492 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1493 1494 if (conn->imc_path.np_dcid.len) 1495 return &conn->imc_path.np_dcid; 1496 else 1497 return CN_SCID(lconn); 1498} 1499 1500 1501static unsigned char 1502ietf_mini_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, 1503 const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 1504{ 1505 struct ietf_mini_conn *conn = (struct ietf_mini_conn *) lconn; 1506 struct lsquic_packet_out *packet_out; 1507 size_t len; 1508 1509 if (NP_IS_IPv6(&conn->imc_path) != (AF_INET6 == peer_sa->sa_family)) 1510 TAILQ_FOREACH(packet_out, &conn->imc_packets_out, po_next) 1511 if ((packet_out->po_flags & (PO_SENT|PO_ENCRYPTED)) == PO_ENCRYPTED) 1512 imico_return_enc_data(conn, packet_out); 1513 1514 len = local_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) 1515 : sizeof(struct sockaddr_in6); 1516 1517 memcpy(conn->imc_path.np_peer_addr, peer_sa, len); 1518 memcpy(conn->imc_path.np_local_addr, local_sa, len); 1519 conn->imc_path.np_peer_ctx = peer_ctx; 1520 return 0; 1521} 1522 1523 1524static const struct conn_iface mini_conn_ietf_iface = { 1525 .ci_abort_error = ietf_mini_conn_ci_abort_error, 1526 .ci_client_call_on_new = ietf_mini_conn_ci_client_call_on_new, 1527 .ci_destroy = ietf_mini_conn_ci_destroy, 1528 .ci_get_engine = ietf_mini_conn_ci_get_engine, 1529 .ci_get_log_cid = ietf_mini_conn_ci_get_log_cid, 1530 .ci_get_path = ietf_mini_conn_ci_get_path, 1531 .ci_hsk_done = ietf_mini_conn_ci_hsk_done, 1532 .ci_internal_error = ietf_mini_conn_ci_internal_error, 1533 .ci_is_tickable = ietf_mini_conn_ci_is_tickable, 1534 .ci_next_packet_to_send = ietf_mini_conn_ci_next_packet_to_send, 1535 .ci_next_tick_time = ietf_mini_conn_ci_next_tick_time, 1536 .ci_packet_in = ietf_mini_conn_ci_packet_in, 1537 .ci_packet_not_sent = ietf_mini_conn_ci_packet_not_sent, 1538 .ci_packet_sent = ietf_mini_conn_ci_packet_sent, 1539 .ci_record_addrs = ietf_mini_conn_ci_record_addrs, 1540 .ci_tick = ietf_mini_conn_ci_tick, 1541 .ci_tls_alert = ietf_mini_conn_ci_tls_alert, 1542}; 1543