27#include "TCP_Header.h"
30static void send_syn(PNETSIM_SOCKET s);
32void tcp_active_open(PNETSIM_SOCKET s)
34 print_tcp_log(
"Creating TCB");
36 print_tcp_log(
"Sending Syn");
40void tcp_passive_open(PNETSIM_SOCKET s, PNETSIM_SOCKET ls)
42 print_tcp_log(
"Creating TCB");
44 memcpy(&s->tcb->SEG, &ls->tcb->SEG,
sizeof s->tcb->SEG);
45 tcp_change_state(s, TCPCONNECTION_LISTEN);
48static void send_syn(PNETSIM_SOCKET s)
50 NetSim_PACKET* syn = create_syn(s,pstruEventDetails->dEventTime);
52 s->tcb->SND.UNA = s->tcb->ISS;
53 s->tcb->SND.NXT = s->tcb->ISS + 1;
54 tcp_change_state(s, TCPCONNECTION_SYN_SENT);
58 s->tcpMetrics->synSent++;
60 send_to_network(syn, s);
61 add_timeout_event(s,syn);
64void resend_syn(PNETSIM_SOCKET s)
66 PTCP_DEV_VAR tcp = GET_TCP_DEV_VAR(pstruEventDetails->nDeviceId);
68 if (s->tcb->tcp_state != TCPCONNECTION_SYN_SENT &&
69 s->tcb->tcp_state != TCPCONNECTION_SYN_RECEIVED)
71 print_tcp_log(
"ERROR: %s is called for different TCP state %s. it must be %s or %s",
73 state_to_str(s->tcb->tcp_state),
74 state_to_str(TCPCONNECTION_SYN_SENT),
75 state_to_str(TCPCONNECTION_SYN_RECEIVED));
79 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(pstruEventDetails->pPacket);
81 NetSim_PACKET* syn = get_segment_from_queue(&s->tcb->retransmissionQueue, hdr->SeqNum);
83 fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);
84 pstruEventDetails->pPacket = NULL;
86 if (s->tcb->synRetries < tcp->MaxSynRetries)
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;
92 send_to_network(syn, s);
93 add_timeout_event(s, syn);
95 if(syn->nControlDataType == TCPPACKET_SYN)
96 s->tcpMetrics->synSent++;
98 s->tcpMetrics->synAckSent++;
100 s->tcb->synRetries++;
104 print_tcp_log(
"Connection fails for local address %s:%d, Remote address %s:%d",
105 s->localAddr->ip->str_ip,
107 s->remoteAddr->ip->str_ip,
108 s->remoteAddr->port);
109 tcp_close_socket(s,pstruEventDetails->nDeviceId);
113void process_syn(PNETSIM_SOCKET s,NetSim_PACKET* p)
117 s->listen_callback(s, p);
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))
130 s->listen_callback(s, p);
133 fn_NetSim_Packet_FreePacket(p);
136void rcv_SYN(PNETSIM_SOCKET s, NetSim_PACKET* syn)
138 s->tcb->RCV.NXT = s->tcb->SEG.SEQ + 1;
139 s->tcb->IRS = s->tcb->SEG.SEQ;
142 PWsopt wsopt = get_tcp_option(TCP_GET_SEGMENT_HDR(syn),
143 TCP_OPTION_WINDOW_SCALE);
145 set_window_scaling(s, wsopt);
148 PMSS_OPTION opt = get_tcp_option(TCP_GET_SEGMENT_HDR(syn),TCP_OPTION_MSS);
150 s->tcb->set_MSS(s, opt->MSSData);
153 PTSopt tsopt = get_tcp_option(TCP_GET_SEGMENT_HDR(syn),
154 TCP_OPTION_TIMESTAMP);
155 set_timestamp_value(s, TCP_GET_SEGMENT_HDR(syn), tsopt);
157 if (s->tcb->isSackPermitted)
160 PSACKPERMITTED_OPTION sackp = get_tcp_option(TCP_GET_SEGMENT_HDR(syn), TCP_OPTION_SACK_PERMITTED);
162 s->tcb->isSackPermitted =
true;
164 s->tcb->isSackPermitted =
false;
167 NetSim_PACKET* synAck = create_synAck(s, pstruEventDetails->dEventTime);
168 tcp_change_state(s, TCPCONNECTION_SYN_RECEIVED);
170 s->tcb->SND.UNA = s->tcb->ISS;
171 s->tcb->SND.NXT = s->tcb->ISS + 1;
173 s->tcb->synRetries++;
175 s->tcpMetrics->synAckSent++;
177 send_to_network(synAck, s);
178 add_timeout_event(s, synAck);
181void send_rst(PNETSIM_SOCKET s, NetSim_PACKET* p, UINT c)
183 print_tcp_log(
"Sending RST packet");
184 NetSim_PACKET* rst = create_rst(p, pstruEventDetails->dEventTime, c);
185 send_to_network(rst, s);
188void send_ack(PNETSIM_SOCKET s,
double time, UINT32 seqNo, UINT32 ackNo)
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);
196void send_fin_ack(PNETSIM_SOCKET s,
double time, UINT32 seqNo, UINT32 ackNo)
198 print_tcp_log(
"Sending fin-ack with seq=%d, Ack=%d.", seqNo, ackNo);
199 NetSim_PACKET* ack = create_ack(s, time, seqNo, ackNo);
200 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(ack);
202 s->tcpMetrics->ackSent++;
203 send_to_network(ack, s);
206void packet_arrive_at_closed_state(PNETSIM_SOCKET s, NetSim_PACKET* p)
208 print_tcp_log(
"TCP_STATE=CLOSED");
211 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
225 print_tcp_log(
"Discarding segment");
227 fn_NetSim_Packet_FreePacket(p);
228 pstruEventDetails->pPacket = NULL;
231void packet_arrives_at_listen_state(PNETSIM_SOCKET s, NetSim_PACKET* p)
233 print_tcp_log(
"TCP_STATE=LISTEN");
234 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
248 fnNetSimError(
"Unknown processing mode in %s",
253 print_tcp_log(
"Discarding Packet");
255 fn_NetSim_Packet_FreePacket(p);
256 pstruEventDetails->pPacket = NULL;
259void packet_arrives_at_synsent_state(PNETSIM_SOCKET s, NetSim_PACKET* p)
261 bool isAckAcceptable =
false;
262 print_tcp_log(
"TCP_STATE = SYN-SENT");
264 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
267 if (s->tcb->SEG.ACK <= s->tcb->ISS ||
268 s->tcb->SEG.ACK > s->tcb->SND.NXT)
274 if (s->tcb->SND.UNA <= s->tcb->SEG.ACK &&
275 s->tcb->SEG.ACK <= s->tcb->SND.NXT)
276 isAckAcceptable =
true;
282 print_tcp_log(
"Error: Connection reset");
284 tcp_change_state(s, TCPCONNECTION_CLOSED);
285 tcp_close_socket(s, s->localDeviceId);
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;
302 PMSS_OPTION opt = get_tcp_option(hdr, TCP_OPTION_MSS);
304 s->tcb->set_MSS(s, opt->MSSData);
309 PTSopt tsopt = get_tcp_option(hdr,
310 TCP_OPTION_TIMESTAMP);
311 set_timestamp_value(s, hdr, tsopt);
314 delete_segment_from_queue(&s->tcb->retransmissionQueue, s->tcb->SEG.ACK);
316 if (s->tcb->SND.UNA > s->tcb->ISS)
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;
324 pstruEventDetails->dEventTime,
327 tcp_change_state(s, TCPCONNECTION_ESTABLISHED);
335 print_tcp_log(
"Discarding Packet");
337 fn_NetSim_Packet_FreePacket(p);
338 pstruEventDetails->pPacket = NULL;
341void send_fin(PNETSIM_SOCKET s)
343 static bool isShowError =
true;
344 NetSim_PACKET* fin = create_fin(s, pstruEventDetails->dEventTime);
346 send_to_network(fin, s);
350 fnNetSimError(
"RTO timeout is not implemented for FIN");