From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Subject: Re: [PATCH v2] alfred: notify event listener via unix socket
Date: Sat, 14 May 2022 11:51:38 +0200 [thread overview]
Message-ID: <1727325.kRQH6uYu6r@sven-desktop> (raw)
In-Reply-To: <20220502114651.771309-1-mareklindner@neomailbox.ch>
[-- Attachment #1.1: Type: text/plain, Size: 1209 bytes --]
On Monday, 2 May 2022 13:46:51 CEST Marek Lindner wrote:
> The alfred server instance accepts event notification registration
> via the unix socket. These notification sockets only inform
> registered parties of the availability of an alfred datatype change.
> The actual data itself needs to be retrieved via the existing data
> retrieval mechanisms.
>
> Unlike the update-command this event monitor allows:
>
> - multiple parallel listeners
> - programmatic access to changes without requiring multiple processes
>
> The alfred client allows to monitor events via the newly added '-E'
> (event monitor) command line option. Serving as debugging tool and
> example code at the same time.
>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> ---
>
> v2:
> - fix typ0s
> - replace list_del_init() with list_del()
> - remove unnecessary INIT_LIST_HEAD()
> - change --event-monitor to not require an argument
This version cannot be applied on top of the current master. I have attached
the diff for the things which (afaik) need to be changed when you rebase the
patch.
I have also attached the change to support the reporting of the source mac for
the changed dataset.
Kind regards,
Sven
[-- Attachment #1.2: 0001-fixup-rebase.patch --]
[-- Type: text/x-patch, Size: 7305 bytes --]
diff --git a/alfred.h b/alfred.h
index 668e856..f00346d 100644
--- a/alfred.h
+++ b/alfred.h
@@ -121,6 +121,7 @@ struct interface {
struct event_listener {
int fd;
+ struct epoll_handle epoll;
struct list_head list;
};
@@ -208,10 +209,6 @@ int unix_sock_open_client(struct globals *globals);
int unix_sock_close(struct globals *globals);
int unix_sock_req_data_finish(struct globals *globals,
struct transaction_head *head);
-int unix_sock_events_select_prepare(struct globals *globals, fd_set *fds,
- fd_set *errfds, int maxsock);
-void unix_sock_events_select_handle(struct globals *globals,
- fd_set *fds, fd_set *errfds);
void unix_sock_events_close_all(struct globals *globals);
void unix_sock_event_notify(struct globals *globals, uint8_t type);
/* vis.c */
diff --git a/main.c b/main.c
index 885b950..3fe7b42 100644
--- a/main.c
+++ b/main.c
@@ -164,12 +164,8 @@ static struct globals *alfred_init(int argc, char *argv[])
{"modeswitch", required_argument, NULL, 'M'},
{"change-interface", required_argument, NULL, 'I'},
{"change-bat-iface", required_argument, NULL, 'B'},
-<<<<<<< HEAD
{"server-status", no_argument, NULL, 'S'},
-=======
- {"server-status", required_argument, NULL, 'S'},
{"event-monitor", no_argument, NULL, 'E'},
->>>>>>> 08415c9 (alfred: notify event listener via unix socket)
{"unix-path", required_argument, NULL, 'u'},
{"update-command", required_argument, NULL, 'c'},
{"version", no_argument, NULL, 'v'},
diff --git a/server.c b/server.c
index 15b4d77..0d792b0 100644
--- a/server.c
+++ b/server.c
@@ -513,54 +513,7 @@ int alfred_server(struct globals *globals)
while (1) {
netsock_reopen(globals);
-<<<<<<< HEAD
process_events(globals);
-=======
-
- FD_ZERO(&fds);
- FD_ZERO(&errfds);
- FD_SET(globals->unix_sock, &fds);
- maxsock = globals->unix_sock;
-
- maxsock = netsock_prepare_select(globals, &fds, maxsock);
- maxsock = netsock_prepare_select(globals, &errfds, maxsock);
- maxsock = unix_sock_events_select_prepare(globals, &fds,
- &errfds, maxsock);
-
- ret = pselect(maxsock + 1, &fds, NULL, &errfds, &tv, NULL);
-
- if (ret == -1) {
- perror("main loop select failed ...");
- } else if (ret) {
- netsock_check_error(globals, &errfds);
-
- unix_sock_events_select_handle(globals, &fds, &errfds);
-
- if (FD_ISSET(globals->unix_sock, &fds)) {
- unix_sock_read(globals);
- continue;
- } else {
- recvs = netsock_receive_packet(globals, &fds);
- if (recvs > 0)
- continue;
- }
- }
- clock_gettime(CLOCK_MONOTONIC, &last_check);
-
- if (globals->opmode == OPMODE_PRIMARY) {
- /* we are a primary */
- printf("[%ld.%09ld] announce primary ...\n", last_check.tv_sec, last_check.tv_nsec);
- announce_primary(globals);
- sync_data(globals);
- } else {
- /* send local data to server */
- update_server_info(globals);
- push_local_data(globals);
- }
- purge_data(globals);
- check_if_sockets(globals);
- execute_update_command(globals);
->>>>>>> 08415c9 (alfred: notify event listener via unix socket)
}
netsock_close_all(globals);
diff --git a/unix_sock.c b/unix_sock.c
index 2d7fc2e..14d63dd 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -27,6 +27,9 @@
static void unix_sock_read(struct globals *globals,
struct epoll_handle *handle __unused,
struct epoll_event *ev __unused);
+static void unix_sock_event_listener_handle(struct globals *globals __unused,
+ struct epoll_handle *handle,
+ struct epoll_event *ev);
int unix_sock_open_daemon(struct globals *globals)
{
@@ -496,14 +499,10 @@ err:
return ret;
}
-<<<<<<< HEAD
-static void unix_sock_read(struct globals *globals,
- struct epoll_handle *handle __unused,
- struct epoll_event *ev __unused)
-=======
static int unix_sock_register_listener(struct globals *globals, int client_sock)
{
struct event_listener *listener;
+ struct epoll_event ev;
int ret;
ret = fcntl(client_sock, F_GETFL, 0);
@@ -522,6 +521,16 @@ static int unix_sock_register_listener(struct globals *globals, int client_sock)
if (!listener)
goto err;
+ ev.events = EPOLLIN;
+ ev.data.ptr = &listener->epoll;
+ listener->epoll.handler = unix_sock_event_listener_handle;
+
+ if (epoll_ctl(globals->epollfd, EPOLL_CTL_ADD, client_sock,
+ &ev) == -1) {
+ perror("Failed to add epoll for event listener");
+ goto err;
+ }
+
listener->fd = client_sock;
list_add_tail(&listener->list, &globals->event_listeners);
return 0;
@@ -531,8 +540,9 @@ err:
return -1;
}
-int unix_sock_read(struct globals *globals)
->>>>>>> 08415c9 (alfred: notify event listener via unix socket)
+static void unix_sock_read(struct globals *globals,
+ struct epoll_handle *handle __unused,
+ struct epoll_event *ev __unused)
{
int client_sock;
struct sockaddr_un sun_addr;
@@ -598,7 +608,7 @@ int unix_sock_read(struct globals *globals)
unix_sock_server_status(globals, client_sock);
break;
case ALFRED_EVENT_REGISTER:
- ret = unix_sock_register_listener(globals, client_sock);
+ unix_sock_register_listener(globals, client_sock);
break;
default:
/* unknown packet type */
@@ -642,55 +652,33 @@ static void unix_sock_event_notify_listener(struct event_listener *listener,
unix_sock_event_listener_free(listener);
}
-int unix_sock_events_select_prepare(struct globals *globals, fd_set *fds,
- fd_set *errfds, int maxsock)
+static void unix_sock_event_listener_handle(struct globals *globals __unused,
+ struct epoll_handle *handle,
+ struct epoll_event *ev)
{
struct event_listener *listener;
-
- list_for_each_entry(listener, &globals->event_listeners, list) {
- if (listener->fd < 0)
- continue;
-
- FD_SET(listener->fd, fds);
- FD_SET(listener->fd, errfds);
-
- if (maxsock < listener->fd)
- maxsock = listener->fd;
- }
-
- return maxsock;
-}
-
-void unix_sock_events_select_handle(struct globals *globals,
- fd_set *fds, fd_set *errfds)
-{
- struct event_listener *listener, *tmp;
char buff[4];
int ret;
- list_for_each_entry_safe(listener, tmp,
- &globals->event_listeners, list) {
- if (FD_ISSET(listener->fd, fds)) {
- ret = recv(listener->fd, buff, sizeof(buff),
- MSG_PEEK | MSG_DONTWAIT);
- /* listener has hung up */
- if (ret == 0)
- unix_sock_event_listener_free(listener);
- else if (ret > 0) {
- fprintf(stderr, "Event listener has written to socket: %d - closing\n",
- listener->fd);
- unix_sock_event_listener_free(listener);
- }
-
- if (ret >= 0)
- continue;
- }
+ listener = container_of(handle, struct event_listener, epoll);
+
+ if (ev->events & EPOLLERR) {
+ fprintf(stderr, "Error on event listener detected: %d\n",
+ listener->fd);
+ unix_sock_event_listener_free(listener);
+ return;
+ }
- if (FD_ISSET(listener->fd, errfds)) {
- fprintf(stderr, "Error on event listener detected: %d\n",
+ if (ev->events & EPOLLIN) {
+ ret = recv(listener->fd, buff, sizeof(buff),
+ MSG_PEEK | MSG_DONTWAIT);
+ /* listener has hung up */
+ if (ret == 0)
+ unix_sock_event_listener_free(listener);
+ else if (ret > 0) {
+ fprintf(stderr, "Event listener has written to socket: %d - closing\n",
listener->fd);
unix_sock_event_listener_free(listener);
- continue;
}
}
}
[-- Attachment #1.3: 0002-move-functions-to-same-place.patch --]
[-- Type: text/x-patch, Size: 3985 bytes --]
diff --git a/unix_sock.c b/unix_sock.c
index 14d63dd..fd487b9 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -27,9 +27,8 @@
static void unix_sock_read(struct globals *globals,
struct epoll_handle *handle __unused,
struct epoll_event *ev __unused);
-static void unix_sock_event_listener_handle(struct globals *globals __unused,
- struct epoll_handle *handle,
- struct epoll_event *ev);
+static int unix_sock_register_listener(struct globals *globals,
+ int client_sock);
int unix_sock_open_daemon(struct globals *globals)
{
@@ -499,47 +498,6 @@ err:
return ret;
}
-static int unix_sock_register_listener(struct globals *globals, int client_sock)
-{
- struct event_listener *listener;
- struct epoll_event ev;
- int ret;
-
- ret = fcntl(client_sock, F_GETFL, 0);
- if (ret < 0) {
- perror("failed to get file status flags");
- goto err;
- }
-
- ret = fcntl(client_sock, F_SETFL, ret | O_NONBLOCK);
- if (ret < 0) {
- perror("failed to set file status flags");
- goto err;
- }
-
- listener = malloc(sizeof(*listener));
- if (!listener)
- goto err;
-
- ev.events = EPOLLIN;
- ev.data.ptr = &listener->epoll;
- listener->epoll.handler = unix_sock_event_listener_handle;
-
- if (epoll_ctl(globals->epollfd, EPOLL_CTL_ADD, client_sock,
- &ev) == -1) {
- perror("Failed to add epoll for event listener");
- goto err;
- }
-
- listener->fd = client_sock;
- list_add_tail(&listener->list, &globals->event_listeners);
- return 0;
-
-err:
- close(client_sock);
- return -1;
-}
-
static void unix_sock_read(struct globals *globals,
struct epoll_handle *handle __unused,
struct epoll_event *ev __unused)
@@ -634,24 +592,6 @@ static void unix_sock_event_listener_free(struct event_listener *listener)
free(listener);
}
-static void unix_sock_event_notify_listener(struct event_listener *listener,
- uint8_t type)
-{
- struct alfred_event_notify_v0 notify;
- int ret;
-
- notify.header.type = ALFRED_EVENT_NOTIFY;
- notify.header.version = ALFRED_VERSION;
- notify.header.length = FIXED_TLV_LEN(notify);
- notify.type = type;
-
- ret = write(listener->fd, ¬ify, sizeof(notify));
- if (ret == sizeof(notify))
- return;
-
- unix_sock_event_listener_free(listener);
-}
-
static void unix_sock_event_listener_handle(struct globals *globals __unused,
struct epoll_handle *handle,
struct epoll_event *ev)
@@ -683,6 +623,65 @@ static void unix_sock_event_listener_handle(struct globals *globals __unused,
}
}
+static int unix_sock_register_listener(struct globals *globals, int client_sock)
+{
+ struct event_listener *listener;
+ struct epoll_event ev;
+ int ret;
+
+ ret = fcntl(client_sock, F_GETFL, 0);
+ if (ret < 0) {
+ perror("failed to get file status flags");
+ goto err;
+ }
+
+ ret = fcntl(client_sock, F_SETFL, ret | O_NONBLOCK);
+ if (ret < 0) {
+ perror("failed to set file status flags");
+ goto err;
+ }
+
+ listener = malloc(sizeof(*listener));
+ if (!listener)
+ goto err;
+
+ ev.events = EPOLLIN;
+ ev.data.ptr = &listener->epoll;
+ listener->epoll.handler = unix_sock_event_listener_handle;
+
+ if (epoll_ctl(globals->epollfd, EPOLL_CTL_ADD, client_sock,
+ &ev) == -1) {
+ perror("Failed to add epoll for event listener");
+ goto err;
+ }
+
+ listener->fd = client_sock;
+ list_add_tail(&listener->list, &globals->event_listeners);
+ return 0;
+
+err:
+ close(client_sock);
+ return -1;
+}
+
+static void unix_sock_event_notify_listener(struct event_listener *listener,
+ uint8_t type)
+{
+ struct alfred_event_notify_v0 notify;
+ int ret;
+
+ notify.header.type = ALFRED_EVENT_NOTIFY;
+ notify.header.version = ALFRED_VERSION;
+ notify.header.length = FIXED_TLV_LEN(notify);
+ notify.type = type;
+
+ ret = write(listener->fd, ¬ify, sizeof(notify));
+ if (ret == sizeof(notify))
+ return;
+
+ unix_sock_event_listener_free(listener);
+}
+
void unix_sock_events_close_all(struct globals *globals)
{
struct event_listener *listener, *tmp;
[-- Attachment #1.4: 0003-support-source-in-event.patch --]
[-- Type: text/x-patch, Size: 3582 bytes --]
diff --git a/alfred.h b/alfred.h
index f00346d..127b115 100644
--- a/alfred.h
+++ b/alfred.h
@@ -210,7 +210,8 @@ int unix_sock_close(struct globals *globals);
int unix_sock_req_data_finish(struct globals *globals,
struct transaction_head *head);
void unix_sock_events_close_all(struct globals *globals);
-void unix_sock_event_notify(struct globals *globals, uint8_t type);
+void unix_sock_event_notify(struct globals *globals, uint8_t type,\
+ const uint8_t source[ETH_ALEN]);
/* vis.c */
int vis_update_data(struct globals *globals);
/* netsock.c */
diff --git a/client.c b/client.c
index d86d23c..ace42b9 100644
--- a/client.c
+++ b/client.c
@@ -499,7 +499,11 @@ int alfred_client_event_monitor(struct globals *globals)
if (event_notify.header.type != ALFRED_EVENT_NOTIFY)
continue;
- fprintf(stdout, "Event: type = %hhu\n", event_notify.type);
+ fprintf(stdout, "Event: type = %hhu, source = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ event_notify.type,
+ event_notify.source[0], event_notify.source[1],
+ event_notify.source[2], event_notify.source[3],
+ event_notify.source[4], event_notify.source[5]);
}
err:
diff --git a/packet.h b/packet.h
index 84b027f..b8d528e 100644
--- a/packet.h
+++ b/packet.h
@@ -253,6 +253,7 @@ struct alfred_event_register_v0 {
struct alfred_event_notify_v0 {
struct alfred_tlv header;
uint8_t type;
+ uint8_t source[ETH_ALEN];
} __packed;
/**
diff --git a/recv.c b/recv.c
index 36b3a49..75e3faf 100644
--- a/recv.c
+++ b/recv.c
@@ -78,7 +78,8 @@ static int finish_alfred_push_data(struct globals *globals,
dataset->data.header.length != data_len ||
memcmp(dataset->buf, data->data, data_len) != 0) {
changed_data_type(globals, data->header.type);
- unix_sock_event_notify(globals, data->header.type);
+ unix_sock_event_notify(globals, data->header.type,
+ data->source);
}
/* free old buffer */
diff --git a/unix_sock.c b/unix_sock.c
index fd487b9..ce08a51 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -166,7 +166,8 @@ static int unix_sock_add_data(struct globals *globals,
if (new_entry_created ||
dataset->data.header.length != data_len ||
memcmp(dataset->buf, data->data, data_len) != 0)
- unix_sock_event_notify(globals, data->header.type);
+ unix_sock_event_notify(globals, data->header.type,
+ data->source);
/* free old buffer */
free(dataset->buf);
@@ -665,7 +666,8 @@ err:
}
static void unix_sock_event_notify_listener(struct event_listener *listener,
- uint8_t type)
+ uint8_t type,
+ const uint8_t source[ETH_ALEN])
{
struct alfred_event_notify_v0 notify;
int ret;
@@ -674,6 +676,7 @@ static void unix_sock_event_notify_listener(struct event_listener *listener,
notify.header.version = ALFRED_VERSION;
notify.header.length = FIXED_TLV_LEN(notify);
notify.type = type;
+ memcpy(¬ify.source, source, ETH_ALEN);
ret = write(listener->fd, ¬ify, sizeof(notify));
if (ret == sizeof(notify))
@@ -692,13 +695,14 @@ void unix_sock_events_close_all(struct globals *globals)
}
}
-void unix_sock_event_notify(struct globals *globals, uint8_t type)
+void unix_sock_event_notify(struct globals *globals, uint8_t type,
+ const uint8_t source[ETH_ALEN])
{
struct event_listener *listener, *tmp;
/* if event notify is unsuccessful, listener socket is closed */
list_for_each_entry_safe(listener, tmp,
&globals->event_listeners, list) {
- unix_sock_event_notify_listener(listener, type);
+ unix_sock_event_notify_listener(listener, type, source);
}
}
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2022-05-14 9:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-02 11:46 [PATCH v2] alfred: notify event listener via unix socket Marek Lindner
2022-05-14 9:51 ` Sven Eckelmann [this message]
2022-05-17 7:44 ` Marek Lindner
2022-05-17 11:32 ` Sven Eckelmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1727325.kRQH6uYu6r@sven-desktop \
--to=sven@narfation.org \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
--cc=mareklindner@neomailbox.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox