version 4 sans fiabilite partielle, attention le code ne marche pas d'une compilation a l'autre
This commit is contained in:
parent
0df19ececa
commit
196ee68c96
10 changed files with 123 additions and 114 deletions
BIN
build/TD2_Rezo.o
BIN
build/TD2_Rezo.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/client
BIN
build/client
Binary file not shown.
BIN
build/gateway
BIN
build/gateway
Binary file not shown.
BIN
build/mictcp.o
BIN
build/mictcp.o
Binary file not shown.
BIN
build/server
BIN
build/server
Binary file not shown.
237
src/mictcp.c
237
src/mictcp.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue