build: commit all the waf build files in the tree
[nivanova/samba-autobuild/.git] / source4 / lib / socket / connect_multi.c
index 6c3c6a5a6631287425a12581f109d5cd14e08f64..300e5fb1e531e30331812e1fe6fd18a4abbcc97e 100644 (file)
@@ -9,7 +9,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,
@@ -18,8 +18,7 @@
    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"
@@ -34,7 +33,7 @@
   overall state
 */
 struct connect_multi_state {
-       const char *server_address;
+       struct socket_address *server_address;
        int num_ports;
        uint16_t *ports;
 
@@ -54,8 +53,8 @@ struct connect_one_state {
 };
 
 static void continue_resolve_name(struct composite_context *creq);
-static void connect_multi_timer(struct event_context *ev,
-                                   struct timed_event *te,
+static void connect_multi_timer(struct tevent_context *ev,
+                                   struct tevent_timer *te,
                                    struct timeval tv, void *p);
 static void connect_multi_next_socket(struct composite_context *result);
 static void continue_one(struct composite_context *creq);
@@ -63,16 +62,21 @@ static void continue_one(struct composite_context *creq);
 /*
   setup an async socket_connect, with multiple ports
 */
-_PUBLIC_ struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx,
-                                                   const char *server_address,
+_PUBLIC_ struct composite_context *socket_connect_multi_send(
+                                                   TALLOC_CTX *mem_ctx,
+                                                   const char *server_name,
                                                    int num_server_ports,
                                                    uint16_t *server_ports,
-                                                   struct event_context *event_ctx)
+                                                   struct resolve_context *resolve_ctx,
+                                                   struct tevent_context *event_ctx)
 {
        struct composite_context *result;
        struct connect_multi_state *multi;
        int i;
 
+       struct nbt_name name;
+       struct composite_context *creq;
+               
        result = talloc_zero(mem_ctx, struct composite_context);
        if (result == NULL) return NULL;
        result->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -82,9 +86,6 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx
        if (composite_nomem(multi, result)) goto failed;
        result->private_data = multi;
 
-       multi->server_address = talloc_strdup(multi, server_address);
-       if (composite_nomem(multi->server_address, result)) goto failed;
-
        multi->num_ports = num_server_ports;
        multi->ports = talloc_array(multi, uint16_t, multi->num_ports);
        if (composite_nomem(multi->ports, result)) goto failed;
@@ -93,31 +94,21 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx
                multi->ports[i] = server_ports[i];
        }
 
-       if (!is_ipaddress(server_address)) {
-               /*  
-                   we don't want to do the name resolution separately
+       /*  
+           we don't want to do the name resolution separately
                    for each port, so start it now, then only start on
                    the real sockets once we have an IP
-                */
-               struct nbt_name name;
-               struct composite_context *creq;
-               make_nbt_name_client(&name, server_address);
-               creq = resolve_name_send(&name, result->event_ctx,
-                                        lp_name_resolve_order());
-               if (composite_nomem(creq, result)) goto failed;
-               composite_continue(result, creq, continue_resolve_name, result);
-               return result;
-       }
+       */
+       make_nbt_name_server(&name, server_name);
 
-       /* now we've setup the state we can process the first socket */
-       connect_multi_next_socket(result);
+       creq = resolve_name_all_send(resolve_ctx, multi, 0, multi->ports[0], &name, result->event_ctx);
+       if (composite_nomem(creq, result)) goto failed;
 
-       if (!NT_STATUS_IS_OK(result->status)) {
-               goto failed;
-       }
+       composite_continue(result, creq, continue_resolve_name, result);
 
        return result;
 
+
  failed:
        composite_error(result, result->status);
        return result;
@@ -148,15 +139,16 @@ static void connect_multi_next_socket(struct composite_context *result)
        result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0);
        if (!composite_is_ok(result)) return;
 
-       /* Form up the particular address we are interested in */
-       state->addr = socket_address_from_strings(state, state->sock->backend_name, 
-                                                 multi->server_address, multi->ports[next]);
+       state->addr = socket_address_copy(state, multi->server_address);
        if (composite_nomem(state->addr, result)) return;
 
+       socket_address_set_port(state->addr, multi->ports[next]);
+
        talloc_steal(state, state->sock);
 
        creq = socket_connect_send(state->sock, NULL, 
-                                  state->addr, 0, result->event_ctx);
+                                  state->addr, 0,
+                                  result->event_ctx);
        if (composite_nomem(creq, result)) return;
        talloc_steal(state, creq);
 
@@ -178,8 +170,8 @@ static void connect_multi_next_socket(struct composite_context *result)
 /*
   a timer has gone off telling us that we should try the next port
 */
-static void connect_multi_timer(struct event_context *ev,
-                               struct timed_event *te,
+static void connect_multi_timer(struct tevent_context *ev,
+                               struct tevent_timer *te,
                                struct timeval tv, void *p)
 {
        struct composite_context *result = talloc_get_type(p, struct composite_context);
@@ -196,12 +188,13 @@ static void continue_resolve_name(struct composite_context *creq)
                                                           struct composite_context);
        struct connect_multi_state *multi = talloc_get_type(result->private_data, 
                                                            struct connect_multi_state);
-       const char *addr;
+       struct socket_address **addr;
 
-       result->status = resolve_name_recv(creq, multi, &addr);
+       result->status = resolve_name_all_recv(creq, multi, &addr, NULL);
        if (!composite_is_ok(result)) return;
 
-       multi->server_address = addr;
+       /* Let's just go for the first for now */
+       multi->server_address = addr[0];
 
        connect_multi_next_socket(result);
 }
@@ -263,13 +256,15 @@ _PUBLIC_ NTSTATUS socket_connect_multi_recv(struct composite_context *ctx,
 NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx,
                              const char *server_address,
                              int num_server_ports, uint16_t *server_ports,
-                             struct event_context *event_ctx,
+                             struct resolve_context *resolve_ctx,
+                             struct tevent_context *event_ctx,
                              struct socket_context **result,
                              uint16_t *result_port)
 {
        struct composite_context *ctx =
                socket_connect_multi_send(mem_ctx, server_address,
                                          num_server_ports, server_ports,
+                                         resolve_ctx,
                                          event_ctx);
        return socket_connect_multi_recv(ctx, mem_ctx, result, result_port);
 }