-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathrtt.c
executable file
·121 lines (95 loc) · 2.91 KB
/
rtt.c
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* include rtt1 */
#include "unprtt.h"
int rtt_d_flag = 0; /* debug flag; can be set by caller */
/*
* Calculate the RTO value based on current estimators:
* smoothed RTT plus four times the deviation
*/
#define RTT_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar))
static int rtt_minmax(int rto){
if (rto < RTT_RXTMIN)
rto = RTT_RXTMIN;
else if (rto > RTT_RXTMAX)
rto = RTT_RXTMAX;
return(rto);
}
void rtt_init(struct rtt_info *ptr){
struct timeval tv;
Gettimeofday(&tv, NULL);
ptr->rtt_base = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); /* # sec since 1/1/1970 at start */
ptr->rtt_rtt = 0;
ptr->rtt_srtt = 0;
ptr->rtt_rttvar = 750;
ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));
/* first RTO at (srtt + (4 * rttvar)) = 3 seconds */
}
/* end rtt1 */
/*
* Return the current timestamp.
* Our timestamps are 32-bit integers that count milliseconds since
* rtt_init() was called.
*/
/* include rtt_ts */
uint32_t rtt_ts(struct rtt_info *ptr){
uint32_t ts;
struct timeval tv;
Gettimeofday(&tv, NULL);
ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000);
return(ts);
}
void rtt_newpack(struct rtt_info *ptr){
ptr->rtt_nrexmt = 0;
}
int rtt_start(struct rtt_info *ptr){
return((int) (ptr->rtt_rto + 500)); /* round float to int */
/* 4return value can be used as: alarm(rtt_start(&foo)) */
}
/* end rtt_ts */
/*
* A response was received.
* Stop the timer and update the appropriate values in the structure
* based on this packet's RTT. We calculate the RTT, then update the
* estimators of the RTT and its mean deviation.
* This function should be called right after turning off the
* timer with alarm(0), or right after a timeout occurs.
*/
/* include rtt_stop */
void rtt_stop(struct rtt_info *ptr, uint32_t ms) {
int delta;
ptr->rtt_rtt = ms; /* measured RTT in seconds */
/*
* Update our estimators of RTT and mean deviation of RTT.
* See Jacobson's SIGCOMM '88 paper, Appendix A, for the details.
* We use floating point here for simplicity.
*/
delta = ptr->rtt_rtt - ptr->rtt_srtt;
ptr->rtt_srtt += delta >> 3; /* g = 1/8 */
if (delta < 0)
delta = -delta; /* |delta| */
ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) >> 2; /* h = 1/4 */
ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));
}
/* end rtt_stop */
/*
* A timeout has occurred.
* Return -1 if it's time to give up, else return 0.
*/
/* include rtt_timeout */
int rtt_timeout(struct rtt_info *ptr) {
ptr->rtt_rto << 1; /* next RTO */
ptr->rtt_rto = rtt_minmax(ptr->rtt_rto);
if (++ptr->rtt_nrexmt > RTT_MAXNREXMT)
return(-1); /* time to give up for this packet */
return(0);
}
/* end rtt_timeout */
/*
* Print debugging information on stderr, if the "rtt_d_flag" is nonzero.
*/
void rtt_debug(struct rtt_info *ptr) {
if (rtt_d_flag == 0)
return;
fprintf(stderr, "rtt = %d, srtt = %d, rttvar = %d, rto = %d\n",
ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttvar, ptr->rtt_rto);
fflush(stderr);
}