From 20b9c8985542d1877afa5e6e5a22931b81879935 Mon Sep 17 00:00:00 2001 From: huitema <huitema@huitema.net> Date: Sun, 9 Dec 2018 23:03:20 -0800 Subject: [PATCH] fix series of embarassing migration bugs --- picoquic/frames.c | 4 ++-- picoquic/picoquic.h | 1 + picoquic/quicctx.c | 2 +- picoquic/sender.c | 27 +++++++++++++++------------ picoquicfirst/picoquicdemo.c | 1 - 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/picoquic/frames.c b/picoquic/frames.c index 11a22732..e1184583 100644 --- a/picoquic/frames.c +++ b/picoquic/frames.c @@ -1646,8 +1646,7 @@ static int picoquic_process_ack_range( picoquic_packet_t* next = p->next_packet; picoquic_path_t * old_path = p->send_path; - /* TODO: understand why we need this check, instead of just a check for NULL */ - if (old_path == cnx->path[0]) { + if (old_path != NULL) { if (cnx->congestion_alg != NULL) { cnx->congestion_alg->alg_notify(old_path, picoquic_congestion_notification_acknowledgement, @@ -1661,6 +1660,7 @@ static int picoquic_process_ack_range( old_path->mtu_probe_sent = 0; } } + /* If the packet contained an ACK frame, perform the ACK of ACK pruning logic */ picoquic_process_possible_ack_of_ack_frame(cnx, p); diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h index 7f33a1a8..714a435d 100644 --- a/picoquic/picoquic.h +++ b/picoquic/picoquic.h @@ -208,6 +208,7 @@ typedef struct st_picoquic_packet_t { unsigned int is_evaluated : 1; unsigned int is_pure_ack : 1; unsigned int contains_crypto : 1; + unsigned int is_mtu_probe : 1; uint8_t bytes[PICOQUIC_MAX_PACKET_SIZE]; } picoquic_packet_t; diff --git a/picoquic/quicctx.c b/picoquic/quicctx.c index 0ba74a5e..b000d83e 100644 --- a/picoquic/quicctx.c +++ b/picoquic/quicctx.c @@ -828,7 +828,7 @@ void picoquic_delete_path(picoquic_cnx_t* cnx, int path_index) /* Remove old path data from retransmit queue */ for (picoquic_packet_context_enum pc = 0; pc < picoquic_nb_packet_context; pc++) { - p = cnx->pkt_ctx[pc].retransmit_oldest; + p = cnx->pkt_ctx[pc].retransmit_newest; while (p != NULL) { if (p->send_path == path_x) { diff --git a/picoquic/sender.c b/picoquic/sender.c index 366c8d9b..397e1205 100644 --- a/picoquic/sender.c +++ b/picoquic/sender.c @@ -840,10 +840,11 @@ int picoquic_retransmit_needed(picoquic_cnx_t* cnx, /* TODO: while packets are pure ACK, drop them from retransmit queue */ while (p != NULL) { + picoquic_path_t * old_path = p->send_path; /* should be the path on which the packet was transmitted */ int should_retransmit = 0; int timer_based_retransmit = 0; uint64_t lost_packet_number = p->sequence_number; - picoquic_packet_t* p_next = p->next_packet; + picoquic_packet_t* p_next = p->previous_packet; uint8_t * new_bytes = packet->bytes; int ret = 0; @@ -872,11 +873,11 @@ int picoquic_retransmit_needed(picoquic_cnx_t* cnx, size_t frame_length = 0; size_t byte_index = 0; /* Used when parsing the old packet */ size_t checksum_length = 0; - /* should be the path on which the packet was transmitted */ - picoquic_path_t * old_path = p->send_path; - /* we'll report it where it got lost */ - if (old_path) old_path->retrans_count++; + /* we'll report it where it got lost */ + if (old_path) { + old_path->retrans_count++; + } *header_length = 0; @@ -934,10 +935,12 @@ int picoquic_retransmit_needed(picoquic_cnx_t* cnx, *is_cleartext_mode = 1; } - if (old_path != NULL && (p->length + p->checksum_overhead) > old_path->send_mtu) { - /* MTU probe was lost, presumably because of packet too big */ - old_path->mtu_probe_sent = 0; - old_path->send_mtu_max_tried = (uint32_t)(p->length + p->checksum_overhead); + if (packet->is_mtu_probe) { + if (old_path != NULL) { + /* MTU probe was lost, presumably because of packet too big */ + old_path->mtu_probe_sent = 0; + old_path->send_mtu_max_tried = (uint32_t)(p->length + p->checksum_overhead); + } /* MTU probes should not be retransmitted */ packet_is_pure_ack = 1; do_not_detect_spurious = 0; @@ -1017,12 +1020,11 @@ int picoquic_retransmit_needed(picoquic_cnx_t* cnx, packet->length = length; cnx->nb_retransmission_total++; - /* TODO: understand why we need to check for exact path value, instead of NULL */ - if (cnx->congestion_alg != NULL && old_path == cnx->path[0]) { + if (cnx->congestion_alg != NULL && old_path != NULL) { cnx->congestion_alg->alg_notify(old_path, (timer_based_retransmit == 0) ? picoquic_congestion_notification_repeat : picoquic_congestion_notification_timeout, 0, 0, lost_packet_number, current_time); - } + } break; } @@ -2357,6 +2359,7 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t * path_x, length = picoquic_prepare_mtu_probe(cnx, path_x, header_length, checksum_overhead, bytes); packet->length = length; packet->send_path = path_x; + packet->is_mtu_probe = 1; path_x->mtu_probe_sent = 1; is_pure_ack = 0; } diff --git a/picoquicfirst/picoquicdemo.c b/picoquicfirst/picoquicdemo.c index c44037f2..b3df8a06 100644 --- a/picoquicfirst/picoquicdemo.c +++ b/picoquicfirst/picoquicdemo.c @@ -905,7 +905,6 @@ int quic_client_migrate(picoquic_cnx_t * cnx, SOCKET_TYPE * fd, struct sockaddr { fprintf(F_log, "Switch to new port, sending probe.\n"); } - cnx->path[0]->path_is_demoted = 1; } } } -- GitLab