diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2017-05-10 22:21:53 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2017-05-10 22:21:53 +0100 |
commit | c7be0164ce6ae89d6f2f0ffea14e2612418dd5da (patch) | |
tree | 7fb64d99daff3ff648472da6620c9493eaec4631 | |
parent | d203af4a0219d51adf3587d084bd420affae3a9f (diff) | |
download | dnsmasq-2.77rc2.tar.gz |
Suppress DHCP ping checks when allocating on the loopback interface.v2.77rc2
-rw-r--r-- | src/dhcp.c | 24 | ||||
-rw-r--r-- | src/dnsmasq.h | 7 | ||||
-rw-r--r-- | src/rfc2131.c | 11 |
3 files changed, 24 insertions, 18 deletions
@@ -145,7 +145,7 @@ void dhcp_packet(time_t now, int pxe_fd) struct cmsghdr *cmptr; struct iovec iov; ssize_t sz; - int iface_index = 0, unicast_dest = 0, is_inform = 0; + int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0; int rcvd_iface_index; struct in_addr iface_addr; struct iface_param parm; @@ -223,9 +223,13 @@ void dhcp_packet(time_t now, int pxe_fd) } #endif - if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name)) + if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) || + ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != -1) return; - + + mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base; + loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK); + #ifdef HAVE_LINUX_NETWORK /* ARP fiddling uses original interface even if we pretend to use a different one. */ strncpy(arp_req.arp_dev, ifr.ifr_name, 16); @@ -331,7 +335,7 @@ void dhcp_packet(time_t now, int pxe_fd) /* We're relaying this request */ if (parm.relay_local.s_addr != 0 && - relay_upstream4(parm.relay, (struct dhcp_packet *)daemon->dhcp_packet.iov_base, (size_t)sz, iface_index)) + relay_upstream4(parm.relay, mess, (size_t)sz, iface_index)) return; /* May have configured relay, but not DHCP server */ @@ -340,7 +344,7 @@ void dhcp_packet(time_t now, int pxe_fd) lease_prune(NULL, now); /* lose any expired leases */ iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, - now, unicast_dest, &is_inform, pxe_fd, iface_addr, recvtime); + now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime); lease_update_file(now); lease_update_dns(0); @@ -647,7 +651,7 @@ struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct i This wrapper handles a cache and load-limiting. Return is NULL is address in use, or a pointer to a cache entry recording that it isn't. */ -struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash) +struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash, int loopback) { static struct ping_result dummy; struct ping_result *r, *victim = NULL; @@ -671,9 +675,9 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h } /* didn't find cached entry */ - if ((count >= max) || option_bool(OPT_NO_PING)) + if ((count >= max) || option_bool(OPT_NO_PING) || loopback) { - /* overloaded, or configured not to check, return "not in use" */ + /* overloaded, or configured not to check, loopback interface, return "not in use" */ dummy.hash = 0; return &dummy; } @@ -705,7 +709,7 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h int address_allocate(struct dhcp_context *context, struct in_addr *addrp, unsigned char *hwaddr, int hw_len, - struct dhcp_netid *netids, time_t now) + struct dhcp_netid *netids, time_t now, int loopback) { /* Find a free address: exclude anything in use and anything allocated to a particular hwaddr/clientid/hostname in our configuration. @@ -763,7 +767,7 @@ int address_allocate(struct dhcp_context *context, { struct ping_result *r; - if ((r = do_icmp_ping(now, addr, j))) + if ((r = do_icmp_ping(now, addr, j, loopback))) { /* consec-ip mode: we offered this address for another client (different hash) recently, don't offer it to this one. */ diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 14783c9..06fae35 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -1292,10 +1292,10 @@ struct dhcp_context *narrow_context(struct dhcp_context *context, struct in_addr taddr, struct dhcp_netid *netids); struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, - unsigned int hash); + unsigned int hash, int loopback); int address_allocate(struct dhcp_context *context, struct in_addr *addrp, unsigned char *hwaddr, int hw_len, - struct dhcp_netid *netids, time_t now); + struct dhcp_netid *netids, time_t now, int loopback); void dhcp_read_ethers(void); struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr); char *host_from_dns(struct in_addr addr); @@ -1344,7 +1344,8 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, /* rfc2131.c */ #ifdef HAVE_DHCP size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, - size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe_fd, struct in_addr fallback, time_t recvtime); + size_t sz, time_t now, int unicast_dest, int loopback, + int *is_inform, int pxe_fd, struct in_addr fallback, time_t recvtime); unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr, int clid_len, unsigned char *clid, int *len_out); #endif diff --git a/src/rfc2131.c b/src/rfc2131.c index 023a559..484eeaa 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -67,7 +67,8 @@ static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dh static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid); size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, - size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback, time_t recvtime) + size_t sz, time_t now, int unicast_dest, int loopback, + int *is_inform, int pxe, struct in_addr fallback, time_t recvtime) { unsigned char *opt, *clid = NULL; struct dhcp_lease *ltmp, *lease = NULL; @@ -575,7 +576,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, lease_prune(lease, now); lease = NULL; } - if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now)) + if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now, loopback)) message = _("no address available"); } else @@ -1036,7 +1037,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, else if (have_config(config, CONFIG_DECLINED) && difftime(now, config->decline_time) < (float)DECLINE_BACKOFF) my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs); - else if (!do_icmp_ping(now, config->addr, 0)) + else if (!do_icmp_ping(now, config->addr, 0, loopback)) my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by another host"), addrs); else conf = config->addr; @@ -1050,11 +1051,11 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, !config_find_by_address(daemon->dhcp_conf, lease->addr)) mess->yiaddr = lease->addr; else if (opt && address_available(context, addr, tagif_netid) && !lease_find_by_addr(addr) && - !config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0)) + !config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0, loopback)) mess->yiaddr = addr; else if (emac_len == 0) message = _("no unique-id"); - else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now)) + else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now, loopback)) message = _("no address available"); } |