[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Sun Jun 5 07:18:02 MDT 2011


The branch, master has been updated
       via  13ac91d nss_wins: Add a stackframe to lookup_byname_backend()
       via  10f5fa8 s3: Make use of name_resolve_bcast in nmblookup
       via  2d90a89 s3: Make name_resolve_bcast do parallel lookups to all interfaces
       via  fbe7b47 s3: Add name_queries_send/recv
      from  114fbc3 s3: Fix a valgrind error

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 13ac91d9a1e695aa5b4147bc13c728eb1cb562e8
Author: Volker Lendecke <vl at samba.org>
Date:   Mon May 16 14:48:39 2011 +0200

    nss_wins: Add a stackframe to lookup_byname_backend()
    
    Autobuild-User: Volker Lendecke <vlendec at samba.org>
    Autobuild-Date: Sun Jun  5 15:17:42 CEST 2011 on sn-devel-104

commit 10f5fa8a1e2272cf2388277b17e00082b2973216
Author: Volker Lendecke <vl at samba.org>
Date:   Mon May 2 23:39:09 2011 +0200

    s3: Make use of name_resolve_bcast in nmblookup

commit 2d90a8994245b3611a508fed4ddcf0bd4ad978d9
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 25 18:47:42 2011 +0200

    s3: Make name_resolve_bcast do parallel lookups to all interfaces

commit fbe7b47c343c6f3aaf11acd5b16e499388baaa23
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 25 18:30:35 2011 +0200

    s3: Add name_queries_send/recv

-----------------------------------------------------------------------

Summary of changes:
 nsswitch/wins.c            |   10 +-
 source3/libsmb/namequery.c |  271 ++++++++++++++++++++++++++++++++++++++++----
 source3/utils/nmblookup.c  |   24 +----
 3 files changed, 260 insertions(+), 45 deletions(-)


Changeset truncated at 500 lines:

diff --git a/nsswitch/wins.c b/nsswitch/wins.c
index 1bfdcd9..5c9ad2f 100644
--- a/nsswitch/wins.c
+++ b/nsswitch/wins.c
@@ -59,6 +59,7 @@ static void nss_wins_init(void)
 
 static struct in_addr *lookup_byname_backend(const char *name, int *count)
 {
+	TALLOC_CTX *frame = talloc_stackframe();
 	struct ip_service *address = NULL;
 	struct in_addr *ret = NULL;
 	int j;
@@ -73,16 +74,19 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
 	if (NT_STATUS_IS_OK(resolve_wins(name,0x00,&address,count))) {
 		if ( (ret = SMB_MALLOC_P(struct in_addr)) == NULL ) {
 			free( address );
+			TALLOC_FREE(frame);
 			return NULL;
 		}
 		if (address[0].ss.ss_family != AF_INET) {
 			free(address);
 			free(ret);
+			TALLOC_FREE(frame);
 			return NULL;
 		}
 		*ret = ((struct sockaddr_in *)(void *)&address[0].ss)
 			->sin_addr;
 		free( address );
+		TALLOC_FREE(frame);
 		return ret;
 	}
 
@@ -98,17 +102,17 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
 		}
 		in_addr_to_sockaddr_storage(&ss, *bcast);
 		status = name_query(name, 0x00, True, True, &ss,
-				    NULL, &pss, count, NULL);
+				    talloc_tos(), &pss, count, NULL);
 		if (NT_STATUS_IS_OK(status) && (*count > 0)) {
 			if ((ret = SMB_MALLOC_P(struct in_addr)) == NULL) {
+				TALLOC_FREE(frame);
 				return NULL;
 			}
 			*ret = ((struct sockaddr_in *)pss)->sin_addr;
-			TALLOC_FREE(pss);
 			break;
 		}
 	}
-
+	TALLOC_FREE(frame);
 	return ret;
 }
 
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 1cd5eb7..7bb8caf 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1507,6 +1507,237 @@ static bool convert_ss2service(struct ip_service **return_iplist,
 	return true;
 }
 
