send packets v1

This commit is contained in:
gonzalef 2020-04-16 18:52:19 +02:00
parent 50bb64059b
commit e4e585121e
6 changed files with 272 additions and 34 deletions

View File

@ -156,7 +156,194 @@ void add_data(unsigned char len, int64_t id, int16_t 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,
@ -302,16 +489,27 @@ int update_neighbours(){
};
// We then look at the differents TLVs in the packet.
int work_with_tlvs(char * data, int16_t 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];
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)) {
@ -332,9 +530,7 @@ int work_with_tlvs(char * data, int16_t 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];
@ -345,11 +541,16 @@ int work_with_tlvs(char * data, int16_t 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];
@ -363,8 +564,7 @@ int work_with_tlvs(char * data, int16_t 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
@ -381,8 +581,7 @@ int work_with_tlvs(char * data, int16_t 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
@ -412,8 +611,7 @@ int work_with_tlvs(char * data, int16_t 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];
@ -427,8 +625,7 @@ int work_with_tlvs(char * data, int16_t 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
@ -464,13 +661,19 @@ int work_with_tlvs(char * data, int16_t 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;
}
@ -535,7 +738,7 @@ void listen_for_packets(){
// 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(req, 1024, &sender, s);
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 );

View File

@ -11,6 +11,7 @@
#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
@ -69,21 +70,25 @@ int validate_tlv(char *data, int pos, int16_t packet_len);
int update_neighbours();
int work_with_tlvs(char * data, int16_t 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(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);
// 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);
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();

Binary file not shown.

View File

@ -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)
@ -69,6 +78,9 @@ int build_neighbour_req(tlv *tlv) {
}
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, int16_t 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)
@ -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)
@ -114,6 +132,9 @@ int build_network_state_req(tlv *tlv) {
}
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)
@ -133,6 +154,9 @@ 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) {
// Free the previously allocated memory
free(tlv->pad1);
node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req));
if(new == NULL)
@ -148,6 +172,9 @@ 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) {
// Free the previously allocated memory
free(tlv->pad1);
node_state *new = (node_state*) malloc(sizeof(node_state));
int len = data_len + 26;
@ -175,6 +202,9 @@ int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_
}
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;

View File

@ -19,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
@ -32,7 +32,7 @@ typedef struct pad1 {
typedef struct padn {
unsigned char type;
unsigned char length;
char *mbz;
char mbz[256];
} padn;
// 2 octets
@ -46,7 +46,7 @@ typedef struct neighbour {
unsigned char type;
unsigned char length;
struct in6_addr ip;
short port;
int16_t port;
} neighbour;
// 18 octets
@ -67,7 +67,7 @@ typedef struct node_hash {
unsigned char type;
unsigned char length;
int64_t node_id;
short seqno;
int16_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;
short seqno;
int16_t seqno;
char node_hash[16];
char data[192];
} node_state;
@ -119,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_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, short seqno, char *data);
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, 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);
int build_warning(tlv *tlv, char *message, size_t message_len);
#endif

BIN
src/tlv.o

Binary file not shown.