[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