diff --git a/src/node.c b/src/node.c index 9026f78..7319011 100644 --- a/src/node.c +++ b/src/node.c @@ -1,5 +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. +<<<<<<< HEAD #include #include #include @@ -14,8 +15,9 @@ #include #include #include +======= +>>>>>>> add-message #include "node.h" -#include "debug.h" // Static variables static list *data_list; @@ -206,7 +208,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) { @@ -226,155 +228,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 ---- */ @@ -539,7 +488,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 @@ -645,7 +594,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, @@ -712,7 +661,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]; @@ -804,17 +753,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."); @@ -981,7 +945,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; @@ -1034,7 +998,28 @@ int work_with_tlvs(char * data, int16_t total_packet_len, struct sockaddr_in6 *s printf("%s\n", data + pos ); printf("\x1b[31m[DEBUG]\x1b[0m >> “%ls\0”\n", (const wchar_t*) 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 !"); } @@ -1361,6 +1346,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; } diff --git a/src/node.h b/src/node.h index a45a61e..597de2f 100644 --- a/src/node.h +++ b/src/node.h @@ -12,6 +12,12 @@ #include #include #include +#include +#include +#include +#include +#include +#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 diff --git a/src/tlv.c b/src/tlv.c index 953f91d..0cb470d 100644 --- a/src/tlv.c +++ b/src/tlv.c @@ -144,7 +144,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); @@ -187,7 +187,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); diff --git a/src/tlv.h b/src/tlv.h index d10d3c9..10b4eee 100644 --- a/src/tlv.h +++ b/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