tcp_timer.h revision aa97dd1c
1/*
2 * Copyright (c) 2016  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef _TCP_TIMER_H_
17#define _TCP_TIMER_H_
18
19#include <tle_timer.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25/*
26 * internal defines.
27 * all RTO values are in ms.
28 */
29#define	TCP_RTO_MAX	60000U        /* RFC 6298 (2.5) */
30#define	TCP_RTO_MIN	1000U         /* RFC 6298 (2.4) */
31#define	TCP_RTO_2MSL	(2 * TCP_RTO_MAX)
32#define	TCP_RTO_DEFAULT	TCP_RTO_MIN   /* RFC 6298 (2.1)*/
33#define	TCP_RTO_GRANULARITY	100U
34
35
36static inline void
37timer_stop(struct tle_tcp_stream *s)
38{
39	struct tle_timer_wheel *tw;
40
41	if (s->timer.handle != NULL) {
42		tw = CTX_TCP_TMWHL(s->s.ctx);
43		tle_timer_stop(tw, s->timer.handle);
44		s->timer.handle = NULL;
45	}
46}
47
48static inline void
49timer_start(struct tle_tcp_stream *s)
50{
51	struct tle_timer_wheel *tw;
52
53	if (s->timer.handle == NULL) {
54		tw = CTX_TCP_TMWHL(s->s.ctx);
55		s->timer.handle = tle_timer_start(tw, s, s->tcb.snd.rto);
56		s->tcb.snd.nb_retx = 0;
57	}
58}
59
60static inline void
61timer_restart(struct tle_tcp_stream *s)
62{
63	struct tle_timer_wheel *tw;
64
65	tw = CTX_TCP_TMWHL(s->s.ctx);
66	s->timer.handle = tle_timer_start(tw, s, s->tcb.snd.rto);
67}
68
69
70/*
71 * reset number of retransmissions and restart RTO timer.
72 */
73static inline void
74timer_reset(struct tle_tcp_stream *s)
75{
76	timer_stop(s);
77	timer_start(s);
78}
79
80static inline uint32_t
81rto_roundup(uint32_t rto)
82{
83	rto = RTE_MAX(rto, TCP_RTO_MIN);
84	rto = RTE_MIN(rto, TCP_RTO_MAX);
85	return rto;
86}
87
88/*
89 * RFC6298: Computing TCP's Retransmission Timer
90 * RTTVAR <- (1 - beta) * RTTVAR + beta * |SRTT - R'|
91 * SRTT <- (1 - alpha) * SRTT + alpha * R'
92 * RTO <- SRTT + max (G, K*RTTVAR)
93 * the following computation is based on Jacobson'88 paper referenced
94 * in the RFC6298
95*/
96static inline void
97rto_estimate(struct tcb *tcb, int32_t rtt)
98{
99	uint32_t rto;
100
101	if (!rtt)
102		rtt = 1;
103	if (tcb->rcv.srtt) {
104		rtt -= (tcb->rcv.srtt >> 3); /* alpha = 1/8 */
105		tcb->rcv.srtt += rtt;
106
107		if (rtt < 0)
108			rtt = -rtt;
109		rtt -= (tcb->rcv.rttvar >> 2); /* beta = 1/4 */
110		tcb->rcv.rttvar += rtt;
111
112	} else {
113		tcb->rcv.srtt = rtt << 3;
114		tcb->rcv.rttvar = rtt << 1;
115	}
116
117	rto = (tcb->rcv.srtt >> 3) +
118		RTE_MAX(TCP_RTO_GRANULARITY, tcb->rcv.rttvar);
119	tcb->snd.rto = rto_roundup(rto);
120}
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif /* _TCP_TIMER_H_ */
127