From 5f55d9d4d14635678e7f582215e3642de2e232a4 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Mon, 6 May 2024 02:08:31 +0200 Subject: new ecp directory and vconn server --- ecp/server/timer.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 ecp/server/timer.c (limited to 'ecp/server/timer.c') diff --git a/ecp/server/timer.c b/ecp/server/timer.c new file mode 100644 index 0000000..ab30633 --- /dev/null +++ b/ecp/server/timer.c @@ -0,0 +1,98 @@ +#include +#include +#include + +#include + +#include "dir.h" + +#include "server.h" +#include "timer.h" + +static struct timespec timer_ts_mono; +static timer_t timer_ann_block_id; +static timer_t timer_online_switch_id; + +int timer_set_next(time_t tv_now) { + struct itimerspec its = { 0 }; + time_t tv_midnight; + int rv = 0; + + /* next midnight */ + tv_midnight = (tv_now / ONLINE_SWITCH_PERIOD) * ONLINE_SWITCH_PERIOD + ONLINE_SWITCH_PERIOD; + + if (tv_now < (tv_midnight - ANN_BLOCK_TIME)) { + dir_announce_allow(); + + its.it_value.tv_sec = tv_midnight - ANN_BLOCK_TIME; + rv = timer_settime(timer_ann_block_id, TIMER_ABSTIME, &its, NULL); + if (rv) return ECP_ERR; + } else { + dir_announce_block(); + } + + its.it_value.tv_sec = tv_midnight; + rv = timer_settime(timer_online_switch_id, TIMER_ABSTIME, &its, NULL); + if (rv) return ECP_ERR; + + return ECP_OK; +} + +void timer_ann_block(union sigval timer_data) { + dir_announce_block(); +} + +void timer_online_switch(union sigval timer_data) { + ECPSocket *sock = timer_data.sival_ptr; + struct timespec ts_prev; + int rv; + + ts_prev = timer_ts_mono; + clock_gettime(CLOCK_MONOTONIC, &timer_ts_mono); + + /* exit if someone is messing with realtime clock */ + if ((timer_ts_mono.tv_sec - ts_prev.tv_sec) < (ONLINE_SWITCH_PERIOD / 2)) goto online_switch_fin; + + dir_online_switch(sock, 1); + +online_switch_fin: + rv = timer_set_next(time(NULL)); + if (rv) LOG(LOG_ERR, "timer_online_switch: set next timer err:%d\n", rv); +} + +int timer_init(ECPSocket *sock) { + struct sigevent timer_ann_block_evt = { 0 }; + struct sigevent timer_online_switch_evt = { 0 }; + time_t tv_now; + int rv = 0; + + timer_ann_block_evt.sigev_notify = SIGEV_THREAD; + timer_ann_block_evt.sigev_notify_function = timer_ann_block; + timer_ann_block_evt.sigev_value.sival_ptr = NULL; + rv = timer_create(CLOCK_REALTIME, &timer_ann_block_evt, &timer_ann_block_id); + if (rv) return ECP_ERR; + + timer_online_switch_evt.sigev_notify = SIGEV_THREAD; + timer_online_switch_evt.sigev_notify_function = timer_online_switch; + timer_online_switch_evt.sigev_value.sival_ptr = sock; + rv = timer_create(CLOCK_REALTIME, &timer_online_switch_evt, &timer_online_switch_id); + if (rv) { + timer_delete(timer_ann_block_id); + return ECP_ERR; + } + + /* ensure that first dir_online_switch is executed */ + clock_gettime(CLOCK_MONOTONIC, &timer_ts_mono); + timer_ts_mono.tv_sec -= ONLINE_SWITCH_PERIOD / 2; + + tv_now = time(NULL); + dit_init_serial(tv_now / ONLINE_SWITCH_PERIOD); + rv = timer_set_next(tv_now); + if (rv) { + timer_delete(timer_ann_block_id); + timer_delete(timer_online_switch_id); + return rv; + } + + return ECP_OK; +} -- cgit v1.2.3