unsigned short sd_cal_crc16(unsigned char *ptr, unsigned int len) { return cal_crc(ptr, len); }
int main(int argc, char* argv[]) /* server program called with no argument */ { int sock_ftps, ftps_addr_len; int sock_from_troll_m2, from_troll_addr_len; int sock_ack, ack_addr_len; unsigned short checksum = 0; int buflen = 0; int head = 0; // int tail = 0; struct sockaddr_in ftps_addr; struct sockaddr_in troll_m2_addr; struct sockaddr_in troll_m1_addr; struct sockaddr_in ack_addr; struct hostent *hp; hp = gethostbyname(argv[1]); nr_failed_acks = 0; if(hp == 0) { perror("Unknown host"); exit(1); } TCPD_MSG tcpd_recv; TCPD_MSG ack; TCPD_MSG tcpd_send; int i = 0; int j = 0; //FLAGS int crc_match = FALSE; int ack_buffer_flag = FALSE; int ack_exist = FALSE; int window_index = 0; int lowest_seq = 100000; int lowest_seq_window_index = 0; fd_set read_fds; int new_buf_size = SOCK_BUFF_SIZE; //init window for(i = 0; i < 20; i++) { window_srv[i] = -1; } //init ack for(j = 0; j < 64; j++) { ack_buffer[j] = -1; } /*create from ftps socket*/ if((sock_ftps = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("opening datagram socket for send to ftps"); exit(1); } /*create troll socket*/ if((sock_from_troll_m2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("opening datagram socket for recv from troll m2"); exit(1); } /* create troll_addr with parameters and bind troll_addr to socket */ troll_m2_addr.sin_family = AF_INET; troll_m2_addr.sin_port = htons(TCPD_PORT_M1); troll_m2_addr.sin_addr.s_addr = INADDR_ANY; if(bind(sock_from_troll_m2, (struct sockaddr *)&troll_m2_addr, sizeof(troll_m2_addr)) < 0) { perror("Recv(receive from troll socket Bind failed"); exit(2); } setsockopt(sock_from_troll_m2, SOL_SOCKET, SO_RCVBUF, &new_buf_size, sizeof(&new_buf_size)); if((sock_ack = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("opening datagram socket for send ack to tcpd_m2"); exit(1); } #ifndef LOCALTEST troll_m1_addr.sin_family = AF_INET; troll_m1_addr.sin_port = htons(TROLL_PORT_M1); troll_m1_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); #else troll_m1_addr.sin_family = AF_INET; troll_m1_addr.sin_port = htons(TCPD_PORT_M2); troll_m1_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); #endif //Contruct troll header ack_addr.sin_family = AF_INET; ack_addr.sin_port = htons(TCPD_PORT_M2); bcopy(hp->h_addr, (void*)&ack_addr.sin_addr, hp->h_length); ftps_addr.sin_family = AF_INET; //ftps_addr.sin_port = htons(TCPD_PORT); ftps_addr.sin_port = htons(TCPD_PORT_FTPS); ftps_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //GET LEN FOR RECVFROM ftps_addr_len=sizeof(struct sockaddr_in); from_troll_addr_len=sizeof(struct sockaddr_in); ack_addr_len = sizeof(struct sockaddr_in); bzero(ack.packet.data, MAXBUF); // recvfrom(sock_from_troll_m2, (void *)&recv_buffer[head], sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m2_addr, &from_troll_addr_len); FD_ZERO(&read_fds); FD_SET(sock_from_troll_m2, &read_fds); while(1) { if(select(FD_SETSIZE, &read_fds, NULL, NULL, NULL) < 0) { perror("SELECT ERROR"); exit(0); } if(FD_ISSET(sock_from_troll_m2, &read_fds)) { if(recvfrom(sock_from_troll_m2, (void *)&recv_buffer[head], sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m2_addr, &from_troll_addr_len) < 0) { perror("RECV from troll m2 error"); exit(0); } printf("\nRECV FROM TROLL_M2, SEQ:%d\n", recv_buffer[head].packet.seq_num); if (!is_acceptable_seq(recv_buffer[head].packet.seq_num)) { printf("OUT OF window BOUND\n"); FD_ZERO(&read_fds); FD_SET(sock_from_troll_m2,&read_fds); continue; } checksum = cal_crc((void *)&recv_buffer[head].packet, (unsigned char)sizeof(struct packet_data));//CRC printf("\nCAL CHECKSUM: %u, RECV CHECKSUM: %u\n", checksum, recv_buffer[head].checksum); if(checksum == recv_buffer[head].checksum) { crc_match = TRUE; ack_buffer_flag = FALSE;//CHECK FOR DUP // for(i = 0; i< 64; i++) { if(ack_buffer[i] == recv_buffer[head].packet.seq_num) { ack_buffer_flag = TRUE; } } //printf("\nACK_BUFFER_FLAG STATUS %d\n", ack_buffer_flag); // if(ack_buffer_flag != TRUE)//NOT IN BUFFER { ack_exist = FALSE; for(i = 0; i < 20; i++) { //CHECK WHETHER IN WINOW OR NOT if(window_srv[i] == recv_buffer[head].packet.seq_num) { ack_exist = TRUE; } } if(ack_exist == TRUE) { printf("\nIN THE WINDOWS, WILL ARRIVE FTPS SOON\n",recv_buffer[head].packet.seq_num); } else if(ack_exist == FALSE)//NOT IN WINDOW { window_index = recv_buffer[head].packet.seq_num % 20; // //window_index = recv_buffer[head].packet.seq_num; window_srv[window_index] = recv_buffer[head].packet.seq_num; printf("\nWIN SRV [%d]:%d\n",window_index, recv_buffer[head].packet.seq_num); if(head < 63) { head++; } else { head = 0;//Make buffer back // } } }//end if ack_flag else if(ack_buffer_flag == TRUE) { printf("\nACK FOR DUPLICATE AGAIN\n"); ack.packet.ack = 1; ack.packet.ack_seq = recv_buffer[head].packet.seq_num; ack.tcpd_header = ack_addr; ack.checksum = cal_crc((void *)&ack.packet, (unsigned char)sizeof(struct packet_data)); //sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&ack_addr, sizeof(ack_addr)); if(sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m1_addr, sizeof(troll_m1_addr)) < 0) { perror("send to sock_ack error"); exit(0); } printf("\nSEND ACK SEQ %d, TO TROLL M1\n", ack.packet.ack_seq); } } else { crc_match = FALSE;//checksum wrong printf("\nCRC HAVE SOMETHING WRONG\n"); } // if(crc_match == TRUE) // if(1) { // printf("\nENTER IF CRC_MATCH\n"); // //find the lowest window seq; lowest_seq = 100000; lowest_seq_window_index = -1; for(i = 0; i < 20; i++) { if((window_srv[i] < lowest_seq) && (window_srv[i] != -1)) { lowest_seq = window_srv[i]; lowest_seq_window_index = i; } } //// lowest_seq = find_min(); //// lowest_seq_window_index = find_min_win_index(lowest_seq); printf("\nLOWEST_SEQ %d\n", lowest_seq); printf("\nLASTSENT: %d\n", lastsent); print_win(); if(lowest_seq == (lastsent + 1))//if lowest in win is to be sent { int buffer_index = 0; for(i = 0; i < 64; i++) { if(recv_buffer[i].packet.seq_num == lowest_seq) { buffer_index = i; break; } } // // // int buffer_index = find_min_buffer(lowest_seq); if(sendto(sock_ftps, (void *)&recv_buffer[buffer_index], sizeof(TCPD_MSG), 0, (struct sockaddr *)&ftps_addr, sizeof(ftps_addr)) < 0) { perror("Send to sock_ftps error"); exit(0); } // printf("\nSEND SEQ:%d to ftps\n", recv_buffer[buffer_index].packet.seq_num); // lastsent = recv_buffer[buffer_index].packet.seq_num; printf("[%d]finish bit: %d\n", recv_buffer[buffer_index].packet.seq_num, recv_buffer[buffer_index].packet.fin); if(recv_buffer[buffer_index].packet.fin != 1) { ack.packet.ack = 1; ack.packet.ack_seq = recv_buffer[buffer_index].packet.seq_num; ///////// //lastsent = recv_buffer[buffer_index].packet.seq_num; // printf("\nLAST SENT: %d\n", lastsent); // printf("\nACK.PACKET.ACK_SEQ: %d\n", ack.packet.ack_seq); ack_buffer[pointer] = recv_buffer[buffer_index].packet.seq_num; printf("\nPTR Value %d; lastsent = %d\n", pointer, lastsent); pointer = (pointer + 1)%64; // // if(pointer < 63) // { // pointer++; // } // else // { // pointer = 0; // } // ack.checksum = cal_crc((void*)&ack.packet, (unsigned char)sizeof(struct packet_data)); // printf("\nACK CHECKSUM %d\n", ack.checksum); ack.tcpd_header = ack_addr; #ifdef LOCALTEST // /sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&ack_addr, sizeof(ack_addr)); if(ack.packet.ack_seq % 5 == 0) { sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m1_addr, sizeof(troll_m1_addr)); } else { if (nr_failed_acks > 5) { sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m1_addr, sizeof(troll_m1_addr)); } nr_failed_acks++; } #else sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m1_addr, sizeof(troll_m1_addr)); #endif printf("\nACK SEQ SENT:%d\n", recv_buffer[buffer_index].packet.seq_num); window_srv[lowest_seq_window_index] = -1; }//end if fin != 1 else { printf("\nRECEIVE FIN!!! seq: %d\n", recv_buffer[buffer_index].packet.seq_num); sendto(sock_ftps, (void*)&recv_buffer[buffer_index], sizeof(TCPD_MSG), 0, (struct sockaddr *)&ftps_addr, sizeof(ftps_addr)); // //sendto(sock_ftps, (void*)&recv_buffer[buffer_index], sizeof(TCPD_MSG), 0, (struct sockaddr *)&ftps_addr, sizeof(ftps_addr)); ack.tcpd_header = ack_addr; ack.packet.fin_ack = 1; ack.packet.ack = 0; ack.packet.ack_seq = recv_buffer[buffer_index].packet.seq_num; ack.checksum = cal_crc((void *)&ack.packet, (unsigned char)sizeof(struct packet_data)); window_srv[lowest_seq_window_index] = -1; strcpy(ack.packet.data, "FIN"); //sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&ack_addr, sizeof(ack_addr)); sendto(sock_ack, (void *)&ack, sizeof(TCPD_MSG), 0, (struct sockaddr *)&troll_m1_addr, sizeof(troll_m1_addr)); printf("\nFINISH TRANSFER FILE\n"); close(sock_ack); close(sock_from_troll_m2); close(sock_ftps); exit(0); } }//END IF LAST SENT else { printf("\nSLEEP FOR WAITING\n"); usleep(100000); }//END LOW } else if(crc_match == FALSE) { printf("\nCRC WRONG, RETRANSMIT\n"); } } FD_ZERO(&read_fds); FD_SET(sock_from_troll_m2,&read_fds); } }