changeset 4172:9298bf22c505 draft

arp: fix memory leak Prior patch introduced a memory leak if a new ARP state was added after BPF_FREE was set. Cater for this.
author Roy Marples <roy@marples.name>
date Wed, 25 Oct 2017 00:23:29 +0100
parents 4ff80b2bbba1
children e336de0ca5ae
files src/arp.c
diffstat 1 files changed, 24 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/arp.c	Wed Oct 25 00:04:44 2017 +0100
+++ b/src/arp.c	Wed Oct 25 00:23:29 2017 +0100
@@ -186,6 +186,27 @@
 }
 
 static void
+arp_tryfree(struct interface *ifp)
+{
+	struct iarp_state *state = ARP_STATE(ifp);
+
+	/* If there are no more ARP states, close the socket. */
+	if (TAILQ_FIRST(&state->arp_states) == NULL) {
+		arp_close(ifp);
+		if (state->bpf_flags & BPF_READING)
+			state->bpf_flags |= BPF_EOF | BPF_FREE;
+		else {
+			free(state);
+			ifp->if_data[IF_DATA_ARP] = NULL;
+		}
+	} else {
+		state->bpf_flags &= BPF_FREE;
+		if (bpf_arp(ifp, state->bpf_fd) == -1)
+			logerr(__func__);
+	}
+}
+
+static void
 arp_read(void *arg)
 {
 	struct interface *ifp = arg;
@@ -214,10 +235,8 @@
 	}
 	if (state != NULL) {
 		state->bpf_flags &= ~BPF_READING;
-		if (state->bpf_flags & BPF_FREE) {
-			free(state);
-			ifp->if_data[IF_DATA_ARP] = NULL;
-		}
+		if (state->bpf_flags & BPF_FREE)
+			arp_tryfree(ifp);
 	}
 }
 
@@ -507,19 +526,7 @@
 	if (astate->free_cb)
 		astate->free_cb(astate);
 	free(astate);
-
-	/* If there are no more ARP states, close the socket. */
-	if (TAILQ_FIRST(&state->arp_states) == NULL) {
-		arp_close(ifp);
-		if (state->bpf_flags & BPF_READING)
-			state->bpf_flags |= BPF_EOF | BPF_FREE;
-		else {
-			free(state);
-			ifp->if_data[IF_DATA_ARP] = NULL;
-		}
-	} else
-		if (bpf_arp(ifp, state->bpf_fd) == -1)
-			logerr(__func__);
+	arp_tryfree(ifp);
 }
 
 static void