Browse Source

Work on p2p socket communication, Stylistic changes

master
Apostolos Fanakis 6 years ago
parent
commit
1a33ea4c39
  1. 32
      lib/circ_buff.c
  2. 20
      lib/circ_buff.h
  3. 169
      lib/helpers.c
  4. 31
      lib/helpers.h
  5. 6
      lib/node.c
  6. 8
      lib/node.h
  7. 145
      src/zaqar.c
  8. 6
      src/zaqar.h

32
lib/circ_buff.c

@ -10,7 +10,7 @@
// Defines the circular buffer structure // Defines the circular buffer structure
struct circ_buf_t { struct circ_buf_t {
char** buffer; char **buffer;
size_t head; size_t head;
size_t tail; size_t tail;
size_t max; // of the buffer size_t max; // of the buffer
@ -45,7 +45,7 @@ unit_static void retreat_pointer(cbuf_handle_t cbuf) {
// not exist on cbuf1 are added to the array add1. // not exist on cbuf1 are added to the array add1.
// Both buffers must be ordered on the same way! // Both buffers must be ordered on the same way!
unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2, unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
char*** add1, char*** add2) { char ***add1, char ***add2) {
assert(cbuf1 && cbuf2 && assert(cbuf1 && cbuf2 &&
(circ_buf_element_size(cbuf1) == circ_buf_element_size(cbuf2)) && (circ_buf_element_size(cbuf1) == circ_buf_element_size(cbuf2)) &&
(circ_buf_capacity(cbuf1) == circ_buf_capacity(cbuf2))); (circ_buf_capacity(cbuf1) == circ_buf_capacity(cbuf2)));
@ -54,8 +54,8 @@ unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
(*add1) = (char **) malloc(circ_buf_capacity(cbuf2) * sizeof(char *)); (*add1) = (char **) malloc(circ_buf_capacity(cbuf2) * sizeof(char *));
(*add2) = (char **) malloc(circ_buf_capacity(cbuf1) * 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_str1 = (char*) malloc(circ_buf_element_size(cbuf1) * sizeof(char));
char* curr_str2 = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char)); char *curr_str2 = (char*) malloc(circ_buf_element_size(cbuf2) * sizeof(char));
/*uint8_t diff_array_index = 0; /*uint8_t diff_array_index = 0;
for (uint8_t i = 0; i < circ_buf_size(cbuf1); ++i) { for (uint8_t i = 0; i < circ_buf_size(cbuf1); ++i) {
// Reads current element of cbuf1 // Reads current element of cbuf1
@ -176,7 +176,7 @@ unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2,
// APIs // APIs
cbuf_handle_t circ_buf_init(char** buffer, size_t size, size_t element_size) { cbuf_handle_t circ_buf_init(char **buffer, size_t size, size_t element_size) {
assert(buffer && size); assert(buffer && size);
cbuf_handle_t cbuf = malloc(sizeof(circ_buf_t)); cbuf_handle_t cbuf = malloc(sizeof(circ_buf_t));
@ -228,7 +228,7 @@ size_t circ_buf_capacity(cbuf_handle_t cbuf) {
return cbuf->max; return cbuf->max;
} }
void circ_buf_put(cbuf_handle_t cbuf, const char* data) { void circ_buf_put(cbuf_handle_t cbuf, const char *data) {
assert(cbuf && cbuf->buffer); assert(cbuf && cbuf->buffer);
strcpy(cbuf->buffer[cbuf->head], data); strcpy(cbuf->buffer[cbuf->head], data);
@ -236,13 +236,13 @@ void circ_buf_put(cbuf_handle_t cbuf, const char* data) {
advance_pointer(cbuf); advance_pointer(cbuf);
} }
void circ_buf_mul_add(cbuf_handle_t cbuf, char** data, uint8_t size, void circ_buf_mul_add(cbuf_handle_t cbuf, char **data, uint8_t size,
int (*compar)(const void* , const void*)) { int (*compar)(const void *, const void *)) {
assert(cbuf && data && cbuf->buffer); assert(cbuf && data && cbuf->buffer);
qsort(data, size, sizeof(char*), compar); qsort(data, size, sizeof(char*), compar);
char* last_element = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char)); char *last_element = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char));
for (uint8_t i = 0; i < size; ++i) { for (uint8_t i = 0; i < size; ++i) {
circ_buf_read(cbuf, 0, last_element); circ_buf_read(cbuf, 0, last_element);
@ -256,7 +256,7 @@ void circ_buf_mul_add(cbuf_handle_t cbuf, char** data, uint8_t size,
free(last_element); free(last_element);
int end_buffer_size = circ_buf_size(cbuf); int end_buffer_size = circ_buf_size(cbuf);
char** temp_array = (char **) malloc(end_buffer_size * sizeof(char *)); char **temp_array = (char **) malloc(end_buffer_size * sizeof(char *));
for (uint8_t buff_el = 0; buff_el < end_buffer_size; ++buff_el) { for (uint8_t buff_el = 0; buff_el < end_buffer_size; ++buff_el) {
temp_array[buff_el] = (char *) malloc(circ_buf_element_size(cbuf) * sizeof(char)); temp_array[buff_el] = (char *) malloc(circ_buf_element_size(cbuf) * sizeof(char));
circ_buf_get(cbuf, temp_array[buff_el]); circ_buf_get(cbuf, temp_array[buff_el]);
@ -274,7 +274,7 @@ void circ_buf_mul_add(cbuf_handle_t cbuf, char** data, uint8_t size,
free(temp_array); free(temp_array);
} }
int circ_buf_get(cbuf_handle_t cbuf, char* data) { int circ_buf_get(cbuf_handle_t cbuf, char *data) {
assert(cbuf && data && cbuf->buffer); assert(cbuf && data && cbuf->buffer);
int r = -1; int r = -1;
@ -289,7 +289,7 @@ int circ_buf_get(cbuf_handle_t cbuf, char* data) {
return r; return r;
} }
int circ_buf_read(cbuf_handle_t cbuf, size_t position, char* data) { int circ_buf_read(cbuf_handle_t cbuf, size_t position, char *data) {
assert(cbuf && data && cbuf->buffer && (position < circ_buf_size(cbuf))); assert(cbuf && data && cbuf->buffer && (position < circ_buf_size(cbuf)));
int r = -1; int r = -1;
@ -303,8 +303,8 @@ int circ_buf_read(cbuf_handle_t cbuf, size_t position, char* data) {
return r; return r;
} }
int circ_buf_serialize(cbuf_handle_t cbuf, char** serialized) { int circ_buf_serialize(cbuf_handle_t cbuf, char **serialized) {
char* temp = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char)); char *temp = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char));
const char separator[2] = "\r"; const char separator[2] = "\r";
uint8_t char_sum = circ_buf_size(cbuf) - 1; uint8_t char_sum = circ_buf_size(cbuf) - 1;
uint8_t i; uint8_t i;
@ -331,11 +331,11 @@ int circ_buf_serialize(cbuf_handle_t cbuf, char** serialized) {
return strlen((*serialized)); return strlen((*serialized));
} }
int circ_buf_deserialize(cbuf_handle_t cbuf, const char* serialized) { int circ_buf_deserialize(cbuf_handle_t cbuf, const char *serialized) {
char *str = calloc(strlen(serialized) + 1, sizeof(char)); char *str = calloc(strlen(serialized) + 1, sizeof(char));
strcpy(str, serialized); strcpy(str, serialized);
const char separator[2] = "\r"; const char separator[2] = "\r";
char* token; char *token;
token = strtok(str, separator); token = strtok(str, separator);

20
lib/circ_buff.h

@ -13,21 +13,21 @@
// Circular buffer structure // Circular buffer structure
typedef struct circ_buf_t circ_buf_t; typedef struct circ_buf_t circ_buf_t;
// and handle type // and handle type
typedef circ_buf_t* cbuf_handle_t; typedef circ_buf_t *cbuf_handle_t;
#ifdef TEST //This is a test build #ifdef TEST //This is a test build
// Makes private functions reachable by the tester // Makes private functions reachable by the tester
#define unit_static #define unit_static
unit_static void advance_pointer(cbuf_handle_t cbuf); unit_static void advance_pointer(cbuf_handle_t cbuf);
unit_static void retreat_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); unit_static void diff_bufs(cbuf_handle_t cbuf1, cbuf_handle_t cbuf2, char ***add1, char ***add2);
#else #else
#define unit_static static #define unit_static static
#endif #endif
// Initializes a circular buffer structure and returns the circular buffer handle. // Initializes a circular buffer structure and returns the circular buffer handle.
// Pass in a storage buffer and size. // Pass in a storage buffer and size.
cbuf_handle_t circ_buf_init(char** buffer, size_t size, size_t element_size); cbuf_handle_t circ_buf_init(char **buffer, size_t size, size_t element_size);
// Frees a circular buffer structure. Does not free data buffer! // Frees a circular buffer structure. Does not free data buffer!
void circ_buf_free(cbuf_handle_t cbuf); void circ_buf_free(cbuf_handle_t cbuf);
@ -36,25 +36,25 @@ void circ_buf_free(cbuf_handle_t cbuf);
void circ_buf_reset(cbuf_handle_t cbuf); void circ_buf_reset(cbuf_handle_t cbuf);
// Adds data to the end of the buffer, even if the buffer is full. Old data is overwritten. // Adds data to the end of the buffer, even if the buffer is full. Old data is overwritten.
void circ_buf_put(cbuf_handle_t cbuf, const char* data); void circ_buf_put(cbuf_handle_t cbuf, const char *data);
// Adds multiple entries to the buffer, keeping the data in ascending order according to the // Adds multiple entries to the buffer, keeping the data in ascending order according to the
// function compar provided in the parameters. If the buffer is full, smallest data are overwritten. // function compar provided in the parameters. If the buffer is full, smallest data are overwritten.
// Doesn't check for duplicates! // Doesn't check for duplicates!
void circ_buf_mul_add(cbuf_handle_t cbuf, char** data, uint8_t size, void circ_buf_mul_add(cbuf_handle_t cbuf, char **data, uint8_t size,
int (*compar)(const void* , const void*)); int (*compar)(const void *, const void *));
// Retrieves a value from the buffer. // Retrieves a value from the buffer.
int circ_buf_get(cbuf_handle_t cbuf, char* data); int circ_buf_get(cbuf_handle_t cbuf, char *data);
// Reads a value from the buffer. Does NOT retrieve, size is not reduced! // 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); int circ_buf_read(cbuf_handle_t cbuf, size_t position, char *data);
// Serializes the whole buffer to a single string // Serializes the whole buffer to a single string
int circ_buf_serialize(cbuf_handle_t cbuf, char** serialized); int circ_buf_serialize(cbuf_handle_t cbuf, char **serialized);
// De-serializes a string to a buffer // De-serializes a string to a buffer
int circ_buf_deserialize(cbuf_handle_t cbuf, const char* serialized); int circ_buf_deserialize(cbuf_handle_t cbuf, const char *serialized);
// Checks if the buffer is empty. // Checks if the buffer is empty.
bool circ_buf_empty(cbuf_handle_t cbuf); bool circ_buf_empty(cbuf_handle_t cbuf);

169
lib/helpers.c

@ -1,56 +1,179 @@
#include "helpers.h" #include "helpers.h"
int create_socket(uint16_t port) { void set_timer_and_handler(void (*handler)(int), long int timer_interval) {
int sock; struct itimerval interval_timer;
struct sockaddr_in socket_name; struct sigaction signal_action;
// Installs handler as the signal handler for SIGALRM
memset(&signal_action, 0, sizeof(signal_action));
signal_action.sa_handler = handler;
if (sigaction(SIGALRM, &signal_action, NULL)) {
perror("Couldn't install function handler for SIGALRM signals.");
exit(EXIT_FAILURE);
}
// Sets an interval timer to deliver a SIGALRM signal every timer_interval seconds
interval_timer.it_interval.tv_usec = 0;
interval_timer.it_interval.tv_sec = timer_interval;
interval_timer.it_value.tv_usec = 0;
interval_timer.it_value.tv_sec = timer_interval;
if (setitimer(ITIMER_REAL, &interval_timer, NULL) == -1) {
perror("Couldn't set timer.");
exit(EXIT_FAILURE);
}
}
void enable_echo_broadcast(void) {
if (system("echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts") < 0) {
perror("Couldn't allow echo broadcasts.");
exit(EXIT_FAILURE);
}
}
/*
* Function based on this snippet:
* https://codereview.stackexchange.com/a/58107
*/
void search_for_neighbors(void) {
// Broadcasts ping
if (system("ping -b 10.255.255.255 -c 3 > /dev/null") < 0) {
perror("Couldn't broadcast echo.");
exit(EXIT_FAILURE);
}
// Reads the ARP file checking for connected devices
FILE *arpCache = fopen(ARP_CACHE, "r");
if (!arpCache) {
perror("ARP Cache: Failed to open file \"" ARP_CACHE "\"");
exit(EXIT_FAILURE);
}
// Ignores the first line, which contains the header
char header[ARP_BUFFER_LEN];
if (!fgets(header, sizeof(header), arpCache)) {
perror("Couldn't read ARP file header.");
exit(EXIT_FAILURE);
}
// Extracts IP addresses found in the file
char ipAddr[ARP_BUFFER_LEN];
int count = 0;
while (1 == fscanf(arpCache, ARP_LINE_FORMAT, ipAddr)) {
printf("%03d: [%s]\n", ++count, ipAddr);
}
fclose(arpCache);
}
/*
* Function based on this example:
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
*/
int create_socket_and_listen(uint16_t port, uint8_t backlog_size) {
int in_sock;
struct sockaddr_in own_name;
// Creates the socket // Creates the socket
sock = socket (PF_INET, SOCK_STREAM, 0); //TODO: check if PF_INET is the right one in_sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock < 0) { if (in_sock < 0) {
perror("Couldn't create the socket."); perror("Couldn't create the socket.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Gives the socket a name // Gives the socket a name
socket_name.sin_family = AF_INET; own_name.sin_family = AF_INET;
socket_name.sin_port = htons(port); own_name.sin_port = htons(port);
socket_name.sin_addr.s_addr = htonl(INADDR_ANY); own_name.sin_addr.s_addr = htonl(INADDR_ANY);
// Binds own address structure to socket // Binds own address structure to socket
if (bind(sock, (struct sockaddr *) &socket_name, sizeof(socket_name)) < 0) { if (bind(in_sock, (struct sockaddr *) &own_name, sizeof(own_name)) < 0) {
perror("Couldn't bind the address structure to the socket."); perror("Couldn't bind the address structure to the socket.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return sock; if (listen(in_sock, backlog_size) < 0) {
perror("Couldn't listen for connections on the socket.");
exit(EXIT_FAILURE);
}
return in_sock;
}
void send_message(const char *ipv4, uint16_t port, const char *message) {
int out_sock;
struct sockaddr_in peer_name;
// Creates the socket
out_sock = socket(PF_INET, SOCK_STREAM, 0);
if (out_sock < 0) {
perror("Couldn't create the socket.");
exit(EXIT_FAILURE);
}
// 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 {
// Sends data to the peer
write_to_peer(out_sock, message);
}
close(out_sock);
}
void accept_connection(int sock, struct sockaddr_in *peer_name, fd_set *active_fd_set) {
size_t peer_name_size = sizeof((*peer_name));
int comm_socket = accept(sock, (struct sockaddr *) peer_name, &peer_name_size);
if (comm_socket < 0) {
perror("Couldn't accept the connection.");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Connected to host %s, port %hd.\n",
inet_ntoa((*peer_name).sin_addr), ntohs((*peer_name).sin_port));
FD_SET(comm_socket, active_fd_set);
}
void write_to_peer(int file_desc, const char *message) {
int num_bytes = write(file_desc, message, strlen(message) + 1);
if (num_bytes < 0) {
perror("Couldn't write to peer.");
exit(EXIT_FAILURE);
}
} }
int read_from_client(int file_des, uint16_t max_line) { int read_from_peer(int file_des, uint16_t max_line) {
char buffer[max_line]; char buffer[max_line];
int nbytes; int num_bytes;
nbytes = read(file_des, buffer, sizeof(buffer)); num_bytes = read(file_des, buffer, sizeof(buffer));
if (nbytes < 0) { if (num_bytes < 0) {
perror("Couldn't read from client."); perror("Couldn't read from peer.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (nbytes == 0) } else if (num_bytes == 0)
// End-of-file // End-of-file
return -1; return -1;
else { else {
fprintf(stderr, "Server: got message: `%s'\n", buffer); fprintf(stderr, "Got message: `%s'\n", buffer);
return 0; return 0;
} }
} }
void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port) { /*
* Function based on this example:
* https://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example
*/
void init_sockaddr(struct sockaddr_in *peer_name, const char *ipv4, uint16_t port) {
struct hostent *hostinfo; struct hostent *hostinfo;
name->sin_family = AF_INET; peer_name->sin_family = AF_INET;
name->sin_port = htons(port); peer_name->sin_port = htons(port);
hostinfo = gethostbyname(hostname); hostinfo = gethostbyname(ipv4);
if (hostinfo == NULL) { if (hostinfo == NULL) {
fprintf(stderr, "Unknown host %s.\n", hostname); fprintf(stderr, "Unknown host %s.\n", ipv4);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0]; peer_name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0];
} }

31
lib/helpers.h

@ -11,10 +11,37 @@
#include <netdb.h> #include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <string.h>
int create_socket(uint16_t port); // Macros to turn a numeric macro into a string literal
#define xstr(s) str(s)
#define str(s) #s
int read_from_client(int file_des, uint16_t max_line); // Neighbor discovery related definitions
#define ARP_CACHE "/proc/net/arp"
#define ARP_STRING_LEN 1023
#define ARP_BUFFER_LEN (ARP_STRING_LEN + 1)
// Format for fscanf() to read the 1st field of ARP
#define ARP_LINE_FORMAT "%" xstr(ARP_STRING_LEN) "s %*s %*s %*s %*s %*s"
void set_timer_and_handler(void (*handler)(int), long int timer_interval);
void enable_echo_broadcast(void);
void search_for_neighbors(void);
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 accept_connection(int sock, struct sockaddr_in *client_name, fd_set *active_fd_set);
void write_to_peer(int filedes, const char *message);
int read_from_peer(int file_des, uint16_t max_line);
void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port); void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port);

6
lib/node.c

@ -10,7 +10,7 @@
// Defines the node structure // Defines the node structure
struct node_t { struct node_t {
struct sockaddr_in addr; struct sockaddr_in addr;
uint64_t** events; uint64_t **events;
uint64_t appearance_duration; uint64_t appearance_duration;
uint8_t events_size; uint8_t events_size;
node_status _node_status; node_status _node_status;
@ -53,7 +53,7 @@ void node_add_timestamp(node_handle_t node, time_t timestamp, bool visible) {
} }
if (visible) { if (visible) {
int* realloc_r = realloc(node->events[0], node->events_size + 1); int *realloc_r = realloc(node->events[0], node->events_size + 1);
if (!realloc_r) { if (!realloc_r) {
node_free(node); node_free(node);
perror("Error trying to reallocate memory for event timestamps!"); perror("Error trying to reallocate memory for event timestamps!");
@ -108,7 +108,7 @@ uint8_t node_get_total_appearance_duration(node_handle_t node) {
return node->appearance_duration; return node->appearance_duration;
} }
uint8_t node_get_event_table(node_handle_t node, time_t*** event_table) { uint8_t node_get_event_table(node_handle_t node, time_t ***event_table) {
assert(node && event_table); assert(node && event_table);
if (node->events_size < 1) { if (node->events_size < 1) {

8
lib/node.h

@ -8,7 +8,7 @@
// Node structure // Node structure
typedef struct node_t node_t; typedef struct node_t node_t;
// and handle type // and handle type
typedef node_t* node_handle_t; typedef node_t *node_handle_t;
typedef enum node_status { NODE_INITIALIAZED, NODE_PRESENT, NODE_GONE } node_status; typedef enum node_status { NODE_INITIALIAZED, NODE_PRESENT, NODE_GONE } node_status;
@ -48,12 +48,12 @@ uint8_t node_get_latest_appearance_duration(node_handle_t node);
uint8_t node_get_total_appearance_duration(node_handle_t node); uint8_t node_get_total_appearance_duration(node_handle_t node);
// Returns the event timestamps table for this node. // Returns the event timestamps table for this node.
uint8_t node_get_event_table(node_handle_t node, time_t*** event_table); uint8_t node_get_event_table(node_handle_t node, time_t ***event_table);
// Serializes the whole node to a single string // Serializes the whole node to a single string
//int circ_buf_serialize(node_handle_t node, char** serialized); //int circ_buf_serialize(node_handle_t node, char **serialized);
// De-serializes a string to a node // De-serializes a string to a node
//int circ_buf_deserialize(node_handle_t node, const char* serialized); //int circ_buf_deserialize(node_handle_t node, const char *serialized);
#endif //NODE_H_ #endif //NODE_H_

145
src/zaqar.c

@ -2,154 +2,75 @@
#define MESSAGE "You got mail!!! xo xo xo" #define MESSAGE "You got mail!!! xo xo xo"
volatile sig_atomic_t out_flag = false; volatile sig_atomic_t sigalrm_flag = false;
void write_to_server(int filedes) {
int nbytes;
nbytes = write(filedes, MESSAGE, strlen(MESSAGE) + 1);
if (nbytes < 0) {
perror("write");
exit(EXIT_FAILURE);
}
}
void handle_alarm(int sig) {
if (sig == SIGALRM) {
out_flag = true;
int sock;
struct sockaddr_in servername;
printf("GOT_CL1\n");
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket (client)");
exit(EXIT_FAILURE);
}
/* Connect to the server. */
init_sockaddr (&servername, "10.0.88.79", PORT);
if (connect(sock, (struct sockaddr *) &servername, sizeof (servername))) {
printf("GOT_CL2\n");
//perror("connect (client)");
//exit(EXIT_FAILURE);
} else {
printf("GOT_CL3\n");
/* Send data to the server. */
write_to_server(sock);
}
//close (sock);
}
}
int main(void) { int main(void) {
int sock; int in_sock;
fd_set active_fd_set, read_fd_set; fd_set active_fd_set, read_fd_set;
struct sockaddr_in client_name; struct sockaddr_in peer_name;
size_t size;
alarm(0);
//signal(SIGALRM, handle_alarm);
struct itimerval new;
new.it_interval.tv_usec = 0;
new.it_interval.tv_sec = 8;
new.it_value.tv_usec = 0;
new.it_value.tv_sec = 8;
if (setitimer (ITIMER_REAL, &new, NULL) == -1) { // Sets a timer and handler to produce interrupts for sending messages
perror("Couldn't set timer."); set_timer_and_handler(handle_alarm, TIMER_INTERVAL);
exit(EXIT_FAILURE);
}
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
sigemptyset(&mask); // Searches network for neighbors
sigaddset(&mask, SIGALRM); enable_echo_broadcast();
/*if (sigprocmask(SIGALRM, &mask, NULL) == -1) search_for_neighbors();
perror("sigprocmask");*/
sfd = signalfd(-1, &mask, 0); // Creates a socket and sets it up to accept connections
if (sfd == -1) in_sock = create_socket_and_listen(PORT, BACKLOG_SIZE);
perror("signalfd");
// Creates the socket and sets it up to accept connections
sock = create_socket(PORT);
if (listen(sock, BACKLOG_SIZE) < 0) {
perror("Couldn't listen for connections on the socket.");
exit(EXIT_FAILURE);
}
printf("GOT_SV1\n");
// Initializes the set of active sockets // Initializes the set of active sockets
// Clears the descriptor set // Clears the descriptor set
FD_ZERO(&active_fd_set); FD_ZERO(&active_fd_set);
// Sets socket in active readset // Sets socket in active readset
FD_SET(sock, &active_fd_set); FD_SET(in_sock, &active_fd_set);
FD_SET(sfd, &active_fd_set);
while (1) { while (1) {
printf("GOT_SV2\n"); if (sigalrm_flag) {
// It's time to send a message!
send_message("10.0.82.61", PORT, MESSAGE);
sigalrm_flag = false;
}
// Shallow copies the readset // Shallow copies the readset
read_fd_set = active_fd_set; read_fd_set = active_fd_set;
// Blocks until input arrives on one or more active sockets // Blocks until input arrives on one or more active sockets
if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) { if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
if (out_flag) { // Handles the wake-up from alarm signal interrupts
printf("GOT_SV2.1\n"); if (sigalrm_flag) {
out_flag = false;
continue; continue;
} }
printf("GOT_SV2.2\n");
perror("Couldn't initiate synchronous I/O multiplexing."); perror("Couldn't initiate synchronous I/O multiplexing.");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Services all the sockets with input pending // Services all the sockets with input pending
for (int i = 0; i < FD_SETSIZE; ++i) { //TODO: is this needed? for (int i = 0; i < FD_SETSIZE; ++i) {
if (FD_ISSET(i, &read_fd_set)) { if (FD_ISSET(i, &read_fd_set)) {
printf("GOT_SV3\n"); if (i == in_sock) {
if (i == sock) {
// Connection request on original socket // Connection request on original socket
size = sizeof(client_name); accept_connection(in_sock, &peer_name, &active_fd_set);
int new = accept(sock, (struct sockaddr *) &client_name, &size);
if (new < 0) {
perror("Couldn't accept the connection.");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Server: connect from host %s, port %hd.\n",
inet_ntoa(client_name.sin_addr), ntohs(client_name.sin_port));
FD_SET(new, &active_fd_set);
} else if (i == sfd) {
ssize_t s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
perror("read");
if (fdsi.ssi_signo == SIGALRM) {
printf("Got SIGALRM\n");
handle_alarm(SIGALRM);
} else {
printf("Read unexpected signal\n");
}
} else { } else {
// Data arriving on an already-connected socket // Data arriving on an already-connected socket
if (read_from_client(i, MAXLINE) < 0) { if (read_from_peer(i, MAXLINE) < 0) {
close(i); close(i);
FD_CLR(i, &active_fd_set); FD_CLR(i, &active_fd_set);
} }
} }
} }
} }
printf("GOT_SV4\n");
} }
return 0; return 0;
} }
void handle_alarm(int sig) {
if (sig != SIGALRM) {
return;
} else {
sigalrm_flag = true;
}
}

6
src/zaqar.h

@ -2,8 +2,6 @@
#define ZAQAR_H_ #define ZAQAR_H_
#include <stdbool.h> #include <stdbool.h>
#include <signal.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
@ -14,14 +12,16 @@
#include <netdb.h> #include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h>
#include <sys/signalfd.h> #include <sys/signalfd.h>
#include "helpers.h" #include "helpers.h"
#define TIMER_INTERVAL 10
#define PORT 5000 #define PORT 5000
#define MAXLINE 1024 #define MAXLINE 1024
#define BACKLOG_SIZE 2 #define BACKLOG_SIZE 2
void handle_alarm(int sig);
#endif //ZAQAR_H_ #endif //ZAQAR_H_

Loading…
Cancel
Save