does TCP randomly select a time from an interval to decide when a timeout has occured? - networking

In TCP how is the time for a time out to happen determined? I was told it is randomly selected from an interval that doubles after each time out, but nothing I found on Google mentions anything about random selection and instead says it's calculated used Smoothed Round Trip Time after the first acknowledgment is received. Does it do this for each packet or is there some randomness to the design?

An initial value of the RTT is calculated during the TCP 3-way handshake that starts a connection. It is updated thereafter when qualifying send/acks are seen.
Most modern implementations don't use this method directly but rather using a statistical analysis of the maximum time it should take to get an ACK and retransmit after that interval. The "exponential backoff" (the doubling of the wait interval) happens for further retransmissions of the same data.
A connection "times out" after some number of transmissions with no ACK being received.

Related

Why isn't cwnd restricted by rwnd in a TCP connection?

I'm trying to understand how TCP works and I'm a bit surprised by the (absence of) effect of the receiver window (rwnd) on the congestion window (cwnd).
From what I've read (mainly wikipedia and RFC5681) I understand that if the slow start threshold (ssthresh) has not been reached but the transmission rate is restricted by rwnd (since it is the minimum value between rwnd and cwnd) then cwnd continues to increase during the slow start phase (and even during congestion avoidance) if there are no loss or timeout. Meaning that cwnd could potentially reach a very high value since the initial value of ssthresh is extremely big.
See the following citation to confirm my deduction :
Implementation Note: An easy mistake to make is to simply use cwnd,
rather than FlightSize, which in some implementations may
incidentally increase well beyond rwnd.
[from RFC5681 (this part of the RFC is about setting a new value for ssthresh after a loss)]
In this case wouldn't it be possible to :
keep a connection with a relatively low transmission rate (e.g. setting rwnd to 10mss in every ack) to have no loss and hence keep the connection in the slow start phase,
wait enough time to allow cwnd to be extremely big (like 10 times what the link can handle) and then
set rwnd to an even bigger value to let the transmission rate be restricted only by cwnd ?
This would lead to a massive amount of congestion on the link, especially since it will take quite a lot of time for the server to notice the loss with a timeout and reset cwnd back to its initial value... and this may have a huge impact on other connections using the same link, or at least the same bottleneck link.
I would have imagined that once rcwnd is reached, slow start algorithm stops and congestion avoidance would begin to react to any new change in the network (or an increase in rwnd).
According to https://stackoverflow.com/a/21775731/20003316, Linux implementation of TCP does not allow cwnd to increase when the sending rate is application-controlled (= sending rate is controlled by rwnd and not cwnd).
By looking more in depth into this, I've found that in fact there is an RFC handling this question : https://www.rfc-editor.org/rfc/rfc7661#page-10
When in slow start :
if the number of ACK in the current window is smaller than 0.5*cwnd, then a TCP implementation must not increase the value of cwnd.
if the number of ACK in the current window is greater or equal than 0.5*cwnd, then a TCP implementation must increase the value of cwnd as it would normally do.
When not in slow start:
if the sending rate is restricted by rwnd and not cwnd and the number of ACK in the current window is smaller than 0.5*cwnd, then a TCP implementation must not increase cwnd.
otherwise proceed as usual

Understanding TCP Slow Start

I was trying to get my head around tcp congestion control and came across what is called the slow start phase, where tcp starts by sending just 1 MSS and then keep on adding 1 MSS to the congestion window on receipt of an ack. This much is clear. But after this, almost all books/articles that i refers goes ahead a say that this results in doubling the cwnd every RTT showing a image something like below where i got confused.
The first segment is clear, tcp sends it and receives the ack after a RTT and then doubles the cwnd which now is 2. Now it transmits two segments, the ack for the fist one comes after RTT making the cwnd 3. But the ack for the second segment comes after this making cwnd 4(ie doubling it). So i am not able to understand how the cwnd doubles every RTT, since as per my understanding, in this example, cwnd doubled on the first RTT and got incremented by one on the second RTT and again doubled on some other time(RTT+tx time of the first segment i believe). Is this understanding correct. Please explain.
After the two segments' acks had been received by the sender, the CWND was increased by 2, not 1. Note that the second ack in round 2 arrived right after the first ack in round 2, that's why they were considered in the same round and costed 1 RTT.
I can not agree with you more. I think there is not exist a double mechanism and they get the wrong meaning for the Slow Start.
When the server receives the ACK, the cwnd will increase the value of 1 MSS. So if you send n requests and receive all the ACK, cwnd will become (n + n) MSS.
In the process of Slow Start, the requests can be done in 1 RTT, because it is not easy to happend traffic jam in the Internet. So it looks like it become double per RTT. But, the real mechanism is to add, not multiply.

