adding tlv to packet error fix

This commit is contained in:
nis 2020-05-03 23:43:17 +02:00
parent c56a151762
commit e5ec8b36ae
5 changed files with 121 additions and 102 deletions

View File

@ -33,8 +33,6 @@ void hash_data(pub_data *data, unsigned char *buf) {
printf("%02x", buf[i]);
}
printf("\n");
exit(1);
*/
}

View File

@ -394,7 +394,11 @@ int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
if(pack->length + len > 1020) {
errval = send_packet((char*) pack, pack->length, dest, socket_num);
*pack = (packet) {.magic = 95, .version = 1, .length = 0};
pack->magic = 95;
pack->version = 1;
pack->length = 0;
memset(pack->body, 0, 1020);
sent = 1;
}
@ -403,7 +407,11 @@ int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
// we just ignore that padding, and send out the packet.
if(pack->length >= 1020) {
errval = send_packet((char*) pack, pack->length, dest, socket_num);
*pack = (packet) {.magic = 95, .version = 1, .length = 0};
pack->magic = 95;
pack->version = 1;
pack->length = 0;
memset(pack->body, 0, 1020);
sent = 1;
}
@ -412,47 +420,73 @@ int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num) {
// Copy data from tlv into body
switch(type) {
case 1:
memcpy(pack->body + pack->length, tlv->pad1, 1);
memcpy(pack->body + pack->length, (char*) &tlv->pad1->type, 1);
pack->length += 1;
break;
case 2:
memcpy(pack->body + pack->length, tlv->padn, len);
memcpy(pack->body + pack->length, (char*) &tlv->padn->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->padn->length, 1);
memcpy(pack->body + pack->length + 2, (char*) &tlv->padn->mbz, tlv->padn->length);
pack->length += len;
break;
case 3:
memcpy(pack->body + pack->length, tlv->neighbour, len);
memcpy(pack->body + pack->length, (char*) &tlv->neighbour->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->neighbour->length, 1);
pack->length += len;
break;
case 4:
memcpy(pack->body + pack->length, tlv->network_hash, len);
memcpy(pack->body + pack->length, (char*) &tlv->network_hash->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->network_hash->length, 1);
memcpy(pack->body + pack->length + 2, (char*) &tlv->network_hash->network_hash, 16);
pack->length += len;
break;
case 5:
memcpy(pack->body + pack->length, tlv->network_state_req, len);
memcpy(pack->body + pack->length, (char*) &tlv->network_state_req->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->network_state_req->length, 1);
pack->length += len;
break;
case 6:
memcpy(pack->body + pack->length, tlv->node_hash, len);
memcpy(pack->body + pack->length, (char*) &tlv->node_hash->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->node_hash->length, 1);
memcpy(pack->body + pack->length + 2, (char*) &tlv->node_hash->node_id, 8);
memcpy(pack->body + pack->length + 10, (char*) &tlv->node_hash->seqno, 2);
memcpy(pack->body + pack->length + 12, (char*) &tlv->node_hash->node_hash, 16);
pack->length += len;
break;
case 7:
memcpy(pack->body + pack->length, tlv->node_state_req, len);
memcpy(pack->body + pack->length, (char*) &tlv->node_state_req->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->node_state_req->length, 1);
pack->length += len;
break;
case 8:
memcpy(pack->body + pack->length, tlv->node_state, len);
memcpy(pack->body + pack->length, (char*) &tlv->node_state->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->node_state->length, 1);
memcpy(pack->body + pack->length + 2, (char*) &tlv->node_state->node_id, 8);
memcpy(pack->body + pack->length + 10, (char*) &tlv->node_state->seqno, 2);
memcpy(pack->body + pack->length + 12, (char*) &tlv->node_state->node_hash, 16);
memcpy(pack->body + pack->length + 28, (char*) &tlv->node_state->data, tlv->node_state->length - 26);
pack->length += len;
break;
case 9:
memcpy(pack->body + pack->length, tlv->warning, len);
memcpy(pack->body + pack->length, (char*) &tlv->warning->type, 1);
memcpy(pack->body + pack->length + 1, (char*) &tlv->warning->length, 1);
memcpy(pack->body + pack->length + 2, (char*) &tlv->warning->message, tlv->warning->length);
pack->length += len;
break;
@ -473,7 +507,8 @@ 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, uint16_t length, struct sockaddr_in6 *dest, int socket_num) {
((packet*) packet_buff)->length = htobe16(((packet*) packet_buff)->length);
uint16_t be_len = htobe16(*(uint16_t*) (packet_buff + 2));
memcpy(packet_buff + 2, &be_len, 2);
// Vectorized buffer
struct iovec vec_buff[1];
@ -512,63 +547,80 @@ int send_packet(char *packet_buff, uint16_t length, struct sockaddr_in6 *dest, i
// 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 = 0};
memset(pack.body, 0, 1020);
// Copy data from tlv into body
switch(type) {
switch(type) {
case 1:
memcpy(pack.body, tlv->pad1, 1);
memcpy(pack.body + pack.length, (char*) &tlv->pad1->type, 1);
pack.length += 1;
break;
case 2:
len = tlv->padn->length + 2;
memcpy(pack.body, tlv->padn, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->padn->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->padn->length, 1);
memcpy(pack.body + pack.length + 2, (char*) &tlv->padn->mbz, tlv->padn->length);
pack.length += tlv->padn->length + 2;
break;
case 3:
len = tlv->neighbour->length + 2;
memcpy(pack.body, tlv->neighbour, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->neighbour->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->neighbour->length, 1);
pack.length += tlv->neighbour->length + 2;
break;
case 4:
len = tlv->network_hash->length + 2;
memcpy(pack.body, tlv->network_hash, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->network_hash->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->network_hash->length, 1);
memcpy(pack.body + pack.length + 2, (char*) &tlv->network_hash->network_hash, 16);
pack.length += tlv->network_hash->length + 2;
break;
case 5:
len = tlv->network_state_req->length + 2;
memcpy(pack.body, tlv->network_state_req, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->network_state_req->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->network_state_req->length, 1);
pack.length += tlv->network_state_req->length + 2;
break;
case 6:
len = tlv->node_hash->length + 2;
memcpy(pack.body, tlv->node_hash, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->node_hash->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->node_hash->length, 1);
memcpy(pack.body + pack.length + 2, (char*) &tlv->node_hash->node_id, 8);
memcpy(pack.body + pack.length + 10, (char*) &tlv->node_hash->seqno, 2);
memcpy(pack.body + pack.length + 12, (char*) &tlv->node_hash->node_hash, 16);
pack.length += tlv->node_hash->length + 2;
break;
case 7:
len = tlv->node_state_req->length + 2;
memcpy(pack.body, tlv->node_state_req, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->node_state_req->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->node_state_req->length, 1);
pack.length += tlv->node_state_req->length + 2;
break;
case 8:
len = tlv->node_state->length + 2;
memcpy(pack.body, tlv->node_state, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->node_state->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->node_state->length, 1);
memcpy(pack.body + pack.length + 2, (char*) &tlv->node_state->node_id, 8);
memcpy(pack.body + pack.length + 10, (char*) &tlv->node_state->seqno, 2);
memcpy(pack.body + pack.length + 12, (char*) &tlv->node_state->node_hash, 16);
memcpy(pack.body + pack.length + 28, (char*) &tlv->node_state->data, tlv->node_state->length - 26);
pack.length += tlv->node_state->length + 2;
break;
case 9:
len = tlv->warning->length + 2;
memcpy(pack.body, tlv->warning, len);
pack.length += len;
memcpy(pack.body + pack.length, (char*) &tlv->warning->type, 1);
memcpy(pack.body + pack.length + 1, (char*) &tlv->warning->length, 1);
memcpy(pack.body + pack.length + 2, (char*) &tlv->warning->message, tlv->warning->length);
pack.length += tlv->warning->length + 2;
break;
default:
@ -823,11 +875,8 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
// The TLV we are going to send back.
tlv new_tlv;
// The tlv we are currently looking at.
tlv cur_tlv;
new_tlv.pad1 = NULL;
cur_tlv.pad1 = NULL;
list * tmp_list;
pub_data * pdata;
@ -969,9 +1018,11 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
while(tmp_list != NULL) {
pdata = (pub_data*) tmp_list->data;
build_node_hash(&new_tlv, pdata->id, pdata->seqno, pdata->data);
build_node_hash(&new_tlv, pdata->id, pdata->seqno, pdata->data, pdata->length);
add_tlv(&pack, &new_tlv, sender, socket_num);
tmp_list = tmp_list->next;
printf("%lu\n", *(uint64_t*) (pack.body + 2));
}
// The position is updated
@ -991,8 +1042,6 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
pdata = get_data(be64toh(*id));
printf("Received: %ld\n", be64toh(*id));
// If data is found for this id then we check that both hashes are the same
if(pdata != NULL) {
print_debug(">> Comparing hashes...");
@ -1015,6 +1064,8 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
build_node_state_req(&new_tlv, be64toh(*id));
add_tlv(&pack, &new_tlv, sender, socket_num);
printf(">> Sending node state request for node %lu...\n", be64toh(*id));
// The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2;
@ -1036,7 +1087,7 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
add_tlv(&pack, &new_tlv, sender, socket_num);
} else {
print_debug(">> Found no data for the requested node, skipping...");
printf("Received: %ld\n", be64toh(*id));
printf("Skipped TLV:\nType: %d\nLength: %d\nNode ID: %lu\n", data[pos], data[pos+1], be64toh(*id));
}
// The position is updated
@ -1087,7 +1138,7 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
print_debug(">> Built message: ");
printf("Type : %d\n", data[pos] );
printf("Length : %d\n", pdata_check.length );
printf("Length : %d\n", pdata_check.length + 26);
printf("Node ID : %lu\n", pdata_check.id);
printf("Seqno : %hu\n", pdata_check.seqno);
printf("Hash :");
@ -1170,8 +1221,6 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
case 9:
print_debug(">> \aReceived warning !");
// We received a warning tlv so it's message is printed
cur_tlv.warning = (warning*) (data + pos);
tlv_len = data[pos+1];
cur_message = data + pos + 2;
@ -1269,46 +1318,32 @@ int t_get_network_state(int sock_fd){
while (tmp_list != NULL) {
neighbour_peer * peer = (neighbour_peer *) tmp_list->data;
tlv * new_tlv = malloc(sizeof(union tlv));
memset(new_tlv, 0, sizeof(union tlv));
if (new_tlv == NULL) {
print_error("Error while allocating memory for the TLV !");
return -1;
}
tlv new_tlv;
memset(&new_tlv, 0, sizeof(union tlv));
// Create the structure for the receiver.
struct sockaddr_in6 * receiver = malloc(sizeof(struct sockaddr_in6));
memset(receiver, 0, sizeof(struct sockaddr_in6));
if (receiver == NULL) {
print_error("Error while allocating memory for the peer address!");
return -1;
}
receiver->sin6_family = AF_INET6;
receiver->sin6_addr = peer->ip;
receiver->sin6_port = htobe16(peer->port);
receiver->sin6_scope_id = 0;
struct sockaddr_in6 receiver;
memset(&receiver, 0, sizeof(struct sockaddr_in6));
receiver.sin6_family = AF_INET6;
receiver.sin6_addr = peer->ip;
receiver.sin6_port = htobe16(peer->port);
receiver.sin6_scope_id = 0;
// Send out a TLV network state.
list * tmp_data_list = data_list;
if (build_network_hash(new_tlv, tmp_data_list) < 0) {
if (build_network_hash(&new_tlv, data_list) < 0) {
print_error("Error while building a network hash.");
return -1;
} else {
if (send_single_tlv(new_tlv, receiver, sock_fd) < 0) {
if (send_single_tlv(&new_tlv, &receiver, sock_fd) < 0) {
print_error("Error while sending a network hash to a peer.");
return -1;
} else {
print_debug(">> Sent network hash to a peer.");
}
}
free(new_tlv);
free(receiver);
if (tmp_list->next == NULL) {
break;
} else {
tmp_list = tmp_list->next;
}
tmp_list = tmp_list->next;
}
}
return 0;

View File

@ -63,7 +63,7 @@ typedef struct list {
// The node ID
// #define NODE_ID 42675882021843277
// #define NODE_ID 13809235719890846928
static uint64_t NODE_ID = 80927976239;
#define NODE_ID 1312
// The number of neighbours
// The neighbour table has 15 entries

View File

@ -116,7 +116,7 @@ int build_network_state_req(tlv *tlv) {
return 0;
}
int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data) {
int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, unsigned char length) {
// Free the previously allocated memory
free(tlv->pad1);
@ -131,7 +131,7 @@ int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data) {
new->node_id = htobe64(node_id);
new->seqno = htobe16(seqno);
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
pub_data pdata = (pub_data) {.length = length, .id = node_id, .seqno = seqno, .data = data};
hash_data(&pdata, new->node_hash);
tlv->node_hash = new;
@ -165,24 +165,16 @@ int build_node_state(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, siz
node_state *new = (node_state*) malloc(sizeof(node_state));
memset(new, 0, sizeof(node_state));
int len = data_len + 26;
if(new == NULL)
return -1;
// en mettant cet octet à 0 on est surs de traiter un champ data de taille 192 max
if(len > 192) {
data[192] = 0;
len = 192;
}
new->type = 8;
new->length = 26 + len;
new->length = data_len + 26;
new->node_id = htobe64(node_id);
new->seqno = htobe16(seqno);
memcpy(new->data, data, len);
memcpy(new->data, data, data_len);
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data};
pub_data pdata = (pub_data) {.length = data_len, .id = node_id, .seqno = seqno, .data = data};
hash_data(&pdata, new->node_hash);
tlv->node_state = new;
@ -202,12 +194,6 @@ int build_warning(tlv *tlv, char *message, size_t message_len) {
if(new == NULL)
return -1;
// en mettant cet octet à 0 on est surs de traiter un champ message de taille 256 max
if(len > 256) {
message[256] = 0;
len = 256;
}
new->type = 9;
new->length = len;
memcpy(new->message, message, len);

View File

@ -85,14 +85,14 @@ typedef struct node_state {
uint64_t node_id;
uint16_t seqno;
unsigned char node_hash[16];
unsigned char data[192];
char data[192];
} node_state;
// 2 octets min, 258 ocets max (unsigned char 0 -> 255)
typedef struct warning {
unsigned char type;
unsigned char length;
unsigned char message[256];
char message[256];
} warning;
typedef union tlv {
@ -122,7 +122,7 @@ 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, uint64_t node_id, uint16_t seqno, char *data);
int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, unsigned char length);
int build_node_state_req(tlv *tlv, uint64_t node_id);
int build_node_state(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, size_t data_len);
int build_warning(tlv *tlv, char *message, size_t message_len);