RFC 3522

The Eifel Detection Algorithm for TCP

πŸ“… published April 2003, from ietf

The Eifel Detection Algorithm for TCP ✨

okay so bestie, let's start with the paperwork πŸŽ€ This is RFC 3522, written by R. Ludwig and M. Meyer from Ericsson Research in April 2003. It's filed as an Experimental document, and its title block doesn't list any Obsoletes or Updates entries, so it doesn't replace or modify another RFC. Network Working Group energy all the way πŸ’…

Status of this Memo

ok so this memo defines an Experimental Protocol for the Internet community πŸ§ͺ It is NOT an Internet standard of any kind, so don't treat it like one. The authors are literally asking for discussion and suggestions for improvement, so if you have thoughts, share them 🫢 Distribution of this memo is unlimited, so go wild.

the Internet Society owns the copyright here (2003), and all rights are reserved ©️ πŸ“œ

Abstract

the Eifel detection algorithm lets a TCP sender figure out, after the fact, whether it went into loss recovery for no reason πŸ” To do this it needs the TCP Timestamps option from RFC 1323 turned on for the connection. The whole trick is that Timestamps kill the retransmission ambiguity in TCP ✨ So when the first acceptable ACK shows up during loss recovery, the sender looks at that ACK's timestamp and decides whether the recovery was unnecessary πŸ‘‘ The algorithm is a foundation for future TCP upgrades, including response algorithms that back out of loss recovery by restoring the sender's congestion control state. iconic, honestly.

Terminology

the keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are used here exactly as they're described in [RFC2119] πŸ“š Those are the only places these capitalised words carry that meaning, so keep an eye out for them πŸ‘€

okay now the vocab lesson 🌸 The first time an octet gets sent is the original transmit. Any later send of that same octet is a retransmit. Most of the time you can apply this to whole data segments too, but repacketization is the messy case: one segment can hold both fresh octets and retransmitted ones. In that situation the terms only make sense if you apply them to octets, not segments. The good news is the Eifel algorithm doesn't care, because it still works correctly when repacketization happens πŸ™Œ

when we say 'acceptable ACK' we mean the definition from [RFC793]: an ACK that acknowledges data that was previously unacknowledged πŸ’– 'Duplicate ACK' and the variable dupacks come from [WS95]. dupacks is a counter of the duplicate ACKs a TCP sender has already received before it sends the fast retransmit ✨ Then there's DupThresh, aka the duplicate acknowledgement threshold, which is how many duplicate ACKs have to reach a sender before it triggers a fast retransmit. Right now DupThresh is a fixed value of three [RFC2581]. Future TCPs might make it adaptive, so watch this space πŸ¦‹

1. Introduction πŸ¦‹

so the retransmission ambiguity problem ([Zh86], [KP87]) is basically this: a TCP sender can't tell whether the first acceptable ACK that arrives after a retransmit was answering the original transmit or the retransmit itself 😭 It happens after a timeout-based retransmit and after a fast retransmit. The Eifel detection algorithm uses the TCP Timestamps option from [RFC1323] to wipe out that ambiguity, so the sender can detect after the fact whether it entered loss recovery unnecessarily πŸŽ€

this extra power is super useful in environments where TCP's loss recovery and congestion control keep getting falsely triggered 🫠 That can happen because of packet reordering, packet duplication, or a sudden jump in delay on the data or ACK path that causes a spurious timeout. For example, wide-area wireless access networks often see sudden delay spikes from handovers, resource preemption by higher priority traffic (e.g., voice), or a mobile transmitter wandering into a radio coverage hole (e.g., see [Gu01]) πŸ“‘ In those networks, the go-back-N retransmits that usually follow a spurious timeout are often unnecessary, and that's a real problem. They tank end-to-end throughput, they're useless load on the network, and they waste transmission (battery) power πŸ”‹ The authors also note that timestamps are recommended for these networks anyway [RFC3481] πŸ’œ

once the Eifel detection algorithm has done its job, a TCP sender can choose to add dedicated response algorithms πŸ’… The main goal of a response algorithm is to ease the damage from a falsely triggered loss recovery. That can mean restoring the sender's congestion control state and avoiding those unnecessary go-back-N retransmits. Another goal is adapting protocol parameters, like the duplicate acknowledgement threshold [RFC2581] and the RTT estimators [RFC2988], so the connection is less likely to get falsely triggered again as it goes on πŸ“ BUT these response algorithms are outside the scope of this document, so don't expect them here. Quick note: the original "Eifel algorithm" proposal [LK00] has both a detection and a response part. This document only defines the detection part, and the response part is defined in [LG03] πŸ“š

