Commit 28cddc31 authored by xpetrak2's avatar xpetrak2
Browse files

Global state detached from p2p.h and daemon events

parent 49b420dd
......@@ -6,7 +6,9 @@ src_coincerd_SOURCES = \
src/coincerd.c \
src/configuration.c src/configuration.h \
src/crypto.c src/crypto.h \
src/daemon_events.c src/daemon_events.h \
src/daemon_messages.c src/daemon_messages.h \
src/global_state.c src/global_state.h \
src/hosts.c src/hosts.h \
src/json_parser.c src/json_parser.h \
src/linkedlist.c src/linkedlist.h \
......
......@@ -18,19 +18,13 @@
#include <event2/event.h>
#include <event2/listener.h>
#include <signal.h>
#include <sodium.h>
#include <stdlib.h>
#include <time.h>
#include "daemon_events.h"
#include "global_state.h"
#include "hosts.h"
#include "log.h"
#include "neighbours.h"
#include "p2p.h"
#include "paths.h"
static void signal_cb(evutil_socket_t fd, short events, void *ctx);
static void conns_cb(evutil_socket_t fd, short events, void *ctx);
int main(void)
{
......@@ -52,12 +46,8 @@ int main(void)
* - terminate on SIGTERM
*/
struct event *conns_event;
struct timeval conns_interval;
global_state_t global_state;
struct evconnlistener *listener;
struct event *sigint_event;
struct event *sigterm_event;
if (sodium_init() < 0) {
log_error("Libsodium failed to initialize");
......@@ -67,17 +57,11 @@ int main(void)
/* TODO: use randombytes (from libsodium?) for the seed of randomness */
srand((unsigned) time(NULL));
/* initialize all global_state variables */
global_state.event_loop = NULL;
if (setup_paths(&global_state.filepaths)) {
log_error("Initializing paths to needed files/dirs");
if (global_state_init(&global_state)) {
log_error("Basic daemon setup");
return 1;
}
linkedlist_init(&global_state.pending_neighbours);
linkedlist_init(&global_state.neighbours);
linkedlist_init(&global_state.hosts);
fetch_hosts(global_state.filepaths.hosts, &global_state.hosts);
/* setup everything needed for TCP listening */
......@@ -86,37 +70,9 @@ int main(void)
return 2;
}
/* register SIGINT event to its callback */
sigint_event = evsignal_new(global_state.event_loop,
SIGINT,
signal_cb,
&global_state);
if (!sigint_event || event_add(sigint_event, NULL) < 0) {
log_error("Creating or adding SIGINT event");
return 3;
}
/* register SIGTERM event too */
sigterm_event = evsignal_new(global_state.event_loop,
SIGTERM,
signal_cb,
&global_state);
if (!sigterm_event || event_add(sigterm_event, NULL) < 0) {
log_error("Creating or adding SIGTERM event");
return 3;
}
/* setup a function that actively checks the number of neighbours */
conns_interval.tv_sec = 10;
conns_interval.tv_usec = 0;
conns_event = event_new(global_state.event_loop,
-1,
EV_PERSIST,
conns_cb,
&global_state);
if (!conns_event || event_add(conns_event, &conns_interval) < 0) {
log_error("Creating or adding Connections event");
/* setup needed daemon events */
if (daemon_events_setup(&global_state)) {
log_error("Setting up events");
return 3;
}
......@@ -126,59 +82,13 @@ int main(void)
/* start the event loop */
event_base_dispatch(global_state.event_loop);
/* SIGINT received, loop terminated; the clean-up part */
clear_neighbours(&global_state.pending_neighbours);
clear_neighbours(&global_state.neighbours);
/* store peers into 'peers' file before cleaning them */
store_peers(global_state.filepaths.peers, &global_state.peers);
clear_peers(&global_state.peers);
clear_paths(&global_state.filepaths);
/* SIGINT or SIGTERM received, the loop is terminated */
/* store hosts into 'hosts' file before clearing global_state */
store_hosts(global_state.filepaths.hosts, &global_state.hosts);
evconnlistener_free(listener);
event_free(sigint_event);
event_free(sigterm_event);
event_free(conns_event);
event_base_free(global_state.event_loop);
global_state_clear(&global_state);
return 0;
}
/**
* Callback function for a received signal.
*
* @param signal What signal was invoked.
* @param events Flags of the event occurred.
* @param ctx Global state.
*/
static void signal_cb(evutil_socket_t signal __attribute__((unused)),
short events __attribute__((unused)),
void *ctx)
{
global_state_t *global_state = (global_state_t *) ctx;
event_base_loopexit(global_state->event_loop, NULL);
}
/**
* Actively check the number of neighbours and add more if needed.
*
* @param fd File descriptor.
* @param events Event flags.
* @param ctx Global state.
*/
static void conns_cb(int fd __attribute__((unused)),
short events __attribute__((unused)),
void *ctx)
{
int needed_conns;
global_state_t *global_state = (global_state_t *) ctx;
needed_conns = MIN_NEIGHBOURS -
linkedlist_size(&global_state->neighbours);
if (needed_conns > 0) {
log_debug("conns_cb - we need %d more neighbours");
/* ask twice more peers than we need; it's preferable
* to have more neighbours than minimum */
add_more_connections(global_state, 2 * needed_conns);
}
}
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <event2/event.h>
#include <signal.h>
#include "daemon_events.h"
#include "global_state.h"
#include "linkedlist.h"
#include "log.h"
#include "neighbours.h"
#include "p2p.h"
static void signal_cb(evutil_socket_t signal __attribute__((unused)),
short events __attribute__((unused)),
void *ctx);
/**
* Actively check the number of neighbours and ask for more if needed.
*
* @param fd File descriptor.
* @param events Event flags.
* @param ctx Global state.
*/
static void conns_cb(int fd __attribute__((unused)),
short events __attribute__((unused)),
void *ctx)
{
global_state_t *global_state;
int needed_conns;
global_state = (global_state_t *) ctx;
needed_conns = MIN_NEIGHBOURS -
linkedlist_size(&global_state->neighbours);
if (needed_conns > 0) {
log_debug("conns_cb - we need %d more neighbours");
/* ask twice more hosts than we need; it's preferable
* to have more neighbours than minimum */
add_more_connections(global_state, 2 * needed_conns);
}
}
/**
* Setup and add daemon events into global state's event loop.
*
* @param global_state Global state.
*
* @return 0 Successfully set up.
* @return 1 Creating or adding an event failed.
*/
int daemon_events_setup(global_state_t *global_state)
{
struct event *event;
linkedlist_t *events;
struct timeval interval;
events = &global_state->events;
/* register SIGINT event to its callback */
event = evsignal_new(global_state->event_loop,
SIGINT,
signal_cb,
global_state);
if (!event ||
event_add(event, NULL) < 0 ||
!linkedlist_append(events, event)) {
log_error("Creating or adding SIGINT event");
return 1;
}
/* register SIGTERM event too */
event = evsignal_new(global_state->event_loop,
SIGTERM,
signal_cb,
global_state);
if (!event ||
event_add(event, NULL) < 0 ||
!linkedlist_append(events, event)) {
log_error("Creating or adding SIGTERM event");
return 1;
}
/* check the number of neighbours every 10 seconds */
interval.tv_sec = 10;
interval.tv_usec = 0;
event = event_new(global_state->event_loop,
-1,
EV_PERSIST,
conns_cb,
global_state);
if (!event ||
event_add(event, &interval) < 0 ||
!linkedlist_append(events, event)) {
log_error("Creating or adding Connections event");
return 1;
}
return 0;
}
/**
* Callback function for a received signal.
*
* @param signal What signal was invoked.
* @param events Flags of the event occurred.
* @param ctx Global state.
*/
static void signal_cb(evutil_socket_t signal __attribute__((unused)),
short events __attribute__((unused)),
void *ctx)
{
global_state_t *global_state = (global_state_t *) ctx;
event_base_loopexit(global_state->event_loop, NULL);
}
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DAEMON_EVENTS_H
#define DAEMON_EVENTS_H
#include "global_state.h"
int daemon_events_setup(global_state_t *global_state);
#endif /* DAEMON_EVENTS_H */
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <event2/event.h>
#include "global_state.h"
#include "linkedlist.h"
#include "log.h"
#include "neighbours.h"
#include "paths.h"
/**
* Clear global state variables.
*
* @param global_state The global state.
*/
void global_state_clear(global_state_t *global_state)
{
linkedlist_destroy(&global_state->pending_neighbours, clear_neighbour);
linkedlist_destroy(&global_state->neighbours, clear_neighbour);
linkedlist_destroy(&global_state->hosts, NULL);
/* event nodes' data are not malloc'd; just apply the removal */
linkedlist_apply(&global_state->events, event_free, linkedlist_remove);
clear_paths(&global_state->filepaths);
event_base_free(global_state->event_loop);
}
/**
* Initialize global state variables.
*
* @param global_state The global state.
*/
int global_state_init(global_state_t *global_state)
{
global_state->event_loop = NULL;
if (setup_paths(&global_state->filepaths)) {
log_error("Initializing paths to needed files/dirs");
return 1;
}
linkedlist_init(&global_state->events);
linkedlist_init(&global_state->hosts);
linkedlist_init(&global_state->neighbours);
linkedlist_init(&global_state->pending_neighbours);
return 0;
}
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLOBAL_STATE_H
#define GLOBAL_STATE_H
#include <event2/event.h>
#include "linkedlist.h"
#include "paths.h"
/**
* Event loop works with the data stored in an instance of this struct.
*/
typedef struct s_global_state {
/** For holding and polling events. */
struct event_base *event_loop;
/** A list of registered events of the event loop. */
linkedlist_t events;
/** Holder of paths to needed files/dirs. */
filepaths_t filepaths;
/** Linked list of some known hosts in the network. */
linkedlist_t hosts;
/** Linked list of our neighbours. */
linkedlist_t neighbours;
/** Hosts that didn't accept/reject us yet. */
linkedlist_t pending_neighbours;
} global_state_t;
void global_state_clear(global_state_t *global_state);
int global_state_init(global_state_t *global_state);
#endif /* GLOBAL_STATE_H */
......@@ -22,31 +22,13 @@
#include <event2/listener.h>
#include <netinet/in.h>
#include "linkedlist.h"
#include "neighbours.h"
#include "paths.h"
#include "global_state.h"
/* default port for TCP listening */
/** Default port for TCP listening. */
#define DEFAULT_PORT 31070
/* after TIMEOUT_TIME seconds invoke timeout callback */
/** After TIMEOUT_TIME seconds invoke timeout callback. */
#define TIMEOUT_TIME 30
/**
* Event loop works with the data stored in an instance of this struct.
*/
typedef struct s_global_state {
/** For holding and polling events. */
struct event_base *event_loop;
/** Holder of paths to needed files/dirs. */
filepaths_t filepaths;
/** Linked list of our neighbours. */
linkedlist_t neighbours;
/** Linked list of some peers in the network. */
linkedlist_t peers;
/** Peers that didn't accept/reject us yet. */
linkedlist_t pending_neighbours;
} global_state_t;
void add_more_connections(global_state_t *global_state, size_t conns_amount);
int connect_to_addr(global_state_t *global_state,
......
Markdown is supported
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