cfdd2cf
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
cfdd2cf
index 1896a64..aa5ec84 100644
cfdd2cf
--- a/src/dnsmasq.h
cfdd2cf
+++ b/src/dnsmasq.h
cfdd2cf
@@ -487,6 +487,7 @@ struct serverfd {
cfdd2cf
   int fd;
cfdd2cf
   union mysockaddr source_addr;
cfdd2cf
   char interface[IF_NAMESIZE+1];
cfdd2cf
+  unsigned int ifindex, used;
cfdd2cf
   struct serverfd *next;
cfdd2cf
 };
cfdd2cf
 
cfdd2cf
diff --git a/src/network.c b/src/network.c
cfdd2cf
index e7722fd..d87d08f 100644
cfdd2cf
--- a/src/network.c
cfdd2cf
+++ b/src/network.c
cfdd2cf
@@ -1204,6 +1204,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
cfdd2cf
 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
cfdd2cf
 {
cfdd2cf
   struct serverfd *sfd;
cfdd2cf
+  unsigned int ifindex = 0;
cfdd2cf
   int errsave;
cfdd2cf
 
cfdd2cf
   /* when using random ports, servers which would otherwise use
cfdd2cf
@@ -1224,11 +1225,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
cfdd2cf
 	return NULL;
cfdd2cf
 #endif
cfdd2cf
     }
cfdd2cf
+
cfdd2cf
+  if (intname && strlen(intname) != 0)
cfdd2cf
+    ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
cfdd2cf
       
cfdd2cf
   /* may have a suitable one already */
cfdd2cf
   for (sfd = daemon->sfds; sfd; sfd = sfd->next )
cfdd2cf
     if (sockaddr_isequal(&sfd->source_addr, addr) &&
cfdd2cf
-	strcmp(intname, sfd->interface) == 0)
cfdd2cf
+	strcmp(intname, sfd->interface) == 0 &&
cfdd2cf
+	ifindex == sfd->ifindex) 
cfdd2cf
       return sfd;
cfdd2cf
   
cfdd2cf
   /* need to make a new one. */
cfdd2cf
@@ -1250,11 +1255,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
cfdd2cf
       errno = errsave;
cfdd2cf
       return NULL;
cfdd2cf
     }
cfdd2cf
-    
cfdd2cf
+
cfdd2cf
   strcpy(sfd->interface, intname); 
cfdd2cf
   sfd->source_addr = *addr;
cfdd2cf
   sfd->next = daemon->sfds;
cfdd2cf
+  sfd->ifindex = ifindex;
cfdd2cf
   daemon->sfds = sfd;
cfdd2cf
+
cfdd2cf
   return sfd; 
cfdd2cf
 }
cfdd2cf
 
cfdd2cf
@@ -1429,12 +1436,16 @@ void check_servers(void)
cfdd2cf
 {
cfdd2cf
   struct irec *iface;
cfdd2cf
   struct server *serv;
cfdd2cf
+  struct serverfd *sfd, *tmp, **up;
cfdd2cf
   int port = 0, count;
cfdd2cf
 
cfdd2cf
   /* interface may be new since startup */
cfdd2cf
   if (!option_bool(OPT_NOWILD))
cfdd2cf
     enumerate_interfaces(0);
cfdd2cf
   
cfdd2cf
+  for (sfd = daemon->sfds; sfd; sfd = sfd->next)
cfdd2cf
+    sfd->used = 0;
cfdd2cf
+
cfdd2cf
 #ifdef HAVE_DNSSEC
cfdd2cf
  /* Disable DNSSEC validation when using server=/domain/.... servers
cfdd2cf
     unless there's a configured trust anchor. */
cfdd2cf
@@ -1505,6 +1516,9 @@ void check_servers(void)
cfdd2cf
 	      serv->flags |= SERV_MARK;
cfdd2cf
 	      continue;
cfdd2cf
 	    }
cfdd2cf
+	  
cfdd2cf
+	  if (serv->sfd)
cfdd2cf
+	    serv->sfd->used = 1;
cfdd2cf
 	}
cfdd2cf
       
cfdd2cf
       if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
cfdd2cf
@@ -1547,6 +1561,20 @@ void check_servers(void)
cfdd2cf
   if (count - 1 > SERVERS_LOGGED)
cfdd2cf
     my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
cfdd2cf
 
cfdd2cf
+  /* Remove unused sfds */
cfdd2cf
+  for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
cfdd2cf
+    {
cfdd2cf
+       tmp = sfd->next;
cfdd2cf
+       if (!sfd->used) 
cfdd2cf
+	{
cfdd2cf
+	  *up = sfd->next;
cfdd2cf
+	  close(sfd->fd);
cfdd2cf
+	  free(sfd);
cfdd2cf
+	} 
cfdd2cf
+      else
cfdd2cf
+	up = &sfd->next;
cfdd2cf
+    }
cfdd2cf
+  
cfdd2cf
   cleanup_servers();
cfdd2cf
 }
cfdd2cf