summaryrefslogtreecommitdiff
path: root/source4/lib/netif/interface.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-12-28 03:04:40 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:47:52 -0500
commite4dbcc0d5d6c9c68a7f3c437611b726f9f0211cf (patch)
treecc0456ffcb6dbb4627dd84048f2a22c5efe2a162 /source4/lib/netif/interface.c
parent1f700876633c1f96bfc38d366dd0d5571aaa8696 (diff)
downloadsamba-e4dbcc0d5d6c9c68a7f3c437611b726f9f0211cf.tar.gz
samba-e4dbcc0d5d6c9c68a7f3c437611b726f9f0211cf.tar.bz2
samba-e4dbcc0d5d6c9c68a7f3c437611b726f9f0211cf.zip
r12531: 'make quicktest' was taking 15 minutes on my system due to failing DNS
lookups in load_interfaces(). The reason was my eth0 interface was down, and it was being interpreted as a DNS name. This patch changes load_interfaces() to happening automatically when interfaces are first needed instead of on the startup of every samba binary. This means that (for example) ldbadd doesn't call load_interfaces(), which means no slow DNS lookups. I also reduced the number of static globals in interface.c to 1, and changed from malloc to talloc When you want to force a reload of the interfaces list, you now call unload_interfaces(), which means the next call that needs the interfaces list will reload it (This used to be commit f79d90bd1364b970adb2981b2572e77066431f1e)
Diffstat (limited to 'source4/lib/netif/interface.c')
-rw-r--r--source4/lib/netif/interface.c101
1 files changed, 41 insertions, 60 deletions
diff --git a/source4/lib/netif/interface.c b/source4/lib/netif/interface.c
index 2abb08e090..ce94f482f5 100644
--- a/source4/lib/netif/interface.c
+++ b/source4/lib/netif/interface.c
@@ -25,12 +25,6 @@
#include "lib/netif/netif.h"
#include "dlinklist.h"
-static struct iface_struct *probed_ifaces;
-static int total_probed;
-
-static struct ipv4_addr allones_ip;
-struct ipv4_addr loopback_ip;
-
/* used for network interfaces */
struct interface {
struct interface *next, *prev;
@@ -80,12 +74,12 @@ static void add_interface(struct in_addr ip, struct in_addr nmask)
return;
}
- if (nmask.s_addr == allones_ip.addr) {
+ if (nmask.s_addr == ~0) {
DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
return;
}
- iface = malloc_p(struct interface);
+ iface = talloc(local_interfaces, struct interface);
if (!iface) return;
ZERO_STRUCTPN(iface);
@@ -114,7 +108,9 @@ This handles the following different forms:
4) ip/mask
5) bcast/mask
****************************************************************************/
-static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token)
+static void interpret_interface(const char *token,
+ struct iface_struct *probed_ifaces,
+ int total_probed)
{
struct in_addr ip, nmask;
char *p;
@@ -143,7 +139,7 @@ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token)
ip.s_addr = interpret_addr2(token).addr;
for (i=0;i<total_probed;i++) {
if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
- allones_ip.addr != probed_ifaces[i].netmask.s_addr) {
+ probed_ifaces[i].netmask.s_addr != ~0) {
add_interface(probed_ifaces[i].ip,
probed_ifaces[i].netmask);
return;
@@ -184,40 +180,24 @@ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token)
/****************************************************************************
load the list of network interfaces
****************************************************************************/
-void load_interfaces(void)
+static void load_interfaces(void)
{
const char **ptr;
int i;
struct iface_struct ifaces[MAX_INTERFACES];
- TALLOC_CTX *mem_ctx;
+ struct ipv4_addr loopback_ip;
+ int total_probed;
- ptr = lp_interfaces();
- mem_ctx = talloc_init("load_interfaces");
- if (!mem_ctx) {
- DEBUG(2,("no memory to load interfaces \n"));
+ if (local_interfaces != NULL) {
return;
}
- allones_ip = interpret_addr2("255.255.255.255");
+ ptr = lp_interfaces();
loopback_ip = interpret_addr2("127.0.0.1");
- SAFE_FREE(probed_ifaces);
-
- /* dump the current interfaces if any */
- while (local_interfaces) {
- struct interface *iface = local_interfaces;
- DLIST_REMOVE(local_interfaces, local_interfaces);
- ZERO_STRUCTPN(iface);
- SAFE_FREE(iface);
- }
-
/* probe the kernel for interfaces */
total_probed = get_interfaces(ifaces, MAX_INTERFACES);
- if (total_probed > 0) {
- probed_ifaces = memdup(ifaces, sizeof(ifaces[0])*total_probed);
- }
-
/* if we don't have a interfaces line then use all broadcast capable
interfaces except loopback */
if (!ptr || !*ptr || !**ptr) {
@@ -225,56 +205,43 @@ void load_interfaces(void)
DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
}
for (i=0;i<total_probed;i++) {
- if (probed_ifaces[i].netmask.s_addr != allones_ip.addr &&
- probed_ifaces[i].ip.s_addr != loopback_ip.addr) {
- add_interface(probed_ifaces[i].ip,
- probed_ifaces[i].netmask);
+ if (ifaces[i].netmask.s_addr != ~0 &&
+ ifaces[i].ip.s_addr != loopback_ip.addr) {
+ add_interface(ifaces[i].ip,
+ ifaces[i].netmask);
}
}
- goto exit;
}
- if (ptr) {
- while (*ptr) {
- interpret_interface(mem_ctx, *ptr);
- ptr++;
- }
+ while (ptr && *ptr) {
+ interpret_interface(*ptr, ifaces, total_probed);
+ ptr++;
}
if (!local_interfaces) {
DEBUG(0,("WARNING: no network interfaces found\n"));
}
-
-exit:
- talloc_free(mem_ctx);
}
-/****************************************************************************
-return True if the list of probed interfaces has changed
-****************************************************************************/
-BOOL interfaces_changed(void)
+/*
+ unload the interfaces list, so it can be reloaded when needed
+*/
+void unload_interfaces(void)
{
- int n;
- struct iface_struct ifaces[MAX_INTERFACES];
-
- n = get_interfaces(ifaces, MAX_INTERFACES);
-
- if ((n > 0 )&& (n != total_probed ||
- memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
- return True;
- }
-
- return False;
+ talloc_free(local_interfaces);
+ local_interfaces = NULL;
}
-
/****************************************************************************
check if an IP is one of mine
**************************************************************************/
BOOL ismyip(struct ipv4_addr ip)
{
struct interface *i;
+
+ load_interfaces();
+
for (i=local_interfaces;i;i=i->next) {
if (i->ip.addr == ip.addr) return True;
}
@@ -289,6 +256,8 @@ int iface_count(void)
int ret = 0;
struct interface *i;
+ load_interfaces();
+
for (i=local_interfaces;i;i=i->next)
ret++;
return ret;
@@ -301,6 +270,8 @@ const char *iface_n_ip(int n)
{
struct interface *i;
+ load_interfaces();
+
for (i=local_interfaces;i && n;i=i->next)
n--;
@@ -317,6 +288,8 @@ const char *iface_n_bcast(int n)
{
struct interface *i;
+ load_interfaces();
+
for (i=local_interfaces;i && n;i=i->next)
n--;
@@ -333,6 +306,8 @@ const char *iface_n_netmask(int n)
{
struct interface *i;
+ load_interfaces();
+
for (i=local_interfaces;i && n;i=i->next)
n--;
@@ -350,6 +325,9 @@ const char *iface_best_ip(const char *dest)
{
struct interface *iface;
struct in_addr ip;
+
+ load_interfaces();
+
ip.s_addr = interpret_addr(dest);
iface = iface_find(ip, True);
if (iface) {
@@ -364,6 +342,9 @@ const char *iface_best_ip(const char *dest)
BOOL iface_is_local(const char *dest)
{
struct in_addr ip;
+
+ load_interfaces();
+
ip.s_addr = interpret_addr(dest);
if (iface_find(ip, True)) {
return True;