Add context for libcli_resolve.
[samba-svnmirror.git] / source / libcli / resolve / bcast.c
index d424b5303aed84736f6e7e662a3c7484b83ce489..5a2c49c5ad8846b3af38de1d71f134eff6093528 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "libcli/resolve/resolve.h"
 #include "system/network.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/nbt/libnbt.h"
-#include "libcli/composite/composite.h"
+#include "lib/socket/netif.h"
+#include "param/param.h"
 
-struct bcast_state {
-       struct nbt_name name;
-       struct nbt_name_socket *nbtsock;
-       int num_queries;
-       struct nbt_name_request **queries;
-       struct nbt_name_query *io_queries;
-       const char *reply_addr;
-};
-
-/*
-  handle events during broadcast name resolution
-*/
-static void bcast_handler(struct nbt_name_request *req)
-{
-       struct smbcli_composite *c = talloc_get_type(req->async.private, 
-                                                    struct smbcli_composite);
-       struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
-       int i;
-
-       for (i=0;i<state->num_queries;i++) {
-               if (req == state->queries[i]) break;
-       }
-       if (i == state->num_queries) {
-               /* not for us?! */
-               c->status = NT_STATUS_INTERNAL_ERROR;
-               c->state = SMBCLI_REQUEST_ERROR;                
-               goto done;
-       } 
-
-       c->status = nbt_name_query_recv(req, state, &state->io_queries[i]);
-       if (!NT_STATUS_IS_OK(c->status)) {
-               c->state = SMBCLI_REQUEST_ERROR;
-       } else {
-               c->state = SMBCLI_REQUEST_DONE;
-               state->reply_addr = talloc_steal(state, state->io_queries[i].out.reply_addr);
-       }
-
-done:
-       talloc_free(state->nbtsock);
-       if (c->async.fn) {
-               c->async.fn(c);
-       }
-}
-
-/*
+/**
   broadcast name resolution method - async send
  */
-struct smbcli_composite *resolve_name_bcast_send(struct nbt_name *name, 
-                                                struct event_context *event_ctx)
+struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, 
+                                                 struct event_context *event_ctx,
+                                                 void *userdata,
+                                                 struct nbt_name *name)
 {
-       struct smbcli_composite *c;
-       struct bcast_state *state;
-       int i;
-       NTSTATUS status;
-
-       c = talloc_zero(NULL, struct smbcli_composite);
-       if (c == NULL) goto failed;
-
-       state = talloc(c, struct bcast_state);
-       if (state == NULL) goto failed;
-
-       status = nbt_name_dup(state, name, &state->name);
-       if (!NT_STATUS_IS_OK(status)) goto failed;
-
-       state->nbtsock = nbt_name_socket_init(state, event_ctx);
-       if (state->nbtsock == NULL) goto failed;
-
-       state->num_queries = iface_count();
-
-       state->io_queries = talloc_array(state, struct nbt_name_query, state->num_queries);
-       if (!state->io_queries) goto failed;
-
-       state->queries = talloc_array(state, struct nbt_name_request *, state->num_queries);
-       if (!state->queries) goto failed;
-
-       for (i=0;i<state->num_queries;i++) {
-               struct ipv4_addr *ip = iface_n_bcast(i);
-               const char *addr = sys_inet_ntoa(*ip);
-               if (!addr) goto failed;
-
-               state->io_queries[i].in.name = state->name;
-               state->io_queries[i].in.dest_addr = talloc_strdup(state->io_queries, addr);
-               if (!state->io_queries[i].in.dest_addr) goto failed;
-               state->io_queries[i].in.broadcast = True;
-               state->io_queries[i].in.wins_lookup = False;
-               state->io_queries[i].in.timeout = lp_parm_int(-1, "nbt", "bcastTimeout", 5);
-
-               state->queries[i] = nbt_name_query_send(state->nbtsock, &state->io_queries[i]);
-               if (!state->queries[i]) goto failed;
-
-               state->queries[i]->async.fn = bcast_handler;
-               state->queries[i]->async.private = c;
+       int num_interfaces = iface_count(global_loadparm);
+       const char **address_list;
+       struct composite_context *c;
+       int i, count=0;
+
+       address_list = talloc_array(mem_ctx, const char *, num_interfaces+1);
+       if (address_list == NULL) return NULL;
+
+       for (i=0;i<num_interfaces;i++) {
+               const char *bcast = iface_n_bcast(global_loadparm, i);
+               if (bcast == NULL) continue;
+               address_list[count] = talloc_strdup(address_list, bcast);
+               if (address_list[count] == NULL) {
+                       talloc_free(address_list);
+                       return NULL;
+               }
+               count++;
        }
+       address_list[count] = NULL;
 
-       c->state = SMBCLI_REQUEST_SEND;
-       c->private = state;
-       c->event_ctx = talloc_reference(c, state->nbtsock->event_ctx);
+       c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, true, false);
+       talloc_free(address_list);
 
-       return c;
-
-failed:
-       talloc_free(c);
-       return NULL;
+       return c;       
 }
 
 /*
   broadcast name resolution method - recv side
  */
-NTSTATUS resolve_name_bcast_recv(struct smbcli_composite *c, 
+NTSTATUS resolve_name_bcast_recv(struct composite_context *c, 
                                 TALLOC_CTX *mem_ctx, const char **reply_addr)
 {
-       NTSTATUS status;
-
-       status = smb_composite_wait(c);
-
-       if (NT_STATUS_IS_OK(status)) {
-               struct bcast_state *state = talloc_get_type(c->private, struct bcast_state);
-               *reply_addr = talloc_steal(mem_ctx, state->reply_addr);
-       }
-
-       talloc_free(c);
-       return status;
+       return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr);
 }
 
 /*
@@ -157,7 +75,12 @@ NTSTATUS resolve_name_bcast(struct nbt_name *name,
                            TALLOC_CTX *mem_ctx,
                            const char **reply_addr)
 {
-       struct smbcli_composite *c = resolve_name_bcast_send(name, NULL);
+       struct composite_context *c = resolve_name_bcast_send(mem_ctx, NULL, NULL, name);
        return resolve_name_bcast_recv(c, mem_ctx, reply_addr);
 }
 
+bool resolve_context_add_bcast_method(struct resolve_context *ctx)
+{
+       return resolve_context_add_method(ctx, resolve_name_bcast_send, resolve_name_bcast_recv,
+                                         NULL);
+}