Browse Source

Init message creation mechanism, Bug fixes

master
Apostolos Fanakis 6 years ago
parent
commit
5397db45fe
  1. 264
      lib/circ_buff.c
  2. 8
      lib/circ_buff.h
  3. 96
      lib/helpers.c
  4. 11
      lib/helpers.h
  5. 14
      src/zaqar.c
  6. 2
      src/zaqar.h

264
lib/circ_buff.c

@ -40,140 +40,6 @@ unit_static void retreat_pointer(cbuf_handle_t cbuf) {
cbuf->tail = (cbuf->tail + 1) % cbuf->max;
}
// Compares the buffers cbuf1 and cbuf2. Elements present on cbuf1 that do not
// exist on cbuf2 are added to the array add2, elements present on cbuf2 that do
// not exist on cbuf1 are added to the array add1.
// Both buffers must be ordered on the same way!
unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
char ***add1, char ***add2) {
assert(cbuf1 && cbuf2 &&
(circ_buf_element_size(cbuf1) == circ_buf_element_size(cbuf2)) &&
(circ_buf_capacity(cbuf1) == circ_buf_capacity(cbuf2)));
// Initializes the diff arrays
(*add1) = (char **) malloc(circ_buf_capacity(cbuf2) * sizeof(char *));
(*add2) = (char **) malloc(circ_buf_capacity(cbuf1) * sizeof(char *));
char *curr_str1 = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
char *curr_str2 = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
/*uint8_t diff_array_index = 0;
for (uint8_t i = 0; i < circ_buf_size(cbuf1); ++i) {
// Reads current element of cbuf1
circ_buf_read(cbuf1, i, curr_str1);
bool element_exists = false;
for (uint8_t j = 0; j < circ_buf_size(cbuf2); ++j) {
circ_buf_read(cbuf2, j, curr_str2);
// Checks against cbuf2 elements
if (!strcmp(curr_str2, curr_str1)) {
element_exists = true;
break;
}
}
if (!element_exists) {
(*add2)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add2)[diff_array_index], curr_str1);
++diff_array_index;
}
}
(*add1)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[diff_array_index], EOB);
diff_array_index = 0;
for (uint8_t i = 0; i < circ_buf_size(cbuf2); ++i) {
// Reads current element of cbuf2
circ_buf_read(cbuf2, i, curr_str2);
bool element_exists = false;
for (uint8_t j = 0; j < circ_buf_size(cbuf1); ++j) {
circ_buf_read(cbuf1, j, curr_str1);
// Checks against cbuf1 elements
if (!strcmp(curr_str1, curr_str2)) {
element_exists = true;
break;
}
}
if (!element_exists) {
(*add1)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add1)[diff_array_index], curr_str2);
++diff_array_index;
}
}
(*add2)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[diff_array_index], EOB);*/
uint8_t cbuf1_idx = 0, cbuf2_idx = 0, add1_arr_idx = 0, add2_arr_idx = 0;
while ((cbuf1_idx < circ_buf_size(cbuf1)) &&
(cbuf2_idx < circ_buf_size(cbuf2))) {
circ_buf_read(cbuf1, cbuf1_idx, curr_str1);
circ_buf_read(cbuf2, cbuf2_idx, curr_str2);
int strcmp_res = strcmp(curr_str1, curr_str2);
if (!strcmp_res) {
++cbuf1_idx;
++cbuf2_idx;
} else { // TODO: change the inner comparisons (strtok etc)
if (strcmp_res < 0) {
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[add2_arr_idx], curr_str1);
++add2_arr_idx;
++cbuf1_idx;
}
else if (strcmp_res > 0) {
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[add1_arr_idx], curr_str2);
++add1_arr_idx;
++cbuf2_idx;
}
}
}
while (cbuf1_idx < circ_buf_size(cbuf1)) {
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
circ_buf_read(cbuf1, cbuf1_idx, curr_str1);
strcpy((*add2)[add2_arr_idx], curr_str1);
++add2_arr_idx;
++cbuf1_idx;
}
while (cbuf2_idx < circ_buf_size(cbuf2)) {
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
circ_buf_read(cbuf2, cbuf2_idx, curr_str2);
strcpy((*add1)[add1_arr_idx], curr_str2);
++add1_arr_idx;
++cbuf2_idx;
}
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[add1_arr_idx], EOB);
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[add2_arr_idx], EOB);
free(curr_str1);
free(curr_str2);
/*uint8_t i = 0;
printf("add1:\n");
while (strcmp((*add1)[i], EOB)) {
printf("%s\n", (*add1)[i]);
++i;
}
i = 0;
printf("add2:\n");
while (strcmp((*add2)[i], EOB)) {
printf("%s\n", (*add2)[i]);
++i;
}*/
}
// APIs
cbuf_handle_t circ_buf_init(char **buffer, size_t size, size_t element_size) {
@ -303,6 +169,136 @@ int circ_buf_read(cbuf_handle_t cbuf, size_t position, char *data) {
return r;
}
void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
char ***add1, char ***add2) {
assert(cbuf1 && cbuf2 &&
(circ_buf_element_size(cbuf1) == circ_buf_element_size(cbuf2)) &&
(circ_buf_capacity(cbuf1) == circ_buf_capacity(cbuf2)));
// Initializes the diff arrays
(*add1) = (char **) malloc(circ_buf_capacity(cbuf2) * sizeof(char *));
(*add2) = (char **) malloc(circ_buf_capacity(cbuf1) * sizeof(char *));
char *curr_str1 = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
char *curr_str2 = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
/*uint8_t diff_array_index = 0;
for (uint8_t i = 0; i < circ_buf_size(cbuf1); ++i) {
// Reads current element of cbuf1
circ_buf_read(cbuf1, i, curr_str1);
bool element_exists = false;
for (uint8_t j = 0; j < circ_buf_size(cbuf2); ++j) {
circ_buf_read(cbuf2, j, curr_str2);
// Checks against cbuf2 elements
if (!strcmp(curr_str2, curr_str1)) {
element_exists = true;
break;
}
}
if (!element_exists) {
(*add2)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add2)[diff_array_index], curr_str1);
++diff_array_index;
}
}
(*add1)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[diff_array_index], EOB);
diff_array_index = 0;
for (uint8_t i = 0; i < circ_buf_size(cbuf2); ++i) {
// Reads current element of cbuf2
circ_buf_read(cbuf2, i, curr_str2);
bool element_exists = false;
for (uint8_t j = 0; j < circ_buf_size(cbuf1); ++j) {
circ_buf_read(cbuf1, j, curr_str1);
// Checks against cbuf1 elements
if (!strcmp(curr_str1, curr_str2)) {
element_exists = true;
break;
}
}
if (!element_exists) {
(*add1)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add1)[diff_array_index], curr_str2);
++diff_array_index;
}
}
(*add2)[diff_array_index] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[diff_array_index], EOB);*/
uint8_t cbuf1_idx = 0, cbuf2_idx = 0, add1_arr_idx = 0, add2_arr_idx = 0;
while ((cbuf1_idx < circ_buf_size(cbuf1)) &&
(cbuf2_idx < circ_buf_size(cbuf2))) {
circ_buf_read(cbuf1, cbuf1_idx, curr_str1);
circ_buf_read(cbuf2, cbuf2_idx, curr_str2);
int strcmp_res = strcmp(curr_str1, curr_str2);
if (!strcmp_res) {
++cbuf1_idx;
++cbuf2_idx;
} else { // TODO: change the inner comparisons (strtok etc)
if (strcmp_res < 0) {
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[add2_arr_idx], curr_str1);
++add2_arr_idx;
++cbuf1_idx;
}
else if (strcmp_res > 0) {
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[add1_arr_idx], curr_str2);
++add1_arr_idx;
++cbuf2_idx;
}
}
}
while (cbuf1_idx < circ_buf_size(cbuf1)) {
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
circ_buf_read(cbuf1, cbuf1_idx, curr_str1);
strcpy((*add2)[add2_arr_idx], curr_str1);
++add2_arr_idx;
++cbuf1_idx;
}
while (cbuf2_idx < circ_buf_size(cbuf2)) {
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
circ_buf_read(cbuf2, cbuf2_idx, curr_str2);
strcpy((*add1)[add1_arr_idx], curr_str2);
++add1_arr_idx;
++cbuf2_idx;
}
(*add1)[add1_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
strcpy((*add1)[add1_arr_idx], EOB);
(*add2)[add2_arr_idx] = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
strcpy((*add2)[add2_arr_idx], EOB);
free(curr_str1);
free(curr_str2);
/*uint8_t i = 0;
printf("add1:\n");
while (strcmp((*add1)[i], EOB)) {
printf("%s\n", (*add1)[i]);
++i;
}
i = 0;
printf("add2:\n");
while (strcmp((*add2)[i], EOB)) {
printf("%s\n", (*add2)[i]);
++i;
}*/
}
int circ_buf_serialize(cbuf_handle_t cbuf, char **serialized) {
char *temp = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char));
const char separator[2] = "\r";