the big feature of the Eifel detection algorithm is that it can tell, from the very first acceptable ACK during loss recovery, whether a fast retransmit or a timeout was spurious πŸ”₯ That's crucial for avoiding those go-back-N retransmits. It's also fairly robust against the loss of ACKs, which is a nice bonus 🫢

now the DSACK option ([RFC2883]) can also detect after the fact whether a TCP sender entered loss recovery unnecessarily [BA02]. Here's the catch though: the first ACK carrying a DSACK option usually doesn't arrive until after loss recovery is already over πŸ™ˆ So DSACK can't clear up the retransmission ambiguity, which means it can't help avoid those unnecessary go-back-N retransmits either. On top of that, a DSACK-based detection algorithm is less robust against ACK losses. A recent proposal that uses neither TCP timestamps nor DSACK avoids the DSACK limitation, but it only handles spurious timeouts [SK03] 🧚

2. Events that Falsely Trigger TCP Loss Recovery πŸ’€

these events can falsely trigger a TCP sender's loss recovery and congestion control algorithms 😀 Each one causes a so-called spurious retransmit, plus an unnecessary cut to the sender's congestion window and slow start threshold [RFC2581]. The culprits are:

  • Spurious timeout
  • Packet reordering
  • Packet duplication

a spurious timeout is a timeout that wouldn't have happened if the sender had just "waited longer" πŸ•°οΈ It's usually caused by a sudden increase in delay on the data path, the ACK path, or both. That delay can make an acceptable ACK arrive too late, which means after the sender's retransmission timer has already gone off. For the purpose of specifying the algorithm in Section 3, this case gets the name SPUR_TO (equal 1) ✨

Note: there's another case where a timeout wouldn't have happened if the sender had "waited longer". The retransmission timer expires, and then the sender gets the duplicate ACK that would have triggered a fast retransmit of the oldest outstanding segment. This is called a 'fast timeout', since the timeout beat the fast retransmit algorithm in the race. A fast timeout is NOT spurious, though, because a segment really was lost, so loss recovery was started for a good reason πŸ™…β€β™€οΈ This document doesn't consider fast timeouts.

packet reordering can happen because IP [RFC791] doesn't guarantee in-order delivery of packets πŸ”€ On top of that, a TCP receiver sends a duplicate ACK for every segment that arrives out-of-order. So if three or more data segments arrive out-of-order at a TCP receiver, and at least three of the resulting duplicate ACKs reach the TCP sender, you get a spurious fast retransmit. This assumes the duplicate acknowledgement threshold is set to three, as defined in [RFC2581] πŸŽ€

packet duplication happens because a receiving IP can't remove packets that got duplicated in the network πŸ™ƒ A TCP receiver also sends a duplicate ACK for each duplicate segment. Just like with reordering, if duplication of data segments or ACKs produces three or more duplicate ACKs at the TCP sender, you get a spurious fast retransmit. Again, this assumes the duplicate acknowledgement threshold is set to three.

the performance damage from packet reordering and packet duplication is usually the same: one spurious retransmit (the fast retransmit), plus the unnecessary halving of the sender's congestion window that comes from the fast recovery phase that follows [RFC2581] πŸ“‰

the performance damage from a spurious timeout is way worse 😭 The timeout itself causes one spurious retransmit and needlessly forces the sender into slow start [RFC2581]. Then, as the connection goes on, a chain reaction kicks in and drags performance down even further. Because the timeout was spurious, at least some ACKs for original transmits usually reach the sender before the ACK for the retransmit does. (The exception is if severe packet reordering happens at the same time as the spurious timeout, so that the ACK for the retransmit is the first acceptable ACK to arrive.) Those ACKs for original transmits then set off an implicit go-back-N loss recovery at the sender [LK00]. If none of the outstanding segments and none of the corresponding ACKs were lost, then every outstanding segment gets retransmitted for no reason πŸ’€ During this phase the sender actually breaks the packet conservation principle [Jac88], because the unnecessary go-back-N retransmits go out during slow start. So for every packet that leaves the network and belongs to the first half of the original flight, two useless retransmits get sent into the network πŸ™ƒ On top of that, some TCPs also suffer a spurious fast retransmit. The unnecessary go-back-N retransmits show up at the TCP receiver as duplicates, which triggers a series of duplicate ACKs. This last spurious fast retransmit could be avoided with the careful variant of 'bugfix' [RFC2582] πŸ› οΈ

