NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
TCP.c
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* 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_Header.h"
27#include "TCP_enum.h"
28#include "NetSim_Plot.h"
29#include "NetSim_utility.h"
30#include "../Application/Application.h"
31
32char* GetStringTCP_Subevent(NETSIM_ID);
33static FILE* fpTCP_CWlog = NULL;
34
35#pragma comment(lib,"TCP.lib")
36
37//Function prototype
38int fn_NetSim_TCP_Configure_F(void **var);
39int fn_NetSim_TCP_Init_F(struct stru_NetSim_Network* net,
40 NetSim_EVENTDETAILS* pevent,
41 char* appPath,
42 char* iopath,
43 int version,
44 void** fnPointer);
45int fn_NetSim_TCP_CopyPacket_F(NetSim_PACKET* dst,
46 NetSim_PACKET* src);
47int fn_NetSim_TCP_FreePacket_F(NetSim_PACKET* packet);
48int fn_NetSim_TCP_Finish_F();
49int fn_NetSim_TCP_Metrics_F(PMETRICSWRITER metricsWriter);
50char* fn_NetSim_TCP_ConfigPacketTrace_F(const void* xmlNetSimNode);
51int fn_NetSim_TCP_WritePacketTrace_F(NetSim_PACKET* pstruPacket, char** ppszTrace);
52
53static int fn_NetSim_TCP_HandleTransportOut();
54static int fn_NetSim_TCP_HandleTransportIn();
55static int fn_NetSim_TCP_HandleTimer();
56static void handle_time_wait_timeout();
57
58/**
59This function is called by NetworkStack.dll, whenever the event gets triggered
60inside the NetworkStack.dll for the Transport layer TCP protocol
61It includes TRANSPORT_OUT,TRANSPORT_IN and TIMER_EVENT.
62*/
63_declspec (dllexport) int fn_NetSim_TCP_Run()
64{
65 switch (pstruEventDetails->nEventType)
66 {
67 case TRANSPORT_OUT_EVENT:
68 return fn_NetSim_TCP_HandleTransportOut();
69 break;
70 case TRANSPORT_IN_EVENT:
71 return fn_NetSim_TCP_HandleTransportIn();
72 break;
73 case TIMER_EVENT:
74 return fn_NetSim_TCP_HandleTimer();
75 break;
76 default:
77 fnNetSimError("Unknown event %d for TCP protocol in %s\n",
78 pstruEventDetails->nEventType,
79 __FUNCTION__);
80 return -1;
81 }
82}
83
84/**
85This function is called by NetworkStack.dll, while configuring the device
86TRANSPORT layer for TCP protocol.
87*/
88_declspec(dllexport) int fn_NetSim_TCP_Configure(void** var)
89{
90 return fn_NetSim_TCP_Configure_F(var);
91}
92
93/**
94This function initializes the TCP parameters.
95*/
96_declspec (dllexport) int fn_NetSim_TCP_Init(struct stru_NetSim_Network *NETWORK_Formal,
97 NetSim_EVENTDETAILS *pstruEventDetails_Formal,
98 char *pszAppPath_Formal,
99 char *pszWritePath_Formal,
100 int nVersion_Type,
101 void **fnPointer)
102{
103 init_TCP_congestion_log();
104 return fn_NetSim_TCP_Init_F(NETWORK_Formal,
105 pstruEventDetails_Formal,
106 pszAppPath_Formal,
107 pszWritePath_Formal,
108 nVersion_Type,
109 fnPointer);
110}
111
112/**
113This function is called by NetworkStack.dll, once simulation end to free the
114allocated memory for the network.
115*/
116_declspec(dllexport) int fn_NetSim_TCP_Finish()
117{
118 close_TCP_congestion_log();
119 return fn_NetSim_TCP_Finish_F();
120}
121
122/**
123This function is called by NetworkStack.dll, while writing the event trace
124to get the sub event as a string.
125*/
126_declspec (dllexport) char *fn_NetSim_TCP_Trace(int nSubEvent)
127{
128 return (GetStringTCP_Subevent(nSubEvent));
129}
130
131/**
132This function is called by NetworkStack.dll, to free the TCP protocol
133pstruTransportData->Packet_TransportProtocol.
134*/
135_declspec(dllexport) int fn_NetSim_TCP_FreePacket(NetSim_PACKET* pstruPacket)
136{
137 return fn_NetSim_TCP_FreePacket_F(pstruPacket);
138}
139
140/**
141This function is called by NetworkStack.dll, to copy the TCP protocol
142pstruTransportData->Packet_TransportProtocol from source packet to destination.
143*/
144_declspec(dllexport) int fn_NetSim_TCP_CopyPacket(NetSim_PACKET* pstruDestPacket, NetSim_PACKET* pstruSrcPacket)
145{
146 return fn_NetSim_TCP_CopyPacket_F(pstruDestPacket, pstruSrcPacket);
147}
148
149/**
150This function write the Metrics in Metrics.txt
151*/
152_declspec(dllexport) int fn_NetSim_TCP_Metrics(PMETRICSWRITER metricsWriter)
153{
154 return fn_NetSim_TCP_Metrics_F(metricsWriter);
155}
156
157/**
158This function will return the string to write packet trace heading.
159*/
160_declspec(dllexport) char* fn_NetSim_TCP_ConfigPacketTrace(const void* xmlNetSimNode)
161{
162 return fn_NetSim_TCP_ConfigPacketTrace_F(xmlNetSimNode);
163}
164
165/**
166This function will return the string to write packet trace.
167*/
168_declspec(dllexport) int fn_NetSim_TCP_WritePacketTrace(NetSim_PACKET* pstruPacket, char** ppszTrace)
169{
170 return fn_NetSim_TCP_WritePacketTrace_F(pstruPacket, ppszTrace);
171}
172
173static int fn_NetSim_TCP_HandleTransportOut()
174{
175 switch (pstruEventDetails->nSubEventType)
176 {
177 case 0:
178 return packet_arrive_from_application_layer();
179 break;
180 default:
181 fnNetSimError("Unknown sub-event %d for TCP in %s",
182 pstruEventDetails->nSubEventType,
183 __FUNCTION__);
184 return -1;
185 }
186}
187
188static int fn_NetSim_TCP_HandleTransportIn()
189{
190 switch (pstruEventDetails->nSubEventType)
191 {
192 case 0:
193 packet_arrive_from_network_layer();
194 break;
195 default:
196 fnNetSimError("Unknown sub-event %d for TCP transport in event\n",
197 pstruEventDetails->nSubEventType);
198 break;
199 }
200 return 0;
201}
202
203static int fn_NetSim_TCP_HandleTimer()
204{
205 switch (pstruEventDetails->nSubEventType)
206 {
207 case TCP_RTO_TIMEOUT:
208 handle_rto_timer();
209 break;
210 case TCP_TIME_WAIT_TIMEOUT:
211 handle_time_wait_timeout();
212 break;
213 default:
214 fnNetSimError("Unknown sub-event %d in %s\n",
215 pstruEventDetails->nSubEventType,
216 __FUNCTION__);
217 break;
218 }
219 return 0;
220}
221
222TCPVARIANT get_tcp_variant_from_str(char* szVal)
223{
224 if (!_stricmp(szVal, "OLD_TAHOE"))
225 return TCPVariant_OLDTAHOE;
226 if (!_stricmp(szVal, "TAHOE"))
227 return TCPVariant_TAHOE;
228 if (!_stricmp(szVal, "RENO"))
229 return TCPVariant_RENO;
230 if (!_stricmp(szVal, "NEW_RENO"))
231 return TCPVariant_NEWRENO;
232 if (!_stricmp(szVal, "BIC"))
233 return TCPVariant_BIC;
234 if (!_stricmp(szVal, "CUBIC"))
235 return TCPVariant_CUBIC;
236 else
237 fnNetSimError("Unknown TCP Variant %s\n",szVal);
238 return TCPVariant_TAHOE;
239}
240
241TCPACKTYPE get_tcp_ack_type_from_str(char* szVal)
242{
243 if (!_stricmp(szVal, "Delayed"))
244 return TCPACKTYPE_DELAYED;
245 if (!_stricmp(szVal, "Undelayed"))
246 return TCPACKTYPE_UNDELAYED;
247 fnNetSimError("Unknown TCP ack type %s\n", szVal);
248 return TCPACKTYPE_UNDELAYED;
249}
250
251void start_timewait_timer(PNETSIM_SOCKET s)
252{
253 NetSim_EVENTDETAILS pevent;
254 memcpy(&pevent, pstruEventDetails, sizeof pevent);
255 pevent.dEventTime += s->tcb->timeWaitTimer;
256 pevent.dPacketSize = 0;
257 pevent.nEventType = TIMER_EVENT;
258 pevent.nPacketId = 0;
259 pevent.nProtocolId = TX_PROTOCOL_TCP;
260 pevent.nSegmentId = 0;
261 pevent.nSubEventType = TCP_TIME_WAIT_TIMEOUT;
262 pevent.pPacket = NULL;
263 pevent.szOtherDetails = s;
264 fnpAddEvent(&pevent);
265
266 print_tcp_log("Adding Time-wait_timer at %0.2lf",
267 pevent.dEventTime);
268 print_tcp_log("Canceling all other timer.");
269
270 s->tcb->isOtherTimerCancel = true;
271}
272
273static void handle_time_wait_timeout()
274{
275 PNETSIM_SOCKET s = pstruEventDetails->szOtherDetails;
276 tcp_change_state(s, TCPCONNECTION_CLOSED);
277 delete_tcb(s);
278 tcp_close_socket(s, pstruEventDetails->nDeviceId);
279}
280
281
282void init_TCP_congestion_log()
283{
284 if (get_protocol_log_status("TCP_Congestion_Log"))
285 {
286 char s[BUFSIZ];
287 sprintf(s, "%s\\%s", pszIOLogPath, "TCP_Congestion_Window_Log.csv");
288 fpTCP_CWlog = fopen(s, "w");
289 if (!fpTCP_CWlog)
290 {
291 fnSystemError("Unable to open %s file", s);
292 perror(s);
293 }
294 else
295 {
296 fprintf(fpTCP_CWlog, "%s,%s,%s,%s,%s,%s,%s,",
297 "Time (Microseconds)", "Application ID", "Application Name", "Source Device Name", "Source ID", "Destination Device Name", "Destination ID");
298
299 fprintf(fpTCP_CWlog, "%s,%s,%s,",
300 "Source Socket Address", "Destination Socket Address", "Sender Window Size(Bytes)");
301
302 fprintf(fpTCP_CWlog, "\n");
303 if (nDbgFlag) fflush(fpTCP_CWlog);
304 }
305 }
306}
307
308void write_congestion_plot(PNETSIM_SOCKET s, NetSim_PACKET* packet)
309{
310 UINT win = get_cwnd_print(s);
311
312 if (fpTCP_CWlog == NULL || !packet->nPacketId) return;
313
314 ptrAPPLICATION_INFO pstruappinfo = ((ptrAPPLICATION_INFO*)NETWORK->appInfo)[packet->pstruAppData->nApplicationId - 1];
315
316 fprintf(fpTCP_CWlog, "%lf,%d,%s,%s,%d,%s,%d,", pstruEventDetails->dEventTime,pstruappinfo->id,pstruappinfo->name,
317 DEVICE_NAME(s->localDeviceId),s->localDeviceId,DEVICE_NAME(s->remoteDeviceId),s->remoteDeviceId);
318
319 fprintf(fpTCP_CWlog, "%s,%s,%d,", s->tcpMetrics->localAddr, s->tcpMetrics->remoteAddr,s->tcpMetrics->prevWindowSize);
320
321 fprintf(fpTCP_CWlog, "\n");
322
323 fprintf(fpTCP_CWlog, "%lf,%d,%s,%s,%d,%s,%d,", pstruEventDetails->dEventTime, pstruappinfo->id, pstruappinfo->name,
324 DEVICE_NAME(s->localDeviceId), s->localDeviceId, DEVICE_NAME(s->remoteDeviceId), s->remoteDeviceId);
325
326 fprintf(fpTCP_CWlog, "%s,%s,%d,", s->tcpMetrics->localAddr, s->tcpMetrics->remoteAddr, win);
327
328 fprintf(fpTCP_CWlog, "\n");
329
330 s->tcpMetrics->prevWindowSize = win;
331 }
332
333
334void close_TCP_congestion_log()
335{
336 if (fpTCP_CWlog)
337 fclose(fpTCP_CWlog);
338}
339
340bool isTCPlog()
341{
342 if (get_protocol_log_status("TCP_LOG"))
343 return true;
344 else
345 return false;
346}
347
348bool get_protocol_log_status(char* logname)
349{
350 FILE* fp;
351 char str[BUFSIZ];
352 char data[BUFSIZ];
353
354 sprintf(str, "%s/%s", pszIOPath, "ProtocolLogsConfig.txt");
355 fp = fopen(str, "r");
356 if (!fp)
357 return false;
358
359 sprintf(str, "%s=true", logname);
360
361 while (fgets(data, BUFSIZ, fp))
362 {
363 lskip(data);
364 if (!_strnicmp(data, str, strlen(str)))
365 {
366 fclose(fp);
367 return true;
368 }
369 }
370 fclose(fp);
371
372 return false;
373}