picoquic路径带宽估计流程

帧解析 

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);
}

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值