From 34a206bc1194cfcc72e1ecbe9ed23aa8c85d2995 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 22 Aug 2017 16:43:02 +0200 Subject: [PATCH] dnsmasq: add ubus notifications for new leases Signed-off-by: John Crispin --- package/network/services/dnsmasq/Makefile | 7 +- .../services/dnsmasq/files/dnsmasq_acl.json | 4 + .../services/dnsmasq/patches/240-ubus.patch | 134 ++++++++++++++++++ 3 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 package/network/services/dnsmasq/files/dnsmasq_acl.json create mode 100644 package/network/services/dnsmasq/patches/240-ubus.patch diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile index 2db57c062bd..cd74d047857 100644 --- a/package/network/services/dnsmasq/Makefile +++ b/package/network/services/dnsmasq/Makefile @@ -37,6 +37,7 @@ define Package/dnsmasq/Default CATEGORY:=Base system TITLE:=DNS and DHCP server URL:=http://www.thekelleys.org.uk/dnsmasq/ + DEPENDS:=+libubus USERID:=dnsmasq=453:dnsmasq=453 endef @@ -48,14 +49,14 @@ endef define Package/dnsmasq-dhcpv6 $(call Package/dnsmasq/Default) TITLE += (with DHCPv6 support) - DEPENDS:=@IPV6 + DEPENDS+=@IPV6 VARIANT:=dhcpv6 endef define Package/dnsmasq-full $(call Package/dnsmasq/Default) TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Conntrack, NO_ID enabled by default) - DEPENDS:=+PACKAGE_dnsmasq_full_dnssec:libnettle \ + DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \ +PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \ +PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack VARIANT:=full @@ -159,6 +160,8 @@ define Package/dnsmasq/install $(INSTALL_DATA) ./files/rfc6761.conf $(1)/usr/share/dnsmasq/ $(INSTALL_DIR) $(1)/usr/lib/dnsmasq $(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh + $(INSTALL_DIR) $(1)/usr/share/acl.d + $(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/ endef Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install) diff --git a/package/network/services/dnsmasq/files/dnsmasq_acl.json b/package/network/services/dnsmasq/files/dnsmasq_acl.json new file mode 100644 index 00000000000..00ec7d0f030 --- /dev/null +++ b/package/network/services/dnsmasq/files/dnsmasq_acl.json @@ -0,0 +1,4 @@ +{ + "user": "dnsmasq", + "publish": [ "dnsmasq" ] +} diff --git a/package/network/services/dnsmasq/patches/240-ubus.patch b/package/network/services/dnsmasq/patches/240-ubus.patch new file mode 100644 index 00000000000..41e2848594b --- /dev/null +++ b/package/network/services/dnsmasq/patches/240-ubus.patch @@ -0,0 +1,134 @@ +Index: dnsmasq-2.77/src/dnsmasq.c +=================================================================== +--- dnsmasq-2.77.orig/src/dnsmasq.c ++++ dnsmasq-2.77/src/dnsmasq.c +@@ -17,6 +17,8 @@ + /* Declare static char *compiler_opts in config.h */ + #define DNSMASQ_COMPILE_OPTS + ++#include ++ + #include "dnsmasq.h" + + struct daemon *daemon; +@@ -32,6 +34,62 @@ static void fatal_event(struct event_des + static int read_event(int fd, struct event_desc *evp, char **msg); + static void poll_resolv(int force, int do_reload, time_t now); + ++static struct ubus_context *ubus; ++static struct blob_buf b; ++ ++static struct ubus_object_type ubus_object_type = { ++ .name = "dnsmasq", ++}; ++ ++static struct ubus_object ubus_object = { ++ .name = "dnsmasq", ++ .type = &ubus_object_type, ++}; ++ ++void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name) ++{ ++ if (!ubus || !ubus_object.has_subscribers) ++ return; ++ ++ blob_buf_init(&b, 0); ++ if (mac) ++ blobmsg_add_string(&b, "mac", mac); ++ if (ip) ++ blobmsg_add_string(&b, "ip", ip); ++ if (name) ++ blobmsg_add_string(&b, "name", name); ++ ubus_notify(ubus, &ubus_object, type, b.head, -1); ++} ++ ++static void set_ubus_listeners(void) ++{ ++ if (!ubus) ++ return; ++ ++ poll_listen(ubus->sock.fd, POLLIN); ++ poll_listen(ubus->sock.fd, POLLERR); ++ poll_listen(ubus->sock.fd, POLLHUP); ++} ++ ++static void check_ubus_listeners() ++{ ++ if (!ubus) { ++ ubus = ubus_connect(NULL); ++ if (ubus) ++ ubus_add_object(ubus, &ubus_object); ++ else ++ return; ++ } ++ ++ if (poll_check(ubus->sock.fd, POLLIN)) ++ ubus_handle_event(ubus); ++ ++ if (poll_check(ubus->sock.fd, POLLHUP)) { ++ ubus_free(ubus); ++ ubus = NULL; ++ } ++} ++ + int main (int argc, char **argv) + { + int bind_fallback = 0; +@@ -911,6 +969,7 @@ int main (int argc, char **argv) + set_dbus_listeners(); + #endif + ++ set_ubus_listeners(); + #ifdef HAVE_DHCP + if (daemon->dhcp || daemon->relay4) + { +@@ -1041,6 +1100,8 @@ int main (int argc, char **argv) + check_dbus_listeners(); + #endif + ++ check_ubus_listeners(); ++ + check_dns_listeners(now); + + #ifdef HAVE_TFTP +Index: dnsmasq-2.77/Makefile +=================================================================== +--- dnsmasq-2.77.orig/Makefile ++++ dnsmasq-2.77/Makefile +@@ -85,7 +85,7 @@ all : $(BUILDDIR) + @cd $(BUILDDIR) && $(MAKE) \ + top="$(top)" \ + build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \ +- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \ ++ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) -lubox -lubus" \ + -f $(top)/Makefile dnsmasq + + mostly_clean : +Index: dnsmasq-2.77/src/dnsmasq.h +=================================================================== +--- dnsmasq-2.77.orig/src/dnsmasq.h ++++ dnsmasq-2.77/src/dnsmasq.h +@@ -1389,6 +1389,8 @@ void emit_dbus_signal(int action, struct + # endif + #endif + ++void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name); ++ + /* ipset.c */ + #ifdef HAVE_IPSET + void ipset_init(void); +Index: dnsmasq-2.77/src/rfc2131.c +=================================================================== +--- dnsmasq-2.77.orig/src/rfc2131.c ++++ dnsmasq-2.77/src/rfc2131.c +@@ -1621,6 +1621,10 @@ static void log_packet(char *type, void + daemon->namebuff, + string ? string : "", + err ? err : ""); ++ if (!strcmp(type, "DHCPACK")) ++ ubus_event_bcast("dhcp.ack", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); ++ else if (!strcmp(type, "DHCPRELEASE")) ++ ubus_event_bcast("dhcp.release", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); + } + + static void log_options(unsigned char *start, u32 xid)