"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/liblsquic/lsquic_full_conn_ietf.c" between
lsquic-2.22.1.tar.gz and lsquic-2.23.1.tar.gz

About: LSQUIC is LiteSpeed’s QUIC and HTTP/3 Library. A hint: HTTP/3 uses QUIC as the underlying transport protocol instead of TCP.

lsquic_full_conn_ietf.c  (lsquic-2.22.1):lsquic_full_conn_ietf.c  (lsquic-2.23.1)
skipping to change at line 139 skipping to change at line 139
IFC_HAVE_PEER_SET = 1 << 18, IFC_HAVE_PEER_SET = 1 << 18,
IFC_GOT_PRST = 1 << 19, IFC_GOT_PRST = 1 << 19,
IFC_IGNORE_INIT = 1 << 20, IFC_IGNORE_INIT = 1 << 20,
IFC_RETRIED = 1 << 21, IFC_RETRIED = 1 << 21,
IFC_SWITCH_DCID = 1 << 22, /* Perform DCID switch when a new CID becomes a vailable */ IFC_SWITCH_DCID = 1 << 22, /* Perform DCID switch when a new CID becomes a vailable */
IFC_GOAWAY_CLOSE = 1 << 23, IFC_GOAWAY_CLOSE = 1 << 23,
IFC_FIRST_TICK = 1 << 24, IFC_FIRST_TICK = 1 << 24,
IFC_IGNORE_HSK = 1 << 25, IFC_IGNORE_HSK = 1 << 25,
IFC_PROC_CRYPTO = 1 << 26, IFC_PROC_CRYPTO = 1 << 26,
IFC_MIGRA = 1 << 27, IFC_MIGRA = 1 << 27,
IFC_UNUSED28 = 1 << 28, /* Unused */ IFC_HTTP_INITED = 1 << 28, /* HTTP initialized */
IFC_DELAYED_ACKS = 1 << 29, /* Delayed ACKs are enabled */ IFC_DELAYED_ACKS = 1 << 29, /* Delayed ACKs are enabled */
IFC_TIMESTAMPS = 1 << 30, /* Timestamps are enabled */ IFC_TIMESTAMPS = 1 << 30, /* Timestamps are enabled */
IFC_DATAGRAMS = 1u<< 31, /* Datagrams are enabled */ IFC_DATAGRAMS = 1u<< 31, /* Datagrams are enabled */
}; };
enum more_flags enum more_flags
{ {
MF_VALIDATE_PATH = 1 << 0, MF_VALIDATE_PATH = 1 << 0,
MF_NOPROG_TIMEOUT = 1 << 1, MF_NOPROG_TIMEOUT = 1 << 1,
MF_CHECK_MTU_PROBE = 1 << 2, MF_CHECK_MTU_PROBE = 1 << 2,
MF_IGNORE_MISSING = 1 << 3, MF_IGNORE_MISSING = 1 << 3,
MF_CONN_CLOSE_PACK = 1 << 4, /* CONNECTION_CLOSE has been packetized */ MF_CONN_CLOSE_PACK = 1 << 4, /* CONNECTION_CLOSE has been packetized */
MF_SEND_WRONG_COUNTS= 1 << 5, /* Send wrong ECN counts to peer */ MF_SEND_WRONG_COUNTS= 1 << 5, /* Send wrong ECN counts to peer */
MF_WANT_DATAGRAM_WRITE = 1 << 6, MF_WANT_DATAGRAM_WRITE = 1 << 6,
MF_DOING_0RTT = 1 << 7,
}; };
#define N_PATHS 4 #define N_PATHS 4
enum send enum send
{ {
/* PATH_CHALLENGE and PATH_RESPONSE frames are not retransmittable. They /* PATH_CHALLENGE and PATH_RESPONSE frames are not retransmittable. They
* are positioned first in the enum to optimize packetization. * are positioned first in the enum to optimize packetization.
*/ */
SEND_PATH_CHAL, SEND_PATH_CHAL,
skipping to change at line 558 skipping to change at line 559
static int static int
insert_new_dcid (struct ietf_full_conn *, uint64_t seqno, insert_new_dcid (struct ietf_full_conn *, uint64_t seqno,
const lsquic_cid_t *, const unsigned char *token, int update_cur_dcid); const lsquic_cid_t *, const unsigned char *token, int update_cur_dcid);
static struct conn_cid_elem * static struct conn_cid_elem *
find_cce_by_cid (struct ietf_full_conn *, const lsquic_cid_t *); find_cce_by_cid (struct ietf_full_conn *, const lsquic_cid_t *);
static void static void
mtu_probe_too_large (struct ietf_full_conn *, const struct lsquic_packet_out *); mtu_probe_too_large (struct ietf_full_conn *, const struct lsquic_packet_out *);
static int
apply_trans_params (struct ietf_full_conn *, const struct transport_params *);
static int
init_http (struct ietf_full_conn *);
static unsigned static unsigned
highest_bit_set (unsigned sz) highest_bit_set (unsigned sz)
{ {
#if __GNUC__ #if __GNUC__
unsigned clz = __builtin_clz(sz); unsigned clz = __builtin_clz(sz);
return 31 - clz; return 31 - clz;
#else #else
unsigned n, y; unsigned n, y;
n = 32; n = 32;
y = sz >> 16; if (y) { n -= 16; sz = y; } y = sz >> 16; if (y) { n -= 16; sz = y; }
skipping to change at line 1205 skipping to change at line 1212
conn->ifc_pub.all_streams = lsquic_hash_create(); conn->ifc_pub.all_streams = lsquic_hash_create();
if (!conn->ifc_pub.all_streams) if (!conn->ifc_pub.all_streams)
return -1; return -1;
conn->ifc_pub.u.ietf.qeh = &conn->ifc_qeh; conn->ifc_pub.u.ietf.qeh = &conn->ifc_qeh;
conn->ifc_pub.u.ietf.qdh = &conn->ifc_qdh; conn->ifc_pub.u.ietf.qdh = &conn->ifc_qdh;
conn->ifc_pub.u.ietf.hcso = &conn->ifc_hcso; conn->ifc_pub.u.ietf.hcso = &conn->ifc_hcso;
conn->ifc_peer_hq_settings.header_table_size = HQ_DF_QPACK_MAX_TABLE_CAP ACITY; conn->ifc_peer_hq_settings.header_table_size = HQ_DF_QPACK_MAX_TABLE_CAP ACITY;
conn->ifc_peer_hq_settings.qpack_blocked_streams = HQ_DF_QPACK_BLOCKED_STREA MS; conn->ifc_peer_hq_settings.qpack_blocked_streams = HQ_DF_QPACK_BLOCKED_STREA MS;
conn->ifc_flags = flags | IFC_CREATED_OK | IFC_FIRST_TICK; conn->ifc_flags = flags | IFC_FIRST_TICK;
conn->ifc_max_ack_packno[PNS_INIT] = IQUIC_INVALID_PACKNO; conn->ifc_max_ack_packno[PNS_INIT] = IQUIC_INVALID_PACKNO;
conn->ifc_max_ack_packno[PNS_HSK] = IQUIC_INVALID_PACKNO; conn->ifc_max_ack_packno[PNS_HSK] = IQUIC_INVALID_PACKNO;
conn->ifc_max_ack_packno[PNS_APP] = IQUIC_INVALID_PACKNO; conn->ifc_max_ack_packno[PNS_APP] = IQUIC_INVALID_PACKNO;
conn->ifc_max_ackable_packno_in = 0; conn->ifc_max_ackable_packno_in = 0;
conn->ifc_paths[0].cop_path.np_path_id = 0; conn->ifc_paths[0].cop_path.np_path_id = 0;
conn->ifc_paths[1].cop_path.np_path_id = 1; conn->ifc_paths[1].cop_path.np_path_id = 1;
conn->ifc_paths[2].cop_path.np_path_id = 2; conn->ifc_paths[2].cop_path.np_path_id = 2;
conn->ifc_paths[3].cop_path.np_path_id = 3; conn->ifc_paths[3].cop_path.np_path_id = 3;
#define valid_stream_id(v) ((v) <= VINT_MAX_VALUE) #define valid_stream_id(v) ((v) <= VINT_MAX_VALUE)
conn->ifc_max_req_id = VINT_MAX_VALUE + 1; conn->ifc_max_req_id = VINT_MAX_VALUE + 1;
skipping to change at line 1234 skipping to change at line 1241
return 0; return 0;
} }
struct lsquic_conn * struct lsquic_conn *
lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub, lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
unsigned versions, unsigned flags, unsigned versions, unsigned flags,
const char *hostname, unsigned short base_plpmtu, int is_ipv4, const char *hostname, unsigned short base_plpmtu, int is_ipv4,
const unsigned char *sess_resume, size_t sess_resume_sz, const unsigned char *sess_resume, size_t sess_resume_sz,
const unsigned char *token, size_t token_sz) const unsigned char *token, size_t token_sz)
{ {
const struct transport_params *params;
const struct enc_session_funcs_iquic *esfi; const struct enc_session_funcs_iquic *esfi;
struct ietf_full_conn *conn; struct ietf_full_conn *conn;
enum lsquic_version ver, sess_resume_version; enum lsquic_version ver, sess_resume_version;
lsquic_time_t now; lsquic_time_t now;
conn = calloc(1, sizeof(*conn)); conn = calloc(1, sizeof(*conn));
if (!conn) if (!conn)
goto err0; goto err0;
now = lsquic_time_now(); now = lsquic_time_now();
/* Set the flags early so that correct CID is used for logging */ /* Set the flags early so that correct CID is used for logging */
skipping to change at line 1349 skipping to change at line 1357
if (!conn->ifc_pub.packet_out_malo) if (!conn->ifc_pub.packet_out_malo)
goto err4; goto err4;
conn->ifc_flags |= IFC_PROC_CRYPTO; conn->ifc_flags |= IFC_PROC_CRYPTO;
LSQ_DEBUG("negotiating version %s", LSQ_DEBUG("negotiating version %s",
lsquic_ver2str[conn->ifc_u.cli.ifcli_ver_neg.vn_ver]); lsquic_ver2str[conn->ifc_u.cli.ifcli_ver_neg.vn_ver]);
conn->ifc_process_incoming_packet = process_incoming_packet_verneg; conn->ifc_process_incoming_packet = process_incoming_packet_verneg;
conn->ifc_created = now; conn->ifc_created = now;
LSQ_DEBUG("logging using %s SCID", LSQ_DEBUG("logging using %s SCID",
LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "client" : "server"); LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "client" : "server");
if (sess_resume && (params
= conn->ifc_conn.cn_esf.i->esfi_get_peer_transport_params(
conn->ifc_conn.cn_enc_session), params != NULL))
{
LSQ_DEBUG("initializing transport parameters for 0RTT");
if (0 != apply_trans_params(conn, params))
goto full_err;
if ((conn->ifc_flags & IFC_HTTP) && 0 != init_http(conn))
goto full_err;
conn->ifc_mflags |= MF_DOING_0RTT;
}
conn->ifc_flags |= IFC_CREATED_OK;
return &conn->ifc_conn; return &conn->ifc_conn;
err4: err4:
lsquic_stream_destroy(conn->ifc_u.cli.crypto_streams[ENC_LEV_CLEAR]); lsquic_stream_destroy(conn->ifc_u.cli.crypto_streams[ENC_LEV_CLEAR]);
err3: err3:
conn->ifc_conn.cn_esf.i->esfi_destroy(conn->ifc_conn.cn_enc_session); conn->ifc_conn.cn_esf.i->esfi_destroy(conn->ifc_conn.cn_enc_session);
err2: err2:
lsquic_send_ctl_cleanup(&conn->ifc_send_ctl); lsquic_send_ctl_cleanup(&conn->ifc_send_ctl);
if (conn->ifc_pub.all_streams) if (conn->ifc_pub.all_streams)
lsquic_hash_destroy(conn->ifc_pub.all_streams); lsquic_hash_destroy(conn->ifc_pub.all_streams);
err1: err1:
free(conn); free(conn);
err0: err0:
return NULL; return NULL;
full_err:
ietf_full_conn_ci_destroy(&conn->ifc_conn);
return NULL;
} }
typedef char mini_conn_does_not_have_more_cces[ typedef char mini_conn_does_not_have_more_cces[
sizeof(((struct ietf_mini_conn *)0)->imc_cces) sizeof(((struct ietf_mini_conn *)0)->imc_cces)
<= sizeof(((struct ietf_full_conn *)0)->ifc_cces) ? 1 : -1]; <= sizeof(((struct ietf_full_conn *)0)->ifc_cces) ? 1 : -1];
struct lsquic_conn * struct lsquic_conn *
lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub, lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
unsigned flags, struct lsquic_conn *mini_conn) unsigned flags, struct lsquic_conn *mini_conn)
{ {
skipping to change at line 1488 skipping to change at line 1512
conn->ifc_conn.cn_esf_c->esf_set_conn(conn->ifc_conn.cn_enc_session, conn->ifc_conn.cn_esf_c->esf_set_conn(conn->ifc_conn.cn_enc_session,
&conn->ifc_conn); &conn->ifc_conn);
conn->ifc_process_incoming_packet = process_incoming_packet_fast; conn->ifc_process_incoming_packet = process_incoming_packet_fast;
conn->ifc_send_ctl.sc_cur_packno = imc->imc_next_packno - 1; conn->ifc_send_ctl.sc_cur_packno = imc->imc_next_packno - 1;
lsquic_send_ctl_begin_optack_detection(&conn->ifc_send_ctl); lsquic_send_ctl_begin_optack_detection(&conn->ifc_send_ctl);
for (pns = 0; pns < IMICO_N_PNS; ++pns) for (pns = 0; pns < IMICO_N_PNS; ++pns)
{ {
lsquic_imico_rechist_init(&mini_rechist, imc, pns); lsquic_imico_rechist_init(&mini_rechist, imc, pns);
if (0 != lsquic_rechist_copy_ranges(&conn->ifc_rechist[pns], if (pns < IMICO_N_PNS)
&mini_rechist, lsquic_imico_rechist_first, {
lsquic_imico_rechist_next)) if (0 != lsquic_rechist_copy_ranges(&conn->ifc_rechist[pns],
goto err2; &mini_rechist, lsquic_imico_rechist_first,
conn->ifc_rechist[pns].rh_largest_acked_received lsquic_imico_rechist_next))
goto err2;
conn->ifc_rechist[pns].rh_largest_acked_received
= imc->imc_largest_recvd[pns]; = imc->imc_largest_recvd[pns];
}
} }
/* Mini connection sends out packets 0, 1, 2... and so on. It deletes /* Mini connection sends out packets 0, 1, 2... and so on. It deletes
* packets that have been successfully sent and acked or those that have * packets that have been successfully sent and acked or those that have
* been lost. We take ownership of all packets in mc_packets_out; those * been lost. We take ownership of all packets in mc_packets_out; those
* that are not on the list are recorded in fc_send_ctl.sc_senhist. * that are not on the list are recorded in fc_send_ctl.sc_senhist.
*/ */
have_outgoing_ack = 0; have_outgoing_ack = 0;
next_packno = ~0ULL; next_packno = ~0ULL;
/* mini conn may drop Init packets, making gaps; don't warn about them: */ /* mini conn may drop Init packets, making gaps; don't warn about them: */
skipping to change at line 1547 skipping to change at line 1574
have_outgoing_ack |= packet_out->po_frame_types & have_outgoing_ack |= packet_out->po_frame_types &
(1 << QUIC_FRAME_ACK); (1 << QUIC_FRAME_ACK);
} }
} }
conn->ifc_send_ctl.sc_senhist.sh_flags &= ~SH_GAP_OK; conn->ifc_send_ctl.sc_senhist.sh_flags &= ~SH_GAP_OK;
/* ...Yes, that's a bunch of little annoying steps to suppress the gap /* ...Yes, that's a bunch of little annoying steps to suppress the gap
* warnings, but it would have been even more annoying (and expensive) * warnings, but it would have been even more annoying (and expensive)
* to add packet renumbering logic to the mini conn. * to add packet renumbering logic to the mini conn.
*/ */
for (pns = 0; pns < N_PNS; ++pns) for (pns = 0; pns < IMICO_N_PNS; ++pns)
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
conn->ifc_ecn_counts_in[pns][i] = imc->imc_ecn_counts_in[pns][i]; conn->ifc_ecn_counts_in[pns][i] = imc->imc_ecn_counts_in[pns][i];
conn->ifc_ecn_counts_out[pns][i] = imc->imc_ecn_counts_out[pns][i]; conn->ifc_ecn_counts_out[pns][i] = imc->imc_ecn_counts_out[pns][i];
} }
conn->ifc_incoming_ecn = imc->imc_incoming_ecn; conn->ifc_incoming_ecn = imc->imc_incoming_ecn;
conn->ifc_pub.rtt_stats = imc->imc_rtt_stats; conn->ifc_pub.rtt_stats = imc->imc_rtt_stats;
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_RET_CIDS, lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_RET_CIDS,
ret_cids_alarm_expired, conn); ret_cids_alarm_expired, conn);
skipping to change at line 1586 skipping to change at line 1613
{ {
TAILQ_REMOVE(&imc->imc_app_packets, packet_in, pi_next); TAILQ_REMOVE(&imc->imc_app_packets, packet_in, pi_next);
LSQ_DEBUG("inherit packet %"PRIu64" from mini conn", LSQ_DEBUG("inherit packet %"PRIu64" from mini conn",
packet_in->pi_packno); packet_in->pi_packno);
ietf_full_conn_ci_packet_in(&conn->ifc_conn, packet_in); ietf_full_conn_ci_packet_in(&conn->ifc_conn, packet_in);
lsquic_packet_in_put(conn->ifc_pub.mm, packet_in); lsquic_packet_in_put(conn->ifc_pub.mm, packet_in);
} }
LSQ_DEBUG("logging using %s SCID", LSQ_DEBUG("logging using %s SCID",
LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "server" : "client"); LSQUIC_LOG_CONN_ID == CN_SCID(&conn->ifc_conn) ? "server" : "client");
conn->ifc_flags |= IFC_CREATED_OK;
return &conn->ifc_conn; return &conn->ifc_conn;
err3: err3:
ietf_full_conn_ci_destroy(&conn->ifc_conn); ietf_full_conn_ci_destroy(&conn->ifc_conn);
return NULL; return NULL;
err2: err2:
lsquic_malo_destroy(conn->ifc_pub.packet_out_malo); lsquic_malo_destroy(conn->ifc_pub.packet_out_malo);
err1: err1:
lsquic_send_ctl_cleanup(&conn->ifc_send_ctl); lsquic_send_ctl_cleanup(&conn->ifc_send_ctl);
skipping to change at line 3205 skipping to change at line 3233
params->tp_preferred_address.srst, 0); params->tp_preferred_address.srst, 0);
} }
break; break;
case BM_ERROR: case BM_ERROR:
ABORT_QUIETLY(0, TEC_INTERNAL_ERROR, "error initiating migration"); ABORT_QUIETLY(0, TEC_INTERNAL_ERROR, "error initiating migration");
break; break;
} }
} }
static int static int
handshake_ok (struct lsquic_conn *lconn) apply_trans_params (struct ietf_full_conn *conn,
const struct transport_params *params)
{ {
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
struct lsquic_stream *stream; struct lsquic_stream *stream;
struct lsquic_hash_elem *el; struct lsquic_hash_elem *el;
struct dcid_elem *dce;
const struct transport_params *params;
enum stream_id_type sit; enum stream_id_type sit;
uint64_t limit; uint64_t limit;
char buf[MAX_TP_STR_SZ];
fiu_return_on("full_conn_ietf/handshake_ok", -1);
/* Need to set this flag even we hit an error in the rest of this funciton.
* This is because this flag is used to calculate packet out header size
*/
lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
lconn->cn_enc_session);
if (!params)
{
ABORT_WARN("could not get transport parameters");
return -1;
}
LSQ_DEBUG("peer transport parameters: %s",
((lconn->cn_version == LSQVER_ID27 ? lsquic_tp_to_str_27
: lsquic_tp_to_str)(params, buf, sizeof(buf)), buf));
if ((params->tp_set & (1 << TPI_LOSS_BITS)) if ((params->tp_set & (1 << TPI_LOSS_BITS))
&& conn->ifc_settings->es_ql_bits == 2) && conn->ifc_settings->es_ql_bits == 2)
{ {
LSQ_DEBUG("turn on QL loss bits"); LSQ_DEBUG("turn on QL loss bits");
lsquic_send_ctl_do_ql_bits(&conn->ifc_send_ctl); lsquic_send_ctl_do_ql_bits(&conn->ifc_send_ctl);
} }
if (params->tp_init_max_streams_bidi > (1ull << 60) if (params->tp_init_max_streams_bidi > (1ull << 60)
|| params->tp_init_max_streams_uni > (1ull << 60)) || params->tp_init_max_streams_uni > (1ull << 60))
skipping to change at line 3375 skipping to change at line 3381
else else
conn->ifc_max_udp_payload = TP_DEF_MAX_UDP_PAYLOAD_SIZE; conn->ifc_max_udp_payload = TP_DEF_MAX_UDP_PAYLOAD_SIZE;
if (conn->ifc_max_udp_payload < CUR_NPATH(conn)->np_pack_size) if (conn->ifc_max_udp_payload < CUR_NPATH(conn)->np_pack_size)
{ {
CUR_NPATH(conn)->np_pack_size = conn->ifc_max_udp_payload; CUR_NPATH(conn)->np_pack_size = conn->ifc_max_udp_payload;
LSQ_DEBUG("decrease packet size to %hu bytes", LSQ_DEBUG("decrease packet size to %hu bytes",
CUR_NPATH(conn)->np_pack_size); CUR_NPATH(conn)->np_pack_size);
} }
if (params->tp_active_connection_id_limit > conn->ifc_conn.cn_n_cces)
conn->ifc_active_cids_limit = conn->ifc_conn.cn_n_cces;
else
conn->ifc_active_cids_limit = params->tp_active_connection_id_limit;
conn->ifc_first_active_cid_seqno = conn->ifc_scid_seqno;
return 0;
}
static int
init_http (struct ietf_full_conn *conn)
{
fiu_return_on("full_conn_ietf/init_http", -1);
lsquic_qeh_init(&conn->ifc_qeh, &conn->ifc_conn);
if (0 == avail_streams_count(conn, conn->ifc_flags & IFC_SERVER,
SD_UNI))
{
ABORT_QUIETLY(1, HEC_GENERAL_PROTOCOL_ERROR, "cannot create "
"control stream due to peer-imposed limit");
conn->ifc_error = CONN_ERR(1, HEC_GENERAL_PROTOCOL_ERROR);
return -1;
}
if (0 != create_ctl_stream_out(conn))
{
ABORT_WARN("cannot create outgoing control stream");
return -1;
}
if (0 != lsquic_hcso_write_settings(&conn->ifc_hcso,
&conn->ifc_enpub->enp_settings, conn->ifc_flags & IFC_SERVER))
{
ABORT_WARN("cannot write SETTINGS");
return -1;
}
if (!(conn->ifc_flags & IFC_SERVER)
&& (conn->ifc_u.cli.ifcli_flags & IFCLI_PUSH_ENABLED)
&& 0 != lsquic_hcso_write_max_push_id(&conn->ifc_hcso,
conn->ifc_u.cli.ifcli_max_push_id))
{
ABORT_WARN("cannot write MAX_PUSH_ID");
return -1;
}
if (0 != lsquic_qdh_init(&conn->ifc_qdh, &conn->ifc_conn,
conn->ifc_flags & IFC_SERVER, conn->ifc_enpub,
conn->ifc_settings->es_qpack_dec_max_size,
conn->ifc_settings->es_qpack_dec_max_blocked))
{
ABORT_WARN("cannot initialize QPACK decoder");
return -1;
}
if (avail_streams_count(conn, conn->ifc_flags & IFC_SERVER, SD_UNI) > 0)
{
if (0 != create_qdec_stream_out(conn))
{
ABORT_WARN("cannot create outgoing QPACK decoder stream");
return -1;
}
}
else
{
queue_streams_blocked_frame(conn, SD_UNI);
LSQ_DEBUG("cannot create outgoing QPACK decoder stream due to "
"unidir limits");
}
conn->ifc_flags |= IFC_HTTP_INITED;
return 0;
}
static int
handshake_ok (struct lsquic_conn *lconn)
{
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
struct dcid_elem *dce;
const struct transport_params *params;
char buf[MAX_TP_STR_SZ];
fiu_return_on("full_conn_ietf/handshake_ok", -1);
/* Need to set this flag even we hit an error in the rest of this funciton.
* This is because this flag is used to calculate packet out header size
*/
lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
params = lconn->cn_esf.i->esfi_get_peer_transport_params(
lconn->cn_enc_session);
if (!params)
{
ABORT_WARN("could not get transport parameters");
return -1;
}
LSQ_DEBUG("peer transport parameters: %s",
((lconn->cn_version == LSQVER_ID27 ? lsquic_tp_to_str_27
: lsquic_tp_to_str)(params, buf, sizeof(buf)), buf));
if (0 != apply_trans_params(conn, params))
return -1;
dce = get_new_dce(conn); dce = get_new_dce(conn);
if (!dce) if (!dce)
{ {
ABORT_WARN("cannot allocate DCE"); ABORT_WARN("cannot allocate DCE");
return -1; return -1;
} }
memset(dce, 0, sizeof(*dce)); memset(dce, 0, sizeof(*dce));
dce->de_cid = *CUR_DCID(conn); dce->de_cid = *CUR_DCID(conn);
dce->de_seqno = 0; dce->de_seqno = 0;
skipping to change at line 3406 skipping to change at line 3508
ABORT_WARN("cannot insert DCE"); ABORT_WARN("cannot insert DCE");
return -1; return -1;
} }
} }
} }
else else
dce->de_flags = DE_ASSIGNED; dce->de_flags = DE_ASSIGNED;
LSQ_INFO("applied peer transport parameters"); LSQ_INFO("applied peer transport parameters");
if (conn->ifc_flags & IFC_HTTP) if ((conn->ifc_flags & (IFC_HTTP|IFC_HTTP_INITED)) == IFC_HTTP)
{ if (0 != init_http(conn))
lsquic_qeh_init(&conn->ifc_qeh, &conn->ifc_conn);
if (0 == avail_streams_count(conn, conn->ifc_flags & IFC_SERVER,
SD_UNI))
{
ABORT_QUIETLY(1, HEC_GENERAL_PROTOCOL_ERROR, "cannot create "
"control stream due to peer-imposed limit");
conn->ifc_error = CONN_ERR(1, HEC_GENERAL_PROTOCOL_ERROR);
return -1; return -1;
}
if (0 != create_ctl_stream_out(conn))
{
ABORT_WARN("cannot create outgoing control stream");
return -1;
}
if (0 != lsquic_hcso_write_settings(&conn->ifc_hcso,
&conn->ifc_enpub->enp_settings, conn->ifc_flags & IFC_SERVER))
{
ABORT_WARN("cannot write SETTINGS");
return -1;
}
if (!(conn->ifc_flags & IFC_SERVER)
&& (conn->ifc_u.cli.ifcli_flags & IFCLI_PUSH_ENABLED)
&& 0 != lsquic_hcso_write_max_push_id(&conn->ifc_hcso,
conn->ifc_u.cli.ifcli_max_push_id))
{
ABORT_WARN("cannot write MAX_PUSH_ID");
return -1;
}
if (0 != lsquic_qdh_init(&conn->ifc_qdh, &conn->ifc_conn,
conn->ifc_flags & IFC_SERVER, conn->ifc_enpub,
conn->ifc_settings->es_qpack_dec_max_size,
conn->ifc_settings->es_qpack_dec_max_blocked))
{
ABORT_WARN("cannot initialize QPACK decoder");
return -1;
}
if (avail_streams_count(conn, conn->ifc_flags & IFC_SERVER, SD_UNI) > 0)
{
if (0 != create_qdec_stream_out(conn))
{
ABORT_WARN("cannot create outgoing QPACK decoder stream");
return -1;
}
}
else
{
queue_streams_blocked_frame(conn, SD_UNI);
LSQ_DEBUG("cannot create outgoing QPACK decoder stream due to "
"unidir limits");
}
}
if (params->tp_active_connection_id_limit > conn->ifc_conn.cn_n_cces)
conn->ifc_active_cids_limit = conn->ifc_conn.cn_n_cces;
else
conn->ifc_active_cids_limit = params->tp_active_connection_id_limit;
conn->ifc_first_active_cid_seqno = conn->ifc_scid_seqno;
if (conn->ifc_settings->es_dplpmtud) if (conn->ifc_settings->es_dplpmtud)
conn->ifc_mflags |= MF_CHECK_MTU_PROBE; conn->ifc_mflags |= MF_CHECK_MTU_PROBE;
if (can_issue_cids(conn) && CN_SCID(&conn->ifc_conn)->len != 0) if (can_issue_cids(conn) && CN_SCID(&conn->ifc_conn)->len != 0)
conn->ifc_send_flags |= SF_SEND_NEW_CID; conn->ifc_send_flags |= SF_SEND_NEW_CID;
maybe_create_delayed_streams(conn); maybe_create_delayed_streams(conn);
if (!(conn->ifc_flags & IFC_SERVER))
lsquic_send_ctl_0rtt_to_1rtt(&conn->ifc_send_ctl);
return 0; return 0;
} }
static void static void
ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn, ietf_full_conn_ci_hsk_done (struct lsquic_conn *lconn,
enum lsquic_hsk_status status) enum lsquic_hsk_status status)
{ {
struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn; struct ietf_full_conn *const conn = (struct ietf_full_conn *) lconn;
lsquic_alarmset_unset(&conn->ifc_alset, AL_HANDSHAKE); lsquic_alarmset_unset(&conn->ifc_alset, AL_HANDSHAKE);
skipping to change at line 3502 skipping to change at line 3551
} }
else else
{ {
LSQ_INFO("handshake was reported successful, but later processing " LSQ_INFO("handshake was reported successful, but later processing "
"produced an error"); "produced an error");
status = LSQ_HSK_FAIL; status = LSQ_HSK_FAIL;
handshake_failed(lconn); handshake_failed(lconn);
} }
break; break;
default: default:
case LSQ_HSK_RESUMED_FAIL: /* IETF crypto never returns this */
assert(0); assert(0);
/* fall-through */ /* fall-through */
case LSQ_HSK_FAIL: case LSQ_HSK_FAIL:
case LSQ_HSK_RESUMED_FAIL:
handshake_failed(lconn); handshake_failed(lconn);
break; break;
} }
if (conn->ifc_enpub->enp_stream_if->on_hsk_done) if (conn->ifc_enpub->enp_stream_if->on_hsk_done)
conn->ifc_enpub->enp_stream_if->on_hsk_done(lconn, status); conn->ifc_enpub->enp_stream_if->on_hsk_done(lconn, status);
} }
static void static void
ietf_full_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert) ietf_full_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert)
{ {
skipping to change at line 7179 skipping to change at line 7228
ds->ds_failed_size = ds->ds_probed_size; ds->ds_failed_size = ds->ds_probed_size;
ds->ds_probe_count = 0; ds->ds_probe_count = 0;
} }
} }
assert(0 == ds->ds_probe_sent assert(0 == ds->ds_probe_sent
|| ds->ds_probe_sent + conn->ifc_enpub->enp_mtu_probe_timer < now); || ds->ds_probe_sent + conn->ifc_enpub->enp_mtu_probe_timer < now);
if (!(conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE) if (!(conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
|| (conn->ifc_flags & IFC_CLOSING) || (conn->ifc_flags & IFC_CLOSING)
|| ~0ull == lsquic_senhist_largest(&conn->ifc_send_ctl.sc_senhist)
|| lsquic_senhist_largest(&conn->ifc_send_ctl.sc_senhist) < 30 || lsquic_senhist_largest(&conn->ifc_send_ctl.sc_senhist) < 30
|| lsquic_send_ctl_in_recovery(&conn->ifc_send_ctl) || lsquic_send_ctl_in_recovery(&conn->ifc_send_ctl)
|| !lsquic_send_ctl_can_send_probe(&conn->ifc_send_ctl, || !lsquic_send_ctl_can_send_probe(&conn->ifc_send_ctl,
&cpath->cop_path)) &cpath->cop_path))
{ {
return; return;
} }
if (ds->ds_failed_size) if (ds->ds_failed_size)
mtu_ceiling = ds->ds_failed_size; mtu_ceiling = ds->ds_failed_size;
skipping to change at line 7363 skipping to change at line 7413
"ECN as well"); "ECN as well");
memset(conn->ifc_ecn_counts_in[PNS_APP], 0, memset(conn->ifc_ecn_counts_in[PNS_APP], 0,
sizeof(conn->ifc_ecn_counts_in[PNS_APP])); sizeof(conn->ifc_ecn_counts_in[PNS_APP]));
conn->ifc_mflags |= MF_SEND_WRONG_COUNTS; conn->ifc_mflags |= MF_SEND_WRONG_COUNTS;
force_queueing_ack_app(conn); force_queueing_ack_app(conn);
conn->ifc_send_flags |= SF_SEND_PING; conn->ifc_send_flags |= SF_SEND_PING;
} }
} }
} }
static void
ietf_full_conn_ci_early_data_failed (struct lsquic_conn *lconn)
{
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
LSQ_DEBUG("early data failed");
lsquic_send_ctl_stash_0rtt_packets(&conn->ifc_send_ctl);
}
static size_t static size_t
ietf_full_conn_ci_get_min_datagram_size (struct lsquic_conn *lconn) ietf_full_conn_ci_get_min_datagram_size (struct lsquic_conn *lconn)
{ {
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn; struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
return (size_t) conn->ifc_min_dg_sz; return (size_t) conn->ifc_min_dg_sz;
} }
static int static int
ietf_full_conn_ci_set_min_datagram_size (struct lsquic_conn *lconn, ietf_full_conn_ci_set_min_datagram_size (struct lsquic_conn *lconn,
size_t new_size) size_t new_size)
skipping to change at line 7596 skipping to change at line 7655
} }
lsquic_send_ctl_set_buffer_stream_packets(&conn->ifc_send_ctl, 0); lsquic_send_ctl_set_buffer_stream_packets(&conn->ifc_send_ctl, 0);
if (!(conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)) if (!(conn->ifc_conn.cn_flags & LSCONN_HANDSHAKE_DONE))
{ {
s = lsquic_send_ctl_schedule_buffered(&conn->ifc_send_ctl, s = lsquic_send_ctl_schedule_buffered(&conn->ifc_send_ctl,
BPT_HIGHEST_PRIO); BPT_HIGHEST_PRIO);
conn->ifc_flags |= (s < 0) << IFC_BIT_ERROR; conn->ifc_flags |= (s < 0) << IFC_BIT_ERROR;
if (0 == s) if (0 == s)
process_crypto_stream_write_events(conn); process_crypto_stream_write_events(conn);
goto end_write; if (!(conn->ifc_mflags & MF_DOING_0RTT))
goto end_write;
} }
maybe_conn_flush_special_streams(conn); maybe_conn_flush_special_streams(conn);
s = lsquic_send_ctl_schedule_buffered(&conn->ifc_send_ctl, BPT_HIGHEST_PRIO) ; s = lsquic_send_ctl_schedule_buffered(&conn->ifc_send_ctl, BPT_HIGHEST_PRIO) ;
conn->ifc_flags |= (s < 0) << IFC_BIT_ERROR; conn->ifc_flags |= (s < 0) << IFC_BIT_ERROR;
if (!write_is_possible(conn)) if (!write_is_possible(conn))
goto end_write; goto end_write;
while ((conn->ifc_mflags & MF_WANT_DATAGRAM_WRITE) && write_datagram(conn)) while ((conn->ifc_mflags & MF_WANT_DATAGRAM_WRITE) && write_datagram(conn))
skipping to change at line 8027 skipping to change at line 8087
.ci_ack_rollback = ietf_full_conn_ci_ack_rollback, \ .ci_ack_rollback = ietf_full_conn_ci_ack_rollback, \
.ci_retire_cid = ietf_full_conn_ci_retire_cid, \ .ci_retire_cid = ietf_full_conn_ci_retire_cid, \
.ci_can_write_ack = ietf_full_conn_ci_can_write_ack, \ .ci_can_write_ack = ietf_full_conn_ci_can_write_ack, \
.ci_cancel_pending_streams = ietf_full_conn_ci_cancel_pending_streams, \ .ci_cancel_pending_streams = ietf_full_conn_ci_cancel_pending_streams, \
.ci_client_call_on_new = ietf_full_conn_ci_client_call_on_new, \ .ci_client_call_on_new = ietf_full_conn_ci_client_call_on_new, \
.ci_close = ietf_full_conn_ci_close, \ .ci_close = ietf_full_conn_ci_close, \
.ci_count_garbage = ietf_full_conn_ci_count_garbage, \ .ci_count_garbage = ietf_full_conn_ci_count_garbage, \
.ci_destroy = ietf_full_conn_ci_destroy, \ .ci_destroy = ietf_full_conn_ci_destroy, \
.ci_drain_time = ietf_full_conn_ci_drain_time, \ .ci_drain_time = ietf_full_conn_ci_drain_time, \
.ci_drop_crypto_streams = ietf_full_conn_ci_drop_crypto_streams, \ .ci_drop_crypto_streams = ietf_full_conn_ci_drop_crypto_streams, \
.ci_early_data_failed = ietf_full_conn_ci_early_data_failed, \
.ci_get_engine = ietf_full_conn_ci_get_engine, \ .ci_get_engine = ietf_full_conn_ci_get_engine, \
.ci_get_log_cid = ietf_full_conn_ci_get_log_cid, \ .ci_get_log_cid = ietf_full_conn_ci_get_log_cid, \
.ci_get_min_datagram_size= ietf_full_conn_ci_get_min_datagram_size, \ .ci_get_min_datagram_size= ietf_full_conn_ci_get_min_datagram_size, \
.ci_get_path = ietf_full_conn_ci_get_path, \ .ci_get_path = ietf_full_conn_ci_get_path, \
.ci_going_away = ietf_full_conn_ci_going_away, \ .ci_going_away = ietf_full_conn_ci_going_away, \
.ci_hsk_done = ietf_full_conn_ci_hsk_done, \ .ci_hsk_done = ietf_full_conn_ci_hsk_done, \
.ci_internal_error = ietf_full_conn_ci_internal_error, \ .ci_internal_error = ietf_full_conn_ci_internal_error, \
.ci_is_push_enabled = ietf_full_conn_ci_is_push_enabled, \ .ci_is_push_enabled = ietf_full_conn_ci_is_push_enabled, \
.ci_is_tickable = ietf_full_conn_ci_is_tickable, \ .ci_is_tickable = ietf_full_conn_ci_is_tickable, \
.ci_make_stream = ietf_full_conn_ci_make_stream, \ .ci_make_stream = ietf_full_conn_ci_make_stream, \
 End of changes. 25 change blocks. 
92 lines changed or deleted 153 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)