|
@ -68,6 +68,8 @@ node_id_t extract_id_from_ip(const ipv4_t ip) { |
|
|
void set_timer_and_handler(void (*handler)(int), long int wakeup_time) { |
|
|
void set_timer_and_handler(void (*handler)(int), long int wakeup_time) { |
|
|
assert(handler); |
|
|
assert(handler); |
|
|
|
|
|
|
|
|
|
|
|
logI("Setting up new wakeup timer."); |
|
|
|
|
|
|
|
|
struct itimerval timer; |
|
|
struct itimerval timer; |
|
|
struct sigaction signal_action; |
|
|
struct sigaction signal_action; |
|
|
|
|
|
|
|
@ -76,7 +78,8 @@ void set_timer_and_handler(void (*handler)(int), long int wakeup_time) { |
|
|
memset(&signal_action, 0, sizeof(signal_action)); |
|
|
memset(&signal_action, 0, sizeof(signal_action)); |
|
|
signal_action.sa_handler = handler; |
|
|
signal_action.sa_handler = handler; |
|
|
if (sigaction(SIGALRM, &signal_action, NULL)) { |
|
|
if (sigaction(SIGALRM, &signal_action, NULL)) { |
|
|
perror("Couldn't install function handler for SIGALRM signals."); |
|
|
logE("Couldn't install function handler for SIGALRM signals."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -87,7 +90,8 @@ void set_timer_and_handler(void (*handler)(int), long int wakeup_time) { |
|
|
timer.it_value.tv_sec = wakeup_time; |
|
|
timer.it_value.tv_sec = wakeup_time; |
|
|
|
|
|
|
|
|
if (setitimer(ITIMER_REAL, &timer, NULL) == -1) { |
|
|
if (setitimer(ITIMER_REAL, &timer, NULL) == -1) { |
|
|
perror("Couldn't set timer."); |
|
|
logE("Couldn't set timer."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -95,11 +99,15 @@ void set_timer_and_handler(void (*handler)(int), long int wakeup_time) { |
|
|
uint16_t create_message(char *new_message, uint16_t max_message_length, node_handle_t *neighbors, |
|
|
uint16_t create_message(char *new_message, uint16_t max_message_length, node_handle_t *neighbors, |
|
|
uint8_t num_neighbors, node_id_t own_id) { |
|
|
uint8_t num_neighbors, node_id_t own_id) { |
|
|
assert(new_message && neighbors); |
|
|
assert(new_message && neighbors); |
|
|
|
|
|
|
|
|
|
|
|
logI("Creating new message."); |
|
|
|
|
|
|
|
|
node_handle_t random_node = neighbors[rand() % (num_neighbors)]; |
|
|
node_handle_t random_node = neighbors[rand() % (num_neighbors)]; |
|
|
|
|
|
|
|
|
node_id_t peer_id = node_get_id(random_node); |
|
|
node_id_t peer_id = node_get_id(random_node); |
|
|
if (!peer_id) { |
|
|
if (!peer_id) { |
|
|
perror("Couldn't extract peer's ID."); |
|
|
logE("Couldn't extract peer's ID."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -114,13 +122,16 @@ uint16_t create_message(char *new_message, uint16_t max_message_length, node_han |
|
|
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
|
|
|
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
|
|
|
*/ |
|
|
*/ |
|
|
int create_socket_and_listen(port_t port, uint8_t backlog_size) { |
|
|
int create_socket_and_listen(port_t port, uint8_t backlog_size) { |
|
|
|
|
|
logI("Creating the socket for input connections."); |
|
|
|
|
|
|
|
|
int in_sock; |
|
|
int in_sock; |
|
|
address_t own_name; |
|
|
address_t own_name; |
|
|
|
|
|
|
|
|
// Creates the socket
|
|
|
// Creates the socket
|
|
|
in_sock = socket(PF_INET, SOCK_STREAM, 0); |
|
|
in_sock = socket(PF_INET, SOCK_STREAM, 0); |
|
|
if (in_sock < 0) { |
|
|
if (in_sock < 0) { |
|
|
perror("Couldn't create the socket."); |
|
|
logE("Couldn't create the socket."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -131,12 +142,14 @@ int create_socket_and_listen(port_t port, uint8_t backlog_size) { |
|
|
|
|
|
|
|
|
// Binds own address structure to socket
|
|
|
// Binds own address structure to socket
|
|
|
if (bind(in_sock, (struct sockaddr *) &own_name, sizeof(own_name)) < 0) { |
|
|
if (bind(in_sock, (struct sockaddr *) &own_name, sizeof(own_name)) < 0) { |
|
|
perror("Couldn't bind the address structure to the socket."); |
|
|
logE("Couldn't bind the address structure to the socket."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (listen(in_sock, backlog_size) < 0) { |
|
|
if (listen(in_sock, backlog_size) < 0) { |
|
|
perror("Couldn't listen for connections on the socket."); |
|
|
logE("Couldn't listen for connections on the socket."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -146,13 +159,16 @@ int create_socket_and_listen(port_t port, uint8_t backlog_size) { |
|
|
void send_message(node_handle_t peer, message_handle_t message) { |
|
|
void send_message(node_handle_t peer, message_handle_t message) { |
|
|
assert(peer && message); |
|
|
assert(peer && message); |
|
|
|
|
|
|
|
|
|
|
|
logI("Sending message.") |
|
|
|
|
|
|
|
|
int out_sock; |
|
|
int out_sock; |
|
|
address_t peer_address = node_get_addr(peer); |
|
|
address_t peer_address = node_get_addr(peer); |
|
|
|
|
|
|
|
|
// Creates the socket
|
|
|
// Creates the socket
|
|
|
out_sock = socket(PF_INET, SOCK_STREAM, 0); |
|
|
out_sock = socket(PF_INET, SOCK_STREAM, 0); |
|
|
if (out_sock < 0) { |
|
|
if (out_sock < 0) { |
|
|
perror("Couldn't create the socket."); |
|
|
logE("Couldn't create the socket."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -175,10 +191,13 @@ node_id_t accept_connection(int sock, address_t *peer_name, fd_set *active_fd_se |
|
|
int *listens_on) { |
|
|
int *listens_on) { |
|
|
assert(peer_name && active_fd_set && listens_on); |
|
|
assert(peer_name && active_fd_set && listens_on); |
|
|
|
|
|
|
|
|
|
|
|
logI("Accepting new connection."); |
|
|
|
|
|
|
|
|
size_t peer_name_size = sizeof((*peer_name)); |
|
|
size_t peer_name_size = sizeof((*peer_name)); |
|
|
int comm_socket = accept(sock, (struct sockaddr *) peer_name, &peer_name_size); |
|
|
int comm_socket = accept(sock, (struct sockaddr *) peer_name, &peer_name_size); |
|
|
if (comm_socket < 0) { |
|
|
if (comm_socket < 0) { |
|
|
perror("Couldn't accept the connection."); |
|
|
logE("Couldn't accept the connection."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
// TODO maye be remove this?
|
|
|
// TODO maye be remove this?
|
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
@ -198,6 +217,8 @@ uint16_t checkAddNode(node_handle_t **neighbors, uint16_t num_neighbors , |
|
|
address_t peer_name, node_id_t node_id) { |
|
|
address_t peer_name, node_id_t node_id) { |
|
|
assert(neighbors); |
|
|
assert(neighbors); |
|
|
|
|
|
|
|
|
|
|
|
logI("Adding new node."); |
|
|
|
|
|
|
|
|
bool node_exists = false; |
|
|
bool node_exists = false; |
|
|
|
|
|
|
|
|
for (int i = 0; i < num_neighbors; ++i) { |
|
|
for (int i = 0; i < num_neighbors; ++i) { |
|
@ -211,7 +232,8 @@ uint16_t checkAddNode(node_handle_t **neighbors, uint16_t num_neighbors , |
|
|
(num_neighbors + 1) * sizeof(node_handle_t)); |
|
|
(num_neighbors + 1) * sizeof(node_handle_t)); |
|
|
if (!r_neighbors) { |
|
|
if (!r_neighbors) { |
|
|
free(r_neighbors); |
|
|
free(r_neighbors); |
|
|
perror("Unable to reallocate memory for neighbor IP."); |
|
|
logE("Unable to reallocate memory for neighbor IP."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -227,9 +249,12 @@ uint16_t checkAddNode(node_handle_t **neighbors, uint16_t num_neighbors , |
|
|
void write_to_peer(int file_desc, const char *message) { |
|
|
void write_to_peer(int file_desc, const char *message) { |
|
|
assert(message); |
|
|
assert(message); |
|
|
|
|
|
|
|
|
|
|
|
logI("Writing to peer."); |
|
|
|
|
|
|
|
|
int num_bytes = write(file_desc, message, strlen(message) + 1); |
|
|
int num_bytes = write(file_desc, message, strlen(message) + 1); |
|
|
if (num_bytes < 0) { |
|
|
if (num_bytes < 0) { |
|
|
perror("Couldn't write to peer."); |
|
|
logE("Couldn't write to peer."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
// TODO maye be remove this?
|
|
|
// TODO maye be remove this?
|
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
@ -237,12 +262,15 @@ void write_to_peer(int file_desc, const char *message) { |
|
|
|
|
|
|
|
|
int read_from_peer(int file_des, uint16_t max_line, cbuf_handle_t *message_buffer, |
|
|
int read_from_peer(int file_des, uint16_t max_line, cbuf_handle_t *message_buffer, |
|
|
node_handle_t **neighbors, uint16_t num_neighbors) { |
|
|
node_handle_t **neighbors, uint16_t num_neighbors) { |
|
|
|
|
|
logI("Reading from peer."); |
|
|
|
|
|
|
|
|
char buffer[max_line]; |
|
|
char buffer[max_line]; |
|
|
int num_bytes; |
|
|
int num_bytes; |
|
|
|
|
|
|
|
|
num_bytes = read(file_des, buffer, sizeof(buffer)); |
|
|
num_bytes = read(file_des, buffer, sizeof(buffer)); |
|
|
if (num_bytes < 0) { |
|
|
if (num_bytes < 0) { |
|
|
perror("Couldn't read from peer."); |
|
|
logE("Couldn't read from peer."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
// TODO maye be remove this?
|
|
|
// TODO maye be remove this?
|
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} else if (num_bytes == 0) { |
|
|
} else if (num_bytes == 0) { |
|
@ -269,25 +297,30 @@ int read_from_peer(int file_des, uint16_t max_line, cbuf_handle_t *message_buffe |
|
|
|
|
|
|
|
|
uint16_t fread_neighbors(char *AEM_file, node_handle_t **neighbors, port_t port) { |
|
|
uint16_t fread_neighbors(char *AEM_file, node_handle_t **neighbors, port_t port) { |
|
|
assert(AEM_file && neighbors); |
|
|
assert(AEM_file && neighbors); |
|
|
|
|
|
|
|
|
|
|
|
logI("Reading peers from file."); |
|
|
|
|
|
|
|
|
uint16_t num_neighbors = 0; |
|
|
uint16_t num_neighbors = 0; |
|
|
|
|
|
|
|
|
// Reads the ARP file checking for connected devices
|
|
|
// Reads the ARP file checking for connected devices
|
|
|
FILE *aems_file = fopen(AEM_file, "r"); |
|
|
FILE *aems_file = fopen(AEM_file, "r"); |
|
|
if (!aems_file) { |
|
|
if (!aems_file) { |
|
|
perror("Neighbors file: Failed to open file containing the AEMs."); |
|
|
logE("Neighbors file: Failed to open file containing the AEMs."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Extracts IP addresses found in the file
|
|
|
// Extracts IP addresses found in the file
|
|
|
char ip_addr[AEM_BUFFER_LEN]; |
|
|
char ip_addr[AEM_BUFFER_LEN]; |
|
|
char **neighbors_ips; |
|
|
char **neighbors_ips = NULL; |
|
|
while (1 == fscanf(aems_file, AEM_LINE_FORMAT, ip_addr)) { |
|
|
while (1 == fscanf(aems_file, AEM_LINE_FORMAT, ip_addr)) { |
|
|
++num_neighbors; |
|
|
++num_neighbors; |
|
|
|
|
|
|
|
|
char **r_neighbors_ips = realloc(neighbors_ips, num_neighbors * sizeof(char *)); |
|
|
char **r_neighbors_ips = realloc(neighbors_ips, num_neighbors * sizeof(char *)); |
|
|
if (!r_neighbors_ips) { |
|
|
if (!r_neighbors_ips) { |
|
|
free(r_neighbors_ips); |
|
|
free(r_neighbors_ips); |
|
|
perror("Unable to reallocate memory for neighbor IP."); |
|
|
logE("Unable to reallocate memory for neighbor IP."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -300,16 +333,16 @@ uint16_t fread_neighbors(char *AEM_file, node_handle_t **neighbors, port_t port) |
|
|
// Allocates memory for the new neighbors structs
|
|
|
// Allocates memory for the new neighbors structs
|
|
|
(*neighbors) = (node_handle_t *) malloc(num_neighbors * sizeof(node_handle_t)); |
|
|
(*neighbors) = (node_handle_t *) malloc(num_neighbors * sizeof(node_handle_t)); |
|
|
if (!neighbors_ips) { |
|
|
if (!neighbors_ips) { |
|
|
perror("Unable to allocate memory for nodes."); |
|
|
logE("Unable to allocate memory for nodes."); |
|
|
|
|
|
logI("Exiting..."); |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Creates the neighbors structs
|
|
|
// Creates the neighbors structs
|
|
|
for (uint8_t i = 0; i < num_neighbors; ++i) { |
|
|
for (uint8_t i = 0; i < num_neighbors; ++i) { |
|
|
address_t peer_name; |
|
|
address_t peer_name; |
|
|
init_sockaddr(&peer_name, neighbors_ips[i], port); |
|
|
init_sockaddr(&peer_name, build_ip_from_id(neighbors_ips[i]), port); |
|
|
(*neighbors)[num_neighbors++] = node_init(peer_name, |
|
|
(*neighbors)[i] = node_init(peer_name, atoi(neighbors_ips[i])); |
|
|
extract_id_from_ip(get_ip_from_sockaddr(peer_name))); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fclose(aems_file); |
|
|
fclose(aems_file); |
|
@ -322,7 +355,6 @@ uint16_t fread_neighbors(char *AEM_file, node_handle_t **neighbors, port_t port) |
|
|
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
|
|
|
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
|
|
|
*/ |
|
|
*/ |
|
|
void init_sockaddr(address_t *peer_name, const ipv4_t hostname, port_t port) { |
|
|
void init_sockaddr(address_t *peer_name, const ipv4_t hostname, port_t port) { |
|
|
assert(peer_name && hostname); |
|
|
|
|
|
struct hostent *hostinfo; |
|
|
struct hostent *hostinfo; |
|
|
|
|
|
|
|
|
peer_name->sin_family = AF_INET; |
|
|
peer_name->sin_family = AF_INET; |
|
@ -335,3 +367,32 @@ void init_sockaddr(address_t *peer_name, const ipv4_t hostname, port_t port) { |
|
|
|
|
|
|
|
|
peer_name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0]; |
|
|
peer_name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char *build_ip_from_id(char *id) { |
|
|
|
|
|
static char ip[11]; |
|
|
|
|
|
node_id_t id_int = atoi(id); |
|
|
|
|
|
|
|
|
|
|
|
snprintf(ip, 11, "10.0.%2d.%2d", id_int / 100, id_int % 100); |
|
|
|
|
|
|
|
|
|
|
|
return ip; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void _zlog(LOG_LEVEL level, char *message, char *file, int line) { |
|
|
|
|
|
switch(level) { |
|
|
|
|
|
case DEBUG: |
|
|
|
|
|
printf(CYAN_BOLD "debug: %s:%d - %s\n" COLOR_RESET, file, line, message); |
|
|
|
|
|
break; |
|
|
|
|
|
case INFO: |
|
|
|
|
|
printf(BLUE_BOLD "info: %s:%d - %s\n" COLOR_RESET, file, line, message); |
|
|
|
|
|
break; |
|
|
|
|
|
case WARN: |
|
|
|
|
|
printf(YELLOW_BOLD "warn: %s:%d - %s\n" COLOR_RESET, file, line, message); |
|
|
|
|
|
break; |
|
|
|
|
|
case ERROR: |
|
|
|
|
|
printf(RED_BOLD "error: %s:%d - %s\n" COLOR_RESET, file, line, message); |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
printf("%s:%d - %s\n", file, line, message); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|