NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
TCP_Socket.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 "List.h"
27
28typedef struct stru_socket_list
29{
30 PNETSIM_SOCKET s;
31 _ele* ele;
32}SOCKET_LIST, *PSOCKET_LIST;
33#define SOCKET_LIST_ALLOC() (PSOCKET_LIST)list_alloc(sizeof(SOCKET_LIST),offsetof(SOCKET_LIST,ele))
34#define SOCKET_LIST_NEXT(sl) (PSOCKET_LIST)LIST_NEXT(sl)
35
36static UINT socket_id = 0;
37
38static bool compare_socketaddr(PSOCKETADDRESS sa1, PSOCKETADDRESS sa2)
39{
40 return !IP_COMPARE(sa1->ip, sa2->ip) &&
41 sa1->port == sa2->port;
42}
43
44static bool compare_socket(PNETSIM_SOCKET s1, PNETSIM_SOCKET s2)
45{
46 bool l = false;
47 bool r = false;
48 if (s1->localAddr)
49 {
50 if (s2->localAddr)
51 l = compare_socketaddr(s1->localAddr, s2->localAddr);
52 else
53 return false;
54 }
55 else
56 {
57 if (s2->localAddr)
58 return false;
59 else
60 l = true;
61 }
62
63 if (s1->remoteAddr)
64 {
65 if (s2->remoteAddr)
66 r = compare_socketaddr(s1->remoteAddr, s2->remoteAddr);
67 else
68 return false;
69 }
70 else
71 {
72 if (s2->remoteAddr)
73 return false;
74 else
75 r = true;
76 }
77
78 return l && r;
79}
80
81static PSOCKET_LIST find_socket_list(NETSIM_ID devid, PNETSIM_SOCKET s)
82{
83 PTCP_DEV_VAR tcp = GET_TCP_DEV_VAR(devid);
84 PSOCKET_LIST sl = tcp->socket_list;
85 while (sl)
86 {
87 if (compare_socket(sl->s, s))
88 return sl;
89 sl = SOCKET_LIST_NEXT(sl);
90 }
91 return NULL;
92}
93
94void add_to_socket_list(NETSIM_ID devId, PNETSIM_SOCKET s)
95{
96 PTCP_DEV_VAR tcp = GET_TCP_DEV_VAR(devId);
97
98 PSOCKET_LIST sl = find_socket_list(devId, s);
99 if (!sl)
100 {
101 sl = SOCKET_LIST_ALLOC();
102 sl->s = s;
103 LIST_ADD_LAST(&tcp->socket_list, sl);
104 }
105}
106
107void remove_from_socket_list(NETSIM_ID devId, PNETSIM_SOCKET s)
108{
109 PTCP_DEV_VAR tcp = GET_TCP_DEV_VAR(devId);
110 PSOCKET_LIST sl = find_socket_list(devId, s);
111 if (sl)
112 {
113 LIST_FREE(&tcp->socket_list, sl);
114 }
115}
116
117PNETSIM_SOCKET find_socket(NETSIM_ID devId,
118 NETSIM_IPAddress srcIP,
119 NETSIM_IPAddress destIP,
120 UINT16 srcPort,
121 UINT16 destPort)
122{
123 NETSIM_SOCKET s;
124
125 SOCKETADDRESS ssa;
126 ssa.ip = srcIP;
127 ssa.port = srcPort;
128
129 SOCKETADDRESS dsa;
130 dsa.ip = destIP;
131 dsa.port = destPort;
132
133 s.localAddr = &ssa;
134 s.remoteAddr = &dsa;
135
136 PSOCKET_LIST psl = find_socket_list(devId, &s);
137 return psl ? psl->s : NULL;
138}
139
140PNETSIM_SOCKET get_Remotesocket(NETSIM_ID d, PSOCKETADDRESS addr)
141{
142 SOCKETADDRESS localAddr;
143 NETSIM_SOCKET s;
144 memset(&s, 0, sizeof s);
145 s.remoteAddr = addr;
146
147 localAddr.ip = DEVICE_NWADDRESS(d, 1);
148 localAddr.port = 0;
149 s.localAddr = &localAddr;
150
151 PSOCKET_LIST psl = find_socket_list(d, &s);
152 return psl ? psl->s : NULL;
153}
154
155PNETSIM_SOCKET find_socket_at_source(NetSim_PACKET* packet)
156{
157 return find_socket(packet->nSourceId,
158 packet->pstruNetworkData->szSourceIP,
159 packet->pstruNetworkData->szDestIP,
160 packet->pstruTransportData->nSourcePort,
161 packet->pstruTransportData->nDestinationPort);
162}
163
164PNETSIM_SOCKET find_socket_at_dest(NetSim_PACKET* packet)
165{
166 PNETSIM_SOCKET s;
167 s = find_socket(get_first_dest_from_packet(packet),
168 packet->pstruNetworkData->szDestIP,
169 packet->pstruNetworkData->szSourceIP,
170 packet->pstruTransportData->nDestinationPort,
171 packet->pstruTransportData->nSourcePort);
172 if (!s && isSynPacket(packet))
173 {
174 extern PSOCKETADDRESS anySocketAddr;
175 s = get_Remotesocket(get_first_dest_from_packet(packet), anySocketAddr);
176 }
177 return s;
178}
179
180PNETSIM_SOCKET tcp_create_socket()
181{
182 PNETSIM_SOCKET s = (PNETSIM_SOCKET)calloc(1, sizeof* s);
183 s->SocketId = ++socket_id;
184 return s;
185}
186
187void tcp_close_socket(PNETSIM_SOCKET s, NETSIM_ID devId)
188{
189 if (s->tcb)
190 {
191 print_tcp_log("Closing socket with local addr %s:%d, Remote addr %s:%d\n",
192 s->localAddr->ip->str_ip,
193 s->localAddr->port,
194 s->remoteAddr->ip->str_ip,
195 s->remoteAddr->port);
196 tcp_change_state(s, TCPCONNECTION_CLOSED);
197 free_tcb(s->tcb);
198 }
199 remove_from_socket_list(devId, s);
200 free(s->localAddr);
201 if(s->remoteAddr->port)
202 free(s->remoteAddr);
203 free(s);
204}
205
206void tcp_connect(PNETSIM_SOCKET s,
207 PSOCKETADDRESS localAddr,
208 PSOCKETADDRESS remoteAddr)
209{
210 s->localAddr = localAddr;
211 s->remoteAddr = remoteAddr;
212 tcp_create_metrics(s);
213 tcp_active_open(s);
214}
215
216void tcp_bind(PNETSIM_SOCKET s,
217 PSOCKETADDRESS addr)
218{
219 s->remoteAddr = addr;
220 create_TCB(s);
221 return;
222}
223
224void tcp_listen(PNETSIM_SOCKET s,
225 void(*listen_callback)(PNETSIM_SOCKET, NetSim_PACKET*))
226{
227 s->listen_callback = listen_callback;
228 tcp_change_state(s, TCPCONNECTION_LISTEN);
229}
230
231PNETSIM_SOCKET tcp_accept(PNETSIM_SOCKET s,
232 NetSim_PACKET* p)
233{
234 PNETSIM_SOCKET localSocket = tcp_create_socket();
235
236 add_to_socket_list(pstruEventDetails->nDeviceId, localSocket);
237
238 PSOCKETADDRESS remotesocketAddr = (PSOCKETADDRESS)calloc(1, sizeof* remotesocketAddr);
239 remotesocketAddr->ip = IP_COPY(p->pstruNetworkData->szSourceIP);
240 remotesocketAddr->port = p->pstruTransportData->nSourcePort;
241
242 PSOCKETADDRESS localsocketAddr = (PSOCKETADDRESS)calloc(1, sizeof* localsocketAddr);
243 localsocketAddr->ip = IP_COPY(p->pstruNetworkData->szDestIP);
244 localsocketAddr->port = p->pstruTransportData->nDestinationPort;
245
246 localSocket->localDeviceId = get_first_dest_from_packet(p);
247 localSocket->remoteDeviceId = p->nSourceId;
248
249 print_tcp_log("\nDevice %d, Time %0.2lf: creating socket with local addr %s:%d, Remote addr %s:%d",
250 localSocket->localDeviceId,
251 pstruEventDetails->dEventTime,
252 localsocketAddr->ip->str_ip,
253 localsocketAddr->port,
254 remotesocketAddr->ip->str_ip,
255 remotesocketAddr->port);
256
257 localSocket->localAddr = localsocketAddr;
258 localSocket->remoteAddr = remotesocketAddr;
259
260 localSocket->sId = fn_NetSim_Socket_GetSocketInterface(localSocket->localDeviceId,
261 0,
262 TX_PROTOCOL_TCP,
263 localSocket->localAddr->port,
264 localSocket->remoteAddr->port);
265
266 tcp_create_metrics(localSocket);
267
268 tcp_passive_open(localSocket, s);
269
270 rcv_SYN(localSocket,p);
271
272 return localSocket;
273}
274
275void close_all_socket(NETSIM_ID devId)
276{
277 PTCP_DEV_VAR tcp = GET_TCP_DEV_VAR(devId);
278 PSOCKET_LIST sl = tcp->socket_list;
279 while (sl)
280 {
281 tcp_close_socket(sl->s, devId);
282 sl = tcp->socket_list;
283 }
284}
285
286void tcp_close(PNETSIM_SOCKET s)
287{
288 if (!isAnySegmentInQueue(&s->tcb->retransmissionQueue))
289 {
290 send_fin(s);
291 tcp_change_state(s, TCPCONNECTION_FIN_WAIT_1);
292 }
293}