Updated the mictcp base with the 2017-03-18 source code distributed to students.
These changes were not made by myself.
This commit is contained in:
parent
5c3e257904
commit
e28e634800
9 changed files with 102 additions and 98 deletions
8
Makefile
8
Makefile
|
@ -25,7 +25,7 @@ vpath %.c $(SRC_DIR)
|
|||
|
||||
define make-goal
|
||||
$1/%.o: %.c
|
||||
$(CC) -ansi -Wall -m32 -g -I $(INCLUDES) -c $$< -o $$@
|
||||
$(CC) -std=gnu99 -Wall -m32 -g -I $(INCLUDES) -c $$< -o $$@
|
||||
endef
|
||||
|
||||
.PHONY: all checkdirs clean
|
||||
|
@ -33,13 +33,13 @@ endef
|
|||
all: checkdirs build/client build/server build/gateway
|
||||
|
||||
build/client: $(OBJ_CLI)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
$(LD) -m32 $^ -o $@ -lm -lpthread
|
||||
|
||||
build/server: $(OBJ_SERV)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
$(LD) -m32 $^ -o $@ -lm -lpthread
|
||||
|
||||
build/gateway: $(OBJ_GWAY)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
$(LD) -m32 $^ -o $@ -lm -lpthread
|
||||
|
||||
checkdirs: $(BUILD_DIR)
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
int initialize_components(start_mode sm);
|
||||
|
||||
int IP_send(mic_tcp_pdu, mic_tcp_sock_addr);
|
||||
int IP_recv(mic_tcp_payload*, mic_tcp_sock_addr*, unsigned long delay);
|
||||
int IP_recv(ip_payload*, mic_tcp_sock_addr*, unsigned long timeout);
|
||||
int app_buffer_get(mic_tcp_payload);
|
||||
void app_buffer_set(mic_tcp_payload);
|
||||
void app_buffer_put(mic_tcp_payload);
|
||||
|
||||
void set_loss_rate(unsigned short);
|
||||
unsigned long get_now_time_msec();
|
||||
|
@ -25,14 +25,14 @@ unsigned long get_now_time_usec();
|
|||
|
||||
#define API_CS_Port 8524
|
||||
#define API_SC_Port 8525
|
||||
#define API_HD_Size 15
|
||||
|
||||
int full_send(mic_tcp_payload);
|
||||
int partial_send(mic_tcp_payload);
|
||||
int mic_tcp_core_send(mic_tcp_payload);
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu);
|
||||
mic_tcp_payload get_data_stream(mic_tcp_payload);
|
||||
mic_tcp_header get_header(char*);
|
||||
mic_tcp_payload get_mic_tcp_data(ip_payload);
|
||||
mic_tcp_header get_mic_tcp_header(ip_payload);
|
||||
void* listening(void*);
|
||||
void print_header(mic_tcp_payload);
|
||||
void print_header(mic_tcp_pdu);
|
||||
|
||||
int min_size(int, int);
|
||||
float mod(int, float);
|
||||
|
|
|
@ -82,6 +82,16 @@ typedef struct mic_tcp_pdu
|
|||
mic_tcp_payload payload; /* charge utile du PDU */
|
||||
} mic_tcp_pdu;
|
||||
|
||||
/*
|
||||
* Structure des données utiles d’un PDU IP
|
||||
*/
|
||||
typedef struct ip_payload
|
||||
{
|
||||
char* data; /* données transport */
|
||||
int size; /* taille des données */
|
||||
} ip_payload;
|
||||
|
||||
|
||||
typedef struct app_buffer
|
||||
{
|
||||
mic_tcp_payload packet;
|
||||
|
@ -102,23 +112,4 @@ int mic_tcp_recv (int socket, char* mesg, int max_mesg_size);
|
|||
void process_received_PDU(mic_tcp_pdu pdu);
|
||||
int mic_tcp_close(int socket);
|
||||
|
||||
/**********************
|
||||
* Variables globales *
|
||||
**********************/
|
||||
mic_tcp_sock local_sock_src;
|
||||
mic_tcp_sock local_sock_dest;
|
||||
unsigned long timer;
|
||||
unsigned long RTT1;
|
||||
unsigned long RTT2;
|
||||
int PE;
|
||||
int PA;
|
||||
float pourcentage_perte_client;
|
||||
float pourcentage_perte_serveur;
|
||||
float compteurDT;
|
||||
float DTperdu;
|
||||
mic_tcp_pdu DT;
|
||||
mic_tcp_pdu Syn;
|
||||
mic_tcp_pdu Ack;
|
||||
mic_tcp_pdu Syn_Ack;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <api/mictcp_core.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <strings.h>
|
||||
|
@ -12,12 +13,8 @@ int initialized = -1;
|
|||
int sys_socket;
|
||||
pthread_t listen_th;
|
||||
pthread_mutex_t lock;
|
||||
float loss_rate = 0.0f;
|
||||
float jump = 0;
|
||||
float range = 0;
|
||||
int count = 0;
|
||||
int reverse = 1;
|
||||
|
||||
unsigned short loss_rate = 0;
|
||||
struct sockaddr_in remote_addr;
|
||||
|
||||
/* This is for the buffer */
|
||||
TAILQ_HEAD(tailhead, app_buffer_entry) app_buffer_head;
|
||||
|
@ -27,15 +24,17 @@ struct app_buffer_entry {
|
|||
TAILQ_ENTRY(app_buffer_entry) entries;
|
||||
};
|
||||
|
||||
/* Condition variable used for passive wait when buffer is empty */
|
||||
pthread_cond_t buffer_empty_cond;
|
||||
|
||||
/*************************
|
||||
* Fonctions Utilitaires *
|
||||
*************************/
|
||||
int initialize_components(start_mode mode)
|
||||
{
|
||||
int bnd;
|
||||
struct sockaddr_in local_addr;
|
||||
struct sockaddr_in remote_addr;
|
||||
struct hostent * hp;
|
||||
struct sockaddr_in local_addr;
|
||||
|
||||
if(initialized != -1) return initialized;
|
||||
if((sys_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return -1;
|
||||
|
@ -44,6 +43,7 @@ int initialize_components(start_mode mode)
|
|||
if((mode == SERVER) & (initialized != -1))
|
||||
{
|
||||
TAILQ_INIT(&app_buffer_head);
|
||||
pthread_cond_init(&buffer_empty_cond, 0);
|
||||
memset((char *) &local_addr, 0, sizeof(local_addr));
|
||||
local_addr.sin_family = AF_INET;
|
||||
local_addr.sin_port = htons(API_CS_Port);
|
||||
|
@ -56,7 +56,7 @@ int initialize_components(start_mode mode)
|
|||
}
|
||||
else
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(local_addr));
|
||||
memset((char *) &remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_SC_Port);
|
||||
hp = gethostbyname("localhost");
|
||||
|
@ -70,7 +70,7 @@ int initialize_components(start_mode mode)
|
|||
{
|
||||
if(initialized != -1)
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(local_addr));
|
||||
memset((char *) &remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_CS_Port);
|
||||
hp = gethostbyname("localhost");
|
||||
|
@ -96,101 +96,100 @@ int initialize_components(start_mode mode)
|
|||
|
||||
int IP_send(mic_tcp_pdu pk, mic_tcp_sock_addr addr)
|
||||
{
|
||||
if(initialized == -1) return -1;
|
||||
if(loss_rate == 0)
|
||||
{
|
||||
|
||||
int result = 0;
|
||||
|
||||
if(initialized == -1) {
|
||||
result = -1;
|
||||
|
||||
} else {
|
||||
mic_tcp_payload tmp = get_full_stream(pk);
|
||||
int sent_size = full_send(tmp);
|
||||
int sent_size = mic_tcp_core_send(tmp);
|
||||
|
||||
free (tmp.data);
|
||||
|
||||
return sent_size;
|
||||
result = sent_size;
|
||||
}
|
||||
else return partial_send(get_full_stream(pk));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int IP_recv(mic_tcp_payload* pk,mic_tcp_sock_addr* addr, unsigned long delay)
|
||||
int IP_recv(ip_payload* pk,mic_tcp_sock_addr* addr, unsigned long timeout)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
struct timeval tv;
|
||||
struct sockaddr_in tmp_addr;
|
||||
socklen_t tmp_addr_size = sizeof(struct sockaddr);
|
||||
|
||||
/* Send data over a fake IP */
|
||||
if(initialized == -1) return -1;
|
||||
|
||||
if(delay == 0) {tv.tv_sec = 3600; tv.tv_usec = 0;}
|
||||
else {tv.tv_sec = 0; tv.tv_usec = delay;}
|
||||
if (setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
|
||||
if(initialized == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int recv_size = recvfrom(sys_socket, pk->data, pk->size, 0, (struct sockaddr *)&tmp_addr, &tmp_addr_size);
|
||||
pk->size = recv_size;
|
||||
return recv_size;
|
||||
}
|
||||
|
||||
/* Compute the number of entire seconds */
|
||||
tv.tv_sec = timeout / 1000;
|
||||
/* Convert the remainder to microseconds */
|
||||
tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
|
||||
|
||||
if ((setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) >= 0) {
|
||||
result = recvfrom(sys_socket, pk->data, pk->size, 0, (struct sockaddr *)&tmp_addr, &tmp_addr_size);
|
||||
pk->size = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu pk)
|
||||
{
|
||||
/* Get a full packet from data and header */
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = 15 + pk.payload.size;
|
||||
tmp.size = API_HD_Size + pk.payload.size;
|
||||
tmp.data = malloc (tmp.size);
|
||||
|
||||
memcpy (tmp.data, &pk.header, 15);
|
||||
memcpy (tmp.data + 15, pk.payload.data, pk.payload.size);
|
||||
memcpy (tmp.data, &pk.header, API_HD_Size);
|
||||
memcpy (tmp.data + API_HD_Size, pk.payload.data, pk.payload.size);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_data_stream(mic_tcp_payload buff)
|
||||
mic_tcp_payload get_mic_tcp_data(ip_payload buff)
|
||||
{
|
||||
mic_tcp_payload tmp;
|
||||
tmp.data = malloc(buff.size-15);
|
||||
memcpy(tmp.data, buff.data+15, tmp.size);
|
||||
tmp.size = buff.size-API_HD_Size;
|
||||
tmp.data = malloc(tmp.size);
|
||||
memcpy(tmp.data, buff.data+API_HD_Size, tmp.size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
mic_tcp_header get_header(char* packet)
|
||||
mic_tcp_header get_mic_tcp_header(ip_payload packet)
|
||||
{
|
||||
/* Get a struct header from an incoming packet */
|
||||
mic_tcp_header tmp;
|
||||
memcpy(&tmp, packet, 15);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_data(mic_tcp_payload packet)
|
||||
{
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = packet.size - 15;
|
||||
tmp.data = malloc(tmp.size);
|
||||
memcpy(tmp.data, packet.data + 15, tmp.size);
|
||||
memcpy(&tmp, packet.data, API_HD_Size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int full_send(mic_tcp_payload buff)
|
||||
{
|
||||
struct sockaddr_in remote_addr;
|
||||
int result = 0;
|
||||
|
||||
result = sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
result = sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int partial_send(mic_tcp_payload buff)
|
||||
int mic_tcp_core_send(mic_tcp_payload buff)
|
||||
{
|
||||
struct sockaddr_in remote_addr;
|
||||
int random = rand();
|
||||
int result = buff.size;
|
||||
int lr_tresh = (int) round(loss_rate*RAND_MAX);
|
||||
int lr_tresh = (int) round(((float)loss_rate/100.0)*RAND_MAX);
|
||||
|
||||
if(random > lr_thresh) {
|
||||
if(random > lr_tresh) {
|
||||
result = sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
} else {
|
||||
printf("[MICTCP-CORE] Perte du paquet\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -204,11 +203,19 @@ int app_buffer_get(mic_tcp_payload app_buff)
|
|||
/* The actual size passed to the application */
|
||||
int result = 0;
|
||||
|
||||
/* Lock a mutex to protect the buffer from corruption */
|
||||
pthread_mutex_lock(&lock);
|
||||
|
||||
/* If the buffer is empty, we wait for insertion */
|
||||
while(app_buffer_head.tqh_first == NULL) {
|
||||
usleep(1000);
|
||||
pthread_cond_wait(&buffer_empty_cond, &lock);
|
||||
}
|
||||
|
||||
/* When we execute the code below, the following conditions are true:
|
||||
- The buffer contains at least 1 element
|
||||
- We hold the lock on the mutex
|
||||
*/
|
||||
|
||||
/* The entry we want is the first one in the buffer */
|
||||
entry = app_buffer_head.tqh_first;
|
||||
|
||||
|
@ -218,9 +225,6 @@ int app_buffer_get(mic_tcp_payload app_buff)
|
|||
/* We copy the actual data in the application allocated buffer */
|
||||
memcpy(app_buff.data, entry->bf.data, result);
|
||||
|
||||
/* Lock a mutex to protect the buffer from corruption */
|
||||
pthread_mutex_lock(&lock);
|
||||
|
||||
/* We remove the entry from the buffer */
|
||||
TAILQ_REMOVE(&app_buffer_head, entry, entries);
|
||||
|
||||
|
@ -234,7 +238,7 @@ int app_buffer_get(mic_tcp_payload app_buff)
|
|||
return result;
|
||||
}
|
||||
|
||||
void app_buffer_set(mic_tcp_payload bf)
|
||||
void app_buffer_put(mic_tcp_payload bf)
|
||||
{
|
||||
/* Prepare a buffer entry to store the data */
|
||||
struct app_buffer_entry * entry = malloc(sizeof(struct app_buffer_entry));
|
||||
|
@ -248,6 +252,10 @@ void app_buffer_set(mic_tcp_payload bf)
|
|||
|
||||
/* Release the mutex */
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
/* We can now signal to any potential thread waiting that the buffer is
|
||||
no longer empty */
|
||||
pthread_cond_broadcast(&buffer_empty_cond);
|
||||
}
|
||||
|
||||
|
||||
|
@ -257,7 +265,7 @@ void* listening(void* arg)
|
|||
mic_tcp_pdu pdu_tmp;
|
||||
int recv_size;
|
||||
mic_tcp_sock_addr remote;
|
||||
mic_tcp_payload tmp_buff;
|
||||
ip_payload tmp_buff;
|
||||
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
|
@ -274,9 +282,12 @@ void* listening(void* arg)
|
|||
|
||||
if(recv_size > 0)
|
||||
{
|
||||
pdu_tmp.header = get_header (tmp_buff.data);
|
||||
pdu_tmp.payload = get_data (tmp_buff);
|
||||
pdu_tmp.header = get_mic_tcp_header (tmp_buff);
|
||||
pdu_tmp.payload = get_mic_tcp_data (tmp_buff);
|
||||
process_received_PDU(pdu_tmp);
|
||||
} else {
|
||||
/* This should never happen */
|
||||
printf("Error in recv\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,12 +295,12 @@ void* listening(void* arg)
|
|||
|
||||
void set_loss_rate(unsigned short rate)
|
||||
{
|
||||
loss_rate = ((float) rate) / 100.0;
|
||||
loss_rate = rate;
|
||||
}
|
||||
|
||||
void print_header(mic_tcp_payload bf)
|
||||
void print_header(mic_tcp_pdu bf)
|
||||
{
|
||||
mic_tcp_header hd = get_header(bf.data);
|
||||
mic_tcp_header hd = bf.header;
|
||||
printf("\nSP: %d, DP: %d, SEQ: %d, ACK: %d", hd.source_port, hd.dest_port, hd.seq_num, hd.ack_num);
|
||||
}
|
||||
|
||||
|
|
12
src/mictcp.c
12
src/mictcp.c
|
@ -7,9 +7,12 @@
|
|||
*/
|
||||
int mic_tcp_socket(start_mode sm)
|
||||
{
|
||||
int result = -1;
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
initialize_components(sm); /* Appel obligatoire */
|
||||
return -1;
|
||||
result = initialize_components(sm); /* Appel obligatoire */
|
||||
set_loss_rate(0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -45,7 +48,6 @@ int mic_tcp_connect(int socket, mic_tcp_sock_addr addr)
|
|||
/*
|
||||
* Permet de réclamer l’envoi d’une donnée applicative
|
||||
* Retourne la taille des données envoyées, et -1 en cas d'erreur
|
||||
* Dans le cas de la vidéo, seul la source va envoyer au puits
|
||||
*/
|
||||
int mic_tcp_send (int mic_sock, char* mesg, int mesg_size)
|
||||
{
|
||||
|
@ -62,7 +64,7 @@ int mic_tcp_send (int mic_sock, char* mesg, int 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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -80,7 +82,7 @@ int mic_tcp_close (int socket)
|
|||
* Traitement d’un 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_add().
|
||||
* app_buffer_put().
|
||||
*/
|
||||
void process_received_PDU(mic_tcp_pdu pdu)
|
||||
{
|
||||
|
|
0
tsock_texte
Normal file → Executable file
0
tsock_texte
Normal file → Executable file
0
tsock_video
Normal file → Executable file
0
tsock_video
Normal file → Executable file
BIN
video/video_starwars.bin
Normal file
BIN
video/video_starwars.bin
Normal file
Binary file not shown.
BIN
video/video_wildlife.bin
Normal file
BIN
video/video_wildlife.bin
Normal file
Binary file not shown.
Loading…
Reference in a new issue