NetSim Source Code Help
Loading...
Searching...
No Matches
TCP_Connection.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 "List.h"
27#include "TCP_Header.h"
28
29//Function prototype
30static void send_syn(PNETSIM_SOCKET s);
31
33{
34 print_tcp_log("Creating TCB");
35 create_TCB(s);
36 print_tcp_log("Sending Syn");
37 send_syn(s);
38}
39
41{
42 print_tcp_log("Creating TCB");
43 create_TCB(s);
44 memcpy(&s->tcb->SEG, &ls->tcb->SEG, sizeof s->tcb->SEG);
46}
47
49{
51
52 s->tcb->SND.UNA = s->tcb->ISS;
53 s->tcb->SND.NXT = s->tcb->ISS + 1;
55
56 s->tcb->synRetries++;
57
58 s->tcpMetrics->synSent++;
59
60 send_to_network(syn, s);
61 add_timeout_event(s,syn);
62}
63
65{
67
70 {
71 print_tcp_log("ERROR: %s is called for different TCP state %s. it must be %s or %s",
72 __FUNCTION__,
76 assert(false);
77 }
78
80
82
85
86 if (s->tcb->synRetries < tcp->MaxSynRetries)
87 {
88 print_tcp_log("Resending syn/syn-ack packet.");
89 s->tcb->SND.UNA = s->tcb->ISS;
90 s->tcb->SND.NXT = s->tcb->ISS + 1;
91
92 send_to_network(syn, s);
93 add_timeout_event(s, syn);
94
96 s->tcpMetrics->synSent++;
97 else
99
100 s->tcb->synRetries++;
101 }
102 else
103 {
104 print_tcp_log("Connection fails for local address %s:%d, Remote address %s:%d",
105 s->localAddr->ip->str_ip,
106 s->localAddr->port,
107 s->remoteAddr->ip->str_ip,
108 s->remoteAddr->port);
110 }
111}
112
114{
115 if (!s->localAddr)
116 {
117 s->listen_callback(s, p);
118 }
119 else
120 {
121 if ((s->tcb->IRS && s->tcb->IRS != s->tcb->SEG.SEQ) ||
122 (s->tcb->RCV.NXT && s->tcb->RCV.NXT != s->tcb->SEG.SEQ +1))
123 {
124 //send_rst(s, p, 1); //RFC 793
125 //Correction made by RFC 1122. Page93
126 send_rst(s, p, 2);
127 }
128 else
129 {
130 s->listen_callback(s, p);
131 }
132 }
134}
135
137{
138 s->tcb->RCV.NXT = s->tcb->SEG.SEQ + 1;
139 s->tcb->IRS = s->tcb->SEG.SEQ;
140
141 //Store the Window scale option based on peer device
144
145 set_window_scaling(s, wsopt);
146
147 //Store MSS based on peer device
149 if (opt)
150 s->tcb->set_MSS(s, opt->MSSData);
151
152 //Store the timestamps option based on peer device
156
157 if (s->tcb->isSackPermitted)
158 {
159 //Store Sack option based on peer device
161 if (sackp)
162 s->tcb->isSackPermitted = true;
163 else
164 s->tcb->isSackPermitted = false;
165 }
166
169
170 s->tcb->SND.UNA = s->tcb->ISS;
171 s->tcb->SND.NXT = s->tcb->ISS + 1;
172
173 s->tcb->synRetries++;
174
176
177 send_to_network(synAck, s);
178 add_timeout_event(s, synAck);
179}
180
182{
183 print_tcp_log("Sending RST packet");
185 send_to_network(rst, s);
186}
187
188void send_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo)
189{
190 print_tcp_log("Sending ack with seq=%d, Ack=%d.", seqNo, ackNo);
191 NetSim_PACKET* ack = create_ack(s, time, seqNo, ackNo);
192 s->tcpMetrics->ackSent++;
193 send_to_network(ack, s);
194}
195
196void send_fin_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo)
197{
198 print_tcp_log("Sending fin-ack with seq=%d, Ack=%d.", seqNo, ackNo);
199 NetSim_PACKET* ack = create_ack(s, time, seqNo, ackNo);
201 hdr->Fin = 1;
202 s->tcpMetrics->ackSent++;
203 send_to_network(ack, s);
204}
205
207{
208 print_tcp_log("TCP_STATE=CLOSED");
209 if (isTCPControl(p))
210 {
212 if (hdr->Rst)
213 goto DISCARD_PACKET;
214 else
215 {
216 send_rst(s, p, 0);
217 goto FREE_SEGMENT;
218 }
219 }
220 else
221 goto DISCARD_PACKET;
222
223DISCARD_PACKET:
224 //Discard packet
225 print_tcp_log("Discarding segment");
226FREE_SEGMENT:
229}
230
232{
233 print_tcp_log("TCP_STATE=LISTEN");
235 if (hdr->Rst)
236 goto DISCARD_PACKET;
237 else if (hdr->Ack)
238 {
239 send_rst(s, p, 0);
240 goto FREE_SEGMENT;
241 }
242 else if (hdr->Syn)
243 {
244 process_syn(s, p);
245 return;
246 }
247 else
248 fnNetSimError("Unknown processing mode in %s",
249 __FUNCTION__);
250
251
252DISCARD_PACKET:
253 print_tcp_log("Discarding Packet");
254FREE_SEGMENT:
257}
258
260{
261 bool isAckAcceptable = false;
262 print_tcp_log("TCP_STATE = SYN-SENT");
263
265 if (hdr->Ack)
266 {
267 if (s->tcb->SEG.ACK <= s->tcb->ISS ||
268 s->tcb->SEG.ACK > s->tcb->SND.NXT)
269 {
270 send_rst(s, p, 0);
271 goto FREE_SEGMENT;
272 }
273
274 if (s->tcb->SND.UNA <= s->tcb->SEG.ACK &&
275 s->tcb->SEG.ACK <= s->tcb->SND.NXT)
276 isAckAcceptable = true;
277 }
278 if (hdr->Rst)
279 {
280 if (isAckAcceptable)
281 {
282 print_tcp_log("Error: Connection reset");
283 delete_tcb(s);
286 return;
287 }
288 else
289 {
290 goto DISCARD_PACKET;
291 }
292 }
293 if (isAckAcceptable)
294 {
295 if (hdr->Syn)
296 {
297 s->tcb->RCV.NXT = s->tcb->SEG.SEQ + 1;
298 s->tcb->IRS = s->tcb->SEG.SEQ;
299 s->tcb->SND.UNA = s->tcb->SEG.ACK;
300
301 //Store MSS based on peer device
303 if (opt)
304 s->tcb->set_MSS(s, opt->MSSData);
305
306 if (s->tcb->isTSopt)
307 {
308 //Store the timestamps option based on peer device
309 PTSopt tsopt = get_tcp_option(hdr,
311 set_timestamp_value(s, hdr, tsopt);
312 }
313
315
316 if (s->tcb->SND.UNA > s->tcb->ISS)
317 {
318 //Correction made by RFC 1122. Page 93.
319 s->tcb->SND.WND = s->tcb->SEG.WND;
320 s->tcb->SND.WL1 = s->tcb->SEG.SEQ;
321 s->tcb->SND.WL2 = s->tcb->SEG.ACK;
322
323 send_ack(s,
325 s->tcb->SND.NXT,
326 s->tcb->RCV.NXT);
328 send_segment(s);
329 return;
330 }
331 }
332 }
333
334DISCARD_PACKET:
335 print_tcp_log("Discarding Packet");
336FREE_SEGMENT:
339}
340
342{
343 static bool isShowError = true;
345
346 send_to_network(fin, s);
347
348#ifdef _DEBUG
349 if(isShowError)
350 fnNetSimError("RTO timeout is not implemented for FIN");
351 isShowError = false;
352 //add_timeout_event(s, fin);
353#endif
354}
#define c
#define UINT
Definition: Linux.h:38
#define UINT32
Definition: Linux.h:35
#define fnNetSimError(x,...)
Definition: Linux.h:56
void add_timeout_event(PNETSIM_SOCKET s, NetSim_PACKET *packet)
Definition: RTO.c:63
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
void create_TCB(PNETSIM_SOCKET s)
Definition: TCB.c:90
void tcp_change_state(PNETSIM_SOCKET s, TCP_CONNECTION_STATE state)
Definition: TCB.c:138
void delete_segment_from_queue(PTCP_QUEUE queue, UINT32 ackNo)
Definition: TCB.c:316
void set_timestamp_value(PNETSIM_SOCKET s, PTCP_SEGMENT_HDR hdr, PTSopt opt)
Definition: TCB.c:427
void delete_tcb(PNETSIM_SOCKET s)
Definition: TCB.c:132
NetSim_PACKET * get_segment_from_queue(PTCP_QUEUE queue, UINT32 seqNo)
Definition: TCB.c:229
char * state_to_str(TCP_CONNECTION_STATE state)
Definition: TCB.c:28
NetSim_PACKET * create_ack(PNETSIM_SOCKET s, double time, UINT32 seqno, UINT32 ackno)
Definition: TCP_Packet.c:297
void send_to_network(NetSim_PACKET *packet, PNETSIM_SOCKET s)
static PTCP_DEV_VAR GET_TCP_DEV_VAR(NETSIM_ID d)
Definition: TCP.h:167
NetSim_PACKET * create_synAck(PNETSIM_SOCKET s, double time)
Definition: TCP_Packet.c:223
NetSim_PACKET * create_rst(NetSim_PACKET *p, double time, UINT c)
Definition: TCP_Packet.c:254
@ TCPCONNECTION_LISTEN
Definition: TCP.h:59
@ TCPCONNECTION_CLOSED
Definition: TCP.h:58
@ TCPCONNECTION_SYN_RECEIVED
Definition: TCP.h:61
@ TCPCONNECTION_SYN_SENT
Definition: TCP.h:60
@ TCPCONNECTION_ESTABLISHED
Definition: TCP.h:62
void print_tcp_log(char *format,...)
#define isTCPControl(p)
Definition: TCP.h:48
void send_segment(PNETSIM_SOCKET s)
Definition: TCP_Outgoing.c:18
NetSim_PACKET * create_syn(PNETSIM_SOCKET s, double time)
Definition: TCP_Packet.c:194
void tcp_close_socket(PNETSIM_SOCKET s, NETSIM_ID devId)
Definition: TCP_Socket.c:187
NetSim_PACKET * create_fin(PNETSIM_SOCKET s, double time)
Definition: TCP_Packet.c:322
void resend_syn(PNETSIM_SOCKET s)
void send_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo)
void send_rst(PNETSIM_SOCKET s, NetSim_PACKET *p, UINT c)
void rcv_SYN(PNETSIM_SOCKET s, NetSim_PACKET *syn)
void tcp_active_open(PNETSIM_SOCKET s)
void send_fin(PNETSIM_SOCKET s)
void packet_arrives_at_synsent_state(PNETSIM_SOCKET s, NetSim_PACKET *p)
void packet_arrive_at_closed_state(PNETSIM_SOCKET s, NetSim_PACKET *p)
void send_fin_ack(PNETSIM_SOCKET s, double time, UINT32 seqNo, UINT32 ackNo)
static void send_syn(PNETSIM_SOCKET s)
void process_syn(PNETSIM_SOCKET s, NetSim_PACKET *p)
void tcp_passive_open(PNETSIM_SOCKET s, PNETSIM_SOCKET ls)
void packet_arrives_at_listen_state(PNETSIM_SOCKET s, NetSim_PACKET *p)
@ TCPPACKET_SYN
Definition: TCP_Header.h:29
void set_window_scaling(PNETSIM_SOCKET s, PWsopt opt)
Definition: WindowScale.c:18
@ TCP_OPTION_WINDOW_SCALE
Definition: TCP_Header.h:41
@ TCP_OPTION_TIMESTAMP
Definition: TCP_Header.h:46
@ TCP_OPTION_MSS
Definition: TCP_Header.h:40
@ TCP_OPTION_SACK_PERMITTED
Definition: TCP_Header.h:42
void * get_tcp_option(PTCP_SEGMENT_HDR hdr, TCP_OPTION type)
Definition: TCP_Packet.c:65
static PTCP_SEGMENT_HDR TCP_GET_SEGMENT_HDR(NetSim_PACKET *packet)
Definition: TCP_Header.h:107
#define fn_NetSim_Packet_FreePacket(pstruPacket)
Definition: main.h:177
struct stru_NetSim_Packet * pPacket
Definition: Stack.h:754
NETSIM_ID nDeviceId
Definition: Stack.h:750
unsigned int nControlDataType
Definition: Packet.h:258
PTCB tcb
Definition: TCP.h:132
PSOCKETADDRESS localAddr
Definition: TCP.h:121
NETSIM_ID localDeviceId
Definition: TCP.h:125
PSOCKETADDRESS remoteAddr
Definition: TCP.h:122
void(* listen_callback)(struct stru_TCP_Socket *s, NetSim_PACKET *)
Definition: TCP.h:138
PTCP_METRICS tcpMetrics
Definition: TCP.h:140
UINT MaxSynRetries
Definition: TCP.h:149
char str_ip[_NETSIM_IP_LEN]
Definition: IP_Addressing.h:54
NETSIM_IPAddress ip
Definition: TCP.h:114
UINT16 port
Definition: TCP.h:115
TCP_CONNECTION_STATE tcp_state
Present State of the TCP Connection.
Definition: TCB.h:47
struct stru_tcp_Transmission_Control_Block::stru_tcb_send_seq_var SND
struct stru_tcp_Transmission_Control_Block::stru_tcb_recv_seq_var RCV
void(* set_MSS)(PNETSIM_SOCKET s, UINT16)
Definition: TCB.h:136
struct stru_tcp_Transmission_Control_Block::stru_tcb_curr_seg_var SEG
UINT synAckSent
Definition: TCP.h:96
UINT ackSent
Definition: TCP.h:100
UINT synSent
Definition: TCP.h:95