diff --git a/build/api/mictcp_core.o b/build/api/mictcp_core.o index 672b290..c2c8dda 100644 Binary files a/build/api/mictcp_core.o and b/build/api/mictcp_core.o differ diff --git a/build/client b/build/client index 65893c2..2a8167f 100755 Binary files a/build/client and b/build/client differ diff --git a/build/gateway b/build/gateway index fa6dd6f..b0c11b8 100755 Binary files a/build/gateway and b/build/gateway differ diff --git a/build/mictcp.o b/build/mictcp.o index 1eae5c4..9c675a1 100644 Binary files a/build/mictcp.o and b/build/mictcp.o differ diff --git a/build/server b/build/server index 9273da9..25dda76 100755 Binary files a/build/server and b/build/server differ diff --git a/src/api/mictcp_core.c b/src/api/mictcp_core.c index 8a0fa05..b1f7ff4 100644 --- a/src/api/mictcp_core.c +++ b/src/api/mictcp_core.c @@ -14,7 +14,7 @@ int initialized = -1; int sys_socket; pthread_t listen_th; pthread_mutex_t lock; -unsigned short loss_rate = 50; //sur 100 +unsigned short loss_rate = 0; //sur 100 struct sockaddr_in remote_addr; /* This is for the buffer */ diff --git a/src/mictcp.c b/src/mictcp.c index 6e9a339..a28c498 100644 --- a/src/mictcp.c +++ b/src/mictcp.c @@ -3,7 +3,7 @@ #include #include #define NBR_SOCKETS 1024 -#define TIMEOUT_DEFAUT 1000 +#define TIMEOUT_DEFAUT 1000000 #define WINDOW_SIZE 10 #define LOSS_ACCEPTABILITY 2 // sur 100 #define ATTENTE_ACK 1 @@ -42,10 +42,11 @@ static enhanced_socket tab_sockets[NBR_SOCKETS]; int timeout = TIMEOUT_DEFAUT; int established = 0; pthread_t envoi_syn_ack_tid; +pthread_t envoi_fin_ack_tid; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t end_accept_cond = PTHREAD_COND_INITIALIZER; char debug=1; -char version=2; +char version=4; //================================== SIGNATURES DES FONCTIONS PRIVEES ============================= int valid_socket(int socket); @@ -61,6 +62,7 @@ int accept_loss(int socket); void set_mic_tcp_pdu(mic_tcp_pdu* pdu, unsigned short source_port, unsigned short dest_port, unsigned int seq_num, unsigned int ack_num, unsigned char syn, unsigned char ack, unsigned char fin, char* data, int size); void process_syn_pdu(mic_tcp_pdu pdu,mic_tcp_sock_addr addr, int mic_sock); void * envoi_syn_ack(void * arg); +void * envoi_fin_ack(void * arg); //================================== FONCTIONS DE MICTCP ============================= @@ -84,6 +86,7 @@ int mic_tcp_socket(start_mode sm) int result = initialize_components(sm); /* Appel obligatoire */ if (result < 0) { + printf("Problème initialize_components\n"); return -1; } @@ -105,7 +108,7 @@ int mic_tcp_bind(int socket, mic_tcp_sock_addr addr) tab_sockets[socket].socket.addr = addr; tab_sockets[socket].socket.state = WAITING; display_enhanced_socket(tab_sockets[socket],""); - + printf("Socket bound\n"); return 0; } @@ -138,6 +141,7 @@ int mic_tcp_accept(int socket, mic_tcp_sock_addr *addr) if(pthread_mutex_unlock(&mutex)!= 0){error("erreur unlock mutex",__LINE__);} //unlock mutex } display_enhanced_socket(tab_sockets[socket], "État du socket aprés la connection :"); + printf("Connexion établie\n"); return 0; } @@ -200,25 +204,25 @@ int mic_tcp_connect(int socket, mic_tcp_sock_addr addr) while (1){ args->recpt=-1; - printf("avant creation thread TAA\n"); + //printf("avant creation thread TAA\n"); pthread_create(&attente_ack_tid, NULL,attente_ack,(void *)args); - printf("aprés creation thread TAA\n"); + //printf("aprés creation thread TAA\n"); usleep(timeout); - if (pthread_cancel(attente_ack_tid)) printf("destruction du TAA"); + if (pthread_cancel(attente_ack_tid)) printf(debug?"destruction du TAA":""); if (args->recpt == -1){ if (tab_sockets[socket].socket.state == ESTABLISHED){ break; } IP_send(pdu, tab_sockets[socket].dist_addr); - printf("SYN ACK pas encore recu, envoi d'un doublon du syn\n"); + printf("SYN ACK pas encore reçu, envoi d'un doublon du SYN\n"); continue; } display_mic_tcp_pdu(args->pdu_r,"pdu reçu :"); if (args->pdu_r.header.ack == 1 && args->pdu_r.header.syn == 1 /*on s'occuppe plus tard de la verif du num de seq*/){ - printf("Bon PDU SYN ACK recu \n"); + //printf("Bon PDU SYN ACK recu \n"); tab_sockets[socket].NoSeqDist = args->pdu_r.header.seq_num; // récupérer n° de seq du server @@ -256,6 +260,7 @@ int mic_tcp_connect(int socket, mic_tcp_sock_addr addr) } display_enhanced_socket(tab_sockets[socket], "État du socket aprés l'établissement de la connection :"); + printf("Connexion établie\n"); return 0; } @@ -268,8 +273,8 @@ int mic_tcp_send(int mic_sock, char *mesg, int mesg_size) if (tab_sockets[mic_sock].socket.state != ESTABLISHED) { - printf("l'utilisateur n’est pas connecté \n"); - exit(1); + printf("le client n’est pas connecté \n"); + return -1; } // create pdu mic_tcp_pdu pdu; @@ -298,24 +303,24 @@ int mic_tcp_send(int mic_sock, char *mesg, int mesg_size) while (1) { args->recpt=-1; - printf("avant creation thread TAA\n"); + //printf("avant creation thread TAA\n"); pthread_create(&attente_ack_tid, NULL,attente_ack,(void *)args); - printf("aprés creation thread TAA\n"); + //printf("aprés creation thread TAA\n"); usleep(timeout); - if (pthread_cancel(attente_ack_tid)) printf("destruction du TAA"); + if (pthread_cancel(attente_ack_tid)) printf(debug?"destruction du TAA":""); if (args->recpt == -1){ // Si on ne reçoit pas le ACK if (version>2){ if (accept_loss(mic_sock)) { // Si on peut accepter la perte, on ne retransmet pas addValueCircularBuff(&tab_sockets[mic_sock].buffer,0); - printf("===========Perte Acceptée============\n"); + printf("Perte acceptée\n"); tab_sockets[mic_sock].socket.state = ESTABLISHED; return sent_size; } else { - printf("============Perte inacceptable=============\n"); + printf("Perte non acceptée\n"); } } sent_size = IP_send(pdu, tab_sockets[mic_sock].dist_addr); @@ -431,9 +436,43 @@ void process_syn_pdu(mic_tcp_pdu pdu,mic_tcp_sock_addr addr, int mic_sock){ args->socket=mic_sock; args->pdu_r=pdu_r; - printf("avant creation thread TESA\n"); + //printf("avant creation thread TESA\n"); pthread_create(&envoi_syn_ack_tid, NULL,envoi_syn_ack,(void *)args); - printf("aprés creation thread TESA\n"); + //printf("aprés creation thread TESA\n"); + + +} + +void process_fin_pdu(mic_tcp_pdu pdu,mic_tcp_sock_addr addr, int mic_sock){ + printf("[MIC-TCP] Appel de la fonction: "); + printf(__FUNCTION__); + printf("\n"); + + tab_sockets[mic_sock].socket.state = CLOSING; + mic_tcp_pdu pdu_r; + + set_mic_tcp_pdu(&pdu_r, + tab_sockets[mic_sock].socket.addr.port, + tab_sockets[mic_sock].dist_addr.port, + tab_sockets[mic_sock].NoSeqLoc, + tab_sockets[mic_sock].NoSeqDist, + 0,1,1,NULL,0 + ); + + display_mic_tcp_pdu(pdu_r, "Construction du Pdu FIN ACK : \n"); + display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "Envoi du PDU FIN ACK à l'adresse:"); + + IP_send(pdu_r, addr); + + + + arg_thread* args = malloc(sizeof(arg_thread)); + args->socket=mic_sock; + args->pdu_r=pdu_r; + + //printf("avant creation thread TESA\n"); + pthread_create(&envoi_fin_ack_tid, NULL,envoi_fin_ack,(void *)args); + //printf("aprés creation thread TESA\n"); } @@ -454,7 +493,7 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre if (version<2) { app_buffer_put(pdu.payload); // envoyer la data dans le buffer - printf("data in the buffer\n"); + //printf("data in the buffer\n"); return; } @@ -466,6 +505,14 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre { printf("Doublon PDU SYN recu\n"); } + if (pdu.header.fin == 1 && tab_sockets[mic_sock].socket.state == ESTABLISHED) // si PDU FIN + { + process_fin_pdu(pdu,addr, mic_sock); + } + else if (pdu.header.syn == 1 && tab_sockets[mic_sock].socket.state == CLOSING) // si Doublon PDU FIN + { + printf("Doublon PDU FIN recu\n"); + } else if (pdu.header.ack == 1 && tab_sockets[mic_sock].socket.state == SYN_RECEIVED) { // Si ACK de connection reçu @@ -476,7 +523,7 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre pthread_cond_broadcast(&end_accept_cond); // Rendre la main au client une fois le accept terminé if(pthread_mutex_unlock(&mutex)!= 0){error("erreur unlock mutex",__LINE__);} //unlock mutex - printf("Connexion établie\n"); + //printf("Connexion établie\n"); } else if(pdu.header.ack == 0 && pdu.header.seq_num == tab_sockets[mic_sock].NoSeqDist && tab_sockets[mic_sock].socket.state == ESTABLISHED) @@ -501,7 +548,7 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre tab_sockets[mic_sock].NoSeqDist = ((tab_sockets[mic_sock].NoSeqDist) + 1) % 2; //update n° seq distant app_buffer_put(pdu.payload); // envoyer la data dans le buffer - printf("data in the buffer\n"); + //printf("data in the buffer\n"); } else if(pdu.header.ack == 0 && pdu.header.seq_num != tab_sockets[mic_sock].NoSeqDist && tab_sockets[mic_sock].socket.state == ESTABLISHED) { // Si Doublon PDU de DATA @@ -525,7 +572,7 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre }else{ - printf("PDU inattendu recu :\n"); + printf("PDU inattendu reçu, PDU rejeté\n"); display_enhanced_socket(tab_sockets[mic_sock], "l'état du socket"); } } @@ -543,8 +590,84 @@ int mic_tcp_close(int socket) if (valid_socket(socket) && tab_sockets[socket].socket.state == ESTABLISHED) { - tab_sockets[socket].socket.state = CLOSED; - tab_sockets[socket].socket.fd = -1; + tab_sockets[socket].socket.state = CLOSING; + mic_tcp_pdu pdu; + set_mic_tcp_pdu( + &pdu, + tab_sockets[socket].socket.addr.port, + tab_sockets[socket].dist_addr.port, + tab_sockets[socket].NoSeqLoc, + -1, + 0,0,1, + NULL,0 + ); + + display_mic_tcp_pdu(pdu, "creation du pdu FIN:"); + + display_mic_tcp_sock_addr(tab_sockets[socket].dist_addr, "envoi du pdu FIN vers l'adresse :"); + + + IP_send(pdu, tab_sockets[socket].dist_addr); + // display_enhanced_socket(tab_sockets[socket], "état du socket en attente du syn ack :"); + + pthread_t attente_ack_tid; + arg_thread* args = malloc(sizeof(arg_thread)); + + while (1){ + + args->recpt=-1; + //printf("avant creation thread TAA\n"); + pthread_create(&attente_ack_tid, NULL,attente_ack,(void *)args); + //printf("aprés creation thread TAA\n"); + + usleep(timeout); + if (pthread_cancel(attente_ack_tid)) //printf("destruction du TAA"); + + if (args->recpt == -1){ + if (tab_sockets[socket].socket.state == CLOSED){ + break; + } + IP_send(pdu, tab_sockets[socket].dist_addr); + printf("ACK pas encore reçu, envoi d'un doublon du FIN\n"); + continue; + } + display_mic_tcp_pdu(args->pdu_r,"pdu reçu :"); + + if (args->pdu_r.header.ack == 1 && args->pdu_r.header.fin == 1 /*on s'occuppe plus tard de la verif du num de seq*/){ + //printf("Bon PDU FIN ACK recu \n"); + + set_mic_tcp_pdu( + &pdu, + tab_sockets[socket].socket.addr.port, + tab_sockets[socket].dist_addr.port, + -1, + args->pdu_r.header.seq_num, + 0,1,0, + NULL,0 + ); + + display_mic_tcp_pdu(pdu, "creation du pdu ACK:"); + + display_mic_tcp_sock_addr(tab_sockets[socket].dist_addr, "envoi du pdu ACK vers l'adresse :"); + + IP_send(pdu, tab_sockets[socket].dist_addr); + + tab_sockets[socket].socket.state = CLOSED; + +/*on attend naivement l'arrivee d'un nouveau fin ack au cas ou le ack a ete perdu, puis on relance la boucle, pour verifier*/ + continue; + + } + else { + continue; + } + + + } + display_enhanced_socket(tab_sockets[socket], "État du socket aprés la fermeture de la connexion :"); + printf("Connexion fermée\n"); + tab_sockets[socket].socket.fd = -1; + return 0; } return -1; } @@ -594,7 +717,75 @@ void set_mic_tcp_pdu(mic_tcp_pdu* pdu, unsigned short source_port, unsigned shor pdu->payload.data = data; pdu->payload.size = size; } - + +void * envoi_syn_ack(void * arg) { + printf(debug?"début du TESA : thread d'envoi de SYN ACK'\n":""); + arg_thread* args = (arg_thread*)arg; + while (1) + { + if (tab_sockets[args->socket].socket.state == SYN_RECEIVED) + { + + display_mic_tcp_pdu(args->pdu_r, "renvoi du pdu syn ack"); + display_mic_tcp_sock_addr(tab_sockets[args->socket].dist_addr,"a l'adresse"); + IP_send(args->pdu_r, tab_sockets[args->socket].dist_addr); + printf(debug?"TESA: je renvoie le Syn ack\n":""); + } + else if (tab_sockets[args->socket].socket.state == ESTABLISHED) + { + printf("!Destruction du TESA!"); + pthread_exit(NULL); + } + usleep(timeout); + } +} + +void * envoi_fin_ack(void * arg) { + printf(debug?"début du TESA : thread d'envoi de FIN ACK'\n":""); + arg_thread* args = (arg_thread*)arg; + while (1) + { + if (tab_sockets[args->socket].socket.state == CLOSING) + { + + display_mic_tcp_pdu(args->pdu_r, "renvoi du pdu fin ack"); + display_mic_tcp_sock_addr(tab_sockets[args->socket].dist_addr,"a l'adresse"); + IP_send(args->pdu_r, tab_sockets[args->socket].dist_addr); + printf(debug?"TESA: je renvoie le FIN ack\n":""); + } + else if (tab_sockets[args->socket].socket.state == CLOSED) + { + printf("!Destruction du TESA!"); + pthread_exit(NULL); + } + usleep(timeout); + } +} + +void error(char * message, int line){ + printf("%s at line %d\n",message,line); + exit(1); +} + +int accept_loss(int socket){ + int sum = 0; + for(int i = 0; i < WINDOW_SIZE; i++){ // somme de tous les packets reçus + sum += tab_sockets[socket].buffer.table[i]; + } + + if(sum < WINDOW_SIZE*(100-LOSS_ACCEPTABILITY)/100){// si le nombre de packets reçus est inférieur au nombre acceptable + return 0; // on accepte pas la perte + } + return 1; +} + +void addValueCircularBuff(circularBuffer* buffer, char Value ){ + buffer->table[buffer->last_index+1%WINDOW_SIZE]=Value; + buffer->last_index = buffer->last_index + 1 % WINDOW_SIZE; +} + +//================================== CORPS DES FONCTIONS DE DEBUG ============================= + void display_mic_tcp_pdu(mic_tcp_pdu pdu, char* prefix) { if (!debug) return ; printf("------------------------------------------\n%s\n", prefix); @@ -661,48 +852,4 @@ void * attente_ack(void * arg) { args->recpt=IP_recv(&args->pdu_r,NULL, 0) ; printf("TAA: reception effectuee, autodestruction entamee\n"); pthread_exit(NULL); -} - -void * envoi_syn_ack(void * arg) { - printf(debug?"début du TESA : thread d'envoi de SYN ACK'\n":""); - arg_thread* args = (arg_thread*)arg; - while (1) - { - if (tab_sockets[args->socket].socket.state == SYN_RECEIVED) - { - - display_mic_tcp_pdu(args->pdu_r, "renvoi du pdu syn ack"); - display_mic_tcp_sock_addr(tab_sockets[args->socket].dist_addr,"a l'adresse"); - IP_send(args->pdu_r, tab_sockets[args->socket].dist_addr); - printf(debug?"TESA: je renvoie le Syn ack\n":""); - } - else if (tab_sockets[args->socket].socket.state == ESTABLISHED) - { - printf("!Destruction du TESA!"); - pthread_exit(NULL); - } - usleep(timeout); - } -} - -void error(char * message, int line){ - printf("%s at line %d\n",message,line); - exit(1); -} - -int accept_loss(int socket){ - int sum = 0; - for(int i = 0; i < WINDOW_SIZE; i++){ // somme de tous les packets reçus - sum += tab_sockets[socket].buffer.table[i]; - } - - if(sum < WINDOW_SIZE*(100-LOSS_ACCEPTABILITY)/100){// si le nombre de packets reçus est inférieur au nombre acceptable - return 0; // on accepte pas la perte - } - return 1; -} - -void addValueCircularBuff(circularBuffer* buffer, char Value ){ - buffer->table[buffer->last_index+1%WINDOW_SIZE]=Value; - buffer->last_index = buffer->last_index + 1 % WINDOW_SIZE; -} +} \ No newline at end of file