Merge branch 'add-message' of gaufre.informatique.univ-paris-diderot.fr:perdriau/dazibao into add-message
This commit is contained in:
commit
c47bff0a55
317
src/node.c
317
src/node.c
@ -1,19 +1,6 @@
|
||||
// This is the main file of the Dazibao project. It represents the node, and
|
||||
// handles all of the main logic, including the network connexions.
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include "node.h"
|
||||
#include "debug.h"
|
||||
|
||||
// Static variables
|
||||
static list *data_list;
|
||||
@ -201,7 +188,7 @@ pub_data *get_data(int64_t id) {
|
||||
}
|
||||
|
||||
// Take data as args and create a pub_data structure in the heap
|
||||
pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data) {
|
||||
pub_data *copy_data(unsigned char len, int64_t id, uint16_t seqno, char *data) {
|
||||
pub_data *new_data = (pub_data*) malloc(sizeof(pub_data));
|
||||
char *_data = (char*) malloc(len);
|
||||
if (_data == NULL) {
|
||||
@ -221,155 +208,102 @@ pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data) {
|
||||
return new_data;
|
||||
}
|
||||
|
||||
// Add new data to data list
|
||||
int add_data(unsigned char len, int64_t id, int16_t seqno, char *data) {
|
||||
print_debug(">> Adding data to the data list.");
|
||||
// If id is the same as this node's id then we only update seqno
|
||||
|
||||
if(id == NODE_ID) {
|
||||
// We create our pub_data.
|
||||
pub_data * message = malloc(sizeof(struct pub_data));
|
||||
if (message == NULL) {
|
||||
print_error("Failed to allocate memory for the message !");
|
||||
// A node state TLV was received and either no data associated to it's id is in our data list or the data was updated, return -1 if an error occurend, 0 if nothing had to be done and 1 if something was updated/added
|
||||
int add_data(unsigned char len, int64_t id, uint16_t seqno, char *data, pub_data *found) {
|
||||
// Check if it's our own id
|
||||
if(id == NODE_ID) {
|
||||
// wtf
|
||||
if(found == NULL) {
|
||||
printf("\x1b[31m[DEBUG]\x1b[0m >> Our own node is not in the data list, something went terribly wrong.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
message->length = len;
|
||||
message->id = id;
|
||||
message->seqno = seqno;
|
||||
message->data = data;
|
||||
|
||||
// If the data list has never been used, or is empty ( same thing )
|
||||
if (data_list == NULL) {
|
||||
data_list = (list*) malloc(sizeof(struct list));
|
||||
if (data_list == NULL) {
|
||||
print_error("Failed to allocate memory to create the data_list !");
|
||||
return -1;
|
||||
}
|
||||
list *tmp = data_list;
|
||||
// We create the next node of the linked list.
|
||||
tmp->data = (void *) message;
|
||||
tmp->next = NULL;
|
||||
|
||||
} else {
|
||||
// we move until the last element of the dala_list,
|
||||
// and add or data there.
|
||||
// We use a temporary address to avoid writing to the static list.
|
||||
// Seems weird but ok.
|
||||
list *tmp = data_list;
|
||||
while(tmp->next != NULL){
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
// We create the next node of the linked list.
|
||||
list * new_node = malloc(sizeof(struct list));
|
||||
if (new_node == NULL) {
|
||||
print_error("Failed to allocate memory for the new node in data list.");
|
||||
return -1;
|
||||
}
|
||||
new_node->data = (void *) message;
|
||||
new_node->next = NULL;
|
||||
|
||||
// Adding the message to the list.
|
||||
tmp->next = (void *) new_node;
|
||||
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
// Copy data
|
||||
pub_data *new_data = copy_data(len, id, seqno, data);
|
||||
if (new_data == NULL) {
|
||||
print_error("Failed to copy data to new_data !");
|
||||
return -1;
|
||||
// If seqno is bigger or equals than our stored seqno then update seqno
|
||||
if( ((seqno - found->seqno) & 32768) == 0 ) {
|
||||
printf(">> Updating seqno of our own published data.\n");
|
||||
found->seqno = (seqno + 1) % (65535);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(data_list == NULL) {
|
||||
// Update list
|
||||
data_list = (list*) malloc(sizeof(list));
|
||||
if (data_list == NULL) {
|
||||
print_error("Failed to allocate memory to create the data_list !");
|
||||
return -1;
|
||||
}
|
||||
data_list->data = (void*) new_data;
|
||||
data_list->next = NULL;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Find correct position for new data
|
||||
list *tmp = data_list;
|
||||
list *last = NULL;
|
||||
list *new_node;
|
||||
int64_t cur_id;
|
||||
|
||||
while(tmp != NULL) {
|
||||
cur_id = ((pub_data*) tmp->data)->id;
|
||||
|
||||
// If id is smaller than cur_id then the new data has to be added at this position
|
||||
if(id < cur_id) {
|
||||
// If last hasn't been set then the new data becomes the head of the list
|
||||
if(last == NULL) {
|
||||
// Update list
|
||||
data_list = (list*) malloc(sizeof(struct list));
|
||||
if (data_list == NULL) {
|
||||
print_error("Failed to allocate memory to create the data_list !");
|
||||
return -1;
|
||||
}
|
||||
data_list->data = (void*) new_data;
|
||||
data_list->next = tmp;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Else, we update the last node
|
||||
new_node = (list*) malloc(sizeof(struct list));
|
||||
if (new_node == NULL) {
|
||||
print_error("Failed to allocate memory for the new node in data list.");
|
||||
return -1;
|
||||
}
|
||||
new_node->data = (void*) new_data;
|
||||
new_node->next = tmp;
|
||||
last->next = new_node;
|
||||
|
||||
return 1;
|
||||
} else if(id == cur_id) {
|
||||
// If data already exists for this id then we update it if it's seqno is greater than the one stored
|
||||
pub_data *cur_data = (pub_data*) tmp->data;
|
||||
|
||||
if(seqno > cur_data->seqno) {
|
||||
// Updata data
|
||||
tmp->data = (void*) new_data;
|
||||
|
||||
// Free old data
|
||||
free(cur_data);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// seqno is smaller so the new data allocated is freed and nothing else is done
|
||||
free(new_data);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Get next node in list
|
||||
last = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
// If no correct position was found then the new data has to be added at the end of the list
|
||||
|
||||
// Update list
|
||||
new_node = (list*) malloc(sizeof(list));
|
||||
if (new_node == NULL) {
|
||||
print_error("Failed to allocate memory for the new node in data list.");
|
||||
return -1;
|
||||
}
|
||||
new_node->data = (void*) new_data;
|
||||
new_node->next = NULL;
|
||||
last->next = new_node;
|
||||
return 3;
|
||||
// Else, do nothing
|
||||
printf(">> Our own seqno didn't need to be updated.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If it's not our own id, update the data if it's already in our data list and seqno is bigger than our stored seqno
|
||||
if(found != NULL) {
|
||||
// Check if seqno is smaller or equals to our stored seqno
|
||||
if( ((found->seqno - seqno) & 32768) == 0 ) {
|
||||
printf(">> Data received has smaller seqno than stored seqno, nothing has to be done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update data
|
||||
found->length = len;
|
||||
found->id = id;
|
||||
found->seqno = seqno;
|
||||
|
||||
// Updata message
|
||||
free(found->data);
|
||||
found->data = (char*) malloc(len);
|
||||
memcpy(found->data, data, len);
|
||||
|
||||
printf(">> Updated %li's published data.\n", id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Else, add new data
|
||||
pub_data *new_data = copy_data(len, id, seqno, data);
|
||||
|
||||
// Find correct position for new data
|
||||
list *tmp = data_list;
|
||||
list *last = NULL;
|
||||
list *new_node;
|
||||
int64_t cur_id;
|
||||
|
||||
while(tmp != NULL) {
|
||||
cur_id = ((pub_data*) tmp->data)->id;
|
||||
|
||||
// If id is smaller than cur_id then the new data has to be added at this position
|
||||
if(id < cur_id) {
|
||||
// If last hasn't been set then the new data becomes the head of the list
|
||||
if(last == NULL) {
|
||||
// Update list
|
||||
data_list = (list*) malloc(sizeof(list));
|
||||
data_list->data = (void*) new_data;
|
||||
data_list->next = tmp;
|
||||
|
||||
printf(">> Added new message to data list.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Else, we update the last node
|
||||
new_node = (list*) malloc(sizeof(list));
|
||||
new_node->data = (void*) new_data;
|
||||
new_node->next = tmp;
|
||||
last->next = new_node;
|
||||
|
||||
printf(">> Added new message to data list.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get next node in list
|
||||
last = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
// If no correct position was found then the new data has to be added at the end of the list
|
||||
new_node = (list*) malloc(sizeof(list));
|
||||
new_node->data = (void*) new_data;
|
||||
new_node->next = NULL;
|
||||
last->next = new_node;
|
||||
|
||||
printf(">> Added new message to data list.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- Fin fonctions utilitaires ---- */
|
||||
@ -534,7 +468,7 @@ int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
|
||||
}
|
||||
|
||||
// Send length bytes from packet
|
||||
int send_packet(char *packet_buff, int16_t length, struct sockaddr_in6 *dest, int socket_num) {
|
||||
int send_packet(char *packet_buff, uint16_t length, struct sockaddr_in6 *dest, int socket_num) {
|
||||
((packet*) packet_buff)->length = htons(((packet*) packet_buff)->length);
|
||||
|
||||
// Vectorized buffer
|
||||
@ -640,7 +574,7 @@ int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
|
||||
return send_packet((char*) &pack, pack.length, dest, socket_num);
|
||||
}
|
||||
|
||||
int send_tlv(tlv *tlv_to_send, int16_t tlv_size, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num){
|
||||
int send_tlv(tlv *tlv_to_send, uint16_t tlv_size, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num){
|
||||
print_debug(">> Building packet to send a TLV.");
|
||||
|
||||
// We first need to build the packet,
|
||||
@ -707,7 +641,7 @@ int send_tlv(tlv *tlv_to_send, int16_t tlv_size, struct sockaddr_in6 * dest_list
|
||||
|
||||
// We need to make sure the TLV announces a length that will no go onto
|
||||
// another tlv, as we might end up reading bullshit.
|
||||
int validate_tlv(char *data, int pos, int16_t packet_len){
|
||||
int validate_tlv(char *data, int pos, uint16_t packet_len){
|
||||
|
||||
char type = data[pos];
|
||||
|
||||
@ -799,17 +733,32 @@ int check_header(char * received_data_buffer, int received_data_len, struct pack
|
||||
}
|
||||
|
||||
int add_message(char * message, int message_len){
|
||||
int seqno = 1337;
|
||||
int rc = add_data((unsigned char) message_len, (int64_t) NODE_ID ,(int16_t) seqno, message);
|
||||
if (rc > 0) {
|
||||
// Don't update the message if it's empty
|
||||
if(message_len == 0)
|
||||
return -1;
|
||||
|
||||
// If not, get our data in the list and update it
|
||||
pub_data *our_data = get_data(NODE_ID);
|
||||
|
||||
if(our_data != NULL) {
|
||||
our_data->seqno = (our_data->seqno + 1) % 65535;
|
||||
our_data->length = message_len;
|
||||
free(our_data->data);
|
||||
our_data->data = (char*) malloc(message_len);
|
||||
memcpy(our_data->data, message, message_len);
|
||||
|
||||
print_debug(">> Message added.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
print_debug(">> Message could not be added because our own ID is not in the data_list, something went wrong.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We then look at the differents TLVs in the packet.
|
||||
int work_with_tlvs(char * data, int16_t total_packet_len, struct sockaddr_in6 *sender, int socket_num){
|
||||
int16_t packet_len = ((packet*) data)->length;
|
||||
int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *sender, int socket_num){
|
||||
uint16_t packet_len = ((packet*) data)->length;
|
||||
|
||||
if(packet_len != total_packet_len - 4) {
|
||||
print_debug(">> Length indicated in packet differs from real length of packet received, disgarding packet.");
|
||||
@ -976,7 +925,7 @@ int work_with_tlvs(char * data, int16_t total_packet_len, struct sockaddr_in6 *s
|
||||
hash_data(pdata, hash);
|
||||
|
||||
// If both hashes are the same then nothing has to be done
|
||||
if(memcmp(hash, cur_tlv.node_hash->node_hash, 16) != 0) {
|
||||
if(memcmp(hash, cur_tlv.node_hash->node_hash, 16) == 0) {
|
||||
// The position is updated
|
||||
tlv_len = data[pos+1];
|
||||
pos += 2;
|
||||
@ -1028,7 +977,28 @@ int work_with_tlvs(char * data, int16_t total_packet_len, struct sockaddr_in6 *s
|
||||
}
|
||||
printf("\x1b[31m[DEBUG]\x1b[0m >> “%s”\n", cur_tlv.node_state->data);
|
||||
}
|
||||
int rc = add_data(cur_tlv.node_state->length - 26, ntohl(cur_tlv.node_state->node_id), ntohs(cur_tlv.node_state->seqno), cur_tlv.node_state->data);
|
||||
|
||||
// Compare hashes
|
||||
pdata = get_data(ntohl(cur_tlv.node_state->node_id));
|
||||
|
||||
// If data is found for this id then we check that both hashes are the same
|
||||
if(pdata != NULL) {
|
||||
// We hash the data stored in the data list
|
||||
hash_data(pdata, hash);
|
||||
|
||||
// If both hashes are the same then nothing has to be done
|
||||
if(memcmp(hash, cur_tlv.node_hash->node_hash, 16) == 0) {
|
||||
// The position is updated
|
||||
tlv_len = data[pos+1];
|
||||
pos += 2;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Else, we update the data
|
||||
int rc = add_data(cur_tlv.node_state->length - 26, ntohl(cur_tlv.node_state->node_id), ntohs(cur_tlv.node_state->seqno), cur_tlv.node_state->data, pdata);
|
||||
if (rc < 0) {
|
||||
print_error("Error while adding node state !");
|
||||
}
|
||||
@ -1293,6 +1263,17 @@ int bootstrap_node(int * sock_fd){
|
||||
neighbour_list->data = (void *) root_peer;
|
||||
neighbour_list->next = NULL;
|
||||
|
||||
print_debug(">> Initializing data list...");
|
||||
data_list = (list*) malloc(sizeof(list));
|
||||
data_list->data = malloc(sizeof(pub_data));
|
||||
data_list->next = NULL;
|
||||
|
||||
pub_data *our_data = (pub_data*) data_list->data;
|
||||
our_data->length = 0;
|
||||
our_data->id = NODE_ID;
|
||||
our_data->seqno = 1337;
|
||||
our_data->data = NULL;
|
||||
|
||||
print_debug(">> Boostraping done.");
|
||||
return 0;
|
||||
}
|
||||
|
22
src/node.h
22
src/node.h
@ -12,6 +12,12 @@
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <net/if.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include "debug.h"
|
||||
|
||||
/* la table de voisins, qui est indexée par adresses de socket (des paires (IP, Port)),
|
||||
* et dont chaque entrée contient un booléen indiquant si le pair est permanent
|
||||
@ -35,7 +41,7 @@ typedef struct neighbour_peer {
|
||||
typedef struct pub_data {
|
||||
unsigned char length;
|
||||
int64_t id;
|
||||
int16_t seqno;
|
||||
uint16_t seqno;
|
||||
char *data;
|
||||
} pub_data;
|
||||
|
||||
@ -69,17 +75,17 @@ int listen_for_packets(char * received_data_buffer, int received_data_len, struc
|
||||
|
||||
int check_header(char * received_data_buffer, int received_data_len, packet * packet_to_return);
|
||||
|
||||
int validate_tlv(char *data, int pos, int16_t packet_len);
|
||||
int validate_tlv(char *data, int pos, uint16_t packet_len);
|
||||
|
||||
int update_neighbours();
|
||||
|
||||
int ask_for_peers(int socket_num);
|
||||
|
||||
int work_with_tlvs(char * data, int16_t packet_len, struct sockaddr_in6 *sender, int socket_num);
|
||||
int work_with_tlvs(char * data, uint16_t packet_len, struct sockaddr_in6 *sender, int socket_num);
|
||||
|
||||
int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
int send_packet(char *packet_buff, int16_t length, struct sockaddr_in6 *dest, int socket_num);
|
||||
int send_packet(char *packet_buff, uint16_t length, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
@ -89,12 +95,12 @@ int run_node(int sock_fd);
|
||||
/* Takes a TLV and sends it over to everyone in the list of addresses.
|
||||
* Returns -1 in case of error, 0 otherwise.
|
||||
*/
|
||||
int send_tlv(tlv *tlv_to_send, int16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
|
||||
int send_tlv(tlv *tlv_to_send, uint16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
|
||||
|
||||
/* Takes a list of TLV and sends them over to everyone in the list of addresses.
|
||||
* Returns -1 in case of error, 0 otherwise.
|
||||
*/
|
||||
int send_tlvs(struct list * tlv_list, int16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
|
||||
int send_tlvs(struct list * tlv_list, uint16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
|
||||
|
||||
/* Check our peer list. If we have less than 5 peers, send out a
|
||||
TLV NEIGHBOUR_REQUEST to a random peer
|
||||
@ -133,9 +139,9 @@ int add_n_update_neighbour(struct in6_addr *ip, int16_t port);
|
||||
pub_data *get_data(int64_t id);
|
||||
|
||||
// Take data as args and create a pub_data structure in the heap
|
||||
pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data);
|
||||
pub_data *copy_data(unsigned char len, int64_t id, uint16_t seqno, char *data);
|
||||
|
||||
// add new data to data list
|
||||
int add_data(unsigned char len, int64_t id, int16_t seqno, char *data);
|
||||
int add_data(unsigned char len, int64_t id, uint16_t seqno, char *data, pub_data *found);
|
||||
|
||||
#endif
|
||||
|
@ -138,7 +138,7 @@ int build_network_state_req(tlv *tlv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, int16_t seqno, char *data) {
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, uint16_t seqno, char *data) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
@ -178,7 +178,7 @@ int build_node_state_req(tlv *tlv, int64_t node_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_t data_len) {
|
||||
int build_node_state(tlv *tlv, int64_t node_id, uint16_t seqno, char *data, size_t data_len) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
|
10
src/tlv.h
10
src/tlv.h
@ -19,7 +19,7 @@
|
||||
typedef struct packet {
|
||||
unsigned char magic; // 95 (si autre, ignorer)
|
||||
unsigned char version; // 1 (si autre, ignorer)
|
||||
int16_t length; // 1020 max
|
||||
uint16_t length; // 1020 max
|
||||
char body[1020];
|
||||
} packet;
|
||||
|
||||
@ -67,7 +67,7 @@ typedef struct node_hash {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
int64_t node_id;
|
||||
int16_t seqno;
|
||||
uint16_t seqno;
|
||||
char node_hash[16];
|
||||
} node_hash;
|
||||
|
||||
@ -83,7 +83,7 @@ typedef struct node_state {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
int64_t node_id;
|
||||
int16_t seqno;
|
||||
uint16_t seqno;
|
||||
char node_hash[16];
|
||||
char data[192];
|
||||
} node_state;
|
||||
@ -122,9 +122,9 @@ int build_neighbour_req(union tlv *tlv);
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port);
|
||||
int build_network_hash(tlv *tlv, list *data_list);
|
||||
int build_network_state_req(tlv *tlv);
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, int16_t seqno, char *data);
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, uint16_t seqno, char *data);
|
||||
int build_node_state_req(tlv *tlv, int64_t node_id);
|
||||
int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_t data_len);
|
||||
int build_node_state(tlv *tlv, int64_t node_id, uint16_t seqno, char *data, size_t data_len);
|
||||
int build_warning(tlv *tlv, char *message, size_t message_len);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user