Merge branch '11-envoie-des-paquets' into 14-implement-poll
This commit is contained in:
commit
eefea551f7
10
src/hash.h
10
src/hash.h
@ -2,20 +2,22 @@
|
|||||||
#define HASH_H
|
#define HASH_H
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include "node.h"
|
|
||||||
#include "tlv.h"
|
#include "tlv.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
// Hash a single data
|
// Hash a single data
|
||||||
void hash_data(pub_data *data, unsigned char *buf);
|
void hash_data(struct pub_data *data, unsigned char *buf);
|
||||||
|
|
||||||
// Hash every data contained in data_list then return a network hash
|
// Hash every data contained in data_list then return a network hash
|
||||||
void hash_network(list *data_list, unsigned char *buf);
|
void hash_network(struct list *data_list, unsigned char *buf);
|
||||||
|
|
||||||
// Truncate 32 octet hash to 16 octets
|
// Truncate 32 octet hash to 16 octets
|
||||||
void hash_trunc(unsigned char *hash256bit, unsigned char *buf);
|
void hash_trunc(unsigned char *hash256bit, unsigned char *buf);
|
||||||
|
|
||||||
// Concat all fields of data and put them in buf
|
// Concat all fields of data and put them in buf
|
||||||
void concat_data(pub_data *data, unsigned char *buf);
|
void concat_data(struct pub_data *data, unsigned char *buf);
|
||||||
|
|
||||||
// Concat hash2 to hash1 (hash1 is modified)
|
// Concat hash2 to hash1 (hash1 is modified)
|
||||||
void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size);
|
void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size);
|
||||||
|
346
src/node.c
346
src/node.c
@ -8,8 +8,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "tlv.h"
|
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "tlv.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
|
||||||
/* ---- Fonctions utilitaires ---- */
|
/* ---- Fonctions utilitaires ---- */
|
||||||
|
|
||||||
@ -43,8 +46,182 @@ neighbour_peer *get_random_neighbour() {
|
|||||||
return (neighbour_peer*) tmp->data;
|
return (neighbour_peer*) tmp->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get data associated with id, if it doesn't exist return NULL
|
||||||
|
pub_data *get_data(long id) {
|
||||||
|
list *tmp = data_list;
|
||||||
|
pub_data *data;
|
||||||
|
|
||||||
|
while(tmp != NULL) {
|
||||||
|
data = (pub_data*) tmp->data;
|
||||||
|
|
||||||
|
if(data->id == id)
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take data as args and create a pub_data structure in the heap
|
||||||
|
pub_data *copy_data(unsigned char len, long id, short seqno, char *data) {
|
||||||
|
pub_data *new_data = (pub_data*) malloc(sizeof(pub_data));
|
||||||
|
char *_data = (char*) malloc(len);
|
||||||
|
new_data->length = len;
|
||||||
|
new_data->id = id;
|
||||||
|
new_data->seqno = seqno;
|
||||||
|
new_data->data = _data;
|
||||||
|
memcpy(_data, data, len);
|
||||||
|
|
||||||
|
return new_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new data to data list
|
||||||
|
void add_data(unsigned char len, long id, short seqno, char *data) {
|
||||||
|
// If id is the same as this node's id then we only update seqno
|
||||||
|
if(id == NODE_ID) {
|
||||||
|
pub_data *node_data = get_data(NODE_ID);
|
||||||
|
|
||||||
|
if(seqno >= node_data->seqno) {
|
||||||
|
node_data->seqno = seqno ^ 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
pub_data *new_data = copy_data(len, id, seqno, data);
|
||||||
|
|
||||||
|
if(data_list == NULL) {
|
||||||
|
// Update list
|
||||||
|
data_list = (list*) malloc(sizeof(list));
|
||||||
|
data_list->data = (void*) new_data;
|
||||||
|
data_list->next = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find correct position for new data
|
||||||
|
list *tmp = data_list;
|
||||||
|
list *last = NULL;
|
||||||
|
list *new_node;
|
||||||
|
long 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;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
return;
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seqno is smaller so the new data allocated is freed and nothing else is done
|
||||||
|
free(new_data);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
new_node->data = (void*) new_data;
|
||||||
|
new_node->next = NULL;
|
||||||
|
last->next = new_node;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---- Fin fonctions utilitaires ---- */
|
/* ---- Fin fonctions utilitaires ---- */
|
||||||
|
|
||||||
|
int send_tlv(union tlv * tlv_to_send, int tlv_size, struct sockaddr_in6 * dest_list[], int dest_list_size, int socket_num){
|
||||||
|
// debug_print("Building packet to send a TLV.");
|
||||||
|
|
||||||
|
// We first need to build the packet,
|
||||||
|
char packet_buff[1024];
|
||||||
|
struct packet pack;
|
||||||
|
pack.magic = 95;
|
||||||
|
pack.version = 1;
|
||||||
|
if (tlv_size > 1020) {
|
||||||
|
perror(">> Unable to send the tlv, it's size if above 1020 bytes.");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
memcpy((void *) pack.body, tlv_to_send, tlv_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the content of the paquet struct to a buffer
|
||||||
|
// That will be send out in a vectorized buffer.
|
||||||
|
// packet_buff = (char *) pack;
|
||||||
|
memcpy(&packet_buff,&pack,1024);
|
||||||
|
|
||||||
|
// debug_print("Packet has been built.");
|
||||||
|
|
||||||
|
// Vectorized buffer
|
||||||
|
struct iovec vec_buff = { .iov_len = sizeof(packet_buff), .iov_base = packet_buff };
|
||||||
|
|
||||||
|
int error_while_sending = 0;
|
||||||
|
|
||||||
|
// For every dest
|
||||||
|
for (size_t i = 0; i < dest_list_size; i++) {
|
||||||
|
// Creating the struct to send out with sendmsg
|
||||||
|
struct msghdr packet_tlv_send_out = {
|
||||||
|
.msg_name = &dest_list[i],
|
||||||
|
.msg_namelen = sizeof(dest_list[i]),
|
||||||
|
.msg_iov = &vec_buff,
|
||||||
|
.msg_iovlen = 1 // We have only one iovec buffer. But if we had 2, we would write 2.
|
||||||
|
};
|
||||||
|
|
||||||
|
int response_code = sendmsg((int) socket_num, &packet_tlv_send_out, 0);
|
||||||
|
if (response_code < 0) {
|
||||||
|
// debug_print("Unable to send out the packet to peer %i", i);
|
||||||
|
error_while_sending = 1;
|
||||||
|
continue;
|
||||||
|
} else if (response_code < sizeof(packet_tlv_send_out)) {
|
||||||
|
// debug_print("Sent out only part of the packet.");
|
||||||
|
error_while_sending = 1;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// debug_print("Send out packet to peer %i", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_while_sending == 1) {
|
||||||
|
// debug_print("Error occured while sending out a packet.");
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We need to make sure the TLV announces a length that will no go onto
|
// We need to make sure the TLV announces a length that will no go onto
|
||||||
// another tlv, as we might end up reading bullshit.
|
// another tlv, as we might end up reading bullshit.
|
||||||
int validate_tlv(char *data, int pos, short packet_len){
|
int validate_tlv(char *data, int pos, short packet_len){
|
||||||
@ -61,7 +238,7 @@ int validate_tlv(char *data, int pos, short packet_len){
|
|||||||
unsigned char tlv_len = data[pos+1];
|
unsigned char tlv_len = data[pos+1];
|
||||||
|
|
||||||
// Check that the tlv does not exceed the packet length
|
// Check that the tlv does not exceed the packet length
|
||||||
if(pos + length >= packet_len)
|
if(pos + tlv_len >= packet_len)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Returns the type of the tlv or -1 if something went wrong
|
// Returns the type of the tlv or -1 if something went wrong
|
||||||
@ -99,9 +276,9 @@ int validate_tlv(char *data, int pos, short packet_len){
|
|||||||
// For every packet recivied,
|
// For every packet recivied,
|
||||||
// then we make sure it's conform
|
// then we make sure it's conform
|
||||||
// We then extract the data from it to make it easy to work with
|
// We then extract the data from it to make it easy to work with
|
||||||
int check_header(char * req[], int buffer_size, struct packet * packet_to_return){
|
int check_header(char * received_datagram[], int buffer_len, struct packet * packet_to_return){
|
||||||
|
|
||||||
packet * packet_to_return = (packet*) req;
|
packet_to_return = (packet*) received_datagram;
|
||||||
|
|
||||||
// We need to check a few things ;
|
// We need to check a few things ;
|
||||||
// The first byte must be worth 95,
|
// The first byte must be worth 95,
|
||||||
@ -116,7 +293,7 @@ int check_header(char * req[], int buffer_size, struct packet * packet_to_return
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet_to_return.length + 4 > buffer_size ) {
|
if (packet_to_return->length + 4 > buffer_len ) {
|
||||||
perror(">> The packet length is bigger than the UDP datagram, which is not possible with the current laws of physics.");
|
perror(">> The packet length is bigger than the UDP datagram, which is not possible with the current laws of physics.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -132,91 +309,175 @@ int update_neighbours(){
|
|||||||
};
|
};
|
||||||
|
|
||||||
// We then look at the differents TLVs in the packet.
|
// We then look at the differents TLVs in the packet.
|
||||||
void work_with_tlvs(char *data, short packet_len, struct sockaddr_in6 sender){
|
int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
unsigned char tlv_len;
|
unsigned char tlv_len, hash[16], warn[32];
|
||||||
tlv tmp_tlv;
|
tlv new_tlv, cur_tlv;
|
||||||
|
list *tmp_list;
|
||||||
|
pub_data *pdata;
|
||||||
|
|
||||||
|
struct neighbour_peer * random_neighbour;
|
||||||
|
|
||||||
|
|
||||||
while(pos < packet_len) {
|
while(pos < packet_len) {
|
||||||
switch(validate_tlv(data, pos, packet_len)) {
|
switch(validate_tlv(data, pos, packet_len)) {
|
||||||
case 0:
|
case 0:
|
||||||
// We received a padding tlv so it is ignored
|
// We received a padding tlv so it is ignored
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// We received a padding tlv so it is ignored
|
// We received a padding tlv so it is ignored
|
||||||
tlv_len = data[pos+1];
|
tlv_len = data[pos+1];
|
||||||
pos += tlv_len + 2;
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// We received a neighbour request so a random neighbor tlv has to be sent
|
// We received a neighbour request so a random neighbor tlv has to be sent
|
||||||
|
|
||||||
|
// Send a neighbour tlv
|
||||||
|
random_neighbour = get_random_neighbour();
|
||||||
|
build_neighbour(&new_tlv, random_neighbour->ip, random_neighbour->port);
|
||||||
|
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 3);
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
tlv_len = data[pos+1];
|
tlv_len = data[pos+1];
|
||||||
pos += tlv_len + 2;
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
// Send a neighbour tlv
|
|
||||||
neighbour_peer *random = get_random_neighbour();
|
|
||||||
build_neighbour(&tmp_tlv, random->ip, random->port);
|
|
||||||
|
|
||||||
// NOT FINISHED - What packet is it added to?
|
|
||||||
add_tlv(packet, &tmp_tlv, 3);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// We received a neighbour tlv so a tlv network hash is sent to that address
|
// We received a neighbour tlv so a tlv network hash is sent to that address
|
||||||
neighbour* cur_tlv = ((neighbour*) data) + pos;
|
cur_tlv.neighbour = (neighbour*) (data + pos);
|
||||||
struct in6_addr ip = cur_tlv->ip;
|
|
||||||
short port = cur_tlv->port;
|
|
||||||
|
|
||||||
|
// Build network hash
|
||||||
|
build_network_hash(&new_tlv, data_list);
|
||||||
|
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 4);
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
tlv_len = data[pos+1];
|
tlv_len = data[pos+1];
|
||||||
pos += tlv_len + 2;
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
// Build network hash
|
|
||||||
unsigned char hash[16];
|
|
||||||
hash_network(neighbour_list, hash);
|
|
||||||
build_network_hash(&tmp_tlv, hash);
|
|
||||||
|
|
||||||
// NOT FINISHED - What packet is it added to?
|
|
||||||
add_tlv(packet, &tmp_tlv, 4);
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// We reveived a network hash tlv so
|
// We reveived a network hash tlv so we compare the hash with our own, if they differ we send a network state request tlv
|
||||||
tlv_len = data[pos+1];
|
cur_tlv.network_hash = (network_hash*) (data + pos);
|
||||||
pos += tlv_len +2;
|
hash_network(data_list, hash);
|
||||||
|
|
||||||
// NOT FINISHED - Where is network_hash?
|
if(memcmp(hash, cur_tlv.network_hash->network_hash, 16) == 0) {
|
||||||
build_neighbour(&tmp_tlv, network_hash);
|
build_network_state_req(&new_tlv);
|
||||||
// NOT FINISHED - What packet is it added to?
|
// NOT FINISHED - What packet is it added to?
|
||||||
add_tlv(packet, &tmp_tlv, 4);
|
// add_tlv(packet, &new_tlv, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
tlv_len = data[pos+1];
|
||||||
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// We received a network state request tlv so a series of tlv node hash have to be sent for each data known
|
// We received a network state request tlv so a series of tlv node hash have to be sent for each data known
|
||||||
pos += 2;
|
|
||||||
|
|
||||||
// NOT FINISHED - for each known data
|
// for each known data build a node hash and add to packet
|
||||||
list *tmp_list = data_list;
|
tmp_list = data_list;
|
||||||
pub_data *tmp_data;
|
|
||||||
|
|
||||||
while(tmp_list != NULL) {
|
while(tmp_list != NULL) {
|
||||||
tmp_data = (pub_data*) tmp_list->data;
|
pdata = (pub_data*) tmp_list->data;
|
||||||
build_node_hash(&tmp_tlv, tmp_data->id, tmp_data->seqno);
|
build_node_hash(&new_tlv, pdata->id, pdata->seqno, pdata->data);
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// We received a node hash tlv
|
// We received a node hash tlv so if there is no entry for node_id in the data list or the hashes differ we send a node state request, if the hashes are identical nothing has to be done
|
||||||
|
cur_tlv.node_hash = (node_hash*) (data + pos);
|
||||||
|
pdata = get_data(cur_tlv.node_hash->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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no pub_data was found or the hashes differ then we send a node state request
|
||||||
|
build_node_state_req(&new_tlv, cur_tlv.node_hash->node_id);
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 7);
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
tlv_len = data[pos+1];
|
||||||
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// We received a node state request tlv
|
// We received a node state request tlv so a node state tlv for this node id has to be sent, if no pub_data exists for this id nothing is sent
|
||||||
|
cur_tlv.node_state_req = (node_state_req*) (data + pos);
|
||||||
|
pdata = get_data(cur_tlv.node_state_req->node_id);
|
||||||
|
|
||||||
|
if(pdata != NULL) {
|
||||||
|
build_node_state(&new_tlv, pdata->id, pdata->seqno, pdata->data, pdata->length);
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
tlv_len = data[pos+1];
|
||||||
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// We received a node state tlv
|
// We received a node state tlv so we add it to the data list or update the data stored
|
||||||
|
cur_tlv.node_state = (node_state*) (data + pos);
|
||||||
|
|
||||||
|
add_data(cur_tlv.node_state->length - 26, cur_tlv.node_state->node_id, cur_tlv.node_state->seqno, cur_tlv.node_state->data);
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
tlv_len = data[pos+1];
|
||||||
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
// We received a warning tlv so it's message is printed
|
// We received a warning tlv so it's message is printed
|
||||||
|
cur_tlv.warning = (warning*) (data + pos);
|
||||||
|
|
||||||
|
// Print exactly new_tlv.length characters from new_tlv.message
|
||||||
|
sprintf(warn, ">> WARNING:\n%%.%ds", cur_tlv.warning->length + 1);
|
||||||
|
printf(warn, cur_tlv.warning->message);
|
||||||
|
|
||||||
|
// The position is updated
|
||||||
|
tlv_len = data[pos+1];
|
||||||
|
pos += tlv_len + 2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ;
|
// A malformed packet was found so we stop looking for more packets and send a warning tlv
|
||||||
|
strcpy(warn, "Packet is malformed.");
|
||||||
|
build_warning(&new_tlv, warn, strlen(warn));
|
||||||
|
// NOT FINISHED - What packet is it added to?
|
||||||
|
// add_tlv(packet, &new_tlv, 9);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We listen forever for new paquets;
|
// We listen forever for new paquets;
|
||||||
@ -280,7 +541,7 @@ void listen_for_packets(){
|
|||||||
|
|
||||||
// struct tlv_list received_tlvs;
|
// struct tlv_list received_tlvs;
|
||||||
// if (validate_tlvs(formated_rec_datagram) < 0)
|
// if (validate_tlvs(formated_rec_datagram) < 0)
|
||||||
int nbr_success_tlv = work_with_tlvs(formated_rec_datagram, &req, sender);
|
int nbr_success_tlv = work_with_tlvs(&req, 1024, sender);
|
||||||
if (nbr_success_tlv < 0){
|
if (nbr_success_tlv < 0){
|
||||||
perror(">> Error while treating the TLVs of the packet.");
|
perror(">> Error while treating the TLVs of the packet.");
|
||||||
printf(">> Managed to deal with %i TLVs\n", -nbr_success_tlv );
|
printf(">> Managed to deal with %i TLVs\n", -nbr_success_tlv );
|
||||||
@ -291,12 +552,13 @@ void listen_for_packets(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
|
printf(">> Starting node\n");
|
||||||
int cont = 1;
|
int cont = 1;
|
||||||
|
|
||||||
while(cont){
|
while(cont){
|
||||||
|
|
||||||
// We create the neighbourhood table
|
// We create the neighbourhood table
|
||||||
neighbour_peer neighbour_list[NEIGHBOUR_MAX];
|
// neighbour_peer neighbour_list[NEIGHBOUR_MAX];
|
||||||
// We create the message table
|
// We create the message table
|
||||||
|
|
||||||
// We create our own message.
|
// We create our own message.
|
||||||
|
29
src/node.h
29
src/node.h
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "tlv.h"
|
#include "tlv.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
// On which port do we listen to
|
// On which port do we listen to
|
||||||
#define LISTEN_PORT 1212
|
#define LISTEN_PORT 1212
|
||||||
@ -65,20 +66,29 @@ static list *neighbour_list;
|
|||||||
// fonctions signatures
|
// fonctions signatures
|
||||||
void listen_for_packets();
|
void listen_for_packets();
|
||||||
|
|
||||||
int check_header(char * received_datagram[], int len, struct packet pack);
|
int check_header(char * received_datagram[], int buffer_len, struct packet * packet_to_return);
|
||||||
|
|
||||||
int validate_tlvs(struct packet * pack, struct tlv_list * tlv_l);
|
int validate_tlvs(struct packet * pack, struct tlv_list * tlv_l);
|
||||||
|
|
||||||
int update_neighbours();
|
int update_neighbours();
|
||||||
|
|
||||||
int work_with_tlvs(struct packet received_packet, char * data_from_packet[], struct sockaddr_in6 sender);
|
int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender);
|
||||||
|
|
||||||
void add_tlv(packet *packet, tlv *tlv, char type);
|
void add_tlv(struct packet *packet, union tlv *tlv, char type);
|
||||||
|
|
||||||
int send_packet(struct tlv_list tlvs_to_send, );
|
// int send_packet();
|
||||||
|
|
||||||
|
/* 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(union tlv * tlv_to_send, int tlv_size, 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, int tlv_size, struct sockaddr_in6 * dest_list[], int dest_list_size, int socket_num);
|
||||||
|
|
||||||
// threaded functions
|
// threaded functions
|
||||||
|
|
||||||
void t_ask_for_more_peers();
|
void t_ask_for_more_peers();
|
||||||
|
|
||||||
void t_update_neighbours();
|
void t_update_neighbours();
|
||||||
@ -90,4 +100,13 @@ int len_list(list *l);
|
|||||||
|
|
||||||
neighbour_peer *get_random_neighbour();
|
neighbour_peer *get_random_neighbour();
|
||||||
|
|
||||||
|
// get data associated with id, if it doesn't exist return NULL
|
||||||
|
pub_data *get_data(long id);
|
||||||
|
|
||||||
|
// Take data as args and create a pub_data structure in the heap
|
||||||
|
pub_data *copy_data(unsigned char len, long id, short seqno, char *data);
|
||||||
|
|
||||||
|
// add new data to data list
|
||||||
|
void add_data(unsigned char len, long id, short seqno, char *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
27
src/tlv.c
27
src/tlv.c
@ -18,7 +18,12 @@ int build_tlv(tlv *tlv, cmd_token token) {
|
|||||||
case ERROR:
|
case ERROR:
|
||||||
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'post {message}'");
|
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'post {message}'");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
perror("Unrecognized tlv type.");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_pad1(tlv *tlv) {
|
int build_pad1(tlv *tlv) {
|
||||||
@ -79,7 +84,7 @@ int build_neighbour(tlv *tlv, struct in6_addr ip, short port) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_network_hash(tlv *tlv, char *hash) {
|
int build_network_hash(tlv *tlv, list *data_list) {
|
||||||
network_hash *new = (network_hash*) malloc(sizeof(network_hash));
|
network_hash *new = (network_hash*) malloc(sizeof(network_hash));
|
||||||
|
|
||||||
if(new == NULL)
|
if(new == NULL)
|
||||||
@ -87,7 +92,7 @@ int build_network_hash(tlv *tlv, char *hash) {
|
|||||||
|
|
||||||
new->type = 4;
|
new->type = 4;
|
||||||
new->length = 16;
|
new->length = 16;
|
||||||
memcpy(new->network_hash, hash, 16);
|
hash_network(data_list, new->network_hash);
|
||||||
|
|
||||||
tlv->network_hash = new;
|
tlv->network_hash = new;
|
||||||
|
|
||||||
@ -108,7 +113,7 @@ int build_network_state_req(tlv *tlv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_node_hash(tlv *tlv, long node_id, short seqno, char *hash) {
|
int build_node_hash(tlv *tlv, long node_id, short seqno, char *data) {
|
||||||
node_hash *new = (node_hash*) malloc(sizeof(node_hash));
|
node_hash *new = (node_hash*) malloc(sizeof(node_hash));
|
||||||
|
|
||||||
if(new == NULL)
|
if(new == NULL)
|
||||||
@ -118,7 +123,9 @@ int build_node_hash(tlv *tlv, long node_id, short seqno, char *hash) {
|
|||||||
new->length = 26;
|
new->length = 26;
|
||||||
new->node_id = node_id;
|
new->node_id = node_id;
|
||||||
new->seqno = seqno;
|
new->seqno = seqno;
|
||||||
memcpy(new->node_hash, hash, 16);
|
|
||||||
|
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
|
||||||
|
hash_data(&pdata, new->node_hash);
|
||||||
|
|
||||||
tlv->node_hash = new;
|
tlv->node_hash = new;
|
||||||
|
|
||||||
@ -140,9 +147,9 @@ int build_node_state_req(tlv *tlv, long node_id) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data) {
|
int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t data_len) {
|
||||||
node_state *new = (node_state*) malloc(sizeof(node_state));
|
node_state *new = (node_state*) malloc(sizeof(node_state));
|
||||||
int len = strlen(data);
|
int len = data_len + 26;
|
||||||
|
|
||||||
if(new == NULL)
|
if(new == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -157,17 +164,19 @@ int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char
|
|||||||
new->length = 26 + len;
|
new->length = 26 + len;
|
||||||
new->node_id = node_id;
|
new->node_id = node_id;
|
||||||
new->seqno = seqno;
|
new->seqno = seqno;
|
||||||
memcpy(new->node_hash, node_hash, 16);
|
|
||||||
memcpy(new->data, data, len);
|
memcpy(new->data, data, len);
|
||||||
|
|
||||||
|
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
|
||||||
|
hash_data(&pdata, new->node_hash);
|
||||||
|
|
||||||
tlv->node_state = new;
|
tlv->node_state = new;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_warning(tlv *tlv, char *message) {
|
int build_warning(tlv *tlv, char *message, size_t message_len) {
|
||||||
warning *new = (warning*) malloc(sizeof(warning));
|
warning *new = (warning*) malloc(sizeof(warning));
|
||||||
int len = strlen(message);
|
int len = message_len;
|
||||||
|
|
||||||
if(new == NULL)
|
if(new == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
18
src/tlv.h
18
src/tlv.h
@ -4,8 +4,10 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "parser.h"
|
|
||||||
|
#include "node.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
#define LEN_NEIGHBOUR_REQ 0
|
#define LEN_NEIGHBOUR_REQ 0
|
||||||
#define LEN_NEIGHBOUR 18
|
#define LEN_NEIGHBOUR 18
|
||||||
@ -33,7 +35,7 @@ typedef struct pad1 {
|
|||||||
typedef struct padn {
|
typedef struct padn {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char length;
|
unsigned char length;
|
||||||
char mbz[256];
|
char *mbz;
|
||||||
} padn;
|
} padn;
|
||||||
|
|
||||||
// 2 octets
|
// 2 octets
|
||||||
@ -110,18 +112,18 @@ typedef union tlv {
|
|||||||
} tlv;
|
} tlv;
|
||||||
|
|
||||||
// build tlv from token
|
// build tlv from token
|
||||||
int build_tlv(tlv *tlv, cmd_token token);
|
int build_tlv(tlv *tlv, struct cmd_token token);
|
||||||
|
|
||||||
// build specific tlv
|
// build specific tlv
|
||||||
int build_pad1(tlv *tlv);
|
int build_pad1(tlv *tlv);
|
||||||
int build_padn(tlv *tlv, size_t len);
|
int build_padn(tlv *tlv, size_t len);
|
||||||
int build_neighbour_req(tlv *tlv);
|
int build_neighbour_req(union tlv *tlv);
|
||||||
int build_neighbour(tlv *tlv, struct in6_addr ip, short port);
|
int build_neighbour(tlv *tlv, struct in6_addr ip, short port);
|
||||||
int build_network_hash(tlv *tlv, char *network_hash);
|
int build_network_hash(tlv *tlv, struct list *data_list);
|
||||||
int build_network_state_req(tlv *tlv);
|
int build_network_state_req(tlv *tlv);
|
||||||
int build_node_hash(tlv *tlv, long node_id, short seqno, char *node_hash);
|
int build_node_hash(tlv *tlv, long node_id, short seqno, char *data);
|
||||||
int build_node_state_req(tlv *tlv, long node_id);
|
int build_node_state_req(tlv *tlv, long node_id);
|
||||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data);
|
int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t data_len);
|
||||||
int build_warning(tlv *tlv, char *message);
|
int build_warning(tlv *tlv, char *message, size_t message_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user