Résumé

  • RFC 3517 transformait ACK cumulatif et blocs SACK en tableau tenu par l’émetteur, puis SetPipe() estimait les octets à considérer encore en transit.
  • Le double comptage de certaines retransmissions exprimait une incertitude réelle. La marge cwnd - pipe autorisait un envoi ; elle ne mesurait ni le chemin ni la livraison.

Un bloc SACK décrit une île reçue au-delà d’un trou. Il améliore fortement la reprise après plusieurs pertes, mais ne place aucun observateur dans les routeurs. RFC 2018 le disait autrement : l’information SACK restait consultative. Le récepteur pouvait renoncer à des données déjà signalées, et l’émetteur devait garder celles-ci jusqu’à l’avancement de l’acquittement cumulatif.

RFC 3517 organisa cette information. HighACK, HighData, HighRxt et RecoveryPoint bornaient l’état. Update() alimentait le tableau. IsLost() classait une zone comme perdue après un seuil de blocs discontinus ou d’octets SACKés plus hauts. Ce verdict répondait à une règle ; il ne localisait pas la perte.

SetPipe() parcourait ensuite l’espace de séquence non SACKé. Les octets ni acquittés ni déclarés perdus augmentaient pipe, car l’émetteur les supposait encore dans le réseau. Les octets retransmis jusqu’à HighRxt l’augmentaient aussi. Le résultat était explicitement une estimation.

La règle la plus honnête concernait une retransmission lancée avant que la donnée soit déclarée perdue. Original et copie pouvaient alors compter deux fois. L’émetteur ignorait si une seule transmission, ou les deux, avait quitté le réseau. La prudence limitait donc l’injection suivante. Elle ne prétendait pas transformer l’ignorance en observation.

Au seuil des ACK dupliqués, la reprise fixait RecoveryPoint à HighData, réduisait la fenêtre conformément au contrôle de congestion, retransmettait la première perte présumée et calculait pipe. Chaque ACK ultérieur mettait le tableau à jour. Une marge d’au moins un SMSS dans cwnd - pipe permettait à NextSeg() de choisir une retransmission, parfois une donnée neuve ou un secours.

Ce calcul était une autorisation locale. L’incrément après envoi modifiait le compte de l’émetteur ; il ne prouvait ni l’entrée dans une file précise, ni la présence persistante sur le chemin, ni l’arrivée chez l’application. Seul un ACK cumulatif dépassant RecoveryPoint fermait l’épisode de reprise, et même ce reçu restait distinct de la consommation applicative.

RFC 3042 avait déjà permis à Limited Transmit d’utiliser les premiers ACK dupliqués. RFC 2883 ajoutait D-SACK pour signaler des doublons. RFC 5681 posait le cadre de congestion, tandis que RFC 6582 décrivait NewReno. Ces pièces enrichissaient la décision sans fournir un inventaire physique du réseau.

Le délai d’expiration gardait son rôle de repli. Après RTO, le récepteur pouvait avoir renoncé ; les anciens blocs SACK ne constituaient donc pas un registre durable. Le tableau le plus détaillé restait une projection de preuves partielles.

RFC 6675 remplaça RFC 3517 en 2012. Il précisa l’inférence de perte, l’entrée en reprise et la retransmission de secours, tout en conservant le mot essentiel : estimation. RFC 6937 proposa ensuite Proportional Rate Reduction, un autre compte pour rythmer la reprise. La politique de contrôle évoluait ; le chemin ne devenait pas directement visible.

RFC 9293 porte aujourd’hui la base TCP et le registre IANA conserve les numéros des options SACK. Le registre prouve une attribution, pas la négociation d’une connexion ni sa livraison. L’héritage de RFC 3517 est donc méthodologique : une variable peut être assez solide pour agir sans être assez large pour raconter toute la réalité.

Sources