* Cleanup the code computing the retransmission timeout.
* Fix an initialization bug for the scaled variance of the RTO. MFC after: 3 months.
This commit is contained in:
parent
d4e6572128
commit
d11e62523e
@ -245,7 +245,7 @@ struct sctp_nets {
|
||||
/* smoothed average things for RTT and RTO itself */
|
||||
int lastsa;
|
||||
int lastsv;
|
||||
int rtt; /* last measured rtt value in ms */
|
||||
uint64_t rtt; /* last measured rtt value in us */
|
||||
unsigned int RTO;
|
||||
|
||||
/* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */
|
||||
@ -254,6 +254,10 @@ struct sctp_nets {
|
||||
|
||||
/* last time in seconds I sent to it */
|
||||
struct timeval last_sent_time;
|
||||
|
||||
/* JRS - struct used in HTCP algorithm */
|
||||
struct htcp htcp_ca;
|
||||
|
||||
int ref_count;
|
||||
|
||||
/* Congestion stats per destination */
|
||||
@ -267,7 +271,6 @@ struct sctp_nets {
|
||||
uint32_t ecn_prev_cwnd; /* ECN prev cwnd at first ecn_echo seen in new
|
||||
* window */
|
||||
uint32_t partial_bytes_acked; /* in CA tracks when to incr a MTU */
|
||||
uint32_t prev_rtt;
|
||||
/* tracking variables to avoid the aloc/free in sack processing */
|
||||
unsigned int net_ack;
|
||||
unsigned int net_ack2;
|
||||
@ -298,7 +301,6 @@ struct sctp_nets {
|
||||
uint32_t tos_flowlabel;
|
||||
|
||||
struct timeval start_time; /* time when this net was created */
|
||||
struct timeval last_measured_rtt;
|
||||
uint32_t marked_retrans;/* number or DATA chunks marked for timer
|
||||
* based retransmissions */
|
||||
uint32_t marked_fastretrans;
|
||||
@ -348,8 +350,6 @@ struct sctp_nets {
|
||||
uint8_t RTO_measured; /* Have we done the first measure */
|
||||
uint8_t last_hs_used; /* index into the last HS table entry we used */
|
||||
uint8_t lan_type;
|
||||
/* JRS - struct used in HTCP algorithm */
|
||||
struct htcp htcp_ca;
|
||||
uint32_t flowid;
|
||||
#ifdef INVARIANTS
|
||||
uint8_t flowidset;
|
||||
|
@ -477,7 +477,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
|
||||
xraddr.cwnd = net->cwnd;
|
||||
xraddr.flight_size = net->flight_size;
|
||||
xraddr.mtu = net->mtu;
|
||||
xraddr.rtt = net->rtt;
|
||||
xraddr.rtt = net->rtt / 1000;
|
||||
xraddr.start_time.tv_sec = (uint32_t) net->start_time.tv_sec;
|
||||
xraddr.start_time.tv_usec = (uint32_t) net->start_time.tv_usec;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
|
@ -113,7 +113,7 @@ rto_logging(struct sctp_nets *net, int from)
|
||||
|
||||
memset(&sctp_clog, 0, sizeof(sctp_clog));
|
||||
sctp_clog.x.rto.net = (void *)net;
|
||||
sctp_clog.x.rto.rtt = net->prev_rtt;
|
||||
sctp_clog.x.rto.rtt = net->rtt / 1000;
|
||||
SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
|
||||
SCTP_LOG_EVENT_RTT,
|
||||
from,
|
||||
@ -2475,9 +2475,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
|
||||
* given an association and the starting time of the current RTT
|
||||
* period (in value1/value2) return RTO in number of msecs.
|
||||
*/
|
||||
int calc_time = 0;
|
||||
int o_calctime;
|
||||
uint32_t new_rto = 0;
|
||||
int32_t rtt; /* RTT in ms */
|
||||
uint32_t new_rto;
|
||||
int first_measure = 0;
|
||||
struct timeval now, then, *old;
|
||||
|
||||
@ -2497,95 +2496,58 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
|
||||
/************************/
|
||||
/* get the current time */
|
||||
(void)SCTP_GETTIME_TIMEVAL(&now);
|
||||
/*
|
||||
* Record the real time of the last RTT for use in DC-CC.
|
||||
*/
|
||||
net->last_measured_rtt = now;
|
||||
timevalsub(&net->last_measured_rtt, old);
|
||||
timevalsub(&now, old);
|
||||
/* store the current RTT in us */
|
||||
net->rtt = (uint64_t) 10000000 *(uint64_t) now.tv_sec +
|
||||
(uint64_t) now.tv_usec;
|
||||
|
||||
/* computer rtt in ms */
|
||||
rtt = net->rtt / 1000;
|
||||
|
||||
/* Do we need to determine the lan type? */
|
||||
if ((local_lan_determine == SCTP_DETERMINE_LL_OK) && (net->lan_type == SCTP_LAN_UNKNOWN)) {
|
||||
if ((net->last_measured_rtt.tv_sec) ||
|
||||
(net->last_measured_rtt.tv_usec > SCTP_LOCAL_LAN_RTT)) {
|
||||
if ((local_lan_determine == SCTP_DETERMINE_LL_OK) &&
|
||||
(net->lan_type == SCTP_LAN_UNKNOWN)) {
|
||||
if (net->rtt > SCTP_LOCAL_LAN_RTT) {
|
||||
net->lan_type = SCTP_LAN_INTERNET;
|
||||
} else {
|
||||
net->lan_type = SCTP_LAN_LOCAL;
|
||||
}
|
||||
}
|
||||
/* compute the RTT value */
|
||||
if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
|
||||
calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
|
||||
if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
|
||||
calc_time += (((u_long)now.tv_usec -
|
||||
(u_long)old->tv_usec) / 1000);
|
||||
} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
|
||||
/* Borrow 1,000ms from current calculation */
|
||||
calc_time -= 1000;
|
||||
/* Add in the slop over */
|
||||
calc_time += ((int)now.tv_usec / 1000);
|
||||
/* Add in the pre-second ms's */
|
||||
calc_time += (((int)1000000 - (int)old->tv_usec) / 1000);
|
||||
}
|
||||
} else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
|
||||
if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
|
||||
calc_time = ((u_long)now.tv_usec -
|
||||
(u_long)old->tv_usec) / 1000;
|
||||
} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
|
||||
/* impossible .. garbage in nothing out */
|
||||
goto calc_rto;
|
||||
} else if ((u_long)now.tv_usec == (u_long)old->tv_usec) {
|
||||
/*
|
||||
* We have to have 1 usec :-D this must be the
|
||||
* loopback.
|
||||
*/
|
||||
calc_time = 1;
|
||||
} else {
|
||||
/* impossible .. garbage in nothing out */
|
||||
goto calc_rto;
|
||||
}
|
||||
} else {
|
||||
/* Clock wrapped? */
|
||||
goto calc_rto;
|
||||
}
|
||||
/***************************/
|
||||
/* 2. update RTTVAR & SRTT */
|
||||
/***************************/
|
||||
net->rtt = o_calctime = calc_time;
|
||||
/* this is Van Jacobson's integer version */
|
||||
/*-
|
||||
* Compute the scaled average lastsa and the
|
||||
* scaled variance lastsv as described in van Jacobson
|
||||
* Paper "Congestion Avoidance and Control", Annex A.
|
||||
*
|
||||
* (net->lastsa >> SCTP_RTT_SHIFT) is the srtt
|
||||
* (net->lastsa >> SCTP_RTT_VAR_SHIFT) is the rttvar
|
||||
*/
|
||||
if (net->RTO_measured) {
|
||||
calc_time -= (net->lastsa >> SCTP_RTT_SHIFT); /* take away 1/8th when
|
||||
* shift=3 */
|
||||
rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
|
||||
net->lastsa += rtt;
|
||||
if (rtt < 0) {
|
||||
rtt = -rtt;
|
||||
}
|
||||
rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);
|
||||
net->lastsv += rtt;
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
|
||||
rto_logging(net, SCTP_LOG_RTTVAR);
|
||||
}
|
||||
net->prev_rtt = o_calctime;
|
||||
net->lastsa += calc_time; /* add 7/8th into sa when
|
||||
* shift=3 */
|
||||
if (calc_time < 0) {
|
||||
calc_time = -calc_time;
|
||||
}
|
||||
calc_time -= (net->lastsv >> SCTP_RTT_VAR_SHIFT); /* take away 1/4 when
|
||||
* VAR shift=2 */
|
||||
net->lastsv += calc_time;
|
||||
if (net->lastsv == 0) {
|
||||
net->lastsv = SCTP_CLOCK_GRANULARITY;
|
||||
}
|
||||
} else {
|
||||
/* First RTO measurment */
|
||||
net->RTO_measured = 1;
|
||||
net->lastsa = calc_time << SCTP_RTT_SHIFT; /* Multiply by 8 when
|
||||
* shift=3 */
|
||||
net->lastsv = calc_time;
|
||||
if (net->lastsv == 0) {
|
||||
net->lastsv = SCTP_CLOCK_GRANULARITY;
|
||||
}
|
||||
first_measure = 1;
|
||||
net->prev_rtt = o_calctime;
|
||||
net->lastsa = rtt << SCTP_RTT_SHIFT;
|
||||
net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT;
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
|
||||
rto_logging(net, SCTP_LOG_INITIAL_RTT);
|
||||
}
|
||||
}
|
||||
calc_rto:
|
||||
if (net->lastsv == 0) {
|
||||
net->lastsv = SCTP_CLOCK_GRANULARITY;
|
||||
}
|
||||
new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
|
||||
if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
|
||||
(stcb->asoc.sat_network_lockout == 0)) {
|
||||
|
Loading…
Reference in New Issue
Block a user