8
lib/circ_buff.h

@ -20,7 +20,6 @@ typedef circ_buf_t *cbuf_handle_t;
#define unit_static
unit_static void advance_pointer(cbuf_handle_t cbuf);
unit_static void retreat_pointer(cbuf_handle_t cbuf);
unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2, char ***add1, char ***add2);
#else
#define unit_static static
#endif
@ -50,6 +49,13 @@ int circ_buf_get(cbuf_handle_t cbuf, char *data);
// Reads a value from the buffer. Does NOT retrieve, size is not reduced!
int circ_buf_read(cbuf_handle_t cbuf, size_t position, char *data);
// Compares the buffers cbuf1 and cbuf2. Elements present on cbuf1 that do not
// exist on cbuf2 are added to the array add2, elements present on cbuf2 that do
// not exist on cbuf1 are added to the array add1.
// Both buffers must be ordered on the same way!
void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
char ***add1, char ***add2);
// Serializes the whole buffer to a single string
int circ_buf_serialize(cbuf_handle_t cbuf, char **serialized);

96
lib/helpers.c

@ -1,5 +1,86 @@
#include "helpers.h"
/*
* Function based on this example:
* http://man7.org/linux/man-pages/man3/getifaddrs.3.html#EXAMPLE
*/
int get_own_id(void) {
int id = -1;
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1) {
perror("Couldn't get network interfaces.");
exit(EXIT_FAILURE);
}
// Walks through linked list, maintaining head pointer so we can free list later
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL) {
continue;
}
family = ifa->ifa_addr->sa_family;
// Gets the address of an AF_INET* interface address
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
id = extract_id_from_ip(host);
if (id < 0) {
continue;
}
break;
}
}
freeifaddrs(ifaddr);
return(id);
}
int extract_id_from_ip(const char *ip) {
const char separator[2] = ".";
int id = 0;
char *rest, *token, *ip_cp;
ip_cp = malloc(strlen(ip) * sizeof(char));
strcpy(ip_cp, ip);
rest = ip_cp;
token = strtok_r(rest, separator, &rest);
if (!token || atoi(token) != 10) {
return -1;
}
token = strtok_r(rest, separator, &rest);
if (!token || atoi(token) != 0) {
return -1;
}
token = strtok_r(rest, separator, &rest);
if (!token) {
return -1;
}
id = atoi(token) * 100;
token = strtok_r(rest, separator, &rest);
if (!token) {
return -1;
}
id += atoi(token);
return id;
}
void set_timer_and_handler(void (*handler)(int), long int timer_interval) {
struct itimerval interval_timer;
struct sigaction signal_action;
@ -132,6 +213,20 @@ void search_for_neighbors(node_handle_t **neighbors, uint16_t *num_neighbors, ui
fclose(arpCache);
}
void create_message(node_handle_t *neighbors, char *new_message, int own_id,
uint8_t num_neighbors, uint16_t max_message_length) {
node_handle_t random_node = neighbors[rand() % (num_neighbors)];
int peer_id = extract_id_from_ip(inet_ntoa((node_get_addr(random_node)).sin_addr));
if (peer_id < 0) {
perror("Couldn't extract own ID.");
exit(EXIT_FAILURE);
}
snprintf(new_message, max_message_length, "%04d_%04d_%ld_%s", own_id, peer_id, time(NULL),
"It's amazing... It's fantastic!");
}
bool check_node_alive(const char *ipv4) {
char command[64];
@ -253,5 +348,6 @@ void init_sockaddr(struct sockaddr_in *peer_name, const char *ipv4, uint16_t por
fprintf(stderr, "Unknown host %s.\n", ipv4);
exit(EXIT_FAILURE);
}
peer_name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0];
}