for more detailed explanations, including TCP trace plots that show the effects of spurious timeouts and packet reordering, check out the original proposal [LK00] πŸ“ˆβœ¨

3. The Eifel Detection Algorithm 🌈

3.1 The Idea

okay so the big goal of the Eifel detection algorithm is to let a TCP sender figure out, after the fact, whether it went into loss recovery for no reason πŸ•΅οΈβ€β™€οΈβœ¨ and ideally it should be able to decide that from the very first acceptable ACK that shows up after it sent either the timeout-based retransmit or the fast retransmit πŸ’…. To pull that off, the ACKs need extra info so the sender can tell whether that first ACK was replying to the original transmit or to the retransmit. That extra info comes from the TCP Timestamps option [RFC1323] 🧚. Basically, timestamps are steadily increasing "serial numbers" stuck onto every segment, and they get echoed back in the matching ACKs πŸ”’. The Eifel algorithm uses that trick like this πŸ‘‡

okay so if timestamps are turned on for a connection, the TCP sender always saves the timestamp from the retransmit it sent at the start of loss recovery (so either the timeout-based one or the fast one) πŸ“Œ. Then, when the first acceptable ACK arrives after that retransmit went out, it checks the timestamp on that ACK. If the timestamp is smaller than the saved RetransmitTS, the ACK has to be a reply to an original transmit, which means the sender went into loss recovery for no reason 😭. Lowkey devastating, but it's how we know πŸ’”.

Why is deciding on the first acceptable ACK such a big deal? Because it's what lets future response algorithms skip those unnecessary go-back-N retransmits that usually happen after a spurious timeout πŸ™…β€β™€οΈ. Also, if loss recovery was entered by mistake, there's a whole window's worth of ACKs still floating around, and every one of them has a timestamp smaller than the saved retransmit timestamp 🌊. So the algorithm only needs any one of those ACKs to do its job, which makes it super robust against ACK losses πŸ›‘οΈ. Even the ACK that answers the retransmit (the one carrying the saved timestamp itself) can get lost and the algorithm still works πŸ™Œ. Iconic resilience, honestly πŸ‘‘.


3.2 The Algorithm

So if the TCP Timestamps option [RFC1323] is enabled for a connection, a TCP sender MAY use the Eifel detection algorithm described in this subsection πŸŽ€.

If a TCP sender is using the Eifel detection algorithm, it MUST follow the steps below, but only at the moment loss recovery starts, meaning when either the timeout-based retransmit or the fast retransmit goes out πŸš€. The Eifel detection algorithm MUST NOT be restarted once loss recovery has already begun πŸ™…β€β™€οΈ. That includes repeated timeouts for the same segment, and it also includes retransmitting anything other than the oldest outstanding segment, like during selective loss recovery 🚫.

   (1)     Set a "SpuriousRecovery" variable to FALSE (equal 0).

   (2)     Set a "RetransmitTS" variable to the value of the
           Timestamp Value field of the Timestamps option included in
           the retransmit sent when loss recovery is initiated.  A
           TCP sender must ensure that RetransmitTS does not get
           overwritten as loss recovery progresses, e.g., in case of
           a second timeout and subsequent second retransmit of the
           same octet.

   (3)     Wait for the arrival of an acceptable ACK.  When an
           acceptable ACK has arrived, proceed to step (4).

   (4)     If the value of the Timestamp Echo Reply field of the
           acceptable ACK's Timestamps option is smaller than the
           value of RetransmitTS, then proceed to step (5),

           else proceed to step (DONE).

   (5)     If the acceptable ACK carries a DSACK option [RFC2883],
           then proceed to step (DONE),

           else if during the lifetime of the TCP connection the TCP
           sender has previously received an ACK with a DSACK option,
           or the acceptable ACK does not acknowledge all outstanding
           data, then proceed to step (6),

           else proceed to step (DONE).

   (6)     If the loss recovery has been initiated with a timeout-
           based retransmit, then set
               SpuriousRecovery <- SPUR_TO (equal 1),

           else set
               SpuriousRecovery <- dupacks+1

   (RESP)  Do nothing (Placeholder for a response algorithm).

   (DONE)  No further processing.