+struct name_queries_state {
+	struct tevent_context *ev;
+	const char *name;
+	int name_type;
+	bool bcast;
+	bool recurse;
+	const struct sockaddr_storage *addrs;
+	int num_addrs;
+	int wait_msec;
+	int timeout_msec;
+
+	struct tevent_req **subreqs;
+	int num_received;
+	int num_sent;
+
+	int received_index;
+	struct sockaddr_storage *result_addrs;
+	int num_result_addrs;
+	uint8_t flags;
+};
+
+static void name_queries_done(struct tevent_req *subreq);
+static void name_queries_next(struct tevent_req *subreq);
+
+/*
+ * Send a name query to multiple destinations with a wait time in between
+ */
+
+static struct tevent_req *name_queries_send(
+	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+	const char *name, int name_type,
+	bool bcast, bool recurse,
+	const struct sockaddr_storage *addrs,
+	int num_addrs, int wait_msec, int timeout_msec)
+{
+	struct tevent_req *req, *subreq;
+	struct name_queries_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct name_queries_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->name = name;
+	state->name_type = name_type;
+	state->bcast = bcast;
+	state->recurse = recurse;
+	state->addrs = addrs;
+	state->num_addrs = num_addrs;
+	state->wait_msec = wait_msec;
+	state->timeout_msec = timeout_msec;
+
+	state->subreqs = talloc_zero_array(
+		state, struct tevent_req *, num_addrs);
+	if (tevent_req_nomem(state->subreqs, req)) {
+		return tevent_req_post(req, ev);
+	}
+	state->num_sent = 0;
+
+	subreq = name_query_send(
+		state->subreqs, state->ev, name, name_type, bcast, recurse,
+		&state->addrs[state->num_sent]);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	if (!tevent_req_set_endtime(
+		    subreq, state->ev,
+		    timeval_current_ofs(0, state->timeout_msec * 1000))) {
+		tevent_req_nomem(NULL, req);
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, name_queries_done, req);
+
+	state->subreqs[state->num_sent] = subreq;
+	state->num_sent += 1;
+
+	if (state->num_sent < state->num_addrs) {
+		subreq = tevent_wakeup_send(
+			state, state->ev,
+			timeval_current_ofs(0, state->wait_msec * 1000));
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, name_queries_next, req);
+	}
+	return req;
+}
+
+static void name_queries_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct name_queries_state *state = tevent_req_data(
+		req, struct name_queries_state);
+	int i;
+	NTSTATUS status;
+
+	status = name_query_recv(subreq, state, &state->result_addrs,
+				 &state->num_result_addrs, &state->flags);
+
+	for (i=0; i<state->num_sent; i++) {
+		if (state->subreqs[i] == subreq) {
+			break;
+		}
+	}
+	if (i == state->num_sent) {
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+	TALLOC_FREE(state->subreqs[i]);
+
+	state->num_received += 1;
+
+	if (!NT_STATUS_IS_OK(status)) {
+
+		if (state->num_received >= state->num_addrs) {
+			tevent_req_nterror(req, status);
+			return;
+		}
+		/*
+		 * Still outstanding requests, just wait
+		 */
+		return;
+	}
+	state->received_index = i;
+	tevent_req_done(req);
+}
+
+static void name_queries_next(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct name_queries_state *state = tevent_req_data(
+		req, struct name_queries_state);
+
+	if (!tevent_wakeup_recv(subreq)) {
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
+	subreq = name_query_send(
+		state->subreqs, state->ev,
+		state->name, state->name_type, state->bcast, state->recurse,
+		&state->addrs[state->num_sent]);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, name_queries_done, req);
+	if (!tevent_req_set_endtime(
+		    subreq, state->ev,
+		    timeval_current_ofs(0, state->timeout_msec * 1000))) {
+		tevent_req_nomem(NULL, req);
+		return;
+	}
+	state->subreqs[state->num_sent] = subreq;
+	state->num_sent += 1;
+
+	if (state->num_sent < state->num_addrs) {
+		subreq = tevent_wakeup_send(
+			state, state->ev,
+			timeval_current_ofs(0, state->wait_msec * 1000));
+		if (tevent_req_nomem(subreq, req)) {
+			return;
+		}
+		tevent_req_set_callback(subreq, name_queries_next, req);
+	}
+}
+
+static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+				  struct sockaddr_storage **result_addrs,
+				  int *num_result_addrs, uint8_t *flags,
+				  int *received_index)
+{
+	struct name_queries_state *state = tevent_req_data(
+		req, struct name_queries_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+
+	if (result_addrs != NULL) {
+		*result_addrs = talloc_move(mem_ctx, &state->result_addrs);
+	}
+	if (num_result_addrs != NULL) {
+		*num_result_addrs = state->num_result_addrs;
+	}
+	if (flags != NULL) {
+		*flags = state->flags;
+	}
+	if (received_index != NULL) {
+		*received_index = state->received_index;
+	}
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS name_queries(const char *name, int name_type,
+			     bool bcast, bool recurse,
+			     const struct sockaddr_storage *addrs,
+			     int num_addrs, int wait_msec, int timeout_msec,
+			     TALLOC_CTX *mem_ctx,
+			     struct sockaddr_storage **result_addrs,
+			     int *num_result_addrs, uint8_t *flags,
+			     int *received_index)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct event_context *ev;
+	struct tevent_req *req;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	ev = event_context_init(frame);
+	if (ev == NULL) {
+		goto fail;
+	}
+	req = name_queries_send(frame, ev, name, name_type, bcast,
+				recurse, addrs, num_addrs, wait_msec,
+				timeout_msec);
+	if (req == NULL) {
+		goto fail;
+	}
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		goto fail;
+	}
+	status = name_queries_recv(req, mem_ctx, result_addrs,
+				   num_result_addrs, flags, received_index);
+ fail:
+	TALLOC_FREE(frame);
+	return status;
+}
+
 /********************************************************
  Resolve via "bcast" method.
 *********************************************************/
