build: commit all the waf build files in the tree
[nivanova/samba-autobuild/.git] / source4 / lib / socket / connect.c
index 116a8c67d866026b8761b5935d2e9e438c5e6973..b943de8c1448d6a76a9af74614bbf85edc3b9d18 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,
    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 "lib/socket/socket.h"
 #include "lib/events/events.h"
-#include "librpc/gen_ndr/nbt.h"
 #include "libcli/composite/composite.h"
 
 
 struct connect_state {
        struct socket_context *sock;
-       const char *my_address;
-       int my_port;
-       const char *server_address;
-       int server_port;
+       const struct socket_address *my_address;
+       const struct socket_address *server_address;
        uint32_t flags;
 };
 
-static void socket_connect_handler(struct event_context *ev,
-                                  struct fd_event *fde, 
-                                  uint16_t flags, void *private);
-static void continue_resolve_name(struct composite_context *ctx);
-static void continue_socket_connect(struct composite_context *creq);
+static void socket_connect_handler(struct tevent_context *ev,
+                                  struct tevent_fd *fde, 
+                                  uint16_t flags, void *private_data);
 
 /*
   call the real socket_connect() call, and setup event handler
 */
 static void socket_send_connect(struct composite_context *result)
 {
-       struct composite_context *creq;
-       struct fd_event *fde;
+       struct tevent_fd *fde;
        struct connect_state *state = talloc_get_type(result->private_data, 
                                                      struct connect_state);
 
-       creq = talloc_zero(state, struct composite_context);
-       if (composite_nomem(creq, result)) return;
-       creq->state = COMPOSITE_STATE_IN_PROGRESS;
-       creq->event_ctx = result->event_ctx;
-       creq->async.fn = continue_socket_connect;
-       creq->async.private_data = result;
-
        result->status = socket_connect(state->sock,
                                        state->my_address,
-                                       state->my_port, 
                                        state->server_address,
-                                       state->server_port,
                                        state->flags);
        if (NT_STATUS_IS_ERR(result->status) && 
            !NT_STATUS_EQUAL(result->status,
@@ -76,7 +60,7 @@ static void socket_send_connect(struct composite_context *result)
 
        fde = event_add_fd(result->event_ctx, result,
                           socket_get_fd(state->sock),
-                          EVENT_FD_WRITE, 
+                          EVENT_FD_READ|EVENT_FD_WRITE, 
                           socket_connect_handler, result);
        composite_nomem(fde, result);
 }
@@ -86,71 +70,58 @@ static void socket_send_connect(struct composite_context *result)
   send a socket connect, potentially doing some name resolution first
 */
 struct composite_context *socket_connect_send(struct socket_context *sock,
-                                             const char *my_address,
-                                             int my_port,
-                                             const char *server_address,
-                                             int server_port,
+                                             struct socket_address *my_address,
+                                             struct socket_address *server_address, 
                                              uint32_t flags,
-                                             struct event_context *event_ctx)
+                                             struct tevent_context *event_ctx)
 {
        struct composite_context *result;
        struct connect_state *state;
 
-       result = talloc_zero(sock, struct composite_context);
+       result = composite_create(sock, event_ctx);
        if (result == NULL) return NULL;
-       result->state = COMPOSITE_STATE_IN_PROGRESS;
-       result->event_ctx = event_ctx;
 
        state = talloc_zero(result, struct connect_state);
-       if (composite_nomem(state, result)) goto failed;
+       if (composite_nomem(state, result)) return result;
        result->private_data = state;
 
        state->sock = talloc_reference(state, sock);
-       if (composite_nomem(state->sock, result)) goto failed;
+       if (composite_nomem(state->sock, result)) return result;
 
        if (my_address) {
-               state->my_address = talloc_strdup(state, my_address);
-               if (composite_nomem(state->my_address, result)) goto failed;
+               void *ref = talloc_reference(state, my_address);
+               if (composite_nomem(ref, result)) {
+                       return result;
+               }
+               state->my_address = my_address;
        }
-       state->my_port = my_port;
 
-       state->server_address = talloc_strdup(state, server_address);
-       if (composite_nomem(state->server_address, result)) goto failed;
+       {
+               void *ref = talloc_reference(state, server_address);
+               if (composite_nomem(ref, result)) {
+                       return result;
+               }
+               state->server_address = server_address;
+       }
 
-       state->server_port = server_port;
        state->flags = flags;
 
-       set_blocking(socket_get_fd(sock), False);
-
-       if (strcmp(sock->backend_name, "ipv4") == 0) {
-               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;
-       }
+       set_blocking(socket_get_fd(sock), false);
 
        socket_send_connect(result);
 
        return result;
-
-failed:
-       composite_error(result, result->status);
-       return result;
 }
 
 /*
   handle write events on connect completion
 */
-static void socket_connect_handler(struct event_context *ev,
-                                  struct fd_event *fde, 
-                                  uint16_t flags, void *private)
+static void socket_connect_handler(struct tevent_context *ev,
+                                  struct tevent_fd *fde, 
+                                  uint16_t flags, void *private_data)
 {
        struct composite_context *result =
-               talloc_get_type(private, struct composite_context);
+               talloc_get_type(private_data, struct composite_context);
        struct connect_state *state = talloc_get_type(result->private_data,
                                                      struct connect_state);
 
@@ -160,37 +131,6 @@ static void socket_connect_handler(struct event_context *ev,
        composite_done(result);
 }
 
-/*
-  recv name resolution reply then send the connect
-*/
-static void continue_resolve_name(struct composite_context *creq)
-{
-       struct composite_context *result = talloc_get_type(creq->async.private_data, 
-                                                          struct composite_context);
-       struct connect_state *state = talloc_get_type(result->private_data, struct connect_state);
-       const char *addr;
-
-       result->status = resolve_name_recv(creq, state, &addr);
-       if (!composite_is_ok(result)) return;
-
-       state->server_address = addr;
-
-       socket_send_connect(result);
-}
-
-/*
-  called when a connect has finished. Complete the top level composite context
-*/
-static void continue_socket_connect(struct composite_context *creq)
-{
-       struct composite_context *result = talloc_get_type(creq->async.private_data, 
-                                                          struct composite_context);
-       result->status = creq->status;
-       if (!composite_is_ok(result)) return;
-       composite_done(result);
-}
-
-
 /*
   wait for a socket_connect_send() to finish
 */
@@ -206,12 +146,13 @@ NTSTATUS socket_connect_recv(struct composite_context *result)
   like socket_connect() but takes an event context, doing a semi-async connect
 */
 NTSTATUS socket_connect_ev(struct socket_context *sock,
-                          const char *my_address, int my_port,
-                          const char *server_address, int server_port,
-                          uint32_t flags, struct event_context *ev)
+                          struct socket_address *my_address,
+                          struct socket_address *server_address, 
+                          uint32_t flags,
+                          struct tevent_context *ev)
 {
        struct composite_context *ctx;
-       ctx = socket_connect_send(sock, my_address, my_port,
-                                 server_address, server_port, flags, ev);
+       ctx = socket_connect_send(sock, my_address, 
+                                 server_address, flags, ev);
        return socket_connect_recv(ctx);
 }