summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--announce.c64
-rw-r--r--cfgdir.c8
-rw-r--r--server.c69
-rw-r--r--server.h9
-rw-r--r--utils.c12
-rw-r--r--utils.h5
6 files changed, 136 insertions, 31 deletions
diff --git a/announce.c b/announce.c
index 8194f1c..9af2236 100644
--- a/announce.c
+++ b/announce.c
@@ -9,11 +9,14 @@
#include "uring.h"
#include "config.h"
#include "announce.h"
+#include "server.h"
struct announce {
uint64_t value;
struct uring_task task;
+
struct uring_task mcast_task;
+ struct sockaddr_in mcast_addr;
};
static void
@@ -31,32 +34,39 @@ mcast_sent(struct cfg *cfg, struct uring_task *task, int res)
}
static void
-mcast_send(struct cfg *cfg, struct announce *aev)
+mcast_send(struct cfg *cfg, struct announce *aev, struct server *server)
{
- struct sockaddr_in addr;
- struct msghdr msg;
- char buf[] = "[MOTD]fumbor - test[/MOTD][AD]1234[/AD]";
- struct iovec iov = {
- .iov_base = buf,
- .iov_len = sizeof(buf)
- };
+ int len;
+
+ if (!server || !server->pretty_name || server->announce_port < 1)
+ return;
+
+ len = snprintf(server->mcast_buf, sizeof(server->mcast_buf),
+ "[MOTD]%s[/MOTD][AD]%" PRIu16 "[/AD]",
+ server->pretty_name, server->announce_port);
+
+ if (len < 1 || len >= sizeof(server->mcast_buf)) {
+ error("%s: snprintf returned %i\n", __func__, len);
+ return;
+ }
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr("224.0.2.60");
- addr.sin_port = htons(4445);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = &addr;
- msg.msg_namelen = sizeof(addr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- fprintf(stderr, "Manual: %zi\n", sendmsg(aev->mcast_task.fd, &msg, 0));
- uring_sendmsg(cfg, &aev->mcast_task, &msg, mcast_sent);
+ server->mcast_msg.msg_name = &aev->mcast_addr;
+ server->mcast_msg.msg_namelen = sizeof(aev->mcast_addr);
+ server->mcast_iov.iov_len = len;
+
+ //uring_task_get(cfg, &server->task); <--- need to put in mcast_sent
+ uring_sendmsg(cfg, &aev->mcast_task, &server->mcast_msg, mcast_sent);
+}
+
+static void
+mcast_send_all(struct cfg *cfg, struct announce *aev)
+{
+ struct server *server;
+
+ list_for_each_entry(server, &cfg->servers, list) {
+ fprintf(stderr, "Announcing server: %s\n", server->name);
+ mcast_send(cfg, aev, server);
+ }
}
static void
@@ -76,7 +86,7 @@ announce_cb(struct cfg *cfg, struct uring_task *task, int res)
perrordie("timerfd_read");
fprintf(stderr, "%s: called with value %" PRIu64 "\n", __func__, aev->value);
- mcast_send(cfg, aev);
+ mcast_send_all(cfg, aev);
uring_read(cfg, &aev->task, &aev->value, sizeof(aev->value), 0, announce_cb);
}
@@ -171,6 +181,10 @@ announce_init(struct cfg *cfg)
uring_task_init(&aev->mcast_task, "aev_mcast", &aev->task, mcast_free);
uring_task_set_fd(&aev->mcast_task, sfd);
+ memset(&aev->mcast_addr, 0, sizeof(aev->mcast_addr));
+ aev->mcast_addr.sin_family = AF_INET;
+ aev->mcast_addr.sin_addr.s_addr = inet_addr("224.0.2.60");
+ aev->mcast_addr.sin_port = htons(4445);
cfg->aev = aev;
uring_read(cfg, &aev->task, &aev->value, sizeof(aev->value), 0, announce_cb);
diff --git a/cfgdir.c b/cfgdir.c
index 34283f4..443ec5e 100644
--- a/cfgdir.c
+++ b/cfgdir.c
@@ -159,7 +159,8 @@ scfg_open_cb(struct cfg *cfg, struct uring_task *task, int res)
struct server *scfg = container_of(task, struct server, task);
if (res < 0) {
- fprintf(stderr, "Open failed\n");
+ fprintf(stderr, "%s: open(%s) failed: %s\n",
+ __func__, scfg->name, strerror(-res));
server_delete(cfg, scfg);
return;
}
@@ -291,7 +292,8 @@ inotify_cb(struct cfg *cfg, struct uring_task *task, int res)
server_delete_by_name(cfg, event->name);
else if (event->mask & (IN_MOVED_TO | IN_CREATE | IN_CLOSE_WRITE)) {
scfg = server_new(cfg, event->name);
- uring_openat(cfg, &scfg->task, event->name, scfg_open_cb);
+ fprintf(stderr, "%s: calling openat(%s)\n", __func__, scfg->name);
+ uring_openat(cfg, &scfg->task, scfg->name, scfg_open_cb);
} else
error("inotify: weird, unknown event: 0x%08x\n", event->mask);
}
@@ -361,7 +363,7 @@ cfgdir_init(struct cfg *cfg)
continue;
scfg = server_new(cfg, dent->d_name);
- uring_openat(cfg, &scfg->task, dent->d_name, scfg_open_cb);
+ uring_openat(cfg, &scfg->task, scfg->name, scfg_open_cb);
}
closedir(cfgdir);
diff --git a/server.c b/server.c
index 9b9788b..25cfad7 100644
--- a/server.c
+++ b/server.c
@@ -203,9 +203,71 @@ bool
server_commit(struct cfg *cfg, struct server *scfg)
{
struct server_local *local;
+ uint16_t port;
+
+ if (!scfg || !scfg->name)
+ return false;
+
+ if (!list_empty(&scfg->proxys))
+ return false;
+
+ /* FIXME: running? */
+
+ switch (scfg->type) {
+ case SERVER_TYPE_ANNOUNCE:
+ if (scfg->announce_port < 1)
+ return false;
+ if (!list_empty(&scfg->locals))
+ return false;
+ if (!list_empty(&scfg->remotes))
+ return false;
+ break;
+
+ case SERVER_TYPE_PROXY:
+ if (scfg->announce_port >= 1)
+ return false;
+ if (list_empty(&scfg->locals))
+ return false;
+ if (list_empty(&scfg->remotes))
+ return false;
+
+ list_for_each_entry(local, &scfg->locals, list) {
+ port = sockaddr_port(&local->addr);
+
+ if (port == 0)
+ return false;
+
+ if (scfg->announce_port < 1)
+ scfg->announce_port = port;
+
+ if (scfg->announce_port != port) {
+ fprintf(stderr, "Multiple announce ports!?\n");
+ return false;
+ }
+ }
+
+ if (scfg->announce_port < 1)
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ if (!scfg->pretty_name) {
+ char *suffix;
+
+ suffix = strrchr(scfg->name, '.');
+ if (!suffix || suffix == scfg->name)
+ return false;
+
+ scfg->pretty_name = strndup(scfg->name, suffix - scfg->name);
+ if (!scfg->pretty_name)
+ return false;
+ }
/* FIXME: config, dont reread config if server running, make sure fd is available before this is called */
- /* FIXME: verify correct cfg */
server_dump(scfg);
list_for_each_entry(local, &scfg->locals, list) {
@@ -315,6 +377,11 @@ server_new(struct cfg *cfg, const char *name)
list_init(&scfg->remotes);
list_init(&scfg->locals);
list_init(&scfg->proxys);
+ memset(&scfg->mcast_iov, 0, sizeof(scfg->mcast_iov));
+ scfg->mcast_iov.iov_base = scfg->mcast_buf;
+ memset(&scfg->mcast_msg, 0, sizeof(scfg->mcast_msg));
+ scfg->mcast_msg.msg_iov = &scfg->mcast_iov;
+ scfg->mcast_msg.msg_iovlen = 1;
list_add(&scfg->list, &cfg->servers);
return scfg;
diff --git a/server.h b/server.h
index d066588..a6936cd 100644
--- a/server.h
+++ b/server.h
@@ -17,9 +17,16 @@ struct server {
struct list_head proxys;
bool running;
- struct uring_task task;
+ /* For config files */
char buf[4096];
size_t len;
+
+ /* For announce messages */
+ struct iovec mcast_iov;
+ struct msghdr mcast_msg;
+ char mcast_buf[4096];
+
+ struct uring_task task;
struct list_head list;
};
diff --git a/utils.c b/utils.c
index 91e44b3..87ed0fe 100644
--- a/utils.c
+++ b/utils.c
@@ -7,6 +7,18 @@
#include "main.h"
#include "utils.h"
+uint16_t sockaddr_port(struct sockaddr_in46 *addr)
+{
+ switch (addr->storage.ss_family) {
+ case AF_INET:
+ return ntohs(addr->in4.sin_port);
+ case AF_INET6:
+ return ntohs(addr->in6.sin6_port);
+ default:
+ return 0;
+ }
+}
+
char *
sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen)
{
diff --git a/utils.h b/utils.h
index 89bcccc..7110265 100644
--- a/utils.h
+++ b/utils.h
@@ -95,10 +95,13 @@ struct sockaddr_in46 {
struct list_head list;
};
-int strtou16_strict(const char *str, uint16_t *result);
+uint16_t sockaddr_port(struct sockaddr_in46 *addr);
char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen);
+int strtou16_strict(const char *str, uint16_t *result);
+
+
/*
#define _cleanup_(x) __attribute__((cleanup(x)))