This commit is contained in:
jules-ian 2023-05-16 19:26:19 +02:00 committed by GitHub
commit 6de6a58fec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1235 additions and 113 deletions

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"cmake.configureOnOpen": true
}

Binary file not shown.

110
README.md
View file

@ -1,89 +1,49 @@
# BE RESEAU
## TPs BE Reseau - 3 MIC
Les détails du sujet du BE est accessible depuis le cours "Programmation Système et Réseau" sur moodle.
## TPs BE Reseau - 3 MIC Aittaleb Mohamed Barnavon Jules-iana
## Contenu du dépôt « template » fourni
Ce dépôt inclut le code source initial fourni pour démarrer le BE. Plus précisément :
- README.md (ce fichier) qui notamment décrit la préparation de lenvironnement de travail et le suivi des versions de votre travail;
## Contenu du dépôqui vous interesse
Ce dépôt inclunotre code source final pour mictcp
- README.md (ce fichier)
- tsock_texte et tsock_video : lanceurs pour les applications de test fournies.
- dossier include : contenant les définitions des éléments fournis que vous aurez à manipuler dans le cadre du BE.
- dossier src : contenant l'implantation des éléments fournis et à compléter dans le cadre du BE.
- src/mictcp.c : fichier au sein duquel vous serez amenés à faire l'ensemble de vos contributions (hors bonus éventuels).
- src/mictcp.c : code source que l'on a d<>veloppé
- configurer.sh : script shell qui vous demandera la version que vous voudrez utiliser et la tol<6F>rance aux pertes que vous souhaitez pour la v3 et au-delas
## Choir la version
La méthode pour choisir la version que nous recommandons est d'utiliser le script `configurer.sh`, assurez vous de le rendre ex<65>cutable par la commande :
`chmod +x configurer.sh`. Il ne fait que modifier une variable `version` qui controle la version dans `src/mictcp.c`.
## Création du dépôt mictcp
Si non vous pouvez toujours remonter aux commits tagg<67>s avec le nom de la version que vous voulez.
1. Création dun compte git étudiant : Si vous ne disposez pas dun compte git, connectez vous sur http://github.com/ et créez un compte par binôme.
## Compiler:
Si vous avez utiliséle script pour choisir la version, il n'est pas n<>cessaire de recompiler, si non veuillez ex<65>cuter `make`
2. Afin dêtre capable de mettre à jour le code que vous aurez produit sur le dépôt central Github, il vous faudra créer un jeton daccès qui jouera le rôle de mot de passe. Veuillez le sauvegarder, car il vous le sera demandé lors de l'accès au dépôt central. Pour ce faire, veuillez suivre les étapes décrites : https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
## Notre avancement
Nous arrivéà d<>veloppéune version qui marche de la v4, (i.e fiabilit<69> partielle et <20>tablissement de la connexion.
3. Création dun dépôt Etudiant sur GitHub pour le BE Reseau
Créer une copie du dépôt template enseignant : https://github.com/rezo-insat/mictcp, en vous y rendant et en cliquant sur le bouton « use this template » situé dans le coin en haut, plutôt à droite de la page. Il est demandé de le choisir comme dépôt privé. Il est impératif pour les corrections que vous rajoutiez le compte : rezo-insat comme collaborateur afin de permettre à vos enseignants d'accéder à votre dépôt. Pour ce faire, sélectionner le bouton "settings" puis "collaborators" et rajouter comme utilisateur : rezo-insat. La marche à suivre est décrite ci-après : https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/adding-outside-collaborators-to-repositories-in-your-organization
## Bug observé
Avant d'ex<65>cuter tsock_text, assurez vous de ne pas avoir ex<65>cutétsock_video sur votre machine auparavant, nous avons observéque ceci faisait planter
notre application. La seule solution que l on a trouvéest de simplement reboot la machine.
## Choix remarquables
### Parametres de la fiabilite partielle
Pour implanter la fiabilite partielle, nous repris notre solution pour la fiabilite totale, et nous avons ajoute les elements suivants
Lorsque le client re<72>oit un acquitement, il ajoute un 1 au buffer circulaire de son socket et incr<63>ment le num<75>ro de s<>quence, si non, il calcule la proportion de 1 dans
ce buffer, et si elle est sup<75>rieure <20>au pourcentage de pertes tol<6F>r<EFBFBD>es, il ajoute un 0 au buffer, et retourne au client la taille envoy<6F>e
mais n incremente pas le numero d acquitement, si non, il renvoie le packet et attend toujours l'acquittement.
4. Créer un clone local de votre dépôt Github, i.e. une copie locale du dépôt sur votre compte insa.
cliquer sur le bouton « code » de votre dépôt, copier lURL qui permet de lidentifier.
Ouvrir un terminal de votre machine. En vous plaçant dans le répertoire de travail de votre choix, taper depuis le terminal :
git clone <url de votre dépôt>
Vous avez désormais une copie locale de votre dépôt, que vous pouvez mettre à jour et modifier à volonté au gré de votre avancement sur les TPs.
5. Afin de nous permettre davoir accès à votre dépôt, merci de bien vouloir renseigner l'URL de votre dépôt sur le fichier accessible depuis le lien "fichier URLs dépôts étudiants" se trouvant sur moodle (au niveau de la section: BE Reseau).
## Compilation du protocole mictcp et lancement des applications de test fournies
Pour compiler mictcp et générer les exécutables des applications de test depuis le code source fourni, taper :
make
Deux applicatoins de test sont fournies, tsock_texte et tsock_video, elles peuvent être lancées soit en mode puits, soit en mode source selon la syntaxe suivante:
Usage: ./tsock_texte [-p|-s]
Usage: ./tsock_video [[-p|-s] [-t (tcp|mictcp)]
Seul tsock_video permet d'utiliser, au choix, votre protocole mictcp ou une émulation du comportement de tcp sur un réseau avec pertes.
## Suivi de versions de votre travail
Vous pouvez travailler comme vous le souhaitez sur le contenu du répertoire local. Vous pouvez mettre à jour les fichiers existants, rajouter dautres ainsi que des dossiers et en retirer certains à votre guise.
Pour répercuter les changements que vous faites sur votre répertoire de travail local sur le dépôt central GitHub, sur votre terminal, taper :
Afin de permettre l'implantation de cette fiabilite partielle, nous avons juggéque seul celui qui envoie les packets (ici le client) est en
position de controler cette fonctionalit<69>. De ce fait, il n'y pas de n<>gociation, simplement c est la source envoie, et qui controle le pourcentage de
pertes dans ce qu elle a envoy<6F>.
git add .
git commit -m «un message décrivant la mise à jour»
git push
### La r<>alisation des IP_recv
Si vous vous penchez sur notre code source, vous verrez que l'on a fait usage de thread supl<70>mentaire alors que nous ne sommes pas all<6C>s jusqu'à la v4.2.
La raison de ceci est que nous avons rencontrédes bugs assez troublant concernant les IP_recv, ces derniers adoptent un comportement diff<66>rent d une execution a l'autre.
Nous avons alors d<>cidéde les traiter comme une source de perte en tant que tel, et nous les ex<65>cutons toujours dans un thread c<>tépuit. C<>tésource, vu que le
process_received_pdu est lancé dans un thread a part, cela n'a pas <20>tén<C3A9>cese.
- Marquage des versions successives de votre travail sur mictcp
Lorsque vous le souhaitez, git permet d'associer une étiquette à un état précis de votre dépôt par l'intermédiaires de tags. Il vous est par exemple possible d'utiliser ce mécanisme pour marquer (et par conséquence pouvoir retrouver) l'état de votre dépôt pour chacune des versions successives de votre travail sur mictcp.
### Etablissement de la connexion
Pour l'etablissement de la connexion, notre protocole effectue les op<6F>rations suivantes :
Pour Créer un tag « v1 » et l'associer à l'état courrant de votre dépôt, vous taperez la commande suivante sur votre terminal :
git tag v1
Pour lister les tags existants au sein de votre dépôt
git tag -l
Pour transférer les tags de votre dépôt local vers le dépôt central sur github:
git push origin --tags
Ceci permettra à votre enseignant de positionner le dépôt dans l'état ou il était au moment du marquage avec chacun des tags que vous définissez.
## Suivi de votre avancement
Veuillez utiliser, à minima, un tag pour chacune des versions successives de mictcp qui sont définies au sein du sujet du BE disponible sous moodle.
## Liens utiles
Aide pour la création dun dépôt depuis un template : https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template
Manuel d'utilisation de git: https://git-scm.com/docs
Lorsque le client c<>tésource<63> fat un mic_tcp_connect, l'applicatio fixe le numero de sequence associe a son socket a 0, puis envoie un pdu syn a ce meme numero de sequence 0.
A sa reception cote puit, la fonction process_receive_pdu l'applicatio fixe aussi son numero de sequence associe a son socket a 0, envoie un pdu syn ack ce numero de sequence ,

BIN
build/TD2_Rezo.o Normal file

Binary file not shown.

BIN
build/api/mictcp_core.o Normal file

Binary file not shown.

BIN
build/apps/client.o Normal file

Binary file not shown.

BIN
build/apps/gateway.o Normal file

Binary file not shown.

BIN
build/apps/server.o Normal file

Binary file not shown.

BIN
build/client Executable file

Binary file not shown.

BIN
build/gateway Executable file

Binary file not shown.

BIN
build/mictcp.o Normal file

Binary file not shown.

BIN
build/server Executable file

Binary file not shown.

14
configurer.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
read -p "Donnez la version que vous desirez: " version_number
read -p "Donnez le pourcentage de perte que vous voulez tolérer (marche qu'à partir de la v3): " loss_acceptability_number
file_path="./src/mictcp.c"
sed -i "s/version=[0-9]\+;/version=${version_number};/" "$file_path"
sed -i "s/#define LOSS_ACCEPTABILITY [0-9]\+/#define LOSS_ACCEPTABILITY ${loss_acceptability_number}/" "$file_path"
echo "Valeurs mises à jour avec success."
make

View file

@ -21,7 +21,7 @@
*/
typedef enum protocol_state
{
IDLE, CLOSED, SYN_SENT, SYN_RECEIVED, ESTABLISHED, CLOSING
IDLE, CLOSED, SYN_SENT, SYN_RECEIVED, ESTABLISHED, CLOSING, ACCEPTING, WAITING
} protocol_state;
/*

104
log_marche_bien Normal file
View file

@ -0,0 +1,104 @@
source:
[MIC-TCP] Appel de la fonction: mic_tcp_socket
----------------------------------
état du socket
Socket File Descriptor: 0
Socket Protocol State: IDLE
Socket Address IP:
Socket Address Port: 0
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
[TSOCK] Creation du socket MICTCP: OK
------------------------------------------
creation du pdu SYN:
ACK Flag: 0
FIN Flag: 0
SYN Flag: 1
Source Port: 0
Destination Port: 1234
Sequence Number: 0
Acknowledgment Number: 4294967295
Payload Size: 0
Payload Data is NULL
----------------------------------
----------------------------------
envoi du pdu SYN vers l'adresse :
IP Address: 127.0.0.1
Port: 1234
----------------------------------
puit:
[MIC-TCP] Appel de la fonction: mic_tcp_socket
----------------------------------
état du socket
Socket File Descriptor: 0
Socket Protocol State: IDLE
Socket Address IP:
Socket Address Port: 0
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
[TSOCK] Creation du socket MICTCP: OK
[MIC-TCP] Appel de la fonction: mic_tcp_bind
----------------------------------
Socket File Descriptor: 0
Socket Protocol State: WAITING
Socket Address IP:
Socket Address Port: 1234
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
[TSOCK] Bind du socket MICTCP: OK
[MIC-TCP] Appel de la fonction: mic_tcp_accept
[MICTCP-CORE] Demarrage du thread de reception reseau...
----------------------------------
état du socket en attendant l'établissement de connection
Socket File Descriptor: 0
Socket Protocol State: ACCEPTING
Socket Address IP:
Socket Address Port: 1234
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
je vais recv
j'ai recv
------------------------------------------
pdu reçu
ACK Flag: 0
FIN Flag: 0
SYN Flag: 1
Source Port: 0
Destination Port: 1234
Sequence Number: 0
Acknowledgment Number: 4294967295
Payload Size: 0
Payload Data is NULL
----------------------------------
[MIC-TCP] Appel de la fonction: process_syn_pdu
------------------------------------------
Construction du Pdu SYN ACK :
ACK Flag: 1
FIN Flag: 0
SYN Flag: 1
Source Port: 1234
Destination Port: 0
Sequence Number: 0
Acknowledgment Number: 0
Payload Size: 0
Payload Data is NULL
----------------------------------
----------------------------------
Envoi du PDU SYN ACK à l'adresse:
IP Address: localhost
Port: 0
----------------------------------

104
log_marche_pas Normal file
View file

@ -0,0 +1,104 @@
source:
[MIC-TCP] Appel de la fonction: mic_tcp_socket
----------------------------------
état du socket
Socket File Descriptor: 0
Socket Protocol State: IDLE
Socket Address IP:
Socket Address Port: 0
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
[TSOCK] Creation du socket MICTCP: OK
------------------------------------------
creation du pdu SYN:
ACK Flag: 0
FIN Flag: 0
SYN Flag: 1
Source Port: 0
Destination Port: 1234
Sequence Number: 0
Acknowledgment Number: 4294967295
Payload Size: 0
Payload Data is NULL
----------------------------------
----------------------------------
envoi du pdu SYN vers l'adresse :
IP Address: 127.0.0.1
Port: 1234
----------------------------------
puit
[MIC-TCP] Appel de la fonction: mic_tcp_socket
----------------------------------
état du socket
Socket File Descriptor: 0
Socket Protocol State: IDLE
Socket Address IP:
Socket Address Port: 0
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
[TSOCK] Creation du socket MICTCP: OK
[MIC-TCP] Appel de la fonction: mic_tcp_bind
----------------------------------
Socket File Descriptor: 0
Socket Protocol State: WAITING
Socket Address IP:
Socket Address Port: 1234
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
[MICTCP-CORE] Demarrage du thread de reception reseau...
----------------------------------
[TSOCK] Bind du socket MICTCP: OK
[MIC-TCP] Appel de la fonction: mic_tcp_accept
----------------------------------
état du socket en attendant l'établissement de connection
Socket File Descriptor: 0
Socket Protocol State: ACCEPTING
Socket Address IP:
Socket Address Port: 1234
Remote Address IP:
Remote Address Port: 0
Local Sequence Number: 0
Remote Sequence Number: 0
----------------------------------
je vais recv
j'ai recv
------------------------------------------
pdu reçu
ACK Flag: 0
FIN Flag: 0
SYN Flag: 1
Source Port: 0
Destination Port: 1234
Sequence Number: 0
Acknowledgment Number: 4294967295
Payload Size: 0
Payload Data is NULL
----------------------------------
[MIC-TCP] Appel de la fonction: process_syn_pdu
------------------------------------------
Construction du Pdu SYN ACK :
ACK Flag: 1
FIN Flag: 0
SYN Flag: 1
Source Port: 1234
Destination Port: 0
Sequence Number: 0
Acknowledgment Number: 0
Payload Size: 0
Payload Data is NULL
----------------------------------
----------------------------------
Envoi du PDU SYN ACK à l'adresse:
IP Address: localhost
Port: 0
----------------------------------

164
src/TD2_Rezo.c Normal file
View file

@ -0,0 +1,164 @@
// /*
// * Permet de créer un socket entre lapplication et MIC-TCP
// * Retourne le descripteur du socket ou bien -1 en cas d'erreur
// */
// int mic_tcp_socket(start_mode sm) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// result = initialize_components(sm); /* Appel obligatoire */
// return -1; }
// /*
// * Permet dattribuer une adresse à un socket.
// * Retourne 0 si succès, et -1 en cas déchec
// */
// int mic_tcp_bind(int socket, mic_tcp_sock_addr addr) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// return -1; }
// /*
// * Met le socket en état d'acceptation de connexion
// * Retourne 0 si succès, -1 si erreur
// */
// int mic_tcp_accept(int socket, mic_tcp_sock_addr* addr) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// return -1; }
// /*
// * Permet de réclamer létablissement dune connexion
// * Retourne 0 si la connexion est établie, et -1 en cas déchec
// */
// int mic_tcp_connect (int socket, mic_tcp_sock_addr addr) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// return -1; }
// /*
// * Permet de réclamer lenvoi dune donnée applicative
// * Retourne la taille des données envoyées, et -1 en cas d'erreur
// */
// int mic_tcp_send (int mic_sock, char* mesg, int mesg_size) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// int sent_size= -1;
// mic_tcp_PDU pdu;
// pdu.header = ...
// pdu.payload.data = mesg;
// pdu.payload.size = mesg_size;
// //IP_recv quand fiabilité implémentée
// sent_size = IP_send(pdu, sock_addr)
// return sent_size;
// }
// /*
// * Permet à lapplication réceptrice de réclamer la récupération dune donnée
// * stockée dans les buffers de réception du socket
// * Retourne le nombre doctets lu ou bien -1 en cas derreur
// * NB : cette fonction fait appel à la fonction app_buffer_get()
// */
// int mic_tcp_recv (int socket, char* mesg, int max_mesg_size) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// int delivered_size = -1;
// mic_tcp_payload *payload;
// payload.data = mesg;
// payload.size = max_mesg_size;
// app_buffer_get(payload);
// return delivered_size;
// }
// /*
// * Permet de traiter un PDU MIC-TCP reçu (mise à jour des numéros de séquence
// * et d'acquittement, etc.) puis d'insérer les données utiles du PDU dans
// * le buffer de réception du socket. Cette fonction utilise la fonction
// * app_buffer_put(). Elle est appelée par initialize_components()
// */
// void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) {
// printf("[MIC-TCP] Appel de la fonction: ");
// printf(__FUNCTION__); printf("\n");
// //éventuellement trouver les bons socket, buffer et app
// app_buffer_put(PDU.body);
// /* Utile quand on fera du reliable
// if(SeqPDU = SeqDist){ //packet valide
// SendAck(SeqDist);
// SeqDist++;
// IP_send(ack);
// }
// */
// }
// /*
// * Permet de réclamer la destruction dun socket.
// * Engendre la fermeture de la connexion suivant le modèle de TCP.
// * Retourne 0 si tout se passe bien et -1 en cas d'erreur
// */
// int mic_tcp_close (int socket) {
// printf("[MIC-TCP] Appel de la fonction : "); printf(__FUNCTION__); printf("\n");
// return -1; }
// // STRUCTURES
// /* États du protocole ( noms des états donnés à titre indicatif => peuvent être modifiés) */
// typedef enum protocol_state {
// IDLE, CONNECTED, ...
// } protocol_state;
// /* Mode de démarrage du protocole. NB : nécessaire à lusage de la fonction initialize_components() */
// typedef enum start_mode { CLIENT, SERVER } start_mode;
// /* Structure dune adresse de socket */
// typedef struct mic_tcp_sock_addr {
// char *ip_addr; // @ IP : à fournir sous forme décimale pointée : ex = “192.168.1.2”
// int ip_addr_size; // taille de ladresse
// unsigned short port; // numéro de port
// } mic_tcp_sock_addr;
// /*
// * Structure d'un socket
// */
// typedef struct mic_tcp_sock {
// int fd; /* descripteur du socket */
// protocol_state state; /* état du protocole */
// mic_tcp_sock_addr addr; /* adresse du socket */
// } mic_tcp_sock;
// /*
// * Structure d'un PDU MIC-TCP
// */
// typedef struct mic_tcp_pdu {
// mic_tcp_header header ; /* entête du PDU */
// mic_tcp_payload payload; /* charge utile du PDU */
// } mic_tcp_pdu;
// /*
// * Structure de l'entête d'un PDU MIC-TCP
// */
// typedef struct mic_tcp_header
// {
// unsigned short source_port; /* numéro de port source */
// unsigned short dest_port; /* numéro de port de destination */
// unsigned int seq_num; /* numéro de séquence */
// unsigned int ack_num; /* numéro d'acquittement */
// unsigned char syn; /* flag SYN (valeur 1 si activé et 0 si non) */
// unsigned char ack; /* flag ACK (valeur 1 si activé et 0 si non) */
// unsigned char fin; /* flag FIN (valeur 1 si activé et 0 si non) */
// } mic_tcp_header;
// /*
// * Structure des données utiles dun PDU MIC-TCP
// */
// typedef struct mic_tcp_payload {
// char* data; /* données applicatives */
// int size; /* taille des données */
// } mic_tcp_payload;

View file

@ -1,4 +1,5 @@
#include <api/mictcp_core.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <math.h>
@ -13,7 +14,7 @@ int initialized = -1;
int sys_socket;
pthread_t listen_th;
pthread_mutex_t lock;
unsigned short loss_rate = 0;
unsigned short loss_rate = 0; //sur 100
struct sockaddr_in remote_addr;
/* This is for the buffer */
@ -81,6 +82,7 @@ int initialize_components(start_mode mode)
local_addr.sin_port = htons(API_SC_Port);
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bnd = bind(sys_socket, (struct sockaddr *) &local_addr, sizeof(local_addr));
//pthread_create (&listen_th, NULL, listening, "1");//ligne rajoutée a enlever
}
}
@ -133,12 +135,15 @@ int IP_recv(mic_tcp_pdu* pk, mic_tcp_sock_addr* addr, unsigned long timeout)
/* Convert the remainder to microseconds */
tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
// printf("values of tv sec and usec : %ld, %ld\n",tv.tv_sec,tv.tv_usec);
/* Create a reception buffer */
int buffer_size = API_HD_Size + pk->payload.size;
char *buffer = malloc(buffer_size);
if ((setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) >= 0) {
int setsockopt_return_value;
if ((setsockopt_return_value=setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) >= 0) {
// printf("debug : %d\n, return value of setsockopt : %d\n",__LINE__,setsockopt_return_value);
result = recvfrom(sys_socket, buffer, buffer_size, 0, (struct sockaddr *)&tmp_addr, &tmp_addr_size);
// printf("debug : %d\n",__LINE__);
}
if (result != -1) {
@ -161,6 +166,7 @@ int IP_recv(mic_tcp_pdu* pk, mic_tcp_sock_addr* addr, unsigned long timeout)
/* Free the reception buffer */
free(buffer);
printf("debug : %d\n",__LINE__);
return result;
}
@ -302,9 +308,11 @@ void* listening(void* arg)
while(1)
{
{
pdu_tmp.payload.size = payload_size;
printf("je vais recv\n");
recv_size = IP_recv(&pdu_tmp, &remote, 0);
printf("j'ai recv\n");
if(recv_size != -1)
{

View file

@ -1,5 +1,70 @@
#include <pthread.h>
#include <stdio.h>
#include <mictcp.h>
#include <api/mictcp_core.h>
#define NBR_SOCKETS 1024
#define TIMEOUT_DEFAUT 1000000
#define WINDOW_SIZE 10
#define LOSS_ACCEPTABILITY 2 // sur 100
#define ATTENTE_ACK 1
#define PAYLOAD_SIZE 64
//================================== STRUCTURES =============================
typedef struct {
char table[WINDOW_SIZE];
char last_index;
} circularBuffer;
typedef struct
{
mic_tcp_sock socket;
mic_tcp_sock_addr dist_addr;
char NoSeqLoc; // = -1;
char NoSeqDist; // = -1;
circularBuffer buffer;
} enhanced_socket;
typedef struct
{
int recpt;
int socket;
mic_tcp_pdu pdu_r;
}arg_thread;
//================================== VARIABLES GLOBALES =============================
static int socket_desc = 0;
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=4;
//================================== SIGNATURES DES FONCTIONS PRIVEES =============================
int valid_socket(int socket);
int bound_socket(int socket);
int same_addr(mic_tcp_sock_addr *addr1, mic_tcp_sock_addr *addr2);
void display_mic_tcp_pdu(mic_tcp_pdu pdu, char* prefix);
void display_enhanced_socket(enhanced_socket sock, char* prefix);
void display_mic_tcp_sock_addr(mic_tcp_sock_addr addr, char* prefix);
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);
void * envoi_syn_ack(void * arg);
void * envoi_fin_ack(void * arg);
//================================== FONCTIONS DE MICTCP =============================
/*
* Permet de créer un socket entre lapplication et MIC-TCP
@ -7,12 +72,25 @@
*/
int mic_tcp_socket(start_mode sm)
{
int result = -1;
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
result = initialize_components(sm); /* Appel obligatoire */
set_loss_rate(0);
printf("[MIC-TCP] Appel de la fonction: ");
printf(__FUNCTION__);
printf("\n");
return result;
enhanced_socket *socket = &tab_sockets[socket_desc];
socket->socket.fd = socket_desc++;
socket->socket.state = IDLE;
// not bound yet
display_enhanced_socket(*socket, "état du socket");
socket->NoSeqLoc =0;
int result = initialize_components(sm); /* Appel obligatoire */
if (result < 0)
{
printf("Problème initialize_components\n");
return -1;
}
return socket->socket.fd;
}
/*
@ -21,38 +99,278 @@ int mic_tcp_socket(start_mode sm)
*/
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
return -1;
printf("[MIC-TCP] Appel de la fonction: ");
printf(__FUNCTION__);
printf("\n");
if (valid_socket(socket) && tab_sockets[socket].socket.state == IDLE)
{
tab_sockets[socket].socket.addr = addr;
tab_sockets[socket].socket.state = WAITING;
display_enhanced_socket(tab_sockets[socket],"");
printf("Socket bound\n");
return 0;
}
return -1;
}
/*
* Met le socket en état d'acceptation de connexions
* Met le socket en état d'acceptation de connexion et bloque jusqu'a ce que la connexion soit établie
* Retourne 0 si succès, -1 si erreur
*/
int mic_tcp_accept(int socket, mic_tcp_sock_addr* addr)
int mic_tcp_accept(int socket, mic_tcp_sock_addr *addr)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
return -1;
printf("[MIC-TCP] Appel de la fonction: ");
printf(__FUNCTION__);
printf("\n");
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");
if (version<4){
tab_sockets[socket].socket.state = ESTABLISHED;
tab_sockets[socket].NoSeqDist=0;
tab_sockets[socket].NoSeqLoc=0;
}
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);
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;
}
return -1;
}
/*
* Permet de réclamer létablissement dune connexion
* Retourne 0 si la connexion est établie, et -1 en cas déchec
*/
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
return -1;
tab_sockets[socket].dist_addr = addr;
tab_sockets[socket].NoSeqLoc = 0;
if (version>2){
circularBuffer* buffer = &tab_sockets[socket].buffer;
buffer->last_index = 0;
for (int i = 0; i<WINDOW_SIZE;i++){
buffer->table[i]=0;
}
}
if (version<4){
tab_sockets[socket].socket.state = ESTABLISHED;
display_enhanced_socket(tab_sockets[socket], "État du socket aprés l'établissement de la connection :");
return 0;
}
tab_sockets[socket].socket.state = SYN_SENT;
// create pdu syn
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,
1,0,0,
NULL,0
);
display_mic_tcp_pdu(pdu, "creation du pdu SYN:");
display_mic_tcp_sock_addr(addr, "envoi du pdu SYN vers l'adresse :");
IP_send(pdu, 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(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 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");
tab_sockets[socket].NoSeqDist = args->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,
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(addr, "envoi du pdu ACK vers l'adresse :");
IP_send(pdu, addr);
// mic_tcp_pdu* args = malloc(sizeof(mic_tcp_pdu));
// args->header=pdu.header;
// args->payload=pdu.payload;
tab_sockets[socket].socket.state = ESTABLISHED;
/*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*/
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 :");
printf("Connexion établie\n");
return 0;
}
/*
* Permet de réclamer lenvoi dune donnée applicative
* Retourne la taille des données envoyées, et -1 en cas d'erreur
*/
int mic_tcp_send (int mic_sock, char* mesg, int mesg_size)
* Permet de réclamer lNULL
*/
int mic_tcp_send(int mic_sock, char *mesg, int mesg_size)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
return -1;
if (tab_sockets[mic_sock].socket.state != ESTABLISHED)
{
printf("le client nest pas connecté \n");
return -1;
}
// create pdu
mic_tcp_pdu pdu;
set_mic_tcp_pdu(
&pdu,
tab_sockets[mic_sock].socket.addr.port,
tab_sockets[mic_sock].dist_addr.port,
tab_sockets[mic_sock].NoSeqLoc,
-1,
0,0,0,
mesg,mesg_size
);
display_mic_tcp_pdu(pdu, "creation du pdu data:");
display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "envoi du pdu data vers l'adresse :");
display_enhanced_socket(tab_sockets[mic_sock],"etat du socket");
int sent_size = IP_send(pdu, tab_sockets[mic_sock].dist_addr);
printf("Packet envoye\n");
if (version<2) return sent_size;
tab_sockets[mic_sock].socket.state = WAITING;
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(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");
tab_sockets[mic_sock].socket.state = ESTABLISHED;
return sent_size;
} else {
printf("Perte non acceptée\n");
}
}
sent_size = IP_send(pdu, tab_sockets[mic_sock].dist_addr);
printf("Pas de pdu recu, envoi d'un doublon\n");
continue;
}
display_mic_tcp_pdu(args->pdu_r,"pdu reçu :");
if (args->pdu_r.header.ack == 1 && (tab_sockets[mic_sock].NoSeqLoc ==args->pdu_r.header.ack_num)){
printf("le bon Ack a été reçu\n");
tab_sockets[mic_sock].socket.state = ESTABLISHED;
tab_sockets[mic_sock].NoSeqLoc = ((tab_sockets[mic_sock].NoSeqLoc + 1) % 2); //maj du no de seq uniquement lorsque ACK reçu (= synchronisation du noseq entre puits et src)
display_enhanced_socket(tab_sockets[mic_sock], "État du socket aprés la reception du ack");
if (version>2){
addValueCircularBuff(&tab_sockets[mic_sock].buffer, 1);
}
return sent_size;
}else if(args->pdu_r.header.ack == 1 && args->pdu_r.header.syn == 1){
printf("PDU SYN ACK recu a nouveau (Doublon) \n");
mic_tcp_pdu pdu_d;
set_mic_tcp_pdu(
&pdu_d,
tab_sockets[mic_sock].socket.addr.port,
tab_sockets[mic_sock].dist_addr.port,
-1,
args->pdu_r.header.seq_num,
0,1,0,
NULL,0
);
display_mic_tcp_pdu(pdu_d, "creation du pdu ACK:");
display_mic_tcp_sock_addr(tab_sockets[mic_sock].dist_addr, "envoi du pdu ACK vers l'adresse :");
IP_send(pdu_d, tab_sockets[mic_sock].dist_addr);
}else {
printf("mauvais pdu reçu\n");
}
// si ACK de bon numéro de séquence
// addValueCircularBuff(&tab_sockets[mic_sock].buffer,1); // PDU bien reçu
//update seq num ?
// tab_sockets[mic_sock].socket.state = ESTABLISHED;
}
}
/*
@ -61,10 +379,202 @@ int mic_tcp_send (int mic_sock, char* mesg, int mesg_size)
* Retourne le nombre doctets lu ou bien -1 en cas derreur
* NB : cette fonction fait appel à la fonction app_buffer_get()
*/
int mic_tcp_recv (int socket, char* mesg, int max_mesg_size)
int mic_tcp_recv(int socket, char *mesg, int max_mesg_size)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
return -1;
printf("[MIC-TCP] Appel de la fonction: ");
printf(__FUNCTION__);
printf("\n");
if (!valid_socket(socket))
{
return -1;
}
int delivered_size;
mic_tcp_payload *payload = malloc(sizeof(mic_tcp_payload));
payload->data = mesg;
payload->size = max_mesg_size;
printf("procède au app_buffer_get\n");
delivered_size = app_buffer_get(*payload);
printf("payload récupéré\n");
return delivered_size;
}
/*
* Permet de traiter un PDU MIC-TCP reçu (mise à jour des numéros de séquence
* et d'acquittement, etc.) puis d'insérer les données utiles du PDU dans
* 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 TESA\n");
pthread_create(&envoi_syn_ack_tid, NULL,envoi_syn_ack,(void *)args);
//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");
}
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) //addr = adresse distante
{
int mic_sock;
display_mic_tcp_pdu(pdu, "pdu reçu");
for (mic_sock = 0; (mic_sock < socket_desc) && !(tab_sockets[mic_sock].socket.addr.port==pdu.header.dest_port); mic_sock++)
; // trouver le socket destinataire
if (mic_sock == socket_desc)
{ // si aucun socket trouvé, alors retourne une erreur
printf(debug?"socket non trouvé\n":"");
}
if (version<2) {
app_buffer_put(pdu.payload); // envoyer la data dans le buffer
//printf("data in the buffer\n");
return;
}
if (pdu.header.syn == 1 && tab_sockets[mic_sock].socket.state == ACCEPTING) // si PDU SYN
{
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");
}
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
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");
mic_tcp_pdu pdu_d;
set_mic_tcp_pdu(
&pdu_d,
tab_sockets[mic_sock].socket.addr.port,
tab_sockets[mic_sock].dist_addr.port,
-1,
pdu.header.seq_num,
0,1,0,
NULL,0
);
display_mic_tcp_pdu(pdu_d, "creation du pdu ACK:");
display_mic_tcp_sock_addr(addr, "envoi du pdu ACK vers l'adresse :");
IP_send(pdu_d, addr);
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");
}
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
printf("PDU data recu (Doublon)\n");
mic_tcp_pdu pdu_d;
set_mic_tcp_pdu(
&pdu_d,
tab_sockets[mic_sock].socket.addr.port,
tab_sockets[mic_sock].dist_addr.port,
-1,
pdu.header.seq_num,
0,1,0,
NULL,0
);
display_mic_tcp_pdu(pdu_d, "recreation du pdu ACK:");
display_mic_tcp_sock_addr(addr, "renvoi du pdu ACK vers l'adresse :");
IP_send(pdu_d, addr);
}else{
printf("PDU inattendu reçu, PDU rejeté\n");
display_enhanced_socket(tab_sockets[mic_sock], "l'état du socket");
}
}
/*
@ -72,19 +582,274 @@ int mic_tcp_recv (int socket, char* mesg, int max_mesg_size)
* Engendre la fermeture de la connexion suivant le modèle de TCP.
* Retourne 0 si tout se passe bien et -1 en cas d'erreur
*/
int mic_tcp_close (int socket)
int mic_tcp_close(int socket)
{
printf("[MIC-TCP] Appel de la fonction : "); printf(__FUNCTION__); printf("\n");
return -1;
printf("[MIC-TCP] Appel de la fonction : ");
printf(__FUNCTION__);
printf("\n");
if (valid_socket(socket) && tab_sockets[socket].socket.state == ESTABLISHED)
{
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;
}
/*
* Traitement dun PDU MIC-TCP reçu (mise à jour des numéros de séquence
* et d'acquittement, etc.) puis insère les données utiles du PDU dans
* le buffer de réception du socket. Cette fonction utilise la fonction
* app_buffer_put().
*/
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr)
//================================== CORPS DES FONCTIONS PRIVEES =============================
int valid_socket(int socket)
{
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
if (socket > socket_desc - 1 || tab_sockets[socket].socket.fd == -1)
{
// printf("ah, ton socket il existe pas\n");
return 0;
}
return 1;
}
int bound_socket(int socket)
{
if (tab_sockets[socket].socket.state == IDLE || tab_sockets[socket].socket.state == CLOSING || tab_sockets[socket].socket.state == CLOSED )
{
// printf("socket not bound\n");
return 0;
}
return 1;
}
int same_addr(mic_tcp_sock_addr *addr1, mic_tcp_sock_addr *addr2)
{
if (addr1->port == addr2->port && addr1->ip_addr_size == addr2->ip_addr_size && !memcmp(addr1->ip_addr, addr2->ip_addr, addr1->ip_addr_size))
{
return 1;
}
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 * 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);
printf("ACK Flag: %d\n", pdu.header.ack);
printf("FIN Flag: %d\n", pdu.header.fin);
printf("SYN Flag: %d\n", pdu.header.syn);
printf("Source Port: %hu\n", pdu.header.source_port);
printf("Destination Port: %hu\n", pdu.header.dest_port);
printf("Sequence Number: %u\n", pdu.header.seq_num);
printf("Acknowledgment Number: %u\n", pdu.header.ack_num);
printf("Payload Size: %d\n", pdu.payload.size);
if (pdu.payload.size != 0) {
printf("Payload Data: %.*s\n", pdu.payload.size, pdu.payload.data);
} else {
printf("Payload Data is NULL\n");
}
printf("----------------------------------\n");
}
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);
const char* protocol_states[] = {"IDLE", "CLOSED", "SYN_SENT", "SYN_RECEIVED", "ESTABLISHED", "CLOSING", "ACCEPTING", "WAITING"};
printf("Socket Protocol State: %s\n", protocol_states[sock.socket.state]);
printf("Socket Address IP: %.*s\n", sock.socket.addr.ip_addr_size, sock.socket.addr.ip_addr);
printf("Socket Address Port: %hu\n", sock.socket.addr.port);
printf("Remote Address IP: %.*s\n", sock.dist_addr.ip_addr_size, sock.dist_addr.ip_addr);
printf("Remote Address Port: %hu\n", sock.dist_addr.port);
printf("Local Sequence Number: %d\n", sock.NoSeqLoc);
printf("Remote Sequence Number: %d\n", sock.NoSeqDist);
if (version>2){
printf("Buffer: --------------- \n");
for (int i =0;i<WINDOW_SIZE; i++){
printf(" %d ;",sock.buffer.table[i]);
}
printf("\n-----------------\n");
}
printf("\n----------------------------------\n");
}
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(debug?"début du TAA: thread d'attente de ACK'\n":"");
arg_thread* args = (arg_thread*)arg;
args->recpt=IP_recv(&args->pdu_r,NULL, 0) ;
printf("TAA: reception effectuee, autodestruction entamee\n");
pthread_exit(NULL);
}