What is the difference between the delay and the jitter in the context of real time applications?

According to Wikipedia Jitter is the undesired deviation from true periodicity of an assumed periodic signal, according to a papper on QoS that I am reading jitter is reffered to as delay variation. Are there any definition of the jitter in the context of real time applications? Are there applications that are sensitive to jitter but not sensitive to delay? If for example a streaming application use some kind of buffer to store packets before show them to the user, is it possible that this application is not sensitive to delay but is sensitive to jitter?
Delay: Is the amount of time data(signal) takes to reach the destination. Now a higher delay generally means congestion of some sort of breaking of the communication link.
Jitter: Is the variation of delay time. This happens when a system is not in deterministic state eg. Video Streaming suffers from jitter a lot because the size of data transferred is quite large and hence no way of saying how long it might take to transfer.
If your application is sensitive to jitter it is definitely sensitive to delay.
In Real-time Protocol (RTP, RFC3550), a header contains a timestamp field. The value of it usually comes from a monotonically incremented counter and the frequency of the increment is the clock-rate. This clock-rate must be the same all over the participant wants something with the timestamp field. The counters have different base offsets, because the start time may different or they contains it because of security reason, etc... All in all we say the clocks are not syncronized.
To show it in an example consider if we refer to snd_timestamp and rcv_timestamp the most recent packet sender timestamp from the RTP header field and receiver timestamp generated by the receiver using the same clock-rate.
The wrong conclusion is that
delay_in_timestamp_unit = rcv_timestamp - snd_timestamp
If the receiver and sender clock-rate has different base offset (and they have), this not gives you the delay, also it doesn't consider the wrap around the 32bit unsigned integer.
But monitoring the time for delivering packets is somehow necessary if we want a proper playout adaption algorithm or if we want to detect and avoid congestions.
Also note that if we have syncronized clocks delay_in_timestamp_unit might be not punctually represent the pure network delay, because of components at the sender or at the receiver side retaining these packets after and/or before the timestamp added and/or exemined. So if you calculate a 2seconds delay between the participant, but you know your network delay is around 100ms, then your packets suffer additional delays at the sender or/and at the receiver side. But that additional delay is somehow (or at least you hope that it is) constant, so the only delay changes in time is - hopefully - the network delay. So you should not say that if packet delay > 500ms then we have a congestion, because you have no idea what is the actual network delay if you use only one packet sender and receiver timestamp information.
But the difference between the delays of two consecutive packets might gives you some information about weather something wrong in the network or not.
diff_delay = delay_t0 - delay_t1
if diff_delay equals to 0 the delay is the same, if it greater than 0 the newly arrived packets needed more time then the previous one, and if it smaller than 0 it needed less time.
And from that relative information based on two consecutive delays you could say something.
How you determine the difference between two delay if the clocks are not syncronized?
Consider you stored the last timestamps in rcv_timestamp_t1 and snd_timestamp_t1
diff_delay = (rcv_timestamp_t0 - snd_timestamp_t0) - (rcv_timestamp_t1 - snd_timestamp_t1)
but that would be problem without maintaining the base offsets of the sender and the receiver, so reordering it:
diff_delay = (rcv_timestamp_t0 - rcv_timestamp_t1) - (snd_timestamp_t0 - snd_timestamp_t1)
and here you can subtract rcv timestamps from each other and it eliminates the offset rcv and snd contain, and then you can extract the rcv_diff from snd_diff and it gives you the information about the difference of the delays of two consecutive packets in the unit of the clock-rate.
Now, according to RFC3550 jitter is "An estimate of the statistical variance of the RTP data packet interarrival time".
In order to finally get to the point your question is
"What is the difference between the delay and the jitter in the context of real time applications?"
Tiny note, but real-time applications usually refer to systems processing data in a range of nanoseconds, so I think you refer to end-to-end systems.
Also despite of several altered definition of jitter, it all uses the difference of the delays of arrived packets and thus provide you information about the relative changes of the network delay, meanwhile delay itself is an absolute value of the time of delivery.

Bandwidth estimation with multiple TCP connections

