svn commit: samba r21085 - in branches/SAMBA_4_0/source/nbt_server/wins: .

metze at samba.org metze at samba.org
Wed Jan 31 13:47:52 GMT 2007


Author: metze
Date: 2007-01-31 13:47:52 +0000 (Wed, 31 Jan 2007)
New Revision: 21085

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21085

Log:
implement something like the parameter
HKEY_LOCAL_MACHINE\System\CurrentControlset\Services\WINS\Parameters\Randomize1CList

nbtd:wins_randomize1Clist=yes
nbtd:wins_randomize1Clist_mask=255.255.0.0

metze
Modified:
   branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c


Changeset:
Modified: branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c
===================================================================
--- branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c	2007-01-31 13:47:37 UTC (rev 21084)
+++ branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c	2007-01-31 13:47:52 UTC (rev 21085)
@@ -29,7 +29,9 @@
 #include "system/time.h"
 #include "libcli/composite/composite.h"
 #include "smbd/service_task.h"
+#include "system/network.h"
 #include "lib/socket/socket.h"
+#include "lib/socket/netif.h"
 #include "lib/ldb/include/ldb.h"
 
 /*
@@ -558,6 +560,98 @@
 	nbtd_name_registration_reply(nbtsock, packet, src, rcode);
 }
 
+static uint32_t ipv4_match_bits(struct ipv4_addr ip1,struct ipv4_addr ip2)
+{
+	uint32_t i, j, match=0;
+	uint8_t *p1, *p2;
+
+	p1 = (uint8_t *)&ip1.addr;
+	p2 = (uint8_t *)&ip2.addr;
+
+	for (i=0; i<4; i++) {
+		if (p1[i] != p2[i]) break;
+		match += 8;
+	}
+
+	if (i==4) return match;
+
+	for (j=0; j<8; j++) {
+		if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
+			break;
+		match++;
+	}
+
+	return match;
+}
+
+static int nbtd_wins_randomize1Clist_sort(void *p1,/* (const char **) */
+					  void *p2,/* (const char **) */
+					  struct socket_address *src)
+{
+	const char *a1 = (const char *)*(const char **)p1;
+	const char *a2 = (const char *)*(const char **)p2;
+	uint32_t match_bits1;
+	uint32_t match_bits2;
+
+	match_bits1 = ipv4_match_bits(interpret_addr2(a1), interpret_addr2(src->addr));
+	match_bits2 = ipv4_match_bits(interpret_addr2(a2), interpret_addr2(src->addr));
+
+	return match_bits2 - match_bits1;
+}
+
+static void nbtd_wins_randomize1Clist(const char **addresses, struct socket_address *src)
+{
+	const char *mask;
+	const char *tmp;
+	uint32_t num_addrs;
+	uint32_t idx, sidx;
+	int r;
+
+	for (num_addrs=0; addresses[num_addrs]; num_addrs++) { /* noop */ }
+
+	if (num_addrs <= 1) return; /* nothing to do */
+
+	/* first sort the addresses depending on the matching to the client */
+	ldb_qsort(addresses, num_addrs , sizeof(addresses[0]),
+		  src, (ldb_qsort_cmp_fn_t)nbtd_wins_randomize1Clist_sort);
+
+	mask = lp_parm_string(-1, "nbtd", "wins_randomize1Clist_mask");
+	if (!mask) {
+		mask = "255.255.255.0";
+	}
+
+	/* 
+	 * choose a random address to be the first in the response to the client,
+	 * preferr the addresses inside the nbtd:wins_randomize1Clist_mask netmask
+	 */
+	r = random();
+	idx = sidx = r % num_addrs;
+
+	while (1) {
+		BOOL same;
+
+		/* if the current one is in the same subnet, use it */
+		same = iface_same_net(addresses[idx], src->addr, mask);
+		if (same) {
+			sidx = idx;
+			break;
+		}
+
+		/* we need to check for idx == 0, after checking for the same net */
+		if (idx == 0) break;
+		/* 
+		 * if we haven't found an address in the same subnet, search in ones
+		 * which match the client more
+		 */
+		idx = r % idx;
+	}
+
+	/* note sidx == 0 is also valid here ... */
+	tmp		= addresses[0];
+	addresses[0]	= addresses[sidx];
+	addresses[sidx]	= tmp;
+}
+
 /*
   query a name
 */
@@ -678,6 +772,17 @@
 		nb_flags |= (rec->node <<13);
 	}
 
+	/*
+	 * since Windows 2000 Service Pack 2 there's on option to trigger this behavior:
+	 *
+	 * HKEY_LOCAL_MACHINE\System\CurrentControlset\Services\WINS\Parameters\Randomize1CList
+	 * Typ: Daten REG_DWORD
+	 * Value: 0 = deactivated, 1 = activated
+	 */
+	if (name->type == NBT_NAME_LOGON && lp_parm_bool(-1, "nbtd", "wins_randomize1Clist", False)) {
+		nbtd_wins_randomize1Clist(addresses, src);
+	}
+
 found:
 	nbtd_name_query_reply(nbtsock, packet, src, name, 
 			      0, nb_flags, addresses);



More information about the samba-cvs mailing list