summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2016-01-04 17:17:41 +0000
committerSimon Kelley <simon@thekelleys.org.uk>2016-01-04 17:17:41 +0000
commitd917275e481add809cd5c40650f339ae994ee35f (patch)
treeb0629d71217465147961fce57c63214e5dc54db4
parentcc7cb0b89326b7c2ecdd4848002d10a4cbed894d (diff)
downloaddnsmasq-d917275e481add809cd5c40650f339ae994ee35f.tar.gz
Fix botch in new arp-cache linked-list code resulting in 100% CPU spin.v2.76test4
-rw-r--r--src/arp.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/arp.c b/src/arp.c
index f41cdec..d17eedb 100644
--- a/src/arp.c
+++ b/src/arp.c
@@ -110,7 +110,7 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
/* If in lazy mode, we cache absence of ARP entries. */
int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
{
- struct arp_record *arp, **up;
+ struct arp_record *arp, *tmp, **up;
int updated = 0;
again:
@@ -155,16 +155,20 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
iface_enumerate(AF_UNSPEC, NULL, filter_mac);
/* Remove all unconfirmed entries to old list. */
- for (arp = arps, up = &arps; arp; arp = arp->next)
- if (arp->status == ARP_MARK)
- {
- *up = arp->next;
- arp->next = old;
- old = arp;
- }
- else
- up = &arp->next;
+ for (arp = arps, up = &arps; arp; arp = tmp)
+ {
+ tmp = arp->next;
+ if (arp->status == ARP_MARK)
+ {
+ *up = arp->next;
+ arp->next = old;
+ old = arp;
+ }
+ else
+ up = &arp->next;
+ }
+
goto again;
}