NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
TCP.h
1/************************************************************************************
2* Copyright (C) 2023 *
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* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14
15#ifndef _NETSIM_TCP_H_
16#define _NETSIM_TCP_H_
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21 /* RFC List
22 * RFC 793 : TRANSMISSION CONTROL PROTOCOL
23 * RFC 1122 : Requirements for Internet Hosts -- Communication Layers
24 * RFC 5681 : TCP Congestion Control
25 * RFC 3390 : Increasing TCP's Initial Window
26 * RFC 6298 : Computing TCP's Retransmission Timer
27 * RFC 2018 : TCP Selective Acknowledgment Options
28 * RFC 6582 : The NewReno Modification to TCP's Fast Recovery Algorithm
29 * RFC 6675 : A Conservative Loss Recovery Algorithm Based on Selective Acknowledgment (SACK) for TCP
30 * RFC 7323 : TCP Extensions for High Performance
31 * RFC 8312 : CUBIC for Fast Long-Distance Network
32 * https://ieeexplore.ieee.org/document/1354672
33 * https://research.csc.ncsu.edu/netsrv/sites/default/files/hystart_techreport_2008.pdf
34 */
35
36//#define _TEST_TCP_ //Enable to test the TCP
37#ifdef _TEST_TCP_
38 static double dropProbability = 0.5;
39 static bool burstDrop = true;
40 static int burstDropSize = 10;
41 static bool isAckDrop = true;
42#endif
43
44#pragma comment (lib,"NetworkStack.lib")
45
46 //USEFUL MACRO
47#define isTCPConfigured(d) (DEVICE_TRXLayer(d) && DEVICE_TRXLayer(d)->isTCP)
48#define isTCPControl(p) (p->nControlDataType/100 == TX_PROTOCOL_TCP)
49
50 //Constant
51#define TCP_DupThresh 3
52
53 //Typedef
54 typedef struct stru_TCP_Socket NETSIM_SOCKET, *PNETSIM_SOCKET;
55
56 typedef enum enum_tcpstate
57 {
58 TCPCONNECTION_CLOSED,
59 TCPCONNECTION_LISTEN,
60 TCPCONNECTION_SYN_SENT,
61 TCPCONNECTION_SYN_RECEIVED,
62 TCPCONNECTION_ESTABLISHED,
63 TCPCONNECTION_FIN_WAIT_1,
64 TCPCONNECTION_FIN_WAIT_2,
65 TCPCONNECTION_CLOSE_WAIT,
66 TCPCONNECTION_CLOSING,
67 TCPCONNECTION_LAST_ACK,
68 TCPCONNECTION_TIME_WAIT,
69 }TCP_CONNECTION_STATE;
70
71 typedef enum enum_tcp_variant
72 {
73 TCPVariant_OLDTAHOE, //Slow Start and Congestion Avoidance
74 TCPVariant_TAHOE, //Fast Retransmit/Fast Recovery
75 TCPVariant_RENO,
76 TCPVariant_NEWRENO,
77 TCPVariant_BIC,
78 TCPVariant_CUBIC,
79 }TCPVARIANT;
80
81 typedef enum enum_tcp_ack_type
82 {
83 TCPACKTYPE_UNDELAYED,
84 TCPACKTYPE_DELAYED,
85 }TCPACKTYPE;
86
87#include "TCB.h"
88
89 typedef struct stru_tcp_metrics
90 {
91 char* source;
92 char* dest;
93 char* localAddr;
94 char* remoteAddr;
95 UINT synSent;
96 UINT synAckSent;
97 UINT segmentSent;
98 UINT segmentReceived;
99 UINT segmentRetransmitted;
100 UINT ackSent;
101 UINT ackReceived;
102 UINT dupAckReceived;
103 UINT timesRTOExpired;
104 UINT dupSegmentReceived;
105 UINT outOfOrderSegmentReceived;
106
107 void* congestionPlot;
108 UINT prevWindowSize;
109 bool isCongestionPlotRequire;
110 }TCP_METRICS,*PTCP_METRICS;
111
112 typedef struct stru_socket_addr
113 {
114 NETSIM_IPAddress ip;
115 UINT16 port;
116 }SOCKETADDRESS, *PSOCKETADDRESS;
117
119 {
120 UINT SocketId;
121 PSOCKETADDRESS localAddr;
122 PSOCKETADDRESS remoteAddr;
123
124 //For simulation
125 NETSIM_ID localDeviceId;
126 NETSIM_ID remoteDeviceId;
127 ptrSOCKETINTERFACE sId;
128 bool waitFromApp;
129 bool isAPPClose;
130 NETSIM_ID appId;
131
132 PTCB tcb; //Transmission control block
133
134 /* Callback function. This is required only for simulator
135 * As all TCP connection is under same system process so
136 * no lock function.
137 */
138 void(*listen_callback)(struct stru_TCP_Socket* s, NetSim_PACKET*);
139
140 PTCP_METRICS tcpMetrics;
141 };
142
143 typedef struct stru_TCP_device_var
144 {
145 TCPVARIANT tcpVariant;
146 void* socket_list;
147 UINT16 initSSThresh;
148 UINT16 MSS;
149 UINT MaxSynRetries;
150 TCPACKTYPE ackType;
151 double timeWaitTimer;
152 double dDelayedAckTime;
153 bool isSackPermitted;
154 bool isWindowScaling;
155 UINT8 shiftCount;
156 bool isTimestampOpt;
157
158 double beta;
159 UINT32 low_window;
160 UINT32 max_increment;
161 UINT32 smooth_part;
162 UINT32 bic_scale;
163 UINT32 hystart_low_window;
164 UINT32 hystart_ack_delta;
165 }TCP_DEV_VAR,*PTCP_DEV_VAR;
166 static PTCP_DEV_VAR GET_TCP_DEV_VAR(NETSIM_ID d)
167 {
168 if (isTCPConfigured(d))
169 return DEVICE_TRXLayer(d)->TCPVar;
170 else return NULL;
171 }
172#define GET_TCP_VARIANT(d) (GET_TCP_DEV_VAR(d)->tcpVariant)
173
174 //Function Prototype
175 //Socket
176 void add_to_socket_list(NETSIM_ID devId, PNETSIM_SOCKET s);
177 PNETSIM_SOCKET find_socket(NETSIM_ID devId,
178 NETSIM_IPAddress srcIP,
179 NETSIM_IPAddress destIP,
180 UINT16 srcPort,
181 UINT16 destPort);
182 PNETSIM_SOCKET find_socket_at_source(NetSim_PACKET* packet);
183 PNETSIM_SOCKET find_socket_at_dest(NetSim_PACKET* packet);
184 PNETSIM_SOCKET tcp_create_socket();
185 void tcp_bind(PNETSIM_SOCKET s, PSOCKETADDRESS addr);
186 void tcp_listen(PNETSIM_SOCKET s,
187 void(*listen_callback)(PNETSIM_SOCKET, NetSim_PACKET*));
188 void tcp_connect(PNETSIM_SOCKET s,
189 PSOCKETADDRESS localAddr,
190 PSOCKETADDRESS remoteAddr);
191 PNETSIM_SOCKET tcp_accept(PNETSIM_SOCKET s,
192 NetSim_PACKET* p);
193 void close_all_socket(NETSIM_ID devId);
194 void tcp_close(PNETSIM_SOCKET s);
195 void tcp_close_socket(PNETSIM_SOCKET s, NETSIM_ID devId);
196
197 //Connection
198 void tcp_active_open(PNETSIM_SOCKET s);
199 void tcp_passive_open(PNETSIM_SOCKET s, PNETSIM_SOCKET ls);
200
201 //RTO
202 double get_RTT(PTCB tcb, UINT ackNo);
203 double calculate_RTO(double R,
204 double* srtt,
205 double* rtt_var);
206 void add_timeout_event(PNETSIM_SOCKET s,
207 NetSim_PACKET* packet);
208 void handle_rto_timer();
209 void restart_rto_timer(PNETSIM_SOCKET s);
210
211 //Time wait Timer
212 void start_timewait_timer(PNETSIM_SOCKET s);
213
214 //TCP Queue
215 bool isSegmentInQueue(PTCP_QUEUE queue, NetSim_PACKET* packet);
216 void add_packet_to_queue(PTCP_QUEUE queue, NetSim_PACKET* packet, double time);
217 NetSim_PACKET* get_segment_from_queue(PTCP_QUEUE queue, UINT32 seqNo);
218 NetSim_PACKET* get_copy_segment_from_queue(PTCP_QUEUE queue, UINT32 seqNo, bool* isSacked);
219 NetSim_PACKET* get_earliest_segment_from_queue(PTCP_QUEUE queue);
220 NetSim_PACKET* get_earliest_copy_segment_from_queue(PTCP_QUEUE queue);
221 void delete_all_segment_from_queue(PTCP_QUEUE queue);
222 void delete_segment_from_queue(PTCP_QUEUE queue, UINT32 ackNo);
223 void check_segment_in_queue(PNETSIM_SOCKET s);
224 NetSim_PACKET* check_for_other_segment_to_send_from_queue(PNETSIM_SOCKET s);
225
226 //TCP Control
227 //RST
228 void send_rst(PNETSIM_SOCKET s, NetSim_PACKET* p, UINT c);
229 //Syn
230 bool isSynPacket(NetSim_PACKET* packet);
231 bool isSynbitSet(NetSim_PACKET* packet);
232 NetSim_PACKET* create_syn(PNETSIM_SOCKET s,
233 double time);
234 void resend_syn(PNETSIM_SOCKET s);
235 void rcv_SYN(PNETSIM_SOCKET s, NetSim_PACKET* syn);
236
237 //Syn-Ack
238 NetSim_PACKET* create_synAck(PNETSIM_SOCKET s,
239 double time);
240
241 //Ack
242 NetSim_PACKET* create_ack(PNETSIM_SOCKET s,
243 double time,
244 UINT32 seqno,
245 UINT32 ackno);
246 void send_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo);
247
248 //FIN
249 NetSim_PACKET* create_fin(PNETSIM_SOCKET s,
250 double time);
251 void send_fin(PNETSIM_SOCKET s);
252
253 //FIN-Ack
254 void send_fin_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo);
255
256 //Rst
257 NetSim_PACKET* create_rst(NetSim_PACKET* p,
258 double time,
259 UINT c);
260
261 //Segment
262 UINT32 get_seg_len(NetSim_PACKET* p);
263 void add_tcp_hdr(NetSim_PACKET* p, PNETSIM_SOCKET s);
264
265 //Segment Processing
266 void packet_arrive_at_closed_state(PNETSIM_SOCKET s, NetSim_PACKET* p);
267 void packet_arrives_at_listen_state(PNETSIM_SOCKET s, NetSim_PACKET* p);
268 void packet_arrives_at_synsent_state(PNETSIM_SOCKET s, NetSim_PACKET* p);
269 void packet_arrives_at_incoming_tcp(PNETSIM_SOCKET s, NetSim_PACKET* p);
270
271 //TCP Outgoing
272 void resend_segment_without_timeout(PNETSIM_SOCKET s, UINT seq);
273 void send_segment(PNETSIM_SOCKET s);
274 void resend_segment(PNETSIM_SOCKET s, NetSim_PACKET* expired);
275
276 //TCP Incoming
277 void update_seq_num_on_receiving(PNETSIM_SOCKET s,
278 NetSim_PACKET* p);
279
280 //TCB
281 void tcp_change_state(PNETSIM_SOCKET s, TCP_CONNECTION_STATE state);
282 void create_TCB(PNETSIM_SOCKET s);
283 void free_tcb(PTCB tcb);
284 void delete_tcb(PNETSIM_SOCKET s);
285
286 //Congestion Algo
287 void congestion_setcallback(PNETSIM_SOCKET s);
288 UINT32 get_cwnd_print(PNETSIM_SOCKET s);
289
290 //Delayed Ack
291 void set_ack_type(PNETSIM_SOCKET s, PTCP_DEV_VAR tcp);
292 bool send_ack_or_not(PNETSIM_SOCKET s);
293
294 //SACK
295 UINT32 get_highAck(PNETSIM_SOCKET s);
296 void set_highRxt(PNETSIM_SOCKET s, UINT32 seq);
297 void set_rescueRxt(PNETSIM_SOCKET s, UINT32 seq);
298 void tcp_sack_fastRetransmit(PNETSIM_SOCKET s);
299 bool tcp_sack_lossRecoveryPhase(PNETSIM_SOCKET s);
300 bool tcp_sack_isLost(PNETSIM_SOCKET s, UINT seqNum);
301
302 //Window scaling
303 UINT8 get_shift_count(PNETSIM_SOCKET s);
304 void set_window_scaling_option(PNETSIM_SOCKET s, PTCP_DEV_VAR tcp);
305 UINT32 window_scale_get_cwnd(PNETSIM_SOCKET s);
306 UINT16 window_scale_get_wnd(PNETSIM_SOCKET s);
307
308 //UTILITY Function
309 void print_tcp_log(char* format, ...);
310 bool get_protocol_log_status(char* logname);
311 void tcp_create_metrics(PNETSIM_SOCKET s);
312 TCPVARIANT get_tcp_variant_from_str(char* szVal);
313 TCPACKTYPE get_tcp_ack_type_from_str(char* szVal);
314 char* state_to_str(TCP_CONNECTION_STATE state);
315 bool isAnySegmentInQueue(PTCP_QUEUE queue);
316 void write_congestion_plot(PNETSIM_SOCKET s, NetSim_PACKET* packet);
317 void init_TCP_congestion_log();
318 void close_TCP_congestion_log();
319
320 //App Layer interface
321 void tcp_init(NETSIM_ID d);
322 NetSim_PACKET* GET_PACKET_FROM_APP(bool isRemove);
323 int packet_arrive_from_application_layer();
324 void send_to_application(PNETSIM_SOCKET s, NetSim_PACKET* p);
325
326 //Network layer interface
327 void packet_arrive_from_network_layer();
328 void send_to_network(NetSim_PACKET* packet, PNETSIM_SOCKET s);
329
330
331#ifdef __cplusplus
332}
333#endif
334#endif //_NETSIM_TCP_H_