Merge branch '11-envoie-des-paquets' into 14-implement-poll
This commit is contained in:
commit
664faa96f0
5
Makefile
5
Makefile
@ -1,16 +1,17 @@
|
||||
TARGET ?= dazibao
|
||||
SRC_DIRS ?= ./src/*
|
||||
CC := gcc
|
||||
CFLAGS= -O2 -Wall -lssl -lcrypto
|
||||
CFLAGS= -O2 -Wall
|
||||
SRCS := $(shell find $(SRC_DIRS) -name *.c -or -name *.s)
|
||||
OBJS := $(addsuffix .o,$(basename $(SRCS)))
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
SSLFLAGS = -lssl -lcrypto
|
||||
|
||||
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
|
||||
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS)
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) $(SSLFLAGS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
@ -2,22 +2,23 @@
|
||||
#define HASH_H
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tlv.h"
|
||||
#include "parser.h"
|
||||
#include "node.h"
|
||||
|
||||
// Hash a single data
|
||||
void hash_data(struct pub_data *data, unsigned char *buf);
|
||||
void hash_data(pub_data *data, unsigned char *buf);
|
||||
|
||||
// Hash every data contained in data_list then return a network hash
|
||||
void hash_network(struct list *data_list, unsigned char *buf);
|
||||
void hash_network(list *data_list, unsigned char *buf);
|
||||
|
||||
// Truncate 32 octet hash to 16 octets
|
||||
void hash_trunc(unsigned char *hash256bit, unsigned char *buf);
|
||||
|
||||
// Concat all fields of data and put them in buf
|
||||
void concat_data(struct pub_data *data, unsigned char *buf);
|
||||
void concat_data(pub_data *data, unsigned char *buf);
|
||||
|
||||
// Concat hash2 to hash1 (hash1 is modified)
|
||||
void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size);
|
||||
|
BIN
src/hash.o
Normal file
BIN
src/hash.o
Normal file
Binary file not shown.
540
src/node.c
540
src/node.c
@ -14,10 +14,10 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "node.h"
|
||||
#include "tlv.h"
|
||||
#include "hash.h"
|
||||
#include "parser.h"
|
||||
|
||||
// Static variables
|
||||
static list *data_list;
|
||||
static list *neighbour_list;
|
||||
|
||||
/* ---- Fonctions utilitaires ---- */
|
||||
|
||||
@ -52,7 +52,7 @@ neighbour_peer *get_random_neighbour() {
|
||||
}
|
||||
|
||||
// get data associated with id, if it doesn't exist return NULL
|
||||
pub_data *get_data(long id) {
|
||||
pub_data *get_data(int64_t id) {
|
||||
list *tmp = data_list;
|
||||
pub_data *data;
|
||||
|
||||
@ -67,7 +67,7 @@ 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) {
|
||||
pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data) {
|
||||
pub_data *new_data = (pub_data*) malloc(sizeof(pub_data));
|
||||
char *_data = (char*) malloc(len);
|
||||
new_data->length = len;
|
||||
@ -80,7 +80,7 @@ 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) {
|
||||
void add_data(unsigned char len, int64_t id, int16_t 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);
|
||||
@ -108,7 +108,7 @@ void add_data(unsigned char len, long id, short seqno, char *data) {
|
||||
list *tmp = data_list;
|
||||
list *last = NULL;
|
||||
list *new_node;
|
||||
long cur_id;
|
||||
int64_t cur_id;
|
||||
|
||||
while(tmp != NULL) {
|
||||
cur_id = ((pub_data*) tmp->data)->id;
|
||||
@ -168,7 +168,194 @@ void add_data(unsigned char len, long id, short seqno, char *data) {
|
||||
|
||||
/* ---- 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){
|
||||
// Add TLV to packet, if it does not fit then send the packet and reset the packet buff to be able to add more TLVs that will be sent afterwards
|
||||
int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
|
||||
char type = tlv->pad1->type, sent = 0, errval = 0;
|
||||
unsigned char len;
|
||||
|
||||
// Check if TLV fits in the packet, if not then send the packet and reset it
|
||||
if(type != 1) {
|
||||
len = tlv->padn->length + 2;
|
||||
|
||||
if(pack->length + len > 1020) {
|
||||
errval = send_packet((char*) pack, pack->length, dest, socket_num);
|
||||
*pack = (packet) {.magic = 95, .version = 1, .length = 0};
|
||||
memset(pack->body, 0, 1020);
|
||||
sent = 1;
|
||||
}
|
||||
} else {
|
||||
if(pack->length >= 1020) {
|
||||
errval = send_packet((char*) pack, pack->length, dest, socket_num);
|
||||
*pack = (packet) {.magic = 95, .version = 1, .length = 0};
|
||||
memset(pack->body, 0, 1020);
|
||||
sent = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data from tlv into body
|
||||
switch(type) {
|
||||
case 1:
|
||||
memcpy(pack->body + pack->length, tlv->pad1, 1);
|
||||
pack->length += 1;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
memcpy(pack->body + pack->length, tlv->padn, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
memcpy(pack->body + pack->length, tlv->neighbour, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
memcpy(pack->body + pack->length, tlv->network_hash, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 5:
|
||||
memcpy(pack->body + pack->length, tlv->network_state_req, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 6:
|
||||
memcpy(pack->body + pack->length, tlv->node_hash, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 7:
|
||||
memcpy(pack->body + pack->length, tlv->node_state_req, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 8:
|
||||
memcpy(pack->body + pack->length, tlv->node_state, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
case 9:
|
||||
memcpy(pack->body + pack->length, tlv->warning, len);
|
||||
pack->length += len;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If the previous packet was went return 1 or -1 if there was an error sending it
|
||||
if(sent)
|
||||
return errval? -1:1;
|
||||
|
||||
// Return 0 if the TLV was added to the packet
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send length bytes from packet
|
||||
int send_packet(char *packet_buff, int16_t length, struct sockaddr_in6 *dest, int socket_num) {
|
||||
// Vectorized buffer
|
||||
struct iovec vec_buff = {.iov_len = length, .iov_base = packet_buff};
|
||||
|
||||
int error_while_sending = 0;
|
||||
|
||||
// Creating the struct to send out with sendmsg
|
||||
struct msghdr packet_tlv_send_out = {
|
||||
.msg_name = dest,
|
||||
.msg_namelen = sizeof(struct sockaddr_in6),
|
||||
.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(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;
|
||||
} else if (response_code < length) {
|
||||
// debug_print("Sent out only part of the packet.");
|
||||
error_while_sending = 1;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a single TLV to the specified addresses, return -1 if an error was encountered, 0 otherwise
|
||||
int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
|
||||
char type = tlv->pad1->type;
|
||||
unsigned char len;
|
||||
packet pack = (packet) {.magic = 95, .version = 1, .length = 4};
|
||||
memset(pack.body, 0, 1020);
|
||||
|
||||
// Copy data from tlv into body
|
||||
switch(type) {
|
||||
case 1:
|
||||
memcpy(pack.body, tlv->pad1, 1);
|
||||
pack.length += 1;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
len = tlv->padn->length + 2;
|
||||
memcpy(pack.body, tlv->padn, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
len = tlv->neighbour->length + 2;
|
||||
memcpy(pack.body, tlv->neighbour, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
len = tlv->network_hash->length + 2;
|
||||
memcpy(pack.body, tlv->network_hash, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 5:
|
||||
len = tlv->network_state_req->length + 2;
|
||||
memcpy(pack.body, tlv->network_state_req, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 6:
|
||||
len = tlv->node_hash->length + 2;
|
||||
memcpy(pack.body, tlv->node_hash, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 7:
|
||||
len = tlv->node_state_req->length + 2;
|
||||
memcpy(pack.body, tlv->node_state_req, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 8:
|
||||
len = tlv->node_state->length + 2;
|
||||
memcpy(pack.body, tlv->node_state, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
case 9:
|
||||
len = tlv->warning->length + 2;
|
||||
memcpy(pack.body, tlv->warning, len);
|
||||
pack.length += len;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Send the packet
|
||||
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){
|
||||
// debug_print("Building packet to send a TLV.");
|
||||
|
||||
// We first need to build the packet,
|
||||
@ -229,7 +416,7 @@ int send_tlv(union tlv * tlv_to_send, int tlv_size, struct sockaddr_in6 * dest_l
|
||||
|
||||
// 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, short packet_len){
|
||||
int validate_tlv(char *data, int pos, int16_t packet_len){
|
||||
char type = data[pos];
|
||||
|
||||
// Nothing to do in this case
|
||||
@ -281,9 +468,9 @@ int validate_tlv(char *data, int pos, short packet_len){
|
||||
// For every packet recivied,
|
||||
// then we make sure it's conform
|
||||
// We then extract the data from it to make it easy to work with
|
||||
int check_header(char * received_datagram[], int buffer_len, struct packet * packet_to_return){
|
||||
int check_header(char * received_data_buffer[], int received_data_len, struct packet * packet_to_return){
|
||||
|
||||
packet_to_return = (packet*) received_datagram;
|
||||
packet_to_return = (packet*) received_data_buffer;
|
||||
|
||||
// We need to check a few things ;
|
||||
// The first byte must be worth 95,
|
||||
@ -298,7 +485,7 @@ int check_header(char * received_datagram[], int buffer_len, struct packet * pac
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_to_return->length + 4 > buffer_len ) {
|
||||
if (packet_to_return->length + 4 > received_data_len ) {
|
||||
perror(">> The packet length is bigger than the UDP datagram, which is not possible with the current laws of physics.");
|
||||
return -1;
|
||||
}
|
||||
@ -313,16 +500,31 @@ int update_neighbours(){
|
||||
return 0;
|
||||
};
|
||||
|
||||
int add_message(char * message, int message_len){
|
||||
return 0;
|
||||
}
|
||||
// We then look at the differents TLVs in the packet.
|
||||
int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
int work_with_tlvs(char * data, int16_t packet_len, struct sockaddr_in6 *sender, int socket_num){
|
||||
int pos = 0;
|
||||
unsigned char tlv_len, hash[16], warn[32];
|
||||
unsigned char tlv_len, hash[16];
|
||||
char warn[32];
|
||||
tlv new_tlv, cur_tlv;
|
||||
new_tlv.pad1 = NULL;
|
||||
cur_tlv.pad1 = NULL;
|
||||
list *tmp_list;
|
||||
pub_data *pdata;
|
||||
struct neighbour_peer *random_neighbour;
|
||||
struct sockaddr_in6 new_neighbour;
|
||||
|
||||
struct neighbour_peer * random_neighbour;
|
||||
packet pack = (packet) {.magic = 95, .version = 1, .length = 0};
|
||||
memset(pack.body, 0, 1020);
|
||||
|
||||
int ifindex = if_nametoindex("eth0");
|
||||
|
||||
if(ifindex == 0) {
|
||||
perror("if_nametoindex failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(pos < packet_len) {
|
||||
switch(validate_tlv(data, pos, packet_len)) {
|
||||
@ -343,9 +545,7 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
// 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);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
|
||||
// The position is updated
|
||||
tlv_len = data[pos+1];
|
||||
@ -356,11 +556,16 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
// We received a neighbour tlv so a tlv network hash is sent to that address
|
||||
cur_tlv.neighbour = (neighbour*) (data + pos);
|
||||
|
||||
// Init dest socket
|
||||
memset(&new_neighbour, 0, sizeof(new_neighbour));
|
||||
new_neighbour.sin6_family = AF_INET6;
|
||||
memcpy(&new_neighbour.sin6_addr, &cur_tlv.neighbour->ip, 16);
|
||||
new_neighbour.sin6_port = htons(LISTEN_PORT);
|
||||
new_neighbour.sin6_scope_id = ifindex;
|
||||
|
||||
// Build network hash
|
||||
build_network_hash(&new_tlv, data_list);
|
||||
|
||||
// NOT FINISHED - What packet is it added to?
|
||||
// add_tlv(packet, &new_tlv, 4);
|
||||
send_single_tlv(&new_tlv, &new_neighbour, socket_num);
|
||||
|
||||
// The position is updated
|
||||
tlv_len = data[pos+1];
|
||||
@ -374,8 +579,7 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
|
||||
if(memcmp(hash, cur_tlv.network_hash->network_hash, 16) == 0) {
|
||||
build_network_state_req(&new_tlv);
|
||||
// NOT FINISHED - What packet is it added to?
|
||||
// add_tlv(packet, &new_tlv, 5);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
}
|
||||
|
||||
// The position is updated
|
||||
@ -392,8 +596,7 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
while(tmp_list != NULL) {
|
||||
pdata = (pub_data*) tmp_list->data;
|
||||
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);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
}
|
||||
|
||||
// The position is updated
|
||||
@ -423,8 +626,7 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
|
||||
// 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);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
|
||||
// The position is updated
|
||||
tlv_len = data[pos+1];
|
||||
@ -438,8 +640,7 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
|
||||
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);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
}
|
||||
|
||||
// The position is updated
|
||||
@ -475,89 +676,62 @@ int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender){
|
||||
// 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);
|
||||
add_tlv(&pack, &new_tlv, sender, socket_num);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the previously allocated memory
|
||||
free(new_tlv.pad1);
|
||||
|
||||
// If the packet still has data in it then send it
|
||||
if(pack.length > 0)
|
||||
send_packet((char*) &pack, pack.length, sender, socket_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We listen forever for new paquets;
|
||||
void listen_for_packets(){
|
||||
|
||||
// Create new socket for UDP
|
||||
int s = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
|
||||
if(s < 0) {
|
||||
perror(">> Error, cannot create socket.");
|
||||
perror(">> Exiting...");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct sockaddr_in6 server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
|
||||
server.sin6_family = AF_INET6;
|
||||
server.sin6_port = htons(LISTEN_PORT);
|
||||
int rc = bind(s, (struct sockaddr*)&server, sizeof(server));
|
||||
if(rc < 0) {
|
||||
perror(">> Error, cannot bind socket to choosen port.");
|
||||
perror(">> Exiting...");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// A paquet has at most a length of 1024 bytes
|
||||
char req[1024];
|
||||
struct sockaddr_in6 sender;
|
||||
struct iovec io = { .iov_len = 1024, .iov_base = req };
|
||||
struct msghdr msg_to_receive = {
|
||||
.msg_name = &sender,
|
||||
.msg_namelen = sizeof(sender),
|
||||
.msg_iov = &io,
|
||||
.msg_iovlen = 1
|
||||
};
|
||||
while(1){
|
||||
memset(req, '\0', 1024);
|
||||
|
||||
rc = recvmsg(s, &msg_to_receive, 0);
|
||||
if(rc < 0) {
|
||||
perror(">> Error while receiving a new datagram.");
|
||||
perror(">> Ignoring, continuing...");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf(">> New paquet received :\n");
|
||||
printf("%s\n", req);
|
||||
|
||||
// TODO : Here, we need to fork.
|
||||
int listen_for_packets(char * received_data_buffer[], int received_data_len, struct sockaddr_in6 * sender, int sock_fd){
|
||||
|
||||
// We verify the received packet is well formated,
|
||||
// and we return it in the struct designed to work with it.
|
||||
struct packet * formated_rec_datagram;
|
||||
if(check_header(&req, 1024, formated_rec_datagram) < 0){
|
||||
struct packet formated_rec_datagram;
|
||||
if(check_header(received_data_buffer, received_data_len, &formated_rec_datagram) < 0){
|
||||
perror(">> Error while checking the header, aborting this packet, by choice, and conviction.");
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO : Add the neighbour check here.
|
||||
|
||||
// struct tlv_list received_tlvs;
|
||||
// if (validate_tlvs(formated_rec_datagram) < 0)
|
||||
int nbr_success_tlv = work_with_tlvs(&req, 1024, sender);
|
||||
int nbr_success_tlv = work_with_tlvs(received_data_buffer, received_data_len, sender, sock_fd);
|
||||
if (nbr_success_tlv < 0){
|
||||
perror(">> Error while treating the TLVs of the packet.");
|
||||
printf(">> Managed to deal with %i TLVs\n", -nbr_success_tlv );
|
||||
return -2;
|
||||
} else {
|
||||
printf(">> Done working with the TLVs of the packet, listenin for new packets.\n");
|
||||
}
|
||||
printf(">> Done working with the TLVs of the packet, listening for new packets.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int run_node(int sock_fd, struct sockaddr_in6 * peer){
|
||||
printf(">> Boostrapping node...\n");
|
||||
int t_ask_for_more_peers(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t_get_network_state(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t_update_neighbours(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int run_node(int sock_fd){
|
||||
printf(">> Running node...\n");
|
||||
|
||||
int ret;
|
||||
ssize_t bytes;
|
||||
@ -565,6 +739,10 @@ int run_node(int sock_fd, struct sockaddr_in6 * peer){
|
||||
char output_buffer[1024];
|
||||
struct pollfd fds[2];
|
||||
|
||||
// Init the ~20s delay for node update.
|
||||
srand(time(NULL));
|
||||
int delay = time(NULL) + 20;
|
||||
|
||||
/* Descriptor zero is stdin */
|
||||
fds[0].fd = 0;
|
||||
fds[1].fd = sock_fd;
|
||||
@ -575,15 +753,36 @@ int run_node(int sock_fd, struct sockaddr_in6 * peer){
|
||||
* we loop endlessly.
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
if (time(NULL) >= delay) {
|
||||
printf(">> Asking for more peers...\n");
|
||||
t_ask_for_more_peers();
|
||||
printf(">> Updating neighbours...\n");
|
||||
t_update_neighbours();
|
||||
printf(">> Getting network state...\n");
|
||||
t_get_network_state();
|
||||
delay = time(NULL) + 20 + (rand() % 10);
|
||||
}
|
||||
|
||||
// This might be cool to add, but we need to find a way to write to stdin
|
||||
// while it's running.
|
||||
// if (time(NULL) < delay) {
|
||||
// // Thanks to :
|
||||
// // https://gist.github.com/amullins83/24b5ef48657c08c4005a8fab837b7499
|
||||
// printf("\b\x1b[2K\r>> Next request in %li seconds..", delay - time(NULL));
|
||||
// fflush(stdout);
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
|
||||
/* Call poll() */
|
||||
ret = poll(fds, 2, -1);
|
||||
ret = poll(fds, 2, 5);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("Error - poll returned error: %s\n", strerror(errno));
|
||||
printf(">> Error - poll returned error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (ret > 0) {
|
||||
|
||||
} else if (ret > 0) {
|
||||
/* Regardless of requested events, poll() can always return these */
|
||||
if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
printf("Error - poll indicated stdin error\n");
|
||||
@ -594,153 +793,94 @@ int run_node(int sock_fd, struct sockaddr_in6 * peer){
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if data to read from stdin */
|
||||
printf(">> ");
|
||||
// Read data from stdin (new message to post )
|
||||
if (fds[0].revents & (POLLIN | POLLPRI)) {
|
||||
bytes = read(0, output_buffer, sizeof(output_buffer));
|
||||
bytes = read(0, input_buffer, sizeof(input_buffer));
|
||||
if (bytes < 0) {
|
||||
printf("Error - stdin error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// // Reset buffer
|
||||
// // memset(&output_buffer, '\0', 1024);
|
||||
//
|
||||
// // Build packet
|
||||
// struct packet message;
|
||||
// message.magic = 95;
|
||||
// message.version = 1;
|
||||
// message.body = malloc(20);
|
||||
//
|
||||
// // Build TLV
|
||||
// struct neighbour_req *neigh_req = (neighbour_req*) malloc(sizeof(neighbour_req));
|
||||
//
|
||||
// neigh_req->type = 2;
|
||||
// neigh_req->length = 0;
|
||||
//
|
||||
// message.length = 2 * sizeof(unsigned char);
|
||||
// printf("(%i)\n", message.length );
|
||||
// // message.body = (char *) neigh_req;
|
||||
//
|
||||
// memcpy(message.body, &neigh_req, sizeof(struct neighbour_req));
|
||||
// memcpy(&output_buffer, &message, sizeof(struct packet));
|
||||
|
||||
struct iovec vec_buff_reply = {.iov_len = sizeof(output_buffer), .iov_base = output_buffer};
|
||||
|
||||
struct sockaddr_in6 ntp_server_adress;
|
||||
memset(&ntp_server_adress, 0, sizeof(ntp_server_adress));
|
||||
|
||||
int inet_p = inet_pton(AF_INET6, "2a00:1080:800::6:1", &ntp_server_adress.sin6_addr);
|
||||
if(inet_p < 1){
|
||||
perror(">> Failed inet_pton.");
|
||||
exit(1);
|
||||
input_buffer[strcspn(input_buffer, "\n")] = 0;
|
||||
printf(">> Adding following message to the table : “%s”\n", input_buffer );
|
||||
// Add message to the message table.
|
||||
if (add_message(&input_buffer, bytes) < 0) {
|
||||
perror(">> Error while trying to add the message to the list of messages, please try again..");
|
||||
}
|
||||
}
|
||||
ntp_server_adress.sin6_family = AF_INET6;
|
||||
ntp_server_adress.sin6_port = htons(1212); // NTP port number.
|
||||
|
||||
const struct msghdr reply = {
|
||||
.msg_name = &ntp_server_adress,
|
||||
.msg_namelen = sizeof(ntp_server_adress),
|
||||
.msg_iov = &vec_buff_reply,
|
||||
.msg_iovlen = 1
|
||||
// Read data from the socket ( incoming packet )
|
||||
if (fds[1].revents & (POLLIN | POLLPRI)) {
|
||||
|
||||
|
||||
// Vectorized buffer
|
||||
struct iovec vec_buff_rec = { .iov_len = sizeof(output_buffer), .iov_base = output_buffer };
|
||||
|
||||
struct sockaddr_in6 sender;
|
||||
// Creating the struct receive the server reponse.
|
||||
// Is empty, will be filled by recvmsg()
|
||||
struct msghdr msg_from_peer = {
|
||||
.msg_name = &sender,
|
||||
.msg_namelen = sizeof(sender),
|
||||
.msg_iov = &vec_buff_rec,
|
||||
.msg_iovlen = 1 // We have only one iovec buffer. But if we had 2, we would write 2.
|
||||
};
|
||||
|
||||
printf("Sending: %li bytes as : %s\n", sizeof(output_buffer), output_buffer);
|
||||
// bytes = sendto(sock_fd, output_buffer, sizeof(output_buffer), 0, (struct sockaddr *)peer, sizeof(struct sockaddr_in));
|
||||
bytes = sendmsg((int) sock_fd, &reply, 0);
|
||||
if (bytes < 0) {
|
||||
perror("deded");
|
||||
printf("Error - sendto error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if data to read from socket */
|
||||
if (fds[1].revents & (POLLIN | POLLPRI)) {
|
||||
bytes = recvfrom(sock_fd, input_buffer, sizeof(input_buffer),
|
||||
0, NULL, NULL);
|
||||
bytes = recvmsg(sock_fd, &msg_from_peer, 0);
|
||||
if (bytes < 0) {
|
||||
printf("Error - recvfrom error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (bytes > 0) {
|
||||
printf("Received: %.*s\r", (int)bytes, input_buffer);
|
||||
printf("Received: %.*s\r", (int)bytes, output_buffer);
|
||||
// Treat incoming packets.
|
||||
int work_tlv_status = listen_for_packets(&output_buffer, bytes, &sender, sock_fd);
|
||||
if (work_tlv_status < 0) {
|
||||
perror(">> Error while treating the incoming packet.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
printf(">> Starting node\n");
|
||||
int cont = 1;
|
||||
|
||||
unsigned long local_port = 1212;
|
||||
unsigned long remote_port = 1212;
|
||||
|
||||
int sock_fd;
|
||||
int bootstrap_node(int * sock_fd){
|
||||
printf(">> Boostraping node...\n");
|
||||
|
||||
struct sockaddr_in6 server_addr;
|
||||
struct sockaddr_in6 peer_addr;
|
||||
|
||||
memset(&peer_addr, 0, sizeof(peer_addr));
|
||||
|
||||
peer_addr.sin6_family = AF_INET6;
|
||||
peer_addr.sin6_port = htons(remote_port);
|
||||
if (inet_pton(AF_INET6, "2001:660:3301:9200::51c2:1b9b", &peer_addr.sin6_addr) < 0) {
|
||||
printf("Error - invalid remote address '%s'\n", "2001:660:3301:9200::51c2:1b9b");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create UDP socket */
|
||||
sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock_fd < 0) {
|
||||
* sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if ( * sock_fd < 0) {
|
||||
printf("Error - failed to open socket: %s\n", strerror(errno));
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bind socket */
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin6_family = AF_INET6;
|
||||
// server_addr.sin6_addr.in6_addr = htonl(INADDR_ANY);
|
||||
server_addr.sin6_port = htons(local_port);
|
||||
if (bind(sock_fd, (struct sockaddr *)(&server_addr), sizeof(server_addr)) < 0) {
|
||||
server_addr.sin6_port = htons(LISTEN_PORT);
|
||||
if (bind( * sock_fd, (struct sockaddr *)(&server_addr), sizeof(server_addr)) < 0) {
|
||||
printf("Error - failed to bind socket: %s\n", strerror(errno));
|
||||
return 1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
run_node(sock_fd, &peer_addr);
|
||||
printf(">> Boostraping done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
printf(">> Starting node\n");
|
||||
|
||||
int sock_fd;
|
||||
bootstrap_node(&sock_fd);
|
||||
run_node(sock_fd);
|
||||
close(sock_fd);
|
||||
//
|
||||
// while(cont){
|
||||
//
|
||||
// // We create the neighbourhood table
|
||||
// // neighbour_peer neighbour_list[NEIGHBOUR_MAX];
|
||||
// // We create the message table
|
||||
//
|
||||
// // We create our own message.
|
||||
//
|
||||
// // Listen for incoming packets
|
||||
// // listen_for_packets();
|
||||
// //
|
||||
// // // This is in it's own fork.
|
||||
// // time_t delay = time(NULL) + 20;
|
||||
// // while(! (delay < time(NULL))) {
|
||||
// // // Theses functions are there for general book-keeping,and run in there own
|
||||
// // // thread, being run every 20 seconds.
|
||||
// // // Every 20 sec, if we have less than 5 neighbours, we ask for more peers
|
||||
// // // by sending out a TLV neighbour Request at a random peer.
|
||||
// // t_ask_for_more_peers();
|
||||
// // // Every 20 sec, we also check for a peer that didn't emit a new message for
|
||||
// // // the past 70 sec, if he's temporary, we delete him from the neighbourhood.
|
||||
// // t_update_neighbours();
|
||||
// // // We send out a TLV Network hash to get an ideal of the network state.
|
||||
// // t_get_network_state();
|
||||
// }
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
112
src/node.h
112
src/node.h
@ -4,12 +4,46 @@
|
||||
#define NODE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <net/if.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
|
||||
* (configuré au lancement) ou transitoire, et la date de dernière réception d’un
|
||||
* paquet de la part de ce pair ;
|
||||
*/
|
||||
typedef struct neighbour_peer {
|
||||
struct in6_addr ip;
|
||||
int16_t port;
|
||||
char is_temporary;
|
||||
struct timeval last_seen;
|
||||
} neighbour_peer;
|
||||
|
||||
// The strucuture to hold the messages
|
||||
/* It's a list of triplets, (Li,Si,Di)
|
||||
* Li : The Node ID of the publisher 64 bits
|
||||
* Si : the sequence number 16 bits
|
||||
* Di : the data of the message 192 bytes
|
||||
*/
|
||||
|
||||
typedef struct pub_data {
|
||||
unsigned char length;
|
||||
int64_t id;
|
||||
int16_t seqno;
|
||||
char *data;
|
||||
} pub_data;
|
||||
|
||||
// General list
|
||||
typedef struct list {
|
||||
void *data;
|
||||
void *next;
|
||||
} list;
|
||||
|
||||
#include "tlv.h"
|
||||
#include "hash.h"
|
||||
@ -25,75 +59,51 @@
|
||||
// The neighbour table has 15 entries
|
||||
#define NEIGHBOUR_MAX 15
|
||||
|
||||
/* 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
|
||||
* (configuré au lancement) ou transitoire, et la date de dernière réception d’un
|
||||
* paquet de la part de ce pair ;
|
||||
*/
|
||||
typedef struct neighbour_peer {
|
||||
struct in6_addr ip;
|
||||
short port;
|
||||
char is_temporary;
|
||||
struct timeval last_seen;
|
||||
} neighbour_peer;
|
||||
|
||||
// The strucuture to hold the messages
|
||||
/* It's a list of triplets, (Li,Si,Di)
|
||||
* Li : The Node ID of the publisher 64 bits
|
||||
* Si : the sequence number 16 bits
|
||||
* Di : the data of the message 192 bytes
|
||||
*/
|
||||
|
||||
typedef struct pub_data {
|
||||
unsigned char length;
|
||||
long id;
|
||||
short seqno;
|
||||
char *data;
|
||||
} pub_data;
|
||||
|
||||
// General list
|
||||
typedef struct list {
|
||||
void *data;
|
||||
void *next;
|
||||
} list;
|
||||
|
||||
// Static variables
|
||||
static list *data_list;
|
||||
static list *neighbour_list;
|
||||
|
||||
// TODO
|
||||
|
||||
// fonctions signatures
|
||||
void listen_for_packets();
|
||||
int listen_for_packets(char * received_data_buffer[], int received_data_len, struct sockaddr_in6 * sender, int sock_fd);
|
||||
|
||||
int check_header(char * received_datagram[], int buffer_len, struct packet * packet_to_return);
|
||||
int check_header(char * received_data_buffer[], int received_data_len, packet * packet_to_return);
|
||||
|
||||
int validate_tlvs(struct packet * pack, struct tlv_list * tlv_l);
|
||||
int validate_tlv(char *data, int pos, int16_t packet_len);
|
||||
|
||||
int update_neighbours();
|
||||
|
||||
int work_with_tlvs(char * data[], short packet_len, struct sockaddr_in6 sender);
|
||||
int work_with_tlvs(char * data, int16_t packet_len, struct sockaddr_in6 *sender, int socket_num);
|
||||
|
||||
void add_tlv(struct packet *packet, union tlv *tlv, char type);
|
||||
int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
// int send_packet();
|
||||
int send_packet(char *packet_buff, int16_t length, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
|
||||
|
||||
// This function is in charge of saying how and what goes where.
|
||||
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(union tlv * tlv_to_send, int tlv_size, struct sockaddr_in6 * dest_list[], int dest_list_size, int socket_num);
|
||||
int send_tlv(tlv *tlv_to_send, int16_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, int tlv_size, struct sockaddr_in6 * dest_list[], int dest_list_size, int socket_num);
|
||||
int send_tlvs(struct list * tlv_list, int16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
|
||||
|
||||
// threaded functions
|
||||
void t_ask_for_more_peers();
|
||||
int t_ask_for_more_peers();
|
||||
|
||||
void t_update_neighbours();
|
||||
int t_update_neighbours();
|
||||
|
||||
void t_get_network_state();
|
||||
int t_get_network_state();
|
||||
|
||||
// This function adds a message to the message table.
|
||||
int add_message(char * message, int message_len);
|
||||
|
||||
// This functions creates the structures needed for the rest of the project,
|
||||
// creates the socket, and returns all of it.
|
||||
int bootstrap_node(int * sock_fd);
|
||||
|
||||
// Helper functions
|
||||
int len_list(list *l);
|
||||
@ -101,12 +111,12 @@ int len_list(list *l);
|
||||
neighbour_peer *get_random_neighbour();
|
||||
|
||||
// get data associated with id, if it doesn't exist return NULL
|
||||
pub_data *get_data(long id);
|
||||
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, long id, short seqno, char *data);
|
||||
pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data);
|
||||
|
||||
// add new data to data list
|
||||
void add_data(unsigned char len, long id, short seqno, char *data);
|
||||
void add_data(unsigned char len, int64_t id, int16_t seqno, char *data);
|
||||
|
||||
#endif
|
||||
|
BIN
src/node.o
Normal file
BIN
src/node.o
Normal file
Binary file not shown.
BIN
src/parser.o
Normal file
BIN
src/parser.o
Normal file
Binary file not shown.
46
src/tlv.c
46
src/tlv.c
@ -27,6 +27,9 @@ int build_tlv(tlv *tlv, cmd_token token) {
|
||||
}
|
||||
|
||||
int build_pad1(tlv *tlv) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
pad1 *new = (pad1*) malloc(sizeof(pad1));
|
||||
|
||||
if(new == NULL)
|
||||
@ -40,6 +43,9 @@ int build_pad1(tlv *tlv) {
|
||||
}
|
||||
|
||||
int build_padn(tlv *tlv, size_t len) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
padn *new = (padn*) malloc(sizeof(padn));
|
||||
|
||||
if(new == NULL)
|
||||
@ -47,7 +53,7 @@ int build_padn(tlv *tlv, size_t len) {
|
||||
|
||||
new->type = 1;
|
||||
new->length = len;
|
||||
new->mbz = (char*) calloc(sizeof(char), len);
|
||||
memset(new->mbz, 0, 256);
|
||||
|
||||
tlv->padn = new;
|
||||
|
||||
@ -55,6 +61,9 @@ int build_padn(tlv *tlv, size_t len) {
|
||||
}
|
||||
|
||||
int build_neighbour_req(tlv *tlv) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
neighbour_req *new = (neighbour_req*) malloc(sizeof(neighbour_req));
|
||||
|
||||
if(new == NULL)
|
||||
@ -68,7 +77,10 @@ int build_neighbour_req(tlv *tlv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, short port) {
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
neighbour *new = (neighbour*) malloc(sizeof(neighbour));
|
||||
|
||||
if(new == NULL)
|
||||
@ -85,6 +97,9 @@ int build_neighbour(tlv *tlv, struct in6_addr ip, short port) {
|
||||
}
|
||||
|
||||
int build_network_hash(tlv *tlv, list *data_list) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
network_hash *new = (network_hash*) malloc(sizeof(network_hash));
|
||||
|
||||
if(new == NULL)
|
||||
@ -92,7 +107,7 @@ int build_network_hash(tlv *tlv, list *data_list) {
|
||||
|
||||
new->type = 4;
|
||||
new->length = 16;
|
||||
hash_network(data_list, new->network_hash);
|
||||
hash_network(data_list, (unsigned char*) new->network_hash);
|
||||
|
||||
tlv->network_hash = new;
|
||||
|
||||
@ -100,6 +115,9 @@ int build_network_hash(tlv *tlv, list *data_list) {
|
||||
}
|
||||
|
||||
int build_network_state_req(tlv *tlv) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
network_state_req *new = (network_state_req*) malloc(sizeof(network_state_req));
|
||||
|
||||
if(new == NULL)
|
||||
@ -113,7 +131,10 @@ int build_network_state_req(tlv *tlv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_hash(tlv *tlv, long node_id, short seqno, char *data) {
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, int16_t seqno, char *data) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
node_hash *new = (node_hash*) malloc(sizeof(node_hash));
|
||||
|
||||
if(new == NULL)
|
||||
@ -125,14 +146,17 @@ int build_node_hash(tlv *tlv, long node_id, short seqno, char *data) {
|
||||
new->seqno = seqno;
|
||||
|
||||
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
|
||||
hash_data(&pdata, new->node_hash);
|
||||
hash_data(&pdata, (unsigned char*) new->node_hash);
|
||||
|
||||
tlv->node_hash = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_state_req(tlv *tlv, long node_id) {
|
||||
int build_node_state_req(tlv *tlv, int64_t node_id) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req));
|
||||
|
||||
if(new == NULL)
|
||||
@ -147,7 +171,10 @@ int build_node_state_req(tlv *tlv, long node_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t data_len) {
|
||||
int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_t data_len) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
node_state *new = (node_state*) malloc(sizeof(node_state));
|
||||
int len = data_len + 26;
|
||||
|
||||
@ -167,7 +194,7 @@ int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t dat
|
||||
memcpy(new->data, data, len);
|
||||
|
||||
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
|
||||
hash_data(&pdata, new->node_hash);
|
||||
hash_data(&pdata, (unsigned char*) new->node_hash);
|
||||
|
||||
tlv->node_state = new;
|
||||
|
||||
@ -175,6 +202,9 @@ int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t dat
|
||||
}
|
||||
|
||||
int build_warning(tlv *tlv, char *message, size_t message_len) {
|
||||
// Free the previously allocated memory
|
||||
free(tlv->pad1);
|
||||
|
||||
warning *new = (warning*) malloc(sizeof(warning));
|
||||
int len = message_len;
|
||||
|
||||
|
37
src/tlv.h
37
src/tlv.h
@ -4,10 +4,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "node.h"
|
||||
#include "hash.h"
|
||||
#include "parser.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define LEN_NEIGHBOUR_REQ 0
|
||||
#define LEN_NEIGHBOUR 18
|
||||
@ -22,8 +19,8 @@
|
||||
typedef struct packet {
|
||||
unsigned char magic; // 95 (si autre, ignorer)
|
||||
unsigned char version; // 1 (si autre, ignorer)
|
||||
short length; // 1020 max
|
||||
char *body;
|
||||
int16_t length; // 1020 max
|
||||
char body[1020];
|
||||
} packet;
|
||||
|
||||
// 1 octet
|
||||
@ -35,7 +32,7 @@ typedef struct pad1 {
|
||||
typedef struct padn {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
char *mbz;
|
||||
char mbz[256];
|
||||
} padn;
|
||||
|
||||
// 2 octets
|
||||
@ -49,7 +46,7 @@ typedef struct neighbour {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
struct in6_addr ip;
|
||||
short port;
|
||||
int16_t port;
|
||||
} neighbour;
|
||||
|
||||
// 18 octets
|
||||
@ -69,8 +66,8 @@ typedef struct network_state_req {
|
||||
typedef struct node_hash {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
short seqno;
|
||||
int64_t node_id;
|
||||
int16_t seqno;
|
||||
char node_hash[16];
|
||||
} node_hash;
|
||||
|
||||
@ -78,15 +75,15 @@ typedef struct node_hash {
|
||||
typedef struct node_state_req {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
int64_t node_id;
|
||||
} node_state_req;
|
||||
|
||||
// 28 octets min, 220 octets max (data 0 -> 192)
|
||||
typedef struct node_state {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
short seqno;
|
||||
int64_t node_id;
|
||||
int16_t seqno;
|
||||
char node_hash[16];
|
||||
char data[192];
|
||||
} node_state;
|
||||
@ -111,6 +108,10 @@ typedef union tlv {
|
||||
warning *warning;
|
||||
} tlv;
|
||||
|
||||
#include "node.h"
|
||||
#include "hash.h"
|
||||
#include "parser.h"
|
||||
|
||||
// build tlv from token
|
||||
int build_tlv(tlv *tlv, struct cmd_token token);
|
||||
|
||||
@ -118,12 +119,12 @@ int build_tlv(tlv *tlv, struct cmd_token token);
|
||||
int build_pad1(tlv *tlv);
|
||||
int build_padn(tlv *tlv, size_t len);
|
||||
int build_neighbour_req(union tlv *tlv);
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, short port);
|
||||
int build_network_hash(tlv *tlv, struct list *data_list);
|
||||
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, long node_id, short seqno, char *data);
|
||||
int build_node_state_req(tlv *tlv, long node_id);
|
||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *data, size_t data_len);
|
||||
int build_node_hash(tlv *tlv, int64_t node_id, int16_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_warning(tlv *tlv, char *message, size_t message_len);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user