Added loss max management
This commit is contained in:
parent
1c06417c48
commit
3e93bf42f6
1 changed files with 192 additions and 43 deletions
179
src/mictcp.c
179
src/mictcp.c
|
@ -6,21 +6,137 @@
|
||||||
#define COLOR_BOLD "\x1b[1m"
|
#define COLOR_BOLD "\x1b[1m"
|
||||||
#define COLOR_RESET "\x1b[0m"
|
#define COLOR_RESET "\x1b[0m"
|
||||||
|
|
||||||
#define LOSS_RATE 5
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#define LOSS_RATE 2
|
||||||
#define TIMEOUT 2
|
#define TIMEOUT 2
|
||||||
|
#define MAX_LOSS_RATE 2
|
||||||
|
#define LIST_LENGTH 200
|
||||||
|
|
||||||
struct mic_tcp_sock g_sock;
|
struct mic_tcp_sock g_sock;
|
||||||
int next_msg_num;
|
int next_msg_num;
|
||||||
|
|
||||||
|
struct node {
|
||||||
|
int isSuccess;
|
||||||
|
struct node *previous;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct node *head;
|
||||||
|
struct node *tail;
|
||||||
|
int size;
|
||||||
|
int errorNumber;
|
||||||
|
} list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets current loss rate
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int getLossRate() {
|
||||||
|
if (list.size > 0)
|
||||||
|
return (100 * list.errorNumber / list.size);
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current loss rate is acceptable
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int isLossAcceptable() {
|
||||||
|
return getLossRate() <= MAX_LOSS_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove last element from the list and remove a success from count if removed element was a success
|
||||||
|
*/
|
||||||
|
void popLast() {
|
||||||
|
if (list.size > 0 ) {
|
||||||
|
struct node *last = list.tail;
|
||||||
|
list.tail = last->previous;
|
||||||
|
list.size--;
|
||||||
|
if (last->isSuccess != 1)
|
||||||
|
list.errorNumber--;
|
||||||
|
free(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new link at the front of the list.
|
||||||
|
* If the list has reached its max length after insertion, remove last element
|
||||||
|
*
|
||||||
|
* @param isSuccess
|
||||||
|
*/
|
||||||
|
void insertFirst(int isSuccess) {
|
||||||
|
struct node *link = (struct node*) malloc(sizeof(struct node));
|
||||||
|
link->isSuccess = isSuccess;
|
||||||
|
link->previous = NULL;
|
||||||
|
|
||||||
|
if (list.size > 0)
|
||||||
|
list.head->previous = link;
|
||||||
|
else
|
||||||
|
list.tail = link;
|
||||||
|
list.head = link;
|
||||||
|
|
||||||
|
if (isSuccess != 1)
|
||||||
|
list.errorNumber++;
|
||||||
|
|
||||||
|
list.size++;
|
||||||
|
|
||||||
|
if (list.size > LIST_LENGTH)
|
||||||
|
popLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearList() {
|
||||||
|
while (list.size > 0) {
|
||||||
|
popLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a network error in the list
|
||||||
|
*/
|
||||||
|
void saveError() {
|
||||||
|
insertFirst(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a network success in the list
|
||||||
|
*/
|
||||||
|
void saveSuccess() {
|
||||||
|
insertFirst(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printList() {
|
||||||
|
if (DEBUG) {
|
||||||
|
printf("========= LIST =========\n");
|
||||||
|
printf("size: %d\n", list.size);
|
||||||
|
printf("errorNumber: %d\n", list.errorNumber);
|
||||||
|
printf("lossRate: %d\n", getLossRate());
|
||||||
|
printf("isLossAcceptable: %d\n", isLossAcceptable());
|
||||||
|
|
||||||
|
if (list.size > 0) {
|
||||||
|
printf("head: %d\n", list.head->isSuccess);
|
||||||
|
printf("tail: %d\n", list.tail->isSuccess);
|
||||||
|
}
|
||||||
|
printf("========================\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permet de créer un socket entre l’application et MIC-TCP.
|
* Permet de créer un socket entre l’application et MIC-TCP.
|
||||||
* @return le descripteur du socket ou bien -1 en cas d'erreur.
|
* @return le descripteur du socket ou bien -1 en cas d'erreur.
|
||||||
*/
|
*/
|
||||||
int mic_tcp_socket(start_mode sm) {
|
int mic_tcp_socket(start_mode sm) {
|
||||||
int result;
|
int result;
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
result = initialize_components(sm); /* Appel obligatoire */
|
result = initialize_components(sm); /* Appel obligatoire */
|
||||||
set_loss_rate(LOSS_RATE);
|
set_loss_rate(LOSS_RATE);
|
||||||
|
|
||||||
|
@ -28,6 +144,9 @@ int mic_tcp_socket(start_mode sm) {
|
||||||
g_sock.state = IDLE;
|
g_sock.state = IDLE;
|
||||||
next_msg_num = 1;
|
next_msg_num = 1;
|
||||||
|
|
||||||
|
list.size = 0;
|
||||||
|
list.errorNumber = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +155,11 @@ int mic_tcp_socket(start_mode sm) {
|
||||||
* @return 0 si succès, et -1 en cas d’échec.
|
* @return 0 si succès, et -1 en cas d’échec.
|
||||||
*/
|
*/
|
||||||
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr) {
|
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
@ -52,9 +173,11 @@ int mic_tcp_bind(int socket, mic_tcp_sock_addr addr) {
|
||||||
* @return 0 si succès, -1 si erreur.
|
* @return 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) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
@ -68,9 +191,11 @@ int mic_tcp_accept(int socket, mic_tcp_sock_addr *addr) {
|
||||||
* @return 0 si la connexion est établie, et -1 en cas d’échec
|
* @return 0 si la connexion est établie, et -1 en cas d’échec
|
||||||
*/
|
*/
|
||||||
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr) {
|
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
@ -85,12 +210,15 @@ int mic_tcp_connect(int socket, mic_tcp_sock_addr addr) {
|
||||||
* @return la taille des données envoyées, et -1 en cas d'erreur
|
* @return la taille des données envoyées, et -1 en cas d'erreur
|
||||||
*/
|
*/
|
||||||
int mic_tcp_send(int socket, char *mesg, int mesg_size) {
|
int mic_tcp_send(int socket, char *mesg, int mesg_size) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
int result = -1;
|
}
|
||||||
|
int result;
|
||||||
|
int errorDetected = 0;
|
||||||
|
|
||||||
while (result == -1) {
|
do {
|
||||||
struct mic_tcp_pdu pdu;
|
struct mic_tcp_pdu pdu;
|
||||||
pdu.payload.data = mesg;
|
pdu.payload.data = mesg;
|
||||||
pdu.payload.size = mesg_size;
|
pdu.payload.size = mesg_size;
|
||||||
|
@ -103,27 +231,39 @@ int mic_tcp_send(int socket, char *mesg, int mesg_size) {
|
||||||
pdu.header.ack = 0;
|
pdu.header.ack = 0;
|
||||||
pdu.header.fin = 0;
|
pdu.header.fin = 0;
|
||||||
|
|
||||||
|
if (DEBUG)
|
||||||
printf("\n[MIC-TCP] Sending PDU\n");
|
printf("\n[MIC-TCP] Sending PDU\n");
|
||||||
|
|
||||||
if ((result = IP_send(pdu, g_sock.addr)) != -1) {
|
if ((result = IP_send(pdu, g_sock.addr)) != -1) {
|
||||||
struct mic_tcp_pdu rcv_pdu;
|
struct mic_tcp_pdu rcv_pdu;
|
||||||
struct mic_tcp_sock_addr rcv_sock_addr;
|
struct mic_tcp_sock_addr rcv_sock_addr;
|
||||||
|
if (DEBUG)
|
||||||
printf("[MIC-TCP] Waiting for ACK\n");
|
printf("[MIC-TCP] Waiting for ACK\n");
|
||||||
|
|
||||||
result = IP_recv(&rcv_pdu, &rcv_sock_addr, TIMEOUT);
|
result = IP_recv(&rcv_pdu, &rcv_sock_addr, TIMEOUT);
|
||||||
if (result == -1)
|
if (result == -1 && DEBUG)
|
||||||
printf("[MIC-TCP] "COLOR_BOLD"Timeout"COLOR_RESET"\n");
|
printf("[MIC-TCP] "COLOR_BOLD"Timeout"COLOR_RESET"\n");
|
||||||
else if (rcv_pdu.header.ack_num != next_msg_num + 1) {
|
else if (rcv_pdu.header.ack_num != next_msg_num + 1) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Received ACK: %d | "COLOR_RED"INVALID"COLOR_RESET"\n", rcv_pdu.header.ack_num);
|
printf("[MIC-TCP] Received ACK: %d | "COLOR_RED"INVALID"COLOR_RESET"\n", rcv_pdu.header.ack_num);
|
||||||
printf("[MIC-TCP] | Expected: %d\n", next_msg_num + 1);
|
printf("[MIC-TCP] | Expected: %d\n", next_msg_num + 1);
|
||||||
printf("[MIC-TCP] | Received: %d\n", rcv_pdu.header.ack_num);
|
printf("[MIC-TCP] | Received: %d\n", rcv_pdu.header.ack_num);
|
||||||
result = -1;
|
|
||||||
} else
|
|
||||||
printf("[MIC-TCP] Received ACK: "COLOR_GREEN"VALID"COLOR_RESET"\n");
|
|
||||||
} else
|
|
||||||
printf("[MIC-TCP] Ip_send "COLOR_RED"ERROR"COLOR_RESET"\n");
|
|
||||||
}
|
}
|
||||||
|
result = -1;
|
||||||
|
} else if (DEBUG)
|
||||||
|
printf("[MIC-TCP] Received ACK: "COLOR_GREEN"VALID"COLOR_RESET"\n");
|
||||||
|
} else if (DEBUG)
|
||||||
|
printf("[MIC-TCP] Ip_send "COLOR_RED"ERROR"COLOR_RESET"\n");
|
||||||
|
|
||||||
|
if (result == -1 && errorDetected == 0) {
|
||||||
|
errorDetected = 1;
|
||||||
|
saveError();
|
||||||
|
}else
|
||||||
|
saveSuccess();
|
||||||
|
printList();
|
||||||
|
} while (result == -1 && isLossAcceptable() == 0);
|
||||||
|
|
||||||
next_msg_num = next_msg_num + 1;
|
next_msg_num = next_msg_num + 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,9 +274,11 @@ int mic_tcp_send(int socket, char *mesg, int mesg_size) {
|
||||||
* NB : cette fonction fait appel à la fonction app_buffer_get()
|
* 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) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
|
@ -157,12 +299,14 @@ int mic_tcp_recv(int socket, char *mesg, int max_mesg_size) {
|
||||||
* @return 0 si tout se passe bien et -1 en cas d'erreur
|
* @return 0 si tout se passe bien et -1 en cas d'erreur
|
||||||
*/
|
*/
|
||||||
int mic_tcp_close(int socket) {
|
int mic_tcp_close(int socket) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction : ");
|
printf("[MIC-TCP] Appel de la fonction : ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
g_sock.state = CLOSED;
|
g_sock.state = CLOSED;
|
||||||
|
clearList();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +317,11 @@ int mic_tcp_close(int socket) {
|
||||||
* app_buffer_put().
|
* app_buffer_put().
|
||||||
*/
|
*/
|
||||||
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) {
|
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) {
|
||||||
|
if (DEBUG) {
|
||||||
printf("[MIC-TCP] Appel de la fonction: ");
|
printf("[MIC-TCP] Appel de la fonction: ");
|
||||||
printf(__FUNCTION__);
|
printf(__FUNCTION__);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct mic_tcp_pdu ack_pdu;
|
struct mic_tcp_pdu ack_pdu;
|
||||||
ack_pdu.header.source_port = 0;
|
ack_pdu.header.source_port = 0;
|
||||||
|
@ -185,17 +331,20 @@ void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr) {
|
||||||
ack_pdu.header.ack = 0;
|
ack_pdu.header.ack = 0;
|
||||||
ack_pdu.header.fin = 0;
|
ack_pdu.header.fin = 0;
|
||||||
|
|
||||||
if (pdu.header.seq_num == next_msg_num) {
|
if (pdu.header.seq_num >= next_msg_num) {
|
||||||
next_msg_num = next_msg_num + 1;
|
next_msg_num = pdu.header.seq_num + 1;
|
||||||
app_buffer_put(pdu.payload);
|
app_buffer_put(pdu.payload);
|
||||||
|
if (DEBUG)
|
||||||
printf("[MIC-TCP] Received PDU: "COLOR_GREEN"VALID"COLOR_RESET"\n");
|
printf("[MIC-TCP] Received PDU: "COLOR_GREEN"VALID"COLOR_RESET"\n");
|
||||||
} else {
|
} else if (DEBUG) {
|
||||||
printf("[MIC-TCP] Received PDU: "COLOR_RED"INVALID"COLOR_RESET"\n");
|
printf("[MIC-TCP] Received PDU: "COLOR_RED"INVALID"COLOR_RESET"\n");
|
||||||
printf("[MIC-TCP] | Expected: %d\n", next_msg_num);
|
printf("[MIC-TCP] | Expected: %d\n", next_msg_num);
|
||||||
printf("[MIC-TCP] | Received: %d\n", pdu.header.seq_num);
|
printf("[MIC-TCP] | Received: %d\n", pdu.header.seq_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
ack_pdu.header.ack_num = next_msg_num;
|
if (DEBUG)
|
||||||
printf("[MIC-TCP] Sending ack: %d\n", next_msg_num);
|
printf("[MIC-TCP] Sending ack: %d\n", next_msg_num);
|
||||||
|
|
||||||
|
ack_pdu.header.ack_num = next_msg_num;
|
||||||
IP_send(ack_pdu, addr);
|
IP_send(ack_pdu, addr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue