NetSim Source Code Help
Loading...
Searching...
No Matches
RTO.c
Go to the documentation of this file.
1/************************************************************************************
2* Copyright (C) 2022 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* This source code is licensed per the NetSim license agreement. *
12* *
13* No portion of this source code may be used as the basis for a derivative work, *
14* or used, for any purpose other than its intended use per the NetSim license *
15* agreement. *
16* *
17* This source code and the algorithms contained within it are confidential trade *
18* secrets of TETCOS and may not be used as the basis for any other software, *
19* hardware, product or service. *
20* *
21* Author: Shashi Kant Suman *
22* *
23* ----------------------------------------------------------------------------------*/
24#include "main.h"
25#include "TCP.h"
26#include "TCP_Enum.h"
27#include "TCP_Header.h"
28
29//RFC 6298
30#define alpha (1/8.0)
31#define beta (1/4.0)
32#define G (0.5*SECOND) /* Min RTO value is set to 0.5 s.
33 * The RFC states this should be 1 s
34 * Linux seems to be currently using 200 ms.
35 */
36#define K (4)
37
38double calculate_RTO(double R,
39 double* srtt,
40 double* rtt_var)
41{
42 double rto;
43 if (!R) //2.1
44 rto = 1 * SECOND;
45 else if (!*srtt) //2.2
46 {
47 *srtt = R;
48 *rtt_var = R / 2.0;
49 rto = *srtt + max(G, K*(*rtt_var));
50 }
51 else //2.3
52 {
53 *rtt_var = (1 - beta) * (*rtt_var) + beta * fabs(*srtt - R);
54 *srtt = (1 - alpha) * (*srtt) + alpha * R;
55 rto = *srtt + max(G, K*(*rtt_var));
56 }
57 return min(max(rto, G), (60 * SECOND)); //2.4 and 2.5
58}
59
60static void Backoff_RTO(double* rto)
61{
62 *rto = min(max((*rto*2), G), (60 * SECOND));
63 print_tcp_log("New RTO = %0.2lf", *rto);
64}
65
67 NetSim_PACKET* packet)
68{
71 if (s->tcb->isRTOTimerRunning) return;
72 s->tcb->isRTOTimerRunning = true;
74 memcpy(&pevent, pstruEventDetails, sizeof pevent);
75 pevent.dEventTime += TCP_RTO(s->tcb);
77 pevent.nEventType = TIMER_EVENT;
78 pevent.nPacketId = packet->nPacketId;
79 if (packet->pstruAppData)
80 {
82 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
83 }
84 else
85 pevent.nSegmentId = 0;
88 pevent.szOtherDetails = NULL;
89 pevent.nSubEventType = TCP_RTO_TIMEOUT;
90 s->tcb->RTOEventId = fnpAddEvent(&pevent);
91 s->tcb->eventPacketptr = pevent.pPacket;
92 print_tcp_log("Adding RTO Timer at %0.1lf", pevent.dEventTime);
93}
94
96{
98 resend_syn(s);
99 else
100 fnNetSimError("Unknown packet %d arrives at %s\n",
102 __FUNCTION__);
103}
104void handle_rto_timer()
105{
107 if (!s)
108 {
109 //Socket is already close. Ignore this event
111 return;
112 }
113 if (!s->tcb || s->tcb->isOtherTimerCancel)
114 {
116 return;
117 }
118
119 s->tcb->isRTOTimerRunning = false;
120 bool isPresent = isAnySegmentInQueue(&s->tcb->retransmissionQueue);
121
122 if (isPresent)
123 {
125
126 print_tcp_log("\nDevice %d, Time %0.2lf: RTO Time expire.",
129
131
132 Backoff_RTO(&TCP_RTO(s->tcb));
133
134 if (isTCPControl(segment))
135 {
137 }
138 else
139 {
140 //Call congestion algorithm
141 s->tcb->rto_expired(s);
142
143 resend_segment(s, segment);
144 }
145
147 }
148 else
149 {
150 //Ignore this event
151 }
153}
154
156{
159 s->tcb->eventPacketptr = NULL;
160 s->tcb->isRTOTimerRunning = false;
161
162 bool isPresent = isAnySegmentInQueue(&s->tcb->retransmissionQueue);
163 if (isPresent)
164 {
165 s->tcb->isRTOTimerRunning = true;
167 NetSim_EVENTDETAILS pevent;
168 memcpy(&pevent, pstruEventDetails, sizeof pevent);
169 pevent.dEventTime += TCP_RTO(s->tcb);
170 pevent.dPacketSize = segment->pstruTransportData->dPacketSize;
171 pevent.nEventType = TIMER_EVENT;
172 pevent.nPacketId = segment->nPacketId;
173 if (segment->pstruAppData)
174 {
175 pevent.nApplicationId = segment->pstruAppData->nApplicationId;
176 pevent.nSegmentId = segment->pstruAppData->nSegmentId;
177 }
178 else
179 pevent.nSegmentId = 0;
181 pevent.pPacket = segment;
182 pevent.szOtherDetails = NULL;
183 pevent.nSubEventType = TCP_RTO_TIMEOUT;
184 s->tcb->RTOEventId = fnpAddEvent(&pevent);
185 s->tcb->eventPacketptr = segment;
186 print_tcp_log("Adding RTO Timer at %0.1lf", pevent.dEventTime);
187 }
188}
#define fnNetSimError(x,...)
Definition: Linux.h:56
#define min(a, b)
Definition: Linux.h:106
#define max(a, b)
Definition: Linux.h:107
#define beta
Definition: RTO.c:31
static void handle_rto_timer_for_ctrl(PNETSIM_SOCKET s)
Definition: RTO.c:92
static void Backoff_RTO(double *rto)
Definition: RTO.c:57
double calculate_RTO(double R, double *srtt, double *rtt_var)
Definition: RTO.c:35
#define K
Definition: RTO.c:33
#define alpha
Definition: RTO.c:30
void handle_rto_timer()
Definition: RTO.c:101
void add_timeout_event(PNETSIM_SOCKET s, NetSim_PACKET *packet)
Definition: RTO.c:63
void restart_rto_timer(PNETSIM_SOCKET s)
Definition: RTO.c:152
#define G
Definition: RTO.c:32
@ TX_PROTOCOL_TCP
Definition: Stack.h:180
#define SECOND
Definition: Stack.h:60
@ TIMER_EVENT
Definition: Stack.h:114
int fnDeleteEvent(unsigned long long int nEventId)
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
bool isAnySegmentInQueue(PTCP_QUEUE queue)
Definition: TCB.c:348
NetSim_PACKET * get_earliest_copy_segment_from_queue(PTCP_QUEUE queue)
Definition: TCB.c:273
void add_packet_to_queue(PTCP_QUEUE queue, NetSim_PACKET *packet, double time)
Definition: TCB.c:164
#define TCP_RTO(tcb)
Definition: TCB.h:118
void resend_syn(PNETSIM_SOCKET s)
void print_tcp_log(char *format,...)
#define isTCPControl(p)
Definition: TCP.h:48
bool isSynbitSet(NetSim_PACKET *packet)
Definition: TCP_Packet.c:38
void resend_segment(PNETSIM_SOCKET s, NetSim_PACKET *expired)
Definition: TCP_Outgoing.c:64
PNETSIM_SOCKET find_socket_at_source(NetSim_PACKET *packet)
Definition: TCP_Socket.c:155
#define fn_NetSim_Packet_CopyPacket(pstruPacket)
Definition: main.h:182
#define fn_NetSim_Packet_FreePacket(pstruPacket)
Definition: main.h:177
#define fnpAddEvent(pstruEvent)
Definition: main.h:191
NETSIM_ID nApplicationId
Definition: Stack.h:752
EVENT_TYPE nEventType
Definition: Stack.h:747
NETSIM_ID nProtocolId
Definition: Stack.h:748
struct stru_NetSim_Packet * pPacket
Definition: Stack.h:754
NETSIM_ID nSubEventType
Definition: Stack.h:757
NETSIM_ID nDeviceId
Definition: Stack.h:750
long long int nPacketId
Definition: Stack.h:755
long long int nPacketId
Definition: Packet.h:256
struct stru_NetSim_Packet_AppLayer * pstruAppData
Definition: Packet.h:273
unsigned int nControlDataType
Definition: Packet.h:258
struct stru_NetSim_Packet_TransportLayer * pstruTransportData
Definition: Packet.h:274
PTCB tcb
Definition: TCP.h:132
PTCP_METRICS tcpMetrics
Definition: TCP.h:140
NetSim_PACKET * eventPacketptr
Definition: TCB.h:123
void(* rto_expired)(PNETSIM_SOCKET)
Definition: TCB.h:133
UINT timesRTOExpired
Definition: TCP.h:103