|
|
@@ -1,277 +0,0 @@
|
|
|
-From a0358e5ddbc1ef3dec791f11f95f5dbe56087a5e Mon Sep 17 00:00:00 2001
|
|
|
-From: Simon Kelley <[email protected]>
|
|
|
-Date: Sat, 7 Jun 2014 13:38:48 +0100
|
|
|
-Subject: [PATCH] Handle async notification of address changes using the event
|
|
|
- system.
|
|
|
-
|
|
|
----
|
|
|
- CHANGELOG | 4 ++++
|
|
|
- src/bpf.c | 6 +++---
|
|
|
- src/dhcp6.c | 10 ----------
|
|
|
- src/dnsmasq.c | 13 +++++++++++--
|
|
|
- src/dnsmasq.h | 6 ++++--
|
|
|
- src/netlink.c | 39 ++++++++++-----------------------------
|
|
|
- src/network.c | 11 +++--------
|
|
|
- 7 files changed, 35 insertions(+), 54 deletions(-)
|
|
|
-
|
|
|
---- a/CHANGELOG
|
|
|
-+++ b/CHANGELOG
|
|
|
-@@ -15,6 +15,10 @@ version 2.71
|
|
|
- regression introduced in 2.69. Thanks to James Hunt and
|
|
|
- the Ubuntu crowd for assistance in fixing this.
|
|
|
-
|
|
|
-+ Fix race condition which could lock up dnsmasq when an
|
|
|
-+ interface goes down and up rapidly. Thanks to Conrad
|
|
|
-+ Kostecki for helping to chase this down.
|
|
|
-+
|
|
|
-
|
|
|
- version 2.70
|
|
|
- Fix crash, introduced in 2.69, on TCP request when dnsmasq
|
|
|
---- a/src/bpf.c
|
|
|
-+++ b/src/bpf.c
|
|
|
-@@ -376,7 +376,7 @@ void route_init(void)
|
|
|
- die(_("cannot create PF_ROUTE socket: %s"), NULL, EC_BADNET);
|
|
|
- }
|
|
|
-
|
|
|
--void route_sock(time_t now)
|
|
|
-+void route_sock(void)
|
|
|
- {
|
|
|
- struct if_msghdr *msg;
|
|
|
- int rc = recv(daemon->routefd, daemon->packet, daemon->packet_buff_sz, 0);
|
|
|
-@@ -401,7 +401,7 @@ void route_sock(time_t now)
|
|
|
- else if (msg->ifm_type == RTM_NEWADDR)
|
|
|
- {
|
|
|
- del_family = 0;
|
|
|
-- newaddress(now);
|
|
|
-+ send_newaddr();
|
|
|
- }
|
|
|
- else if (msg->ifm_type == RTM_DELADDR)
|
|
|
- {
|
|
|
-@@ -439,7 +439,7 @@ void route_sock(time_t now)
|
|
|
- of += sizeof(long) - (diff & (sizeof(long) - 1));
|
|
|
- }
|
|
|
-
|
|
|
-- newaddress(now);
|
|
|
-+ send_newaddr();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
---- a/src/dnsmasq.c
|
|
|
-+++ b/src/dnsmasq.c
|
|
|
-@@ -917,10 +917,10 @@ int main (int argc, char **argv)
|
|
|
-
|
|
|
- #if defined(HAVE_LINUX_NETWORK)
|
|
|
- if (FD_ISSET(daemon->netlinkfd, &rset))
|
|
|
-- netlink_multicast(now);
|
|
|
-+ netlink_multicast();
|
|
|
- #elif defined(HAVE_BSD_NETWORK)
|
|
|
- if (FD_ISSET(daemon->routefd, &rset))
|
|
|
-- route_sock(now);
|
|
|
-+ route_sock();
|
|
|
- #endif
|
|
|
-
|
|
|
- /* Check for changes to resolv files once per second max. */
|
|
|
-@@ -1037,6 +1037,11 @@ void send_alarm(time_t event, time_t now
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-+void send_newaddr(void)
|
|
|
-+{
|
|
|
-+ send_event(pipewrite, EVENT_NEWADDR, 0, NULL);
|
|
|
-+}
|
|
|
-+
|
|
|
- void send_event(int fd, int event, int data, char *msg)
|
|
|
- {
|
|
|
- struct event_desc ev;
|
|
|
-@@ -1230,6 +1235,10 @@ static void async_event(int pipe, time_t
|
|
|
- if (daemon->log_file != NULL)
|
|
|
- log_reopen(daemon->log_file);
|
|
|
- break;
|
|
|
-+
|
|
|
-+ case EVENT_NEWADDR:
|
|
|
-+ newaddress(now);
|
|
|
-+ break;
|
|
|
-
|
|
|
- case EVENT_TERM:
|
|
|
- /* Knock all our children on the head. */
|
|
|
---- a/src/dnsmasq.h
|
|
|
-+++ b/src/dnsmasq.h
|
|
|
-@@ -165,6 +165,7 @@ struct event_desc {
|
|
|
- #define EVENT_LUA_ERR 19
|
|
|
- #define EVENT_TFTP_ERR 20
|
|
|
- #define EVENT_INIT 21
|
|
|
-+#define EVENT_NEWADDR 22
|
|
|
-
|
|
|
- /* Exit codes. */
|
|
|
- #define EC_GOOD 0
|
|
|
-@@ -1289,6 +1290,7 @@ unsigned char *extended_hwaddr(int hwtyp
|
|
|
- int make_icmp_sock(void);
|
|
|
- int icmp_ping(struct in_addr addr);
|
|
|
- #endif
|
|
|
-+void send_newaddr(void);
|
|
|
- void send_alarm(time_t event, time_t now);
|
|
|
- void send_event(int fd, int event, int data, char *msg);
|
|
|
- void clear_cache_and_reload(time_t now);
|
|
|
-@@ -1297,7 +1299,7 @@ void poll_resolv(int force, int do_reloa
|
|
|
- /* netlink.c */
|
|
|
- #ifdef HAVE_LINUX_NETWORK
|
|
|
- void netlink_init(void);
|
|
|
--void netlink_multicast(time_t now);
|
|
|
-+void netlink_multicast(void);
|
|
|
- #endif
|
|
|
-
|
|
|
- /* bpf.c */
|
|
|
-@@ -1306,7 +1308,7 @@ void init_bpf(void);
|
|
|
- void send_via_bpf(struct dhcp_packet *mess, size_t len,
|
|
|
- struct in_addr iface_addr, struct ifreq *ifr);
|
|
|
- void route_init(void);
|
|
|
--void route_sock(time_t now);
|
|
|
-+void route_sock(void);
|
|
|
- #endif
|
|
|
-
|
|
|
- /* bpf.c or netlink.c */
|
|
|
---- a/src/netlink.c
|
|
|
-+++ b/src/netlink.c
|
|
|
-@@ -38,7 +38,7 @@
|
|
|
- static struct iovec iov;
|
|
|
- static u32 netlink_pid;
|
|
|
-
|
|
|
--static int nl_async(struct nlmsghdr *h);
|
|
|
-+static void nl_async(struct nlmsghdr *h);
|
|
|
-
|
|
|
- void netlink_init(void)
|
|
|
- {
|
|
|
-@@ -142,7 +142,7 @@ int iface_enumerate(int family, void *pa
|
|
|
- struct nlmsghdr *h;
|
|
|
- ssize_t len;
|
|
|
- static unsigned int seq = 0;
|
|
|
-- int callback_ok = 1, newaddr = 0;
|
|
|
-+ int callback_ok = 1;
|
|
|
-
|
|
|
- struct {
|
|
|
- struct nlmsghdr nlh;
|
|
|
-@@ -191,21 +191,10 @@ int iface_enumerate(int family, void *pa
|
|
|
- if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
|
|
|
- {
|
|
|
- /* May be multicast arriving async */
|
|
|
-- if (nl_async(h))
|
|
|
-- {
|
|
|
-- newaddr = 1;
|
|
|
-- enumerate_interfaces(1); /* reset */
|
|
|
-- }
|
|
|
-+ nl_async(h);
|
|
|
- }
|
|
|
- else if (h->nlmsg_type == NLMSG_DONE)
|
|
|
-- {
|
|
|
-- /* handle async new interface address arrivals, these have to be done
|
|
|
-- after we complete as we're not re-entrant */
|
|
|
-- if (newaddr)
|
|
|
-- newaddress(dnsmasq_time());
|
|
|
--
|
|
|
-- return callback_ok;
|
|
|
-- }
|
|
|
-+ return callback_ok;
|
|
|
- else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
|
|
|
- {
|
|
|
- struct ifaddrmsg *ifa = NLMSG_DATA(h);
|
|
|
-@@ -330,11 +319,11 @@ int iface_enumerate(int family, void *pa
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
--void netlink_multicast(time_t now)
|
|
|
-+void netlink_multicast(void)
|
|
|
- {
|
|
|
- ssize_t len;
|
|
|
- struct nlmsghdr *h;
|
|
|
-- int flags, newaddr = 0;
|
|
|
-+ int flags;
|
|
|
-
|
|
|
- /* don't risk blocking reading netlink messages here. */
|
|
|
- if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
|
|
|
-@@ -343,24 +332,19 @@ void netlink_multicast(time_t now)
|
|
|
-
|
|
|
- if ((len = netlink_recv()) != -1)
|
|
|
- for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
|
|
-- if (nl_async(h))
|
|
|
-- newaddr = 1;
|
|
|
-+ nl_async(h);
|
|
|
-
|
|
|
- /* restore non-blocking status */
|
|
|
- fcntl(daemon->netlinkfd, F_SETFL, flags);
|
|
|
--
|
|
|
-- if (newaddr)
|
|
|
-- newaddress(now);
|
|
|
- }
|
|
|
-
|
|
|
--static int nl_async(struct nlmsghdr *h)
|
|
|
-+static void nl_async(struct nlmsghdr *h)
|
|
|
- {
|
|
|
- if (h->nlmsg_type == NLMSG_ERROR)
|
|
|
- {
|
|
|
- struct nlmsgerr *err = NLMSG_DATA(h);
|
|
|
- if (err->error != 0)
|
|
|
- my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
|
|
|
-- return 0;
|
|
|
- }
|
|
|
- else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
|
|
|
- {
|
|
|
-@@ -385,18 +369,15 @@ static int nl_async(struct nlmsghdr *h)
|
|
|
- else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
|
|
|
- fd = daemon->rfd_save->fd;
|
|
|
- else
|
|
|
-- return 0;
|
|
|
-+ return;
|
|
|
-
|
|
|
- while(sendto(fd, daemon->packet, daemon->packet_len, 0,
|
|
|
- &daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());
|
|
|
- }
|
|
|
- }
|
|
|
-- return 0;
|
|
|
- }
|
|
|
- else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
|
|
|
-- return 1; /* clever bind mode - rescan */
|
|
|
--
|
|
|
-- return 0;
|
|
|
-+ send_newaddr();
|
|
|
- }
|
|
|
- #endif
|
|
|
-
|
|
|
---- a/src/network.c
|
|
|
-+++ b/src/network.c
|
|
|
-@@ -551,7 +551,7 @@ static int iface_allowed_v4(struct in_ad
|
|
|
- int enumerate_interfaces(int reset)
|
|
|
- {
|
|
|
- static struct addrlist *spare = NULL;
|
|
|
-- static int done = 0, active = 0;
|
|
|
-+ static int done = 0;
|
|
|
- struct iface_param param;
|
|
|
- int errsave, ret = 1;
|
|
|
- struct addrlist *addr, *tmp;
|
|
|
-@@ -570,14 +570,11 @@ int enumerate_interfaces(int reset)
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
-- if (done || active)
|
|
|
-+ if (done)
|
|
|
- return 1;
|
|
|
-
|
|
|
- done = 1;
|
|
|
-
|
|
|
-- /* protect against recusive calls from iface_enumerate(); */
|
|
|
-- active = 1;
|
|
|
--
|
|
|
- if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
|
|
- return 0;
|
|
|
-
|
|
|
-@@ -677,10 +674,8 @@ int enumerate_interfaces(int reset)
|
|
|
- }
|
|
|
-
|
|
|
- errno = errsave;
|
|
|
--
|
|
|
- spare = param.spare;
|
|
|
-- active = 0;
|
|
|
--
|
|
|
-+
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|