|
|
@ -35,7 +35,7 @@ void enable_echo_broadcast(void) { |
|
|
|
* Function based on this snippet: |
|
|
|
* https://codereview.stackexchange.com/a/58107
|
|
|
|
*/ |
|
|
|
void search_for_neighbors(void) { |
|
|
|
void search_for_neighbors(node_handle_t **neighbors, uint16_t *num_neighbors, uint16_t port) { |
|
|
|
// Broadcasts ping
|
|
|
|
if (system("ping -b 10.255.255.255 -c 3 > /dev/null") < 0) { |
|
|
|
perror("Couldn't broadcast echo."); |
|
|
@ -58,14 +58,94 @@ void search_for_neighbors(void) { |
|
|
|
|
|
|
|
// Extracts IP addresses found in the file
|
|
|
|
char ipAddr[ARP_BUFFER_LEN]; |
|
|
|
char **neighbors_ips = (char **) malloc(sizeof(char *)); |
|
|
|
if (!neighbors_ips) { |
|
|
|
perror("Unable to allocate memory for neighbor IP."); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
int count = 0; |
|
|
|
while (1 == fscanf(arpCache, ARP_LINE_FORMAT, ipAddr)) { |
|
|
|
printf("%03d: [%s]\n", ++count, ipAddr); |
|
|
|
++count; |
|
|
|
if (count > 1){ |
|
|
|
char **r_neighbors_ips = realloc(neighbors_ips, count * sizeof(char *)); |
|
|
|
if (!r_neighbors_ips) { |
|
|
|
free(r_neighbors_ips); |
|
|
|
perror("Unable to reallocate memory for neighbor IP."); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
neighbors_ips = r_neighbors_ips; |
|
|
|
} |
|
|
|
|
|
|
|
neighbors_ips[count - 1] = (char *) malloc(ARP_BUFFER_LEN * sizeof(char)); |
|
|
|
strcpy(neighbors_ips[count - 1], ipAddr); |
|
|
|
} |
|
|
|
|
|
|
|
// Allocates memory for the new neighbors structs
|
|
|
|
if (!(*num_neighbors)) { |
|
|
|
// Neighbors array came empty
|
|
|
|
(*neighbors) = (node_handle_t *) malloc(count * sizeof(node_handle_t)); |
|
|
|
if (!neighbors_ips) { |
|
|
|
perror("Unable to allocate memory for nodes."); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
} else { |
|
|
|
node_handle_t *r_neighbors = realloc((*neighbors), count * sizeof(node_handle_t)); |
|
|
|
if (!r_neighbors) { |
|
|
|
free(r_neighbors); |
|
|
|
perror("Unable to reallocate memory for nodes."); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
(*neighbors) = r_neighbors; |
|
|
|
} |
|
|
|
|
|
|
|
// Adds new event timestamps to neighbors structs
|
|
|
|
for (uint8_t i = 0; i < count; ++i) { |
|
|
|
bool found_flag = false; |
|
|
|
|
|
|
|
for (uint8_t j = 0; j < (*num_neighbors); ++j) { |
|
|
|
if (!strcmp(inet_ntoa(node_get_addr((*neighbors)[j]).sin_addr), |
|
|
|
neighbors_ips[i])) { |
|
|
|
bool node_alive = check_node_alive(neighbors_ips[i]); |
|
|
|
node_add_timestamp((*neighbors)[i], time(NULL), node_alive); |
|
|
|
|
|
|
|
found_flag = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!found_flag) { |
|
|
|
// New node found!
|
|
|
|
printf("Adding %s\n", neighbors_ips[i]); |
|
|
|
struct sockaddr_in peer_name; |
|
|
|
init_sockaddr(&peer_name, neighbors_ips[i], port); |
|
|
|
(*neighbors)[(*num_neighbors)++] = node_init(peer_name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!((*num_neighbors) == count)) { |
|
|
|
(*num_neighbors) = count; |
|
|
|
} |
|
|
|
|
|
|
|
fclose(arpCache); |
|
|
|
} |
|
|
|
|
|
|
|
bool check_node_alive(const char *ipv4) { |
|
|
|
char command[64]; |
|
|
|
|
|
|
|
snprintf(command, 64, "ping %s -c 1 -W 1 | grep \"1 received\" > /dev/null", ipv4); |
|
|
|
|
|
|
|
int call_res = system(command); |
|
|
|
if (call_res < 0) { |
|
|
|
perror("Couldn't ping node."); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
return call_res == 0; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Function based on this example: |
|
|
|
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
|
|
|
@ -100,9 +180,8 @@ int create_socket_and_listen(uint16_t port, uint8_t backlog_size) { |
|
|
|
return in_sock; |
|
|
|
} |
|
|
|
|
|
|
|
void send_message(const char *ipv4, uint16_t port, const char *message) { |
|
|
|
void send_message(struct sockaddr_in peer_name, const char *message) { |
|
|
|
int out_sock; |
|
|
|
struct sockaddr_in peer_name; |
|
|
|
|
|
|
|
// Creates the socket
|
|
|
|
out_sock = socket(PF_INET, SOCK_STREAM, 0); |
|
|
@ -112,7 +191,6 @@ void send_message(const char *ipv4, uint16_t port, const char *message) { |
|
|
|
} |
|
|
|
|
|
|
|
// Connects to the peer
|
|
|
|
init_sockaddr(&peer_name, ipv4, port); |
|
|
|
if (connect(out_sock, (struct sockaddr *) &peer_name, sizeof(peer_name))) { |
|
|
|
printf("Couldn't connect to the peer.\n"); |
|
|
|
} else { |
|
|
|