I have problem with switch statement. Like you see I have condition like expression and I have 3 cases (0, 1, 2). To get an overview, this function is three-way handshake between client and server. In case 0 the program going to receive SYN and try to send ACK + SYN in case 1. But when checksum is incorrect the program jump over to case 1 and send ACK + SYN. You can see the print "Im here" with condition value do not show "Im here 4" also the program know we have wrong checksum but still it goes over to case 1. Help me :(
int Server_ThreeWay_Handshake(int fileDescriptor, fd_set *activFdSet, struct sockaddr_in *client)
{
short int condition = 0; // Using in switch for different condition
short int run = 0; // Using in while loop
short int Window_Size = rand() % 7 + 1; // Generat window size
short int i = 0; // Using for while loop
fd_set readFdSet;
RTP Read;
RTP Write;
struct timeval timer;
int len = sizeof(struct sockaddr); // Used in recvfrom to send len of sockaddr
do
{
switch (condition)
{
case 0:{ // In this case the SYN goint to be recevied
printf("Im here 1: %d\n", condition);
readFdSet = *activFdSet;
if (select(FD_SETSIZE, &readFdSet, NULL, NULL, NULL) < 0)
{
perror("\x1b[31mServer: select fail!\x1b[0m\n");
}
if (FD_ISSET(fileDescriptor, &readFdSet))
{
printf("Im here 2: %d\n", condition);
// If we recevied some SYN
if (recvfrom(fileDescriptor, &Read, MAXMSG, 0, (struct sockaddr *)client, &len))
{
printf("Im here 3: %d\n", condition);
int Read_CheckSum = Read.CheckSum;
CheckSum_Function(&Read);
if (Read.SYN == true && Read.CheckSum == 10)
{
printf("Server: revevied SYN with SEQ number: \x1b[32m%d \x1b[0m With CheckSum: \x1b[32m%d\x1b[0m\n", (int)Read.SEQ), Read.CheckSum;
printf("Im here 4: %d\n", condition);
// Controll window_size and set it to Length if Length is < window_size
if (Read.Length < Window_Size)
{
Window_Size = Read.Length;
}
condition = 1;
}
else
{
printf("Im here 5: %d\n", condition);
printf("\x1b[31mServer: Incorrect checksum\x1b[0m\n");
}
}
}
}
case 1:{ // In this case server send ACK on SYN to client
printf("Im here 6: %d\n", condition);
Set_Default_Values(&Write); // Set to default
Write.ACK = true;
Write.SYN = true;
Write.Length = Window_Size;
strcpy(Write.Data, "SYNACK"); // Save SYN like text in Data for checksum
SEQ_Generator(&Write); // Generate SEQ to ACK
Write.ACK_Number = Read.SEQ;
do
{
// Sending ACK + SYN
CheckSum_Function(&Write);
sendto(fileDescriptor, &Write, sizeof(Write), 0, (struct sockaddr *)client, sizeof(*client));
printf("Server: send ACK + SYN number: \x1b[32m%d\x1b[0m, with SEQ number: \x1b[32m%d\x1b[0m with checksum: \x1b[32m%d\x1b[0m\n", (int)Write.ACK_Number, (int)Write.SEQ, (int)Write.CheckSum);
timer.tv_sec = 1;
timer.tv_usec = 0;
readFdSet = *activFdSet;
// Using select for timeout
if (select(FD_SETSIZE, &readFdSet, NULL, NULL, &timer) == -1)
{
printf("\x1b[31mServer: select failed!\x1b[0m\n");
}
if (FD_ISSET(fileDescriptor, &readFdSet))
{
// Recevied last ACK from client
short int Recevied_Last_ACK = recvfrom(fileDescriptor, &Read, MAXMSG, 0, (struct sockaddr *)client, &len);
int checkSum = Read.CheckSum;
CheckSum_Function(&Read);
if (Recevied_Last_ACK == 0)
{
Set_Default_Values(&Read);
}
if (Read.ACK == true && Read.ACK_Number == Write.SEQ && checkSum == Read.CheckSum)
{
printf("Server: recevied ACK number: \x1b[32m%d\x1b[0m with checksum: \x1b[32m%d\x1b[0m\n", (int)Read.SEQ, (int)Read.CheckSum);
condition = 2;
}
else
{
printf("\x1b[31mServer: Don't recevied ACK from client or the checksum is incorrect!\x1b[0m\n");
i++;
}
}
else
{
printf("--- Timeout ---\n");
}
if (i > 0)
{
exit(EXIT_FAILURE);
}
} while (condition == 1 && i <= 3);
}
case 2:{
LastReceviedSEQ = Read.SEQ;
printf("\n--- Server: Three-way handshake successful --- \n");
printf("\n--- The window size is %d ---\n", Window_Size);
break;
}
}
} while (run == 1);
}