Commit d0ca0fdd authored by xpetrak2's avatar xpetrak2 Committed by xHire
Browse files

neighbours: implmeneted usage of linkedlist

parent cf351b92
...@@ -21,52 +21,106 @@ ...@@ -21,52 +21,106 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "linkedlist.h"
#include "neighbours.h" #include "neighbours.h"
void neighbours_init(struct s_neighbours *neighbours) /**
* Initialize the linked list of neighbours to default values.
*
* @param neighbours Linked list to be initialized.
*/
void neighbours_init(linkedlist_t *neighbours)
{ {
neighbours->first = neighbours->last = NULL; linkedlist_init(neighbours);
neighbours->size = 0;
} }
struct s_neighbour *find_neighbour(const struct s_neighbours *neighbours, /**
const struct bufferevent *bev) * Find neighbour in neighbours based on their bufferevent.
*
* @param neighbours Linked list of our neighbours.
* @param bev Neighbour's bufferevent.
*
* @return Desired neighbour.
* @return NULL if not found.
*/
neighbour_t *find_neighbour(const linkedlist_t *neighbours,
const struct bufferevent *bev)
{ {
struct s_neighbour *current = neighbours->first; /* start the search from the first linked list node */
const linkedlist_node_t *current = linkedlist_get_first(neighbours);
while (current != NULL) { while (current != NULL) {
if (current->buffer_event == bev) {
return current; /* data of the 'current' node; struct s_neighbour */
neighbour_t *current_data = (neighbour_t *) current->data;
/* bufferevents equal => neighbour found */
if (current_data->buffer_event == bev) {
/* return node's data; struct s_neighbour */
return current_data;
} }
current = current->next;
/* get next node in the linked list */
current = linkedlist_get_next(neighbours, current);
} }
return NULL; return NULL;
} }
struct s_neighbour *find_neighbour_by_ip(const struct s_neighbours *neighbours, /**
const char *ip_addr) * Find neighbour in neighbours based on their ip_addr.
*
* @param neighbours Linked list of our neighbours.
* @param ip_addr Binary ip address stored in 16 bytes.
*
* @return Desired neighbour.
* @return NULL if not found.
*/
neighbour_t *find_neighbour_by_ip(const linkedlist_t *neighbours,
const unsigned char *ip_addr)
{ {
struct s_neighbour *current = neighbours->first; /* start the search from the first linked list node */
const linkedlist_node_t *current = linkedlist_get_first(neighbours);
while (current != NULL) { while (current != NULL) {
if (strcmp(current->ip_addr, ip_addr) == 0) {
return current; /* data of the 'current' node; struct s_neighbour */
neighbour_t *current_data = (neighbour_t *) current->data;
/* ip addresses match => neighbour found */
if (memcmp(current_data->ip_addr, ip_addr, 16) == 0) {
/* return node's data; struct s_neighbour */
return current_data;
} }
current = current->next;
/* get next node in the linked list */
current = linkedlist_get_next(neighbours, current);
} }
return NULL; return NULL;
} }
struct s_neighbour *add_new_neighbour(struct s_neighbours *neighbours, /**
const char *ip_addr, * Add new neighbour into neighbours.
struct bufferevent *bev) *
* @param neighbours Linked list of our neighbours.
* @param ip_addr Binary ip address stored in 16 bytes.
* @param bev Neighbour's bufferevent.
*
* @return Newly added neighbour.
* @return NULL if neighbour already exists or allocation failure occured.
*/
neighbour_t *add_new_neighbour(linkedlist_t *neighbours,
const unsigned char *ip_addr,
struct bufferevent *bev)
{ {
struct s_neighbour *new_neighbour; /* create new neighbour */
neighbour_t *new_neighbour;
new_neighbour = (struct s_neighbour *) new_neighbour = (neighbour_t *) malloc(sizeof(neighbour_t));
malloc(sizeof(struct s_neighbour));
/* allocation failure */
if (new_neighbour == NULL) { if (new_neighbour == NULL) {
/* WIP */ /* WIP */
perror("malloc for a new neighbour"); perror("malloc for a new neighbour");
...@@ -78,81 +132,86 @@ struct s_neighbour *add_new_neighbour(struct s_neighbours *neighbours, ...@@ -78,81 +132,86 @@ struct s_neighbour *add_new_neighbour(struct s_neighbours *neighbours,
return NULL; return NULL;
} }
/* TODO: comment why it is safe to use strcpy */ /* initialize new neighbour */
strcpy(new_neighbour->ip_addr, ip_addr); memcpy(new_neighbour->ip_addr, ip_addr, 16);
new_neighbour->failed_pings = 0; new_neighbour->failed_pings = 0;
new_neighbour->next = NULL;
new_neighbour->buffer_event = bev; new_neighbour->buffer_event = bev;
/* TODO: comment */ /* add new neighbour into linked list; NULL if allocation failed */
if (neighbours->last == NULL) { if (linkedlist_append(neighbours, new_neighbour) == NULL) {
neighbours->first = neighbours->last = new_neighbour; /* WIP */
} else { perror("malloc for a new neighbour of linkedlist node");
neighbours->last->next = new_neighbour; return NULL;
neighbours->last = new_neighbour;
} }
neighbours->size += 1;
return new_neighbour; return new_neighbour;
} }
void delete_neighbour(struct s_neighbours *neighbours, struct bufferevent *bev) /**
* Delete neighbour from neighbours.
*
* @param neighbours Linked list of our neighbours.
* @param bev Neighbour's bufferevent.
*/
void delete_neighbour(linkedlist_t *neighbours, struct bufferevent *bev)
{ {
struct s_neighbour *current = neighbours->first; neighbour_t *neighbour;
struct s_neighbour *neighbour = find_neighbour(neighbours, bev); linkedlist_node_t *neighbour_node;
if (current == NULL || neighbour == NULL) { neighbour = find_neighbour(neighbours, bev);
/* no neighbour with bufferevent 'bev' => nothing to delete */
if (neighbour == NULL) {
return; return;
} }
if (neighbour->buffer_event != NULL) { neighbour_node = linkedlist_find(neighbours, neighbour);
bufferevent_free(bev);
}
if (neighbours->first == neighbour) { /* since neighbour was found, neighbour_node should never be NULL */
if (neighbours->first == neighbours->last) { if (neighbour_node == NULL) {
neighbours->first = neighbours->last = NULL; /* WIP */
} else { perror("delete_neighbour");
neighbours->first = neighbours->first->next;
}
free(neighbour);
neighbours->size = 0;
return; return;
} }
while (current != NULL) { /* free neighbour's bufferevent */
if (current->next == neighbour) { bufferevent_free(bev);
current->next = neighbour->next;
if (current->next == NULL) { /* free the linked list node's data; neighbour_t * */
neighbours->last = current; free(neighbour_node->data);
}
free(neighbour); /* delete the neighbour from the linked list */
neighbours->size -= 1; linkedlist_delete(neighbours, neighbour_node);
break;
}
current = current->next;
}
} }
void clear_neighbours(struct s_neighbours *neighbours) /**
* Delete all neighbours.
*
* @param neighbours Linked list of our neighbours.
*/
void clear_neighbours(linkedlist_t *neighbours)
{ {
struct s_neighbour *current = neighbours->first; linkedlist_node_t *current_node = linkedlist_get_first(neighbours);
while (current != NULL) { /* safely delete data from the linked list nodes */
while (current_node != NULL) {
struct s_neighbour *temp = current; neighbour_t *current;
current = current->next;
if (temp->buffer_event != NULL) { /* load current node's data into 'current' */
bufferevent_free(temp->buffer_event); current = (neighbour_t *) current_node->data;
}
/* deallocate neighbour's bufferevent */
bufferevent_free(current->buffer_event);
/* deallocate data */
free(current_node->data);
current_node->data = NULL;
free(temp); /* get next node in the linked list */
current_node = linkedlist_get_next(neighbours, current_node);
} }
neighbours_init(neighbours); /* safely delete all nodes in the linked list */
linkedlist_destroy(neighbours);
} }
...@@ -22,55 +22,35 @@ ...@@ -22,55 +22,35 @@
#include <event2/bufferevent.h> #include <event2/bufferevent.h>
#include <stddef.h> #include <stddef.h>
/** data type for the linked list of neighbours */ #include "linkedlist.h"
struct s_neighbour {
/** neighbours's IPv6 address;
* also allows storing IPv4-mapped IPv6 addresses */
char ip_addr[46];
/** bufferevent belonging to this neighbour */ /** Data type for the linked list of neighbours. */
typedef struct s_neighbour {
/**< Neighbours's IPv6 address;
* also allows storing IPv4-mapped IPv6 addresses. */
unsigned char ip_addr[16];
/**< Bufferevent belonging to this neighbour. */
struct bufferevent *buffer_event; struct bufferevent *buffer_event;
/** number of failed ping attempts -- max 3, then disconnect */ /**< Number of failed ping attempts -- max 3, then disconnect. */
size_t failed_pings; size_t failed_pings;
} neighbour_t;
/** next neighbour in the linked list (struct s_neighbours) */ void neighbours_init(linkedlist_t *neighbours);
struct s_neighbour *next;
};
/** linked list of neighbours */
struct s_neighbours {
/** number of neighbours we are connected to */
size_t size;
struct s_neighbour *first;
struct s_neighbour *last;
};
/** set linked list variables to their default values */
void neighbours_init(struct s_neighbours *neighbours);
/** find neighbour in neighbours based on their buffer_event, neighbour_t *find_neighbour(const linkedlist_t *neighbours,
returns NULL if not found */ const struct bufferevent *bev);
struct s_neighbour *find_neighbour(const struct s_neighbours *neighbours,
const struct bufferevent *bev);
/** find neighbour in neighbours based on their ip_addr, neighbour_t *find_neighbour_by_ip(const linkedlist_t *neighbours,
returns NULL if not found */ const unsigned char *ip_addr);
struct s_neighbour *find_neighbour_by_ip(const struct s_neighbours *neighbours,
const char *ip_addr);
/** add new neighbour into neighbours neighbour_t *add_new_neighbour(linkedlist_t *neighbours,
returns NULL if neighbour already exists */ const unsigned char *ip_addr,
struct s_neighbour *add_new_neighbour(struct s_neighbours *neighbours, struct bufferevent *bev);
const char *ip_addr,
struct bufferevent *bev);
/* delete neighbour from neighbours */ void delete_neighbour(linkedlist_t *neighbours, struct bufferevent *bev);
void delete_neighbour(struct s_neighbours *neighbours,
struct bufferevent *bev);
/* delete all neighbours */ void clear_neighbours(linkedlist_t *neighbours);
void clear_neighbours(struct s_neighbours *neighbours);
#endif /* NEIGHBOURS_H */ #endif /* NEIGHBOURS_H */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment