Browse Source

Socket communication fixes

master
Apostolos Fanakis 6 years ago
parent
commit
1b9253348d
  1. 88
      lib/helpers.c
  2. 10
      lib/helpers.h
  3. 2
      lib/node.c
  4. 21
      src/zaqar.c
  5. 1
      src/zaqar.h

88
lib/helpers.c

@ -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 {

10
lib/helpers.h

@ -14,6 +14,9 @@
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include "node.h"
// Macros to turn a numeric macro into a string literal
#define xstr(s) str(s)
@ -23,6 +26,7 @@
#define ARP_CACHE "/proc/net/arp"
#define ARP_STRING_LEN 1023
#define ARP_BUFFER_LEN (ARP_STRING_LEN + 1)
#define PING_BUFFER_LEN 1024
// Format for fscanf() to read the 1st field of ARP
#define ARP_LINE_FORMAT "%" xstr(ARP_STRING_LEN) "s %*s %*s %*s %*s %*s"
@ -31,11 +35,13 @@ void set_timer_and_handler(void (*handler)(int), long int timer_interval);
void enable_echo_broadcast(void);
void search_for_neighbors(void);
void search_for_neighbors(node_handle_t **neighbors, uint16_t *num_neighbors, uint16_t port);
bool check_node_alive(const char *ipv4);
int create_socket_and_listen(uint16_t port, uint8_t backlog_size);
void send_message(const char *ipv4, uint16_t port, const char *message);
void send_message(struct sockaddr_in peer_name, const char *message);
void accept_connection(int sock, struct sockaddr_in *client_name, fd_set *active_fd_set);

2
lib/node.c

@ -5,8 +5,6 @@
#include "node.h"
//enum node_status { NODE_INITIALIAZED, NODE_PRESENT, NODE_GONE };
// Defines the node structure
struct node_t {
struct sockaddr_in addr;

21
src/zaqar.c

@ -8,13 +8,17 @@ int main(void) {
int in_sock;
fd_set active_fd_set, read_fd_set;
struct sockaddr_in peer_name;
node_handle_t *neighbors;
uint16_t num_neighbors = 0;
// Sets a timer and handler to produce interrupts for sending messages
set_timer_and_handler(handle_alarm, TIMER_INTERVAL);
// Enables echo broadcast pings
enable_echo_broadcast();
// Searches network for neighbors
enable_echo_broadcast();
search_for_neighbors();
search_for_neighbors(&neighbors, &num_neighbors, PORT);
// Sets a timer and handler to produce interrupts for sending messages
set_timer_and_handler(handle_alarm, TIMER_INTERVAL);
// Creates a socket and sets it up to accept connections
in_sock = create_socket_and_listen(PORT, BACKLOG_SIZE);
@ -28,7 +32,14 @@ int main(void) {
while (1) {
if (sigalrm_flag) {
// It's time to send a message!
send_message("10.0.82.61", PORT, MESSAGE);
search_for_neighbors(&neighbors, &num_neighbors, PORT);
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);
}
}
sigalrm_flag = false;
}

1
src/zaqar.h

@ -16,6 +16,7 @@
#include <sys/signalfd.h>
#include "helpers.h"
#include "node.h"
#define TIMER_INTERVAL 10
#define PORT 5000

Loading…
Cancel
Save