From 2b2d6ad0541544074fd54c86af6de2e2947e62ce Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Sun, 21 Jun 2020 23:42:05 +0200 Subject: Move mcast task to a per-server task to get refcounting right --- server.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'server.c') diff --git a/server.c b/server.c index 452e45f..4a45b53 100644 --- a/server.c +++ b/server.c @@ -54,6 +54,8 @@ server_refdump(struct server *server) assert_return(server); uring_task_refdump(&server->task); + uring_task_refdump(&server->exec_task); + uring_task_refdump(&server->ann_task); list_for_each_entry(local, &server->locals, list) uring_task_refdump(&local->task); list_for_each_entry(proxy, &server->proxys, list) @@ -94,6 +96,7 @@ server_delete(struct cfg *cfg, struct server *server) assert_return(cfg && server); verbose("Removing server %s", server->name); + server->state = SERVER_STATE_DEAD; idle_delete(cfg, server); rcon_delete(cfg, server); @@ -120,6 +123,7 @@ server_delete(struct cfg *cfg, struct server *server) uring_poll_cancel(cfg, &server->exec_task); uring_task_put(cfg, &server->exec_task); uring_task_destroy(cfg, &server->task); + uring_task_put(cfg, &server->ann_task); } void @@ -452,11 +456,50 @@ server_stop(struct cfg *cfg, struct server *server) return false; } +static void +server_announce_free(struct uring_task *task) +{ + assert_return(task); + + debug(DBG_ANN, "called"); +} + +static void +server_announce_cb(struct cfg *cfg, struct uring_task *task, int res) +{ + struct server *server = container_of(task, struct server, ann_task); + + assert_return(cfg && task); + + if (res < 0) + error("failure %i", res); + else + debug(DBG_ANN, "result %i", res); + + uring_task_set_fd(&server->ann_task, -1); +} + +bool +server_announce(struct cfg *cfg, struct server *server, int fd) +{ + assert_return(cfg && server && fd >= 0, false); + + if (server->state == SERVER_STATE_INIT || + server->state == SERVER_STATE_DEAD) + return false; + + debug(DBG_ANN, "announcing server: %s", server->name); + uring_task_set_fd(&server->ann_task, fd); + uring_tbuf_sendmsg(cfg, &server->ann_task, server_announce_cb); + return true; +} + bool server_commit(struct cfg *cfg, struct server *server) { struct server_local *local; uint16_t port; + int r; assert_return(cfg && server && server->name, false); assert_task_alive_or(DBG_SRV, &server->task, return false); @@ -599,6 +642,15 @@ server_commit(struct cfg *cfg, struct server *server) } } + r = snprintf(server->ann_buf.buf, sizeof(server->ann_buf.buf), + "[MOTD]%s[/MOTD][AD]%" PRIu16 "[/AD]", + server->pretty_name, server->announce_port); + if (r < 1 || r >= sizeof(server->ann_buf.buf)) { + error("%s: unable to create announce msg: %i\n", server->name, r); + return false; + } + server->ann_buf.len = r; + /* FIXME: config, dont reread config if server running, make sure fd is available before this is called */ server_dump(server); @@ -806,6 +858,9 @@ server_new(struct cfg *cfg, const char *name) server->start_method = SERVER_START_METHOD_UNDEFINED; uring_task_init(cfg, &server->task, "server", uring_parent(cfg), server_free); uring_task_set_buf(&server->task, &server->tbuf); + uring_task_init(cfg, &server->ann_task, "announce", &server->task, server_announce_free); + uring_task_set_buf(&server->ann_task, &server->ann_buf); + saddr_set_ipv4(&server->ann_task.saddr, cinet_addr(224,0,2,60), htons(4445)); uring_task_init(cfg, &server->exec_task, "exec", &server->task, server_exec_free); list_init(&server->remotes); list_init(&server->locals); -- cgit v1.2.3