/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include #include #include #include #include "main.h" #include "uring.h" #include "announce.h" #include "server.h" #include "ptimer.h" struct announce { uint64_t value; struct uring_task task; struct ptimer_task ptask; int mcast_fd; }; static void announce_cb(struct ptimer_task *ptask) { struct announce *announce = container_of(ptask, struct announce, ptask); struct server *server; assert_return(ptask); assert_task_alive(DBG_ANN, &announce->task); debug(DBG_ANN, "announcing servers"); list_for_each_entry(server, &cfg->servers, list) server_announce(server, announce->mcast_fd); } static void announce_free(struct uring_task *task) { struct announce *announce = container_of(task, struct announce, task); assert_return(task); debug(DBG_ANN, "task %p, announce 0x%p, mcast_fd: %i", task, announce, announce->mcast_fd); close(announce->mcast_fd); xfree(announce); } void announce_refdump() { assert_return_silent(cfg->announce); uring_task_refdump(&cfg->announce->task); } void announce_delete() { assert_return_silent(cfg->announce); debug(DBG_ANN, "called"); announce_stop(); uring_task_destroy(&cfg->announce->task); cfg->announce = NULL; } void announce_stop() { struct announce *announce = cfg->announce; assert_return_silent(announce); ptimer_del_task(&announce->ptask); } void announce_start(unsigned duration) { struct announce *announce = cfg->announce; unsigned times; assert_return_silent(announce); if (duration == 0) times = 0; else times = MAX(announce->ptask.times, DIV_ROUND_UP(duration, cfg->announce_interval)); announce->ptask.times = times; ptimer_add_task(&announce->ptask); } void announce_init() { struct announce *announce; int sfd; assert_return(!cfg->announce); assert_return_silent(cfg->announce_interval > 0); announce = zmalloc(sizeof(*announce)); if (!announce) die("malloc: %m"); sfd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sfd < 0) die("socket: %m"); uring_task_init(&announce->task, "announce", uring_parent(), announce_free); ptask_init(&announce->ptask, cfg->announce_interval, 0, announce_cb); announce->mcast_fd = sfd; cfg->announce = announce; }