老版本quic如何做fec

3 篇文章 1 订阅

fec在quic新版本中废弃了,据官方说法,在大部分情况下,作用不大。fec从本质上讲是基于冗余的,会浪费带宽。只能恢复随机丢包。大块丢包也无能为力。

不过,quic实现还是代表了一种十分优美的方案,算法简单实用。

quic fec 只能恢复fecgroup里一个包

比如: 10个包+加上一个fec包
接收端:
  1. fec包。fecqroup记录这个,初始化为第一个接受到的group组包
  2. 然后group每来一个数据包,做xor
  3. 当组结束时,检查丢包,如果只有一个丢失,则恭喜,fec包就是丢的那个
  4. 恢复完成
//这里才是数据包的起始入口,哇咔哇
void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
            const IPEndPoint& peer_address,
            const QuicEncryptedPacket& packet) {
    if (!connected_) {
        return;
    }
    #if 0
    // TODO(rtenneti): Remove ScopedTracker below once crbug.com/462789 is fixed.
    tracked_objects::ScopedTracker tracking_profile(
    FROM_HERE_WITH_EXPLICIT_FUNCTION(
    "462789 QuicConnection::ProcessUdpPacket"));
    #endif
    if (debug_visitor_ != nullptr) {
        debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
    }
    last_size_ = packet.length();

    CheckForAddressMigration(self_address, peer_address);

    stats_.bytes_received += packet.length();
    ++stats_.packets_received;

    if (!framer_.ProcessPacket(packet)) {
        // If we are unable to decrypt this packet, it might be
        // because the CHLO or SHLO packet was lost.
        if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
            if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
                undecryptable_packets_.size() < max_undecryptable_packets_) {
                QueueUndecryptablePacket(packet);
            } else if (debug_visitor_ != nullptr) {
                debug_visitor_->OnUndecryptablePacket();
            }
        }
        DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: "
        << last_header_.packet_sequence_number;
        return;
    }

    ++stats_.packets_processed;
    MaybeProcessUndecryptablePackets();
    //here for check revive packet
    MaybeProcessRevivedPacket();
    MaybeSendInResponseToPacket();
    SetPingAlarm();
}

bool QuicFramer::ProcessDataPacket(const QuicPacketPublicHeader& public_header,
                        const QuicEncryptedPacket& packet,
                        char* decrypted_buffer,
                        size_t buffer_length) {
    QuicPacketHeader header(public_header);
    if (!ProcessPacketHeader(&header, packet, decrypted_buffer, buffer_length)) {
        DLOG(WARNING) << "Unable to process packet header. Stopping parsing.";
        return false;
    }

    if (!visitor_->OnPacketHeader(header)) {
        // The visitor suppresses further processing of the packet.
        return true;
    }

    if (packet.length() > kMaxPacketSize) {
        DLOG(WARNING) << "Packet too large: " << packet.length();
        return RaiseError(QUIC_PACKET_TOO_LARGE);
    }

    // Handle the payload.
    if (!header.fec_flag) {
        if (header.is_in_fec_group == IN_FEC_GROUP) {
        StringPiece payload = reader_->PeekRemainingPayload();
        //to do xor payload.update fec_
        visitor_->OnFecProtectedPayload(payload);
    }
    if (!ProcessFrameData(header)) {
        DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessFrameData sets the error.
        DLOG(WARNING) << "Unable to process frame data.";
        return false;
    }
    } else {
        QuicFecData fec_data;
        fec_data.fec_group = header.fec_group;
        fec_data.redundancy = reader_->ReadRemainingPayload();
        // save fec payload 
        visitor_->OnFecData(fec_data);
    }

    visitor_->OnPacketComplete();
    return true;
}

min_protected_packet_ 是fec_group 组号
max_protected_packet_ 是group 最大的那个seqnumber

发送端:
是先发fec包?? 最后发的!!

ReliableQuicStream::WriteOrBufferData—>
ReliableQuicStream::WritevData—>
QuicConnection::SendStreamData—>
QuicPacketGenerator::ConsumeData—>
QuicPacketGenerator::MaybeStartFecProtection—>
QuicPacketCreator::SerializeFec—>
QuicPacketCreator::SerializePacket—>
OnBuiltFecProtectedPayload (header, packet-> FecProtectedData ());

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前进的蜗牛啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值