11
lib/helpers.h

@ -1,6 +1,8 @@
#ifndef HELPERS_H_
#define HELPERS_H_
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@ -11,6 +13,8 @@
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <ifaddrs.h>
#include <linux/if_link.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
@ -31,12 +35,19 @@
// Format for fscanf() to read the 1st field of ARP
#define ARP_LINE_FORMAT "%" xstr(ARP_STRING_LEN) "s %*s %*s %*s %*s %*s"
int get_own_id(void);
int extract_id_from_ip(const char *ip);
void set_timer_and_handler(void (*handler)(int), long int timer_interval);
void enable_echo_broadcast(void);
void search_for_neighbors(node_handle_t **neighbors, uint16_t *num_neighbors, uint16_t port);
void create_message(node_handle_t *neighbors, char *new_message, int own_id,
uint8_t num_neighbors, uint16_t max_message_length);
bool check_node_alive(const char *ipv4);
int create_socket_and_listen(uint16_t port, uint8_t backlog_size);

14
src/zaqar.c

@ -5,12 +5,18 @@
volatile sig_atomic_t sigalrm_flag = false;
int main(void) {
int in_sock;
int in_sock, own_id;
fd_set active_fd_set, read_fd_set;
struct sockaddr_in peer_name;
node_handle_t *neighbors;
uint16_t num_neighbors = 0;
own_id = get_own_id();
if (own_id < 0) {
perror("Couldn't extract own ID.");
exit(EXIT_FAILURE);
}
// Enables echo broadcast pings
enable_echo_broadcast();
@ -32,12 +38,14 @@ int main(void) {
while (1) {
if (sigalrm_flag) {
// It's time to send a message!
char new_message[MAX_MESSAGE_LENGTH];
search_for_neighbors(&neighbors, &num_neighbors, PORT);
create_message(neighbors, new_message, own_id, num_neighbors, MAX_MESSAGE_LENGTH);
for (uint8_t i = 0; i < num_neighbors; ++i) {
if (node_get_status(neighbors[i]) == NODE_PRESENT) {
send_message(node_get_addr(neighbors[i]), MESSAGE);
send_message(node_get_addr(neighbors[i]), new_message);
}
}
@ -66,7 +74,7 @@ int main(void) {
accept_connection(in_sock, &peer_name, &active_fd_set);
} else {
// Data arriving on an already-connected socket
if (read_from_peer(i, MAXLINE) < 0) {
if (read_from_peer(i, MAX_MESSAGE_LENGTH) < 0) {
close(i);
FD_CLR(i, &active_fd_set);
}

2
src/zaqar.h

@ -20,7 +20,7 @@
#define TIMER_INTERVAL 10
#define PORT 5000
#define MAXLINE 1024
#define MAX_MESSAGE_LENGTH 277
#define BACKLOG_SIZE 2
void handle_alarm(int sig);

Loading…
Cancel
Save