diff --git a/picoquic/logger.c b/picoquic/logger.c index ac35a300b9a7234153cecba09e548f5ebdb6d7e2..f7f6098b63b2a351bf361d69f83914bca39922f4 100644 --- a/picoquic/logger.c +++ b/picoquic/logger.c @@ -185,6 +185,9 @@ char const* picoquic_log_state_name(picoquic_state_enum state) case picoquic_state_server_almost_ready: state_name = "server_almost_ready"; break; + case picoquic_state_server_false_start: + state_name = "server_false_start"; + break; case picoquic_state_client_ready: state_name = "client_ready"; break; diff --git a/picoquic/packet.c b/picoquic/packet.c index 7f0788f0646d5dd6e9b0b2585130fe9c6cc00f07..33bd6b6052654d088dc06fcdd2429fea7939e7e7 100644 --- a/picoquic/packet.c +++ b/picoquic/packet.c @@ -1107,6 +1107,7 @@ int picoquic_incoming_client_handshake( if (cnx->cnx_state == picoquic_state_server_init || cnx->cnx_state == picoquic_state_server_handshake || cnx->cnx_state == picoquic_state_server_almost_ready + || cnx->cnx_state == picoquic_state_server_false_start || cnx->cnx_state == picoquic_state_server_ready) { if (picoquic_compare_connection_id(&ph->srce_cnx_id, &cnx->path[0]->remote_cnxid) != 0) { ret = PICOQUIC_ERROR_CNXID_CHECK; @@ -1173,7 +1174,9 @@ int picoquic_incoming_0rtt( picoquic_compare_connection_id(&ph->dest_cnx_id, &cnx->path[0]->local_cnxid) == 0) || picoquic_compare_connection_id(&ph->srce_cnx_id, &cnx->path[0]->remote_cnxid) != 0) { ret = PICOQUIC_ERROR_CNXID_CHECK; - } else if (cnx->cnx_state == picoquic_state_server_almost_ready || cnx->cnx_state == picoquic_state_server_ready) { + } else if (cnx->cnx_state == picoquic_state_server_almost_ready || + cnx->cnx_state == picoquic_state_server_false_start || + cnx->cnx_state == picoquic_state_server_ready) { if (ph->vn != picoquic_supported_versions[cnx->version_index].version) { ret = picoquic_connection_error(cnx, PICOQUIC_TRANSPORT_PROTOCOL_VIOLATION, 0); } else { diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h index a3c1c00f9b9a5596d8f2d12164ccc94527daa69d..5de47b887ad4fee21ac94fcf383caf2e8c1b90b1 100644 --- a/picoquic/picoquic.h +++ b/picoquic/picoquic.h @@ -114,6 +114,7 @@ typedef enum { picoquic_state_handshake_failure, picoquic_state_client_almost_ready, picoquic_state_server_almost_ready, + picoquic_state_server_false_start, picoquic_state_client_ready, picoquic_state_server_ready, picoquic_state_disconnecting, diff --git a/picoquic/sender.c b/picoquic/sender.c index eafe598a56f1bdc1b7c41edcc7976feb6a7d757e..9f909c55e259506212ca6d3b5312aae6e70dc024 100644 --- a/picoquic/sender.c +++ b/picoquic/sender.c @@ -1961,6 +1961,10 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t * path_x, uint32_t send_buffer_min_max = (send_buffer_max > path_x->send_mtu) ? path_x->send_mtu : (uint32_t)send_buffer_max; uint64_t next_wake_time = cnx->latest_progress_time + PICOQUIC_MICROSEC_SILENCE_MAX * (2 - cnx->client_mode); + if (cnx->cnx_state == picoquic_state_server_false_start && + cnx->crypto_context[3].aead_decrypt != NULL) { + cnx->cnx_state = picoquic_state_server_ready; + } /* Verify first that there is no need for retransmit or ack * on initial or handshake context. This does not deal with EOED packets, @@ -2306,6 +2310,7 @@ int picoquic_prepare_segment(picoquic_cnx_t* cnx, picoquic_path_t * path_x, pico case picoquic_state_server_handshake: ret = picoquic_prepare_packet_server_init(cnx, path_x, packet, current_time, send_buffer, send_buffer_max, send_length); break; + case picoquic_state_server_false_start: case picoquic_state_client_ready: case picoquic_state_server_ready: ret = picoquic_prepare_packet_ready(cnx, path_x, packet, current_time, send_buffer, send_buffer_max, send_length); diff --git a/picoquic/tls_api.c b/picoquic/tls_api.c index 73a2deb31af3169c5eb1764ae9fbeb6fbdce86d7..85e4b1e9f43cf3b78aa66643142e2ec21bbc7298 100644 --- a/picoquic/tls_api.c +++ b/picoquic/tls_api.c @@ -1814,7 +1814,7 @@ int picoquic_tls_stream_process(picoquic_cnx_t* cnx) case picoquic_state_server_init: case picoquic_state_server_handshake: /* If client authentication is activated, the client sends the certificates with its `Finished` packet. - The server does not send any further packets, so, we can switch into ready state here. + The server does not send any further packets, so, we can switch into false start state here. */ if (data_pushed == 0 && ((ptls_context_t*)cnx->quic->tls_master_ctx)->require_client_authentication == 1) { cnx->cnx_state = picoquic_state_server_ready; @@ -1829,6 +1829,7 @@ int picoquic_tls_stream_process(picoquic_cnx_t* cnx) case picoquic_state_handshake_failure: case picoquic_state_client_ready: case picoquic_state_server_almost_ready: + case picoquic_state_server_false_start: case picoquic_state_server_ready: case picoquic_state_disconnecting: case picoquic_state_closing_received: