svn commit: samba r13060 - in branches/SAMBA_4_0/source: nbt_server/wins wrepl_server

metze at samba.org metze at samba.org
Sat Jan 21 08:53:57 GMT 2006


Author: metze
Date: 2006-01-21 08:53:56 +0000 (Sat, 21 Jan 2006)
New Revision: 13060

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

Log:
- return only active addresses in name query responses
- replicate only active addresses

metze
Modified:
   branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c
   branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c
   branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c
   branches/SAMBA_4_0/source/wrepl_server/wrepl_scavenging.c


Changeset:
Modified: branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c
===================================================================
--- branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c	2006-01-21 07:57:39 UTC (rev 13059)
+++ branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c	2006-01-21 08:53:56 UTC (rev 13060)
@@ -446,6 +446,7 @@
 	struct winsdb_record *rec;
 	struct ldb_context *wins_db = h->ldb;
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	time_t now = time(NULL);
 
 	/* find the record in the WINS database */
 	ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, name), LDB_SCOPE_BASE, 
@@ -461,17 +462,9 @@
 
 	talloc_steal(tmp_ctx, res);
 
-	status = winsdb_record(h, res->msgs[0], tmp_ctx, &rec);
+	status = winsdb_record(h, res->msgs[0], tmp_ctx, now, &rec);
 	if (!NT_STATUS_IS_OK(status)) goto failed;
 
-	/* see if it has already expired */
-	if (rec->state == WREPL_STATE_ACTIVE &&
-	    rec->expire_time <= time(NULL)) {
-		DEBUG(5,("WINS: expiring name %s (expired at %s)\n", 
-			 nbt_name_string(tmp_ctx, rec->name), timestring(tmp_ctx, rec->expire_time)));
-		rec->state = WREPL_STATE_RELEASED;
-	}
-
 	talloc_steal(mem_ctx, rec);
 	talloc_free(tmp_ctx);
 	*_rec = rec;
@@ -482,13 +475,13 @@
 	return status;
 }
 
-NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct winsdb_record **_rec)
+NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_CTX *mem_ctx, time_t now, struct winsdb_record **_rec)
 {
 	NTSTATUS status;
 	struct winsdb_record *rec;
 	struct ldb_message_element *el;
 	struct nbt_name *name;
-	uint32_t i, num_values;
+	uint32_t i, j, num_values;
 
 	rec = talloc(mem_ctx, struct winsdb_record);
 	if (rec == NULL) {
@@ -549,17 +542,43 @@
 		goto failed;
 	}
 
+	/* see if it has already expired */
+	if (!rec->is_static &&
+	    rec->expire_time <= now &&
+	    rec->state == WREPL_STATE_ACTIVE) {
+		DEBUG(5,("WINS: expiring name %s (expired at %s)\n", 
+			 nbt_name_string(mem_ctx, rec->name), timestring(mem_ctx, rec->expire_time)));
+		rec->state = WREPL_STATE_RELEASED;
+	}
+
 	rec->addresses     = talloc_array(rec, struct winsdb_addr *, num_values+1);
 	if (rec->addresses == NULL) {
 		status = NT_STATUS_NO_MEMORY;
 		goto failed;
 	}
 
-	for (i=0;i<num_values;i++) {
-		status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[i]);
+	for (i=0,j=0;i<num_values;i++) {
+		status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[j]);
 		if (!NT_STATUS_IS_OK(status)) goto failed;
+
+		/*
+		 * the record isn't static and is active
+		 * then don't add the address if it's expired
+		 */
+		if (!rec->is_static &&
+		    rec->addresses[j]->expire_time <= now &&
+		    rec->state == WREPL_STATE_ACTIVE) {
+			DEBUG(5,("WINS: expiring name addr %s of %s (expired at %s)\n", 
+				 rec->addresses[j]->address, nbt_name_string(rec->addresses[j], rec->name),
+				 timestring(rec->addresses[j], rec->addresses[j]->expire_time)));
+			talloc_free(rec->addresses[j]);
+			rec->addresses[j] = NULL;
+			continue;
+		}
+		j++;
 	}
-	rec->addresses[i] = NULL;
+	rec->addresses[j] = NULL;
+	num_values = j;
 
 	if (rec->is_static && rec->state == WREPL_STATE_ACTIVE) {
 		rec->expire_time = get_time_t_max();
@@ -568,6 +587,14 @@
 		}
 	}
 
+	if (rec->state == WREPL_STATE_ACTIVE) {
+		if (num_values < 1) {
+			DEBUG(5,("WINS: expiring name %s (because it has no active addresses)\n", 
+				 nbt_name_string(mem_ctx, rec->name)));
+			rec->state = WREPL_STATE_RELEASED;
+		}
+	}
+
 	*_rec = rec;
 	return NT_STATUS_OK;
 failed:

