version 4 sans fiabilite partielle, attention le code ne marche pas d'une compilation a l'autre

This commit is contained in:
Mohamed Ait-Taleb 2023-05-06 18:22:44 +01:00
parent 0df19ececa
commit 196ee68c96
10 changed files with 123 additions and 114 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,10 +1,11 @@
#include <stdio.h>
#include <mictcp.h>
#include <api/mictcp_core.h>
#define NBR_SOCKETS 1024
#define TIMEOUT_DEFAUT 1000
#define TIMEOUT_DEFAUT 5
#define WINDOW_SIZE 10
#define LOSS_ACCEPTABILITY 0 // sur 10
#define ATTENTE_ACK 1
//================================== STRUCTURES =============================
@ -40,7 +41,7 @@ int established = 0;
pthread_t attente_ack_tid;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t end_accept_cond = PTHREAD_COND_INITIALIZER;
char debug=1;
//================================== SIGNATURES DES FONCTIONS PRIVEES =============================
@ -54,7 +55,8 @@ void * attente_ack(void * arg);
void error(char * message, int line);
void addValueCircularBuff(circularBuffer* buffer, char Value );
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);
//================================== FONCTIONS DE MICTCP =============================
@ -119,6 +121,7 @@ int mic_tcp_accept(int socket, mic_tcp_sock_addr *addr)
if (valid_socket(socket))
{
tab_sockets[socket].socket.state = ACCEPTING;
display_enhanced_socket(tab_sockets[socket], "état du socket en attendant l'établissement de connection");
while (tab_sockets[socket].socket.state != ESTABLISHED){ //attente jusqu'a l'etablissement de la connexion
if(pthread_mutex_lock(&mutex)!= 0){error("erreur lock mutex",__LINE__);} //lock mutex
pthread_cond_wait(&end_accept_cond,&mutex);
@ -142,75 +145,79 @@ int mic_tcp_connect(int socket, mic_tcp_sock_addr addr)
{
tab_sockets[socket].dist_addr = addr;
tab_sockets[socket].NoSeqLoc = 0;
tab_sockets[socket].socket.state = SYN_SENT;
// create pdu syn
mic_tcp_pdu pdu;
pdu.header.source_port = tab_sockets[socket].socket.addr.port;
pdu.header.dest_port = tab_sockets[socket].dist_addr.port;
pdu.header.seq_num = tab_sockets[socket].NoSeqLoc;
pdu.header.ack_num = -1;
pdu.header.syn = 1;
pdu.header.ack = 0;
pdu.header.fin = 0;
set_mic_tcp_pdu(
&pdu,
tab_sockets[socket].socket.addr.port,
tab_sockets[socket].dist_addr.port,
tab_sockets[socket].NoSeqLoc,
-1,
1,0,0,
NULL,0
);
pdu.payload.data = NULL;
pdu.payload.size = 0;
display_enhanced_socket(tab_sockets[socket], "état du socket");
display_mic_tcp_pdu(pdu, "envoi du pdu :");
printf("À l'adresse :\n Remote Address IP: %.*s\n", addr.ip_addr_size, addr.ip_addr);
printf("Remote Address Port: %hu\n", addr.port);
display_mic_tcp_pdu(pdu, "creation du pdu SYN:");
IP_send(pdu, tab_sockets[socket].dist_addr);
tab_sockets[socket].socket.state = SYN_SENT;
display_mic_tcp_sock_addr(addr, "envoi du pdu SYN vers l'adresse :");
mic_tcp_pdu pdu_r;
mic_tcp_sock_addr addr_r;
while (1)
{
IP_send(pdu, addr);
// display_enhanced_socket(tab_sockets[socket], "état du socket en attente du syn ack :");
while (1){
sleep(timeout);
if (IP_recv(&pdu_r,&addr_r, timeout) == -1){
if (tab_sockets[socket].socket.state == ESTABLISHED) return 0;
IP_send(pdu, tab_sockets[socket].dist_addr);
printf("j'envoie un doublon du syn\n");
printf("SYN ACK pas encore recu, envoi d'un doublon du syn\n");
continue;
}
display_mic_tcp_pdu(pdu_r,"pdu reçu :");
if (pdu_r.header.ack == 1 && pdu_r.header.syn == 1){
if (pdu_r.header.ack == 1 && pdu_r.header.syn == 1 /*on s'occuppe plus tard de la verif du num de seq*/){
printf("Bon PDU SYN ACK recu \n");
tab_sockets[socket].NoSeqDist = pdu.header.seq_num; // récupérer n° de seq du client
tab_sockets[socket].NoSeqDist = pdu_r.header.seq_num; // récupérer n° de seq du server
set_mic_tcp_pdu(
&pdu,
tab_sockets[socket].socket.addr.port,
tab_sockets[socket].dist_addr.port,
-1,
pdu_r.header.seq_num,
0,1,0,
NULL,0
);
display_mic_tcp_pdu(pdu, "creation du pdu ACK:");
pdu.header.source_port = tab_sockets[socket].socket.addr.port;
pdu.header.dest_port = tab_sockets[socket].dist_addr.port;
pdu.header.seq_num = -1;
pdu.header.ack_num = tab_sockets[socket].NoSeqDist;
pdu.header.syn = 0;
pdu.header.ack = 1;
pdu.header.fin = 0;
pdu.payload.size = 0;
pdu.payload.data = NULL;
display_mic_tcp_sock_addr(addr, "envoi du pdu ACK vers l'adresse :");
IP_send(pdu, tab_sockets[socket].dist_addr);
IP_send(pdu, addr);
printf("PDU ACK de connexion envoyé\n");
display_mic_tcp_sock_addr(tab_sockets[socket].dist_addr, "à l'adresse:");
display_mic_tcp_pdu(pdu, "Pdu ACK : \n");
mic_tcp_pdu* args = malloc(sizeof(mic_tcp_pdu));
args->header=pdu.header;
args->payload=pdu.payload;
// mic_tcp_pdu* args = malloc(sizeof(mic_tcp_pdu));
// args->header=pdu.header;
// args->payload=pdu.payload;
tab_sockets[socket].socket.state = ESTABLISHED;
break;
/*on attend naivement l'arrivee d'un nouveau syn ack au cas ou le ack a ete perdu, puis on relance la boucle, pour verifier*/
sleep(ATTENTE_ACK*timeout);
continue;
}
else {
printf(debug?"Le pdu recu n'est pas un SYN ACK\n":"");
continue;
}
}
display_enhanced_socket(tab_sockets[socket], "État du socket aprés l'établissement de la connection :");
return 0;
}
@ -329,6 +336,42 @@ int mic_tcp_recv(int socket, char *mesg, int max_mesg_size)
* le buffer de réception du socket. Cette fonction utilise la fonction
* app_buffer_put(). Elle est appelée par initialize_components()
*/
void process_syn_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 = SYN_RECEIVED;
tab_sockets[mic_sock].dist_addr=addr;
tab_sockets[mic_sock].NoSeqDist=pdu.header.seq_num;
tab_sockets[mic_sock].NoSeqLoc=0; //Premier numéro de seq toujours à 0
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,
1,1,0,NULL,0
);
display_mic_tcp_pdu(pdu_r, "Construction du Pdu SYN ACK : \n");
display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "Envoi du PDU SYN 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\n");
pthread_create(&attente_ack_tid, NULL,attente_ack,(void *)args);
printf("aprés creation thread\n");
}
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adresse distante
{
@ -341,72 +384,31 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre
; // trouver le socket destinataire
if (mic_sock == socket_desc)
{ // si aucun socket trouvé, alors retourne une erreur
printf("socket non trouvé\n");
printf(debug?"socket non trouvé\n":"");
}
if (pdu.header.syn == 1 && tab_sockets[mic_sock].socket.state == ACCEPTING) // si PDU SYN
{
printf("PDU SYN recu\n");
tab_sockets[mic_sock].socket.state = SYN_RECEIVED;
mic_tcp_pdu pdu_r;
tab_sockets[mic_sock].NoSeqDist = pdu.header.seq_num;
tab_sockets[mic_sock].dist_addr = addr;
pdu_r.header.source_port = tab_sockets[mic_sock].socket.addr.port;
pdu_r.header.dest_port = tab_sockets[mic_sock].dist_addr.port;
pdu_r.header.seq_num = tab_sockets[mic_sock].NoSeqLoc;
pdu_r.header.ack_num = tab_sockets[mic_sock].NoSeqDist;
pdu_r.header.syn = 1;
pdu_r.header.ack = 1;
pdu_r.header.fin = 0;
pdu_r.payload.size = 0;
pdu_r.payload.data = NULL;
display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "à l'adresse:");
IP_send(pdu_r, tab_sockets[mic_sock].dist_addr);
tab_sockets[mic_sock].socket.state = SYN_RECEIVED;
display_mic_tcp_pdu(pdu_r, "Pdu SYN ACK : \n");
arg_thread* args = malloc(sizeof(arg_thread));
args->socket=mic_sock;
args->pdu_r=pdu_r;
printf("avant creation thread\n");
pthread_create(&attente_ack_tid, NULL,attente_ack,(void *)args);
printf("aprés creation thread\n");
process_syn_pdu(pdu,addr, mic_sock);
}
else if (pdu.header.syn == 1 && tab_sockets[mic_sock].socket.state == SYN_RECEIVED) // si Doublon PDU SYN
{
printf("Doublon PDU SYN recu\n");
// mic_tcp_pdu pdu_r;
// tab_sockets[mic_sock].NoSeqDist = pdu.header.seq_num;
// tab_sockets[mic_sock].dist_addr = addr;
// pdu_r.header.source_port = tab_sockets[mic_sock].socket.addr.port;
// pdu_r.header.dest_port = tab_sockets[mic_sock].dist_addr.port;
// pdu_r.header.seq_num = tab_sockets[mic_sock].NoSeqLoc;
// pdu_r.header.ack_num = tab_sockets[mic_sock].NoSeqDist;
// pdu_r.header.syn = 1;
// pdu_r.header.ack = 1;
// pdu_r.header.fin = 0;
// pdu_r.payload.size = 0;
// pdu_r.payload.data = NULL;
// display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "à l'adresse:");
// IP_send(pdu_r, tab_sockets[mic_sock].dist_addr);
// display_mic_tcp_pdu(pdu_r, "Pdu SYN ACK : \n");
}
else if (pdu.header.ack == 1 && tab_sockets[mic_sock].socket.state == SYN_RECEIVED)
{ // Si ACK de connection reçu
printf("PDU ACK recu \n");
tab_sockets[mic_sock].socket.state = ESTABLISHED;
if(pthread_mutex_lock(&mutex)!= 0){error("erreur lock mutex",__LINE__);} //lock mutex
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");
}
else if(pdu.header.ack == 0 && pdu.header.seq_num == tab_sockets[mic_sock].NoSeqDist && tab_sockets[mic_sock].socket.state == ESTABLISHED)
{ // Si PDU de DATA
printf("PDU data recu \n");
@ -446,18 +448,7 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adre
printf("pdu ack envoyé\n");
}
else if (pdu.header.ack == 1 && tab_sockets[mic_sock].socket.state == SYN_RECEIVED)
{ // Si ACK de connection reçu
printf("PDU ACK recu \n");
tab_sockets[mic_sock].socket.state = ESTABLISHED;
if(pthread_mutex_lock(&mutex)!= 0){error("erreur lock mutex",__LINE__);} //lock mutex
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");
}
else if (pdu.header.ack == 1 && tab_sockets[mic_sock].socket.state == WAITING && (tab_sockets[mic_sock].NoSeqLoc != pdu.header.ack_num))
else if (pdu.header.ack == 1 && tab_sockets[mic_sock].socket.state == WAITING && (tab_sockets[mic_sock].NoSeqLoc != pdu.header.ack_num))
{
// si ACK de bon numéro de séquence
printf("PDU ACK de Data recu \n");
@ -525,7 +516,20 @@ int same_addr(mic_tcp_sock_addr *addr1, mic_tcp_sock_addr *addr2)
return 0;
}
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) {
pdu->header.source_port = source_port;
pdu->header.dest_port = dest_port;
pdu->header.seq_num = seq_num;
pdu->header.ack_num = ack_num;
pdu->header.syn = syn;
pdu->header.ack = ack;
pdu->header.fin = fin;
pdu->payload.data = data;
pdu->payload.size = size;
}
void display_mic_tcp_pdu(mic_tcp_pdu pdu, char* prefix) {
if (!debug) return ;
printf("------------------------------------------\n%s\n", prefix);
printf("ACK Flag: %d\n", pdu.header.ack);
printf("FIN Flag: %d\n", pdu.header.fin);
@ -546,6 +550,7 @@ void display_mic_tcp_pdu(mic_tcp_pdu pdu, char* prefix) {
void display_enhanced_socket(enhanced_socket sock,char* prefix) {
if (!debug) return ;
printf("----------------------------------\n");
printf("%s\n", prefix);
printf("Socket File Descriptor: %d\n", sock.socket.fd);
@ -565,25 +570,29 @@ void display_enhanced_socket(enhanced_socket sock,char* prefix) {
}
void display_mic_tcp_sock_addr(mic_tcp_sock_addr addr, char* prefix) {
printf("----------------------------------\n");
if (!debug) return ;
printf("%s\n", prefix);
printf("IP Address: %.*s\n", addr.ip_addr_size, addr.ip_addr);
printf("Port: %hu\n", addr.port);
printf("----------------------------------\n");
}
void * attente_ack(void * arg) {
printf("début thread d'envoi de SYN ACK'\n");
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)
{
IP_send(args->pdu_r, tab_sockets[args->socket].dist_addr);
printf("je renvoie le Syn ack\n");
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);
}
sleep(timeout);