帧解析
ret = picoquic_decode_frames(cnx, cnx->path[path_id],
bytes + ph->offset, ph->payload_length, received_data,
ph->epoch, addr_from, addr_to, ph->pn64,
path_is_not_allocated, current_time);
到包解析
process_decoded_packet_data(cnx, path_x, epoch, current_time, &packet_data);
在到路径带宽估计
picoquic_estimate_path_bandwidth(cnx, packet_data->path_ack[i].acked_path, packet_data->path_ack[i].largest_sent_time,
packet_data->path_ack[i].delivered_prior, packet_data->path_ack[i].delivered_time_prior, packet_data->path_ack[i].delivered_sent_prior,
(packet_data->last_time_stamp_received == 0) ? current_time : packet_data->last_time_stamp_received,
current_time, packet_data->path_ack[i].rs_is_path_limited);
/* Bandwidth measurement */
uint64_t delivered; /* The total amount of data delivered so far on the path */
uint64_t delivered_last; /* Amount delivered by last bandwidth estimation */
uint64_t delivered_time_last; /* time last delivered packet was delivered */
uint64_t delivered_sent_last; /* time last delivered packet was sent */
uint64_t delivered_limited_index;
uint64_t delivered_last_packet;
uint64_t bandwidth_estimate; /* In bytes per second */
uint64_t bandwidth_estimate_max; /* Maximum of bandwidth estimate over life of path */
uint64_t max_sample_acked_time; /* Time max sample was delivered */
uint64_t max_sample_sent_time; /* Time max sample was sent */
uint64_t max_sample_delivered; /* Delivered value at time of max sample */
uint64_t peak_bandwidth_estimate; /* In bytes per second, measured on short interval with highest bandwidth */
uint64_t bytes_sent; /* Total amount of bytes sent on the path */
uint64_t received; /* Total amount of bytes received from the path */
uint64_t receive_rate_epoch; /* Time of last receive rate measurement */
uint64_t received_prior; /* Total amount received at start of epoch */
uint64_t receive_rate_estimate; /* In bytes per second */
uint64_t receive_rate_max; /* In bytes per second */
路径带宽估计
void picoquic_estimate_path_bandwidth(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uint64_t send_time,
uint64_t delivered_prior, uint64_t delivered_time_prior, uint64_t delivered_sent_prior,
uint64_t delivery_time, uint64_t current_time, int rs_is_path_limited)
{
if (send_time >= path_x->delivered_sent_last) {
if (path_x->delivered_time_last == 0) {
/* No estimate yet, need to initialize the variables */
path_x->delivered_last = path_x->delivered;
path_x->delivered_time_last = delivery_time;
path_x->delivered_sent_last = send_time;
}
else {
uint64_t receive_interval = delivery_time - delivered_time_prior;
if (receive_interval > PICOQUIC_BANDWIDTH_TIME_INTERVAL_MIN) {
uint64_t delivered = path_x->delivered - delivered_prior;
uint64_t send_interval = send_time - delivered_sent_prior;
uint64_t bw_estimate;
if (send_interval > receive_interval) {
receive_interval = send_interval;
}
bw_estimate = delivered * 1000000;
bw_estimate /= receive_interval;
path_x->bandwidth_estimate = bw_estimate;
if (!rs_is_path_limited || bw_estimate > path_x->bandwidth_estimate) {
if (path_x == cnx->path[0]){
if (cnx->is_ack_frequency_negotiated) {
/* Compute the desired value of the ack frequency*/
uint64_t ack_gap;
uint64_t ack_delay_max;
picoquic_compute_ack_gap_and_delay(cnx, cnx->path[0]->rtt_min, cnx->remote_parameters.min_ack_delay,
bw_estimate, &ack_gap, &ack_delay_max);
if (ack_gap != cnx->ack_gap_local) {
cnx->is_ack_frequency_updated = 1;
}
}
}
}
/* Bandwidth was estimated, update the references */
path_x->delivered_last = path_x->delivered;
path_x->delivered_time_last = delivery_time;
path_x->delivered_sent_last = send_time;
path_x->delivered_last_packet = delivered_prior;
path_x->last_bw_estimate_path_limited = rs_is_path_limited;
if (path_x->delivered_last_packet > path_x->delivered_limited_index) {
path_x->delivered_limited_index = 0;
}
/* Statistics */
if (bw_estimate > path_x->bandwidth_estimate_max) {
path_x->bandwidth_estimate_max = bw_estimate;
}
}
}
}
}
再到通知bbr
ack_state.nb_bytes_delivered_since_packet_sent = path_x->delivered - packet_data->path_ack[i].delivered_prior;
ack_state.inflight_prior = packet_data->path_ack[i].inflight_prior;
ack_state.is_app_limited = packet_data->path_ack[i].rs_is_path_limited;
ack_state.is_cwnd_limited = packet_data->path_ack[i].rs_is_cwnd_limited;
packet_data->path_ack[i].acked_path->is_lost_feedback_notified = 0;
cnx->congestion_alg->alg_notify(cnx, packet_data->path_ack[i].acked_path,
picoquic_congestion_notification_acknowledgement,
&ack_state, current_time);
bbr.c 文件
static void picoquic_bbr_notify(
picoquic_cnx_t* cnx,
picoquic_path_t* path_x,
picoquic_congestion_notification_t notification,
picoquic_per_ack_state_t * ack_state,
uint64_t current_time)
{
picoquic_bbr_state_t* bbr_state = (picoquic_bbr_state_t*)path_x->congestion_alg_state;
path_x->is_cc_data_updated = 1;
if (bbr_state != NULL) {
switch (notification) {
case picoquic_congestion_notification_ecn_ec:
/* TODO */
break;
case picoquic_congestion_notification_repeat:
BBRUpdateRecoveryOnLoss(bbr_state, path_x, ack_state->nb_bytes_newly_lost);
break;
case picoquic_congestion_notification_timeout:
BBRExitLostFeedback(bbr_state, path_x);
/* if loss is PTO, we should start the OnPto processing */
BBROnEnterRTO(bbr_state, path_x, ack_state->lost_packet_number);
break;
case picoquic_congestion_notification_spurious_repeat:
/* handling of suspension */
BBROnSpuriousLoss(bbr_state, path_x, ack_state->lost_packet_number, current_time);
break;
case picoquic_congestion_notification_lost_feedback:
/* Feedback has been lost. It will be restored at the next notification. */
BBREnterLostFeedback(bbr_state, path_x);
break;
case picoquic_congestion_notification_rtt_measurement:
/* TODO: this call is subsumed by the acknowledgement notification.
* Consider removing it from the API once other CC algorithms are updated. */
break;
case picoquic_congestion_notification_acknowledgement:
BBRExitLostFeedback(bbr_state, path_x);
picoquic_bbr_notify_ack(bbr_state, path_x, ack_state, current_time);
if (bbr_state->state == picoquic_bbr_alg_startup_long_rtt) {
picoquic_update_pacing_data(cnx, path_x, 1);
}
else if (bbr_state->pacing_rate > 0) {
/* Set the pacing rate in picoquic sender */
picoquic_update_pacing_rate(cnx, path_x, bbr_state->pacing_rate, bbr_state->send_quantum);
}
break;
case picoquic_congestion_notification_cwin_blocked:
break;
case picoquic_congestion_notification_reset:
picoquic_bbr_reset(bbr_state, path_x, current_time);
break;
case picoquic_congestion_notification_seed_cwin:
BBRSetBdpSeed(bbr_state, ack_state->nb_bytes_acknowledged);
break;
default:
/* ignore */
break;
}
}
}
接着再继续更新ack的值,拥塞状态值,检测rtt是否太高等
/* BBRv3 per ACK steps
* The function BBRUpdateOnACK is executed for each ACK notification on the API
*/
static void BBRUpdateModelAndState(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x, bbr_per_ack_state_t * rs, uint64_t current_time)
{
BBRUpdateLatestDeliverySignals(bbr_state, path_x, rs);
BBRUpdateCongestionSignals(bbr_state, path_x, rs);
BBRUpdateACKAggregation(bbr_state, path_x, rs, current_time);
BBRCheckStartupLongRtt(bbr_state, path_x, rs, current_time);
BBRCheckStartupResume(bbr_state, path_x, rs, current_time);
BBRCheckStartupDone(bbr_state, path_x, rs, current_time);
BBRCheckRecovery(bbr_state, path_x, rs, current_time);
BBRCheckDrain(bbr_state, path_x, current_time);
BBRUpdateProbeBWCyclePhase(bbr_state, path_x, rs, current_time);
BBRUpdateMinRTT(bbr_state, path_x, rs, current_time);
BBRCheckProbeRTT(bbr_state, path_x, rs, current_time);
BBRAdvanceLatestDeliverySignals(bbr_state, rs);
BBRAdvanceEcnFrac(bbr_state, path_x, rs);
BBRBoundBWForModel(bbr_state);
}