@@ -1517,8 +1748,8 @@ NTSTATUS name_resolve_bcast(const char *name,
 			struct sockaddr_storage **return_iplist,
 			int *return_count)
 {
-	int i;
-	int num_interfaces = iface_count();
+	struct sockaddr_storage *bcast_addrs;
+	int i, num_addrs, num_bcast_addrs;
 	struct sockaddr_storage *ss_list;
 	NTSTATUS status = NT_STATUS_NOT_FOUND;
 
@@ -1528,9 +1759,6 @@ NTSTATUS name_resolve_bcast(const char *name,
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	*return_iplist = NULL;
-	*return_count = 0;
-
 	/*
 	 * "bcast" means do a broadcast lookup on all the local interfaces.
 	 */
@@ -1538,32 +1766,33 @@ NTSTATUS name_resolve_bcast(const char *name,
 	DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
 		"for name %s<0x%x>\n", name, name_type));
 
+	num_addrs = iface_count();
+	bcast_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
+				   num_addrs);
+	if (bcast_addrs == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	/*
 	 * Lookup the name on all the interfaces, return on
 	 * the first successful match.
 	 */
-	for( i = num_interfaces-1; i >= 0; i--) {
+	num_bcast_addrs = 0;
+
+	for (i=0; i<num_addrs; i++) {
 		const struct sockaddr_storage *pss = iface_n_bcast(i);
 
-		/* Done this way to fix compiler error on IRIX 5.x */
-		if (!pss) {
+		if (pss->ss_family != AF_INET) {
 			continue;
 		}
-		status = name_query(name, name_type, true, true, pss,
-				    talloc_tos(), &ss_list, return_count,
-				    NULL);
-		if (NT_STATUS_IS_OK(status)) {
-			goto success;
-		}
+		bcast_addrs[num_bcast_addrs] = *pss;
+		num_bcast_addrs += 1;
 	}
 
-	/* failed - no response */
-
-	return status;
-
-success:
-	*return_iplist = ss_list;
-	return status;
+	return name_queries(name, name_type, true, true,
+			    bcast_addrs, num_bcast_addrs, 0, 1000,
+			    mem_ctx, return_iplist, return_count,
+			    NULL, NULL);
 }
 
 /********************************************************
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c
index f854540..73db278 100644
--- a/source3/utils/nmblookup.c
+++ b/source3/utils/nmblookup.c
@@ -168,27 +168,9 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
 				    &bcast_addr, talloc_tos(),
 				    &ip_list, &count, &flags);
 	} else {
-		const struct in_addr *bcast;
-		for (j=iface_count() - 1;
-		     !ip_list && j >= 0;
-		     j--) {
-			char addr[INET6_ADDRSTRLEN];
-			struct sockaddr_storage bcast_ss;
-
-			bcast = iface_n_bcast_v4(j);
-			if (!bcast) {
-				continue;
-			}
-			in_addr_to_sockaddr_storage(&bcast_ss, *bcast);
-			print_sockaddr(addr, sizeof(addr), &bcast_ss);
-			d_printf("querying %s on %s\n",
-			       lookup, addr);
-			status = name_query(lookup,lookup_type,
-					    use_bcast,
-					    use_bcast?True:recursion_desired,
-					    &bcast_ss, talloc_tos(),
-					    &ip_list, &count, &flags);
-		}
+		status = name_resolve_bcast(
+			lookup, lookup_type,
+			talloc_tos(), &ip_list, &count);
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list