NS-2上的TCP RTO指數倒退機制

觀察NS-2的tcp原始碼,發現其中關於RTO指數倒退機制(rto backoff mechanism)的定義可區分遵循RFC2988和不遵循RFC2988兩部份。不過即使如此,與認知中仍有些出入,因此特別作個紀錄。

先提一下RFC2988的兩條重要敘述:
(2.4) Whenever RTO is computed, if it is less than 1 second then the RTO SHOULD be rounded up to 1 second.
(2.5) A maximum value MAY be placed on RTO provided it is at least 60 seconds.
簡單說,就是規範了RTO的範圍,最小不可低於1秒,最大不可低於60秒。
接著放上NS-2裡面tcp.cc的相關原始碼。首先是rtt_backoff():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void TcpAgent::rtt_backoff()
{
	if (t_backoff_ < 64 || rfc2988_) 
        	t_backoff_ <<= 1;
        // RFC2988 allows a maximum for the backed-off RTO of 60 seconds.
        // This is applied by maxrto_.

	if (t_backoff_ > 8) {
		/*
		 * If backed off this far, clobber the srtt
		 * value, storing it in the mean deviation
		 * instead.
		 */
		t_rttvar_ += (t_srtt_ >> T_SRTT_BITS);
		t_srtt_ = 0;
	}
}


此函式的定義有些奇怪,理論上若遵循RFC2988,那麼RTO值的上限值應該設定在60秒以上,若不遵循,則RTO值上限可隨意定義(低於60秒?)。
但實際上,此函式卻是若遵循RFC2988則RTO值無上限;若否,則RTO以64為限。
然後是rtt_timeout():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
double TcpAgent::rtt_timeout()
{
	double timeout;
	if (rfc2988_) {
	// Correction from Tom Kelly to be RFC2988-compliant, by
	// clamping minrto_ before applying t_backoff_.
		if (t_rtxcur_ < minrto_ && !use_rtt_)
			timeout = minrto_ * t_backoff_;
		else
			timeout = t_rtxcur_ * t_backoff_;
	} else {
		// only of interest for backwards compatibility
		timeout = t_rtxcur_ * t_backoff_;
		if (timeout < minrto_)
			timeout = minrto_;
	}

	if (timeout > maxrto_)
		timeout = maxrto_;

        if (timeout < 2.0 * tcp_tick_) {
		if (timeout < 0) {
			fprintf(stderr, "TcpAgent: negative RTO!  (%f)\n",
				timeout);
			exit(1);
		} else if (use_rtt_ && timeout < tcp_tick_)
			timeout = tcp_tick_;
		else
			timeout = 2.0 * tcp_tick_;
	}
	use_rtt_ = 0;
	return (timeout);
}
在這個函式中,可以看到針對RFC2988特別作規範,若遵循RFC2988,則會定義RTO最小值(minrto_,原則上應該設定為1秒),並檢查當前的RTO值(t_rtxcur_)是否低於最小值,若是,便在往後運算過程中以最小值取代。



No response to “NS-2上的TCP RTO指數倒退機制” ;

張貼留言