public inbox for b.a.t.m.a.n@lists.open-mesh.org
 help / color / mirror / Atom feed
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, &notify, 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, &notify, 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(&notify.source, source, ETH_ALEN);
 
 	ret = write(listener->fd, &notify, 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 --]

  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