I have a client which issues parallel requests for data from a server. Each request uses a separate TCP connection. I would like to estimate the available throughput (bandwidth) based on the received data.
I know that for one connection TCP connection I can do so by dividing the amount of data the has been download by the duration of time it took to download the data. But given that there are multiple concurrent connections, would it be correct to sum up all the data that has been downloaded by the connections and divide the sum by the duration between sending the first request and the arrival time of the last byte (i.e., the last byte of the download that finishes last)? Or am I overlooking something here?
[This is a rewrite of my previous answer, which was getting too messy]
There are two components that we want to measure in order to calculate throughput: the total number of bytes transferred, and the total amount of time it took to transfer those bytes. Once we have those two figures, we just divide the byte-count by the duration to get the throughput (in bytes-per-second).
Calculating the number of bytes transferred is trivial; just have each TCP connection tally the number of bytes it transferred, and at the end of the sequence, we add up all of the tallies into a single sum.
Calculating the amount of time it takes for a single TCP connection to do its transfer is likewise trivial: just record the time (t0) at which the TCP connection received its first byte, and the time (t1) at which it received its last byte, and that connection's duration is (t1-t0).
Calculating the amount of time it takes for the aggregate process to complete, OTOH, is not so obvious, because there is no guarantee that all of the TCP connections will start and stop at the same time, or even that their download-periods will intersect at all. For example, imagine a scenario where there are five TCP connections, and the first four of them start immediately and finish within one second, while the final TCP connection drops some packets during its handshake, and so it doesn't start downloading until 5 seconds later, and it also finishes one second after it starts. In that scenario, do we say that the aggregate download process's duration was 6 seconds, or 2 seconds, or ???
If we're willing to count the "dead time" where no downloads were active (i.e. the time between t=1 and t=5 above) as part of the aggregate-duration, then calculating the aggregate-duration is easy: Just subtract the smallest t0 value from the largest t1 value. (this would yield an aggregate duration of 6 seconds in the example above). This may not be what we want though, because a single delayed download could drastically reduce the reported bandwidth estimate.
A possibly more accurate way to do it would be say that the aggregate duration should only include time periods when at least one TCP download was active; that way the result does not include any dead time, and is thus perhaps a better reflection of the actual bandwidth of the network path.
To do that, we need to capture the start-times (t0s) and end-times (t1s) of all TCP downloads as a list of time-intervals, and then merge any overlapping time-intervals as shown in the sketch below. We can then add up the durations of the merged time-intervals to get the aggregate duration.
You need to do a weighted average. Let B(n) be the bytes processed for connection 'n' and T(n) be the time required to process those bytes. The total throughput is:
double throughput=0;
for (int n=0; n<Nmax; ++n)
{
throughput += B(n) / T(n);
}
throughtput /= Nmax;

How does iperf calculate throughput and jitter?

I've read that Iperf basically tries to send as much information down a connection as quickly as possible reporting on the throughput achieved. This tool is especially useful in determining the volume of data that links between two machines can supply.
Is it possible to gather the same results by sending regular data, as in not testing data?
What I'm trying to do is sending data in the foreground while gathering statistics in the background (throughput and jitter).
How iperf calculates these two values?
This is the closest thing I've found
http://openmaniak.com/iperf.php
I have the similar question about how iperf works. Please refer to the following post where I did some research and gave an overview.
How iperf calculates network statistics
Generally, in iperf, it embedded timestamps and sequence number in the payload in the sender side. When receiver receives the packet, it extracts these content and calculates the statistics. You can find more detail in the post.
Throughput is simple: assuming the client is saturating the network, the server only needs to count the received bytes, and divide that by some duration.
This post explains this topic in a greater detail.
Iperf 2 calculates Jitter for UDP only. It is based on what is prescribed within by RTP implementation, as stated by the code.
RTP is used in implementations of audio streaming, where jitter plays a major role, so it's a good place to take the algorithm from - what Iperf reports is what many applications where you would be interested in jitter would see.
See RFC 1889, section 6.3.1, "interarrival jitter" field:
The interarrival jitter J is defined to be the mean deviation (smoothed
absolute value) of the difference D in packet spacing at the receiver compared
to the sender for a pair of packets. As shown in the equation below, this is
equivalent to the difference in the "relative transit time" for the two
packets; the relative transit time is the difference between a packet's RTP
timestamp and the receiver's clock at the time of arrival, measured in the same
units.
If Si is the RTP timestamp from packet i, and Ri is the time of arrival in RTP
timestamp units for packet i, then for two packets i and j, D may be expressed
as
D(i,j)=(Rj-Ri)-(Sj-Si)=(Rj-Sj)-(Ri-Si)
The interarrival jitter is calculated continuously as each data packet i is
received from source SSRC_n, using this difference D for that packet and the
previous packet i-1 in order of arrival (not necessarily in sequence),
according to the formula
J=J+(|D(i-1,i)|-J)/16

Resources