Modified: branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c
===================================================================
--- branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c	2006-01-21 07:57:39 UTC (rev 13059)
+++ branches/SAMBA_4_0/source/nbt_server/wins/winsserver.c	2006-01-21 08:53:56 UTC (rev 13060)
@@ -492,7 +492,6 @@
 		/* 
 		 * if the registration is for an address that is currently active, then 
 		 * just update the expiry time of the record and the address
-		 * TODO: is this correct?
 		 */
 		winsdb_addr = winsdb_addr_list_check(rec->addresses, address);
 		if (winsdb_addr) {
@@ -525,9 +524,7 @@
 
 		/* 
 		 * if the registration is for an address that is currently active, then 
-		 * just update the expiry time
 		 * just update the expiry time of the record and the address
-		 * TODO: is this correct?
 		 */
 		winsdb_addr = winsdb_addr_list_check(rec->addresses, address);
 		if (winsdb_addr) {

Modified: branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c
===================================================================
--- branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c	2006-01-21 07:57:39 UTC (rev 13059)
+++ branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c	2006-01-21 08:53:56 UTC (rev 13060)
@@ -30,6 +30,7 @@
 #include "nbt_server/wins/winsdb.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
+#include "system/time.h"
 
 static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call)
 {
@@ -178,7 +179,8 @@
 	struct wrepl_wins_name *names;
 	struct winsdb_record *rec;
 	NTSTATUS status;
-	uint32_t i;
+	uint32_t i, j;
+	time_t now = time(NULL);
 
 	owner = wreplsrv_find_owner(service, service->table, owner_in->address);
 
@@ -258,26 +260,37 @@
 	names = talloc_array(call, struct wrepl_wins_name, res->count);
 	NT_STATUS_HAVE_NO_MEMORY(names);
 
-	for (i = 0; i < res->count; i++) {
-		status = winsdb_record(service->wins_db, res->msgs[i], call, &rec);
+	for (i=0, j=0; i < res->count; i++) {
+		status = winsdb_record(service->wins_db, res->msgs[i], call, now, &rec);
 		NT_STATUS_NOT_OK_RETURN(status);
 
-		status = wreplsrv_record2wins_name(names, &names[i], rec);
-		NT_STATUS_NOT_OK_RETURN(status);
+		/*
+		 * it's possible that winsdb_record() made the record RELEASED
+		 * because it's expired, but in the database it's still stored
+		 * as ACTIVE...
+		 *
+		 * make sure we really only replicate ACTIVE and TOMBSTONE records
+		 */
+		if (rec->state == WREPL_STATE_ACTIVE || rec->state == WREPL_STATE_TOMBSTONE) {
+			status = wreplsrv_record2wins_name(names, &names[j], rec);
+			NT_STATUS_NOT_OK_RETURN(status);
+			j++;
+		}
+
 		talloc_free(rec);
 		talloc_free(res->msgs[i]);
 	}
 
 	/* sort the names before we send them */
-	qsort(names, res->count, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name);
+	qsort(names, j, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name);
 
 	DEBUG(2,("WINSREPL:reply [%u] records owner[%s] min[%llu] max[%llu] to partner[%s]\n",
-		res->count, owner_in->address, 
+		j, owner_in->address, 
 		(long long)owner_in->min_version, 
 		(long long)owner_in->max_version,
 		call->wreplconn->partner->address));
 
-	reply_out->num_names	= res->count;
+	reply_out->num_names	= j;
 	reply_out->names	= names;
 
 	return NT_STATUS_OK;

Modified: branches/SAMBA_4_0/source/wrepl_server/wrepl_scavenging.c
===================================================================
--- branches/SAMBA_4_0/source/wrepl_server/wrepl_scavenging.c	2006-01-21 07:57:39 UTC (rev 13059)
+++ branches/SAMBA_4_0/source/wrepl_server/wrepl_scavenging.c	2006-01-21 08:53:56 UTC (rev 13060)
@@ -84,7 +84,11 @@
 	delete_tombstones = timeval_expired(&tombstone_extra_time);
 
 	for (i=0; i < res->count; i++) {
-		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
+		/*
+		 * we pass '0' as 'now' here,
+		 * because we want to get the raw timestamps which are in the DB
+		 */
+		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
 		NT_STATUS_NOT_OK_RETURN(status);
 		talloc_free(res->msgs[i]);
 
@@ -198,7 +202,11 @@
 	delete_tombstones = timeval_expired(&tombstone_extra_time);
 
 	for (i=0; i < res->count; i++) {
-		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
+		/*
+		 * we pass '0' as 'now' here,
+		 * because we want to get the raw timestamps which are in the DB
+		 */
+		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
 		NT_STATUS_NOT_OK_RETURN(status);
 		talloc_free(res->msgs[i]);
 
@@ -390,7 +398,11 @@
 	DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));
 
 	for (i=0; i < res->count; i++) {
-		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, &rec);
+		/*
+		 * we pass '0' as 'now' here,
+		 * because we want to get the raw timestamps which are in the DB
+		 */
+		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);
 		NT_STATUS_NOT_OK_RETURN(status);
 		talloc_free(res->msgs[i]);
 



More information about the samba-cvs mailing list