The "smaller than" check in step (4) is on the conservative side πŸ€“. In theory, if the timestamp clock is slow or the network is fast, RetransmitTS could end up equal to the timestamp echoed by an ACK that answers an original transmit. When that happens, the loss recovery is assumed to NOT have been falsely triggered 🫢. (Okay, that one's a plain "not" in lowercase prose, so no capitals, just vibes.)

Also, the condition in step (5) about "having previously received an ACK with a DSACK option" would be true if the TCP receiver signaled in the SYN that it is DSACK-enabled πŸ’œ. Unfortunately, [RFC2883] doesn't require receivers to do that, so it's not guaranteed 😀.


3.3 A Corner Case: "Timeout due to loss of all ACKs" (step 5)

this one's a sneaky little plot twist 😈. Even when the oldest outstanding segment actually reached the TCP receiver, the sender can still get pushed into a timeout if every single ACK gets lost 🌧️. The retransmit is technically unnecessary in that situation, but the timeout is unavoidable anyway. So it shouldn't count as spurious πŸ™…β€β™€οΈ. Plus, shrinking the congestion window afterwards is a totally reasonable reaction to heavy congestion on the ACK path 🌊. The original proposal [LK00] handles this case poorly 😬. It basically switches off this implicit congestion control for the ACK path, which TCP doesn't have any other way of doing πŸ’”. Step (5) of the Eifel detection algorithm fixes that, and the rest of this section explains how πŸ”§.

If all the ACKs get lost while the oldest outstanding segment has reached the TCP receiver, the retransmit shows up as a duplicate πŸ‘―. For duplicates, RFC 1323 says the receiver should echo the timestamp of the last segment that arrived in sequence πŸ“œ. That timestamp rides on the first acceptable ACK the TCP sender gets after loss recovery started, and it's usually smaller than the timestamp on the retransmit πŸ“‰. So without help, the Eifel algorithm would wrongly call this timeout spurious 😡, unless the TCP receiver is DSACK-enabled [RFC2883] πŸ’–. If it is, the acceptable ACK carries a DSACK option, and the algorithm ends right there through the first part of step (5) πŸŽ‰.

Note: Not every TCP implementation follows RFC 1323 strictly πŸ™ˆ. When a receiver gets a duplicate data segment, some of them echo the timestamp of that duplicate instead. With those receivers, this corner case doesn't come up at all πŸ™Œ. The retransmit's timestamp would show up in the first acceptable ACK, and the algorithm would end through step (4) 🏁. So even if every ACK was lost, the Eifel detection algorithm would do nothing, whether or not DSACK was enabled for the connection 🫠.

For TCP receivers that aren't DSACK-enabled, turning off that implicit congestion control on the ACK path isn't a real problem as long as data segments are also getting lost on top of the whole ACK flight 🌊. The Eifel algorithm still misreads that timeout as spurious, and the Eifel response algorithm would reverse the congestion control state πŸ”„. But the sender still reacts to congestion in the data path as soon as it learns about the first loss in the outstanding flight 🚨. So it still halves its congestion window for that flight of packets πŸ“‰. Now, if no data segment is lost while the whole flight of ACKs disappears, the first acceptable ACK after loss recovery started acknowledges all outstanding data 🎯. In that case the Eifel algorithm ends through the second part of step (5) 🏁.

Also, there's little concern about breaking the packet conservation principle when TCP re-enters slow start after an unavoidable timeout caused by losing an entire flight of ACKs, meaning cases where the algorithm ended through step (5) πŸ§˜β€β™€οΈ. That's because the acceptable ACK in that case corresponds to the retransmit, which is a strong sign the pipe has fully drained, so no more original transmits are floating around in the network 🌊✨. Spurious timeouts are different, as we covered in Section 2 πŸ’….

3.4 Protecting Against Misbehaving TCP Receivers (the Safe Variant) πŸŽ€

okay bestie, this one is a security moment 😭 A sneaky TCP receiver can totally make a real retransmit look like a spurious one, just by forging the echoed timestamps. not it πŸ’€

BUT we have a fix! πŸ¦‹ The trick is to treat each segment's timestamp like a little secret. A receiver only learns that secret if it actually gets the segment. If a segment was lost, the receiver has no clue what its timestamp is. So to "prove" it got the original transmit of a segment the sender retransmitted, the receiver would need to echo back the timestamp from that original transmit. The Eifel detection algorithm can then say "yep, loss recovery was unnecessary" only if the first acceptable ACK echoes that original timestamp. ✨

so implementers may choose to add these changes:

Step (2) gets swapped out for step (2'):

(2')    Set a "RetransmitTS" variable to the value of the
        Timestamp Value field of the Timestamps option that was
        included in the original transmit corresponding to the
        retransmit.  Note: This step requires that the TCP sender
        stores the timestamps of all outstanding original
        transmits.

And step (4) gets swapped out for step (4'):

(4')    If the value of the Timestamp Echo Reply field of the
        acceptable ACK's Timestamps option is equal to the value
        of the variable RetransmitTS, then proceed to step (5),

        else proceed to step (DONE).

ngl, this comes with a cost πŸ₯Ί The modified algorithm is pretty sensitive to ACK losses, because it depends on the acceptable ACK for the original transmit actually showing up.

Note: The first acceptable ACK that arrives after loss recovery has been unnecessarily entered should echo the timestamp of the original transmit. This assumes that the ACK corresponding to the original transmit was not lost, that that ACK was not reordered in the network, and that the TCP receiver does not forge timestamps but complies with RFC 1323. In case of a spurious fast retransmit, this is implied by the rules for generating ACKs for data segments that fill in all or part of a gap in the sequence space (see section 4.2 of [RFC2581]) and by the rules for echoing timestamps in that case (see rule (C) in section 3.4 of [RFC1323]). In case of a spurious timeout, it is likely that the delay that has caused the spurious timeout has also caused the TCP receiver's delayed ACK timer [RFC1122] to expire before the original transmit arrives. Also, in this case the rules for generating ACKs and the rules for echoing timestamps (see rule (A) in section 3.4 of [RFC1323]) ensure that the original transmit's timestamp is echoed.

the remaining problem is that a TCP receiver might guess a lost segment's timestamp by looking at the timestamps of recently received segments. πŸ™ˆ For example, if segment N was lost while N-1 and N+1 arrived, a receiver could guess a timestamp somewhere in the middle of N-1 and N+1's timestamps, then echo that in the ACK for the retransmit of segment N. If the TCP sender uses a coarse timestamp granularity, a misbehaving receiver has a much better shot at pulling this off. In fact, with the 500 ms granularity suggested in [WS95], it's pretty likely that the timestamps of segments N-1, N, and N+1 are all identical. πŸ’€

one way to lower that risk is to use fine grained timestamps πŸ”₯ The granularity of the timestamps is independent of the granularity of the retransmission timer. For example, some TCP implementations run a timestamp clock that ticks every millisecond. That should make it harder for a receiver to guess a lost segment's timestamp. Alternatively, it might be possible to combine the timestamps with a nonce, the same way it's done for Explicit Congestion Notification (ECN) [RFC3168]. Just be careful, though: the timestamps of consecutive segments need to stay monotonously increasing, and they must not interfere with the RTT timing defined in [RFC1323]. 🫢


4. IPR Considerations 🌸

okay so this part is the legal stuff, and I'm keeping the exact wording because it matters πŸ’…

The IETF has been notified of intellectual property rights claimed in
regard to some or all of the specification contained in this
document.  For more information consult the online list of claimed
rights at http://www.ietf.org/ipr.

The IETF takes no position regarding the validity or scope of any
intellectual property or other rights that might be claimed to
pertain to the implementation or use of the technology described in
this document or the extent to which any license under such rights
might or might not be available; neither does it represent that it
has made any effort to identify any such rights.  Information on the
IETF's procedures with respect to rights in standards-track and
standards-related documentation can be found in BCP-11.  Copies of
claims of rights made available for publication and any assurances of
licenses to be made available, or the result of an attempt made to
obtain a general license or permission for the use of such
proprietary rights by implementors or users of this specification can
be obtained from the IETF Secretariat.

5. Security Considerations πŸ”

okay the security section, and I need you to take this seriously πŸ˜€πŸ’–

good news first: there don't seem to be any security considerations tied to the Eifel detection algorithm itself. πŸŽ‰ That's because the algorithm doesn't change the existing protocol state at a TCP sender. The only thing it needs is changes to the implementation of a TCP sender, nothing else.

BUT πŸ‘€ Section 3.4 proposes a variant that is robust against lying TCP receivers. That becomes relevant once the Eifel detection algorithm gets paired with a response algorithm, like the Eifel response algorithm [LG03]. So be careful there, bestie. Serious. 🚨

Acknowledgments πŸ¦‹

Huge thanks to Keith Sklower, Randy Katz, Stephan Baucke, Sally Floyd, Vern Paxson, Mark Allman, Ethan Blanton, Andrei Gurtov, Pasi Sarolahti, and Alexey Kuznetsov for the useful discussions that helped shape this work. You're all iconic πŸ‘‘πŸ«Ά

Normative References πŸ“š

[RFC2581] Allman, M., Paxson, V. and W. Stevens, "TCP Congestion
          Control", RFC 2581, April 1999.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
          Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2883] Floyd, S., Mahdavi, J., Mathis, M., Podolsky, M. and A.
          Romanow, "An Extension to the Selective Acknowledgement
          (SACK) Option for TCP", RFC 2883, July 2000.

[RFC1323] Jacobson, V., Braden, R. and D. Borman, "TCP Extensions for
          High Performance", RFC 1323, May 1992.

[RFC2018] Mathis, M., Mahdavi, J., Floyd, S. and A. Romanow, "TCP
          Selective Acknowledgement Options", RFC 2018, October 1996.

[RFC793]  Postel, J., "Transmission Control Protocol", STD 7, RFC
          793, September 1981.

Informative References 🧚

[BA02]    Blanton, E. and M. Allman, "Using TCP DSACKs and SCTP
          Duplicate TSNs to Detect Spurious Retransmissions", Work in
          Progress.

[RFC1122] Braden, R., "Requirements for Internet Hosts -
          Communication Layers", STD 3, RFC 1122, October 1989.

[RFC2582] Floyd, S. and T. Henderson, "The NewReno Modification to
          TCP's Fast Recovery Algorithm", RFC 2582, April 1999.

[Gu01]    Gurtov, A., "Effect of Delays on TCP Performance", In
          Proceedings of IFIP Personal Wireless Communications,
          August 2001.

[RFC3481] Inamura, H., Montenegro, G., Ludwig, R., Gurtov, A. and F.
          Khafizov, "TCP over Second (2.5G) and Third (3G) Generation
          Wireless Networks", RFC 3481, February 2003.

[Jac88]   Jacobson, V., "Congestion Avoidance and Control", In
          Proceedings of ACM SIGCOMM 88.

[KP87]    Karn, P. and C. Partridge, "Improving Round-Trip Time
          Estimates in Reliable Transport Protocols", In Proceedings
          of ACM SIGCOMM 87.

[LK00]    Ludwig, R. and R. H. Katz, "The Eifel Algorithm: Making TCP
          Robust Against Spurious Retransmissions", ACM Computer
          Communication Review, Vol. 30, No. 1, January 2000.

[LG03]    Ludwig, R. and A. Gurtov, "The Eifel Response Algorithm for
          TCP", Work in Progress.

[RFC2988] Paxson, V. and M. Allman, "Computing TCP's Retransmission
          Timer", RFC 2988, November 2000.

[RFC791]  Postel, J., "Internet Protocol", STD 5, RFC 791, September
          1981.

[RFC3168] Ramakrishnan, K., Floyd, S. and D. Black, "The Addition of
          Explicit Congestion Notification (ECN) to IP", RFC 3168,
          September 2001.

[SK03]    Sarolahti, P. and M. Kojo, "F-RTO: A TCP RTO Recovery
          Algorithm for Avoiding Unnecessary Retransmissions", Work
          in Progress.

[WS95]    Wright, G. R. and W. R. Stevens, "TCP/IP Illustrated,
          Volume 2 (The Implementation)", Addison Wesley, January
          1995.

[Zh86]    Zhang, L., "Why TCP Timers Don't Work Well", In Proceedings
          of ACM SIGCOMM 86.

Authors' Addresses πŸ’Œ

Reiner Ludwig
Ericsson Research
Ericsson Allee 1
52134 Herzogenrath, Germany

EMail: Reiner.Ludwig@eed.ericsson.se


Michael Meyer
Ericsson Research
Ericsson Allee 1
52134 Herzogenrath, Germany

EMail: Michael.Meyer@eed.ericsson.se

legal text, so it stays word for word 🫢

Copyright (C) The Internet Society (2003).  All Rights Reserved.

This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works.  However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.

The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement ✨

Funding for the RFC Editor function is currently provided by the Internet Society. πŸŒˆπŸ’œ

πŸ“¦ where this page comes from