附录A. 丢包恢复伪代码 (Loss Recovery Pseudocode)
本附录描述了第6章中描述的丢包检测机制的示例实现。
本节中的伪代码段作为代码组件获得许可;请参阅版权声明。
A.1. 跟踪已发送的数据包 (Tracking Sent Packets)
为了正确实现拥塞控制,QUIC发送方跟踪每个引发确认的数据包,直到该数据包被确认或丢失。预期实现将能够通过数据包编号和加密上下文访问此信息,并存储附录A.1.1中的每个数据包字段,用于丢包恢复和拥塞控制。
在数据包被声明丢失后,端点仍然可以在一段时间内维护其状态,以允许数据包重新排序;参见[QUIC-TRANSPORT]的第13.3节。这使发送方能够检测虚假重传。
已发送的数据包按每个数据包编号空间进行跟踪,ACK处理仅适用于单个空间。
A.1.1. 已发送数据包字段 (Sent Packet Fields)
- packet_number: 已发送数据包的数据包编号
- ack_eliciting: 布尔值,指示数据包是否引发确认。如果为true,则预期将收到确认,尽管对等方可能将包含它的ACK帧的发送延迟最多max_ack_delay
- in_flight: 布尔值,指示数据包是否计入在途字节数
- sent_bytes: 数据包中发送的字节数,不包括UDP或IP开销,但包括QUIC帧开销
- time_sent: 数据包发送的时间
A.2. 相关常量 (Constants of Interest)
丢包恢复中使用的常量基于RFC、论文和常见实践的组合。
- kPacketThreshold: 在数据包阈值丢包检测认为数据包丢失之前的最大数据包重新排序。第6.1.1节推荐的值为3
- kTimeThreshold: 在时间阈值丢包检测认为数据包丢失之前的最大时间重新排序。指定为RTT乘数。第6.1.2节推荐的值为9/8
- kGranularity: 定时器粒度。这是一个系统相关的值,第6.1.2节推荐值为1毫秒
- kInitialRtt: 在获取RTT样本之前使用的RTT。第6.2.2节推荐的值为333毫秒
- kPacketNumberSpace: 枚举三个数据包编号空间的枚举:Initial, Handshake, ApplicationData
A.3. 相关变量 (Variables of Interest)
本节描述了实现拥塞控制机制所需的变量。
- latest_rtt: 接收先前未确认数据包的确认时进行的最新RTT测量
- smoothed_rtt: 连接的平滑RTT,按第5.3节所述计算
- rttvar: RTT变化,按第5.3节所述计算
- min_rtt: 在一段时间内看到的最小RTT,忽略确认延迟,如第5.2节所述
- first_rtt_sample: 获取第一个RTT样本的时间
- max_ack_delay: 接收方打算在应用程序数据包编号空间中延迟数据包确认的最大时间量
- loss_detection_timer: 用于丢包检测的多模式定时器
- pto_count: 在未收到确认的情况下发送PTO的次数
- time_of_last_ack_eliciting_packet[kPacketNumberSpace]: 最近发送引发确认的数据包的时间
- largest_acked_packet[kPacketNumberSpace]: 到目前为止在数据包编号空间中确认的最大数据包编号
- loss_time[kPacketNumberSpace]: 基于超过时间重新排序窗口,该数据包编号空间中的下一个数据包可以被视为丢失的时间
- sent_packets[kPacketNumberSpace]: 数据包编号空间中的数据包编号与有关它们的信息的关联
A.4. 初始化 (Initialization)
在连接开始时,按如下方式初始化丢包检测变量。
伪代码详见RFC 9002原文附录A.4。
A.5. 发送数据包时 (On Sending a Packet)
发送数据包后,存储有关该数据包的信息。OnPacketSent的参数在附录A.1.1中详细描述。
伪代码详见RFC 9002原文附录A.5。
A.6. 接收数据报时 (On Receiving a Datagram)
当服务器被反放大限制阻止时,接收数据报会解除阻止,即使数据报中的所有数据包都未成功处理。在这种情况下,需要重新启动PTO定时器。
伪代码详见RFC 9002原文附录A.6。
A.7. 接收确认时 (On Receiving an Acknowledgment)
当收到ACK帧时,它可能新确认任意数量的数据包。
伪代码详见RFC 9002原文附录A.7,包括:
IncludesAckEliciting(packets)OnAckReceived(ack, pn_space)UpdateRtt(ack_delay)
A.8. 设置丢包检测定时器 (Setting the Loss Detection Timer)
QUIC丢包检测对所有超时丢包检测使用单个定时器。定时器的持续时间基于定时器的模式。
伪代码详见RFC 9002原文附录A.8,包括:
GetLossTimeAndSpace()GetPtoTimeAndSpace()PeerCompletedAddressValidation()SetLossDetectionTimer()
A.9. 超时时 (On Timeout)
当丢包检测定时器到期时,定时器的模式决定要执行的操作。
伪代码详见RFC 9002原文附录A.9:
OnLossDetectionTimeout()
A.10. 检测丢失的数据包 (Detecting Lost Packets)
每次收到ACK或时间阈值丢包检测定时器到期时都会调用DetectAndRemoveLostPackets。此函数对该数据包编号空间的sent_packets进行操作,并返回新检测为丢失的数据包列表。
伪代码详见RFC 9002原文附录A.10:
DetectAndRemoveLostPackets(pn_space)
A.11. 丢弃Initial或Handshake密钥时 (Upon Dropping Initial or Handshake Keys)
当丢弃Initial或Handshake密钥时,来自该空间的数据包被丢弃,并更新丢包检测状态。
伪代码详见RFC 9002原文附录A.11:
OnPacketNumberSpaceDiscarded(pn_space)
注意:完整的伪代码实现请参考RFC 9002官方文档附录A。所有变量名、函数名和算法逻辑保持原样,以确保实现的准确性和一致性。