Author: mimir
Date: 2005-12-16 20:02:41 +0000 (Fri, 16 Dec 2005)
New Revision: 12294

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12294

Log:
Move dcerpc_pipe_open_sock() to async implementation.


rafal


Modified:
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c


Changeset:
Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c  2005-12-16 19:28:46 UTC 
(rev 12293)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_sock.c  2005-12-16 20:02:41 UTC 
(rev 12294)
@@ -27,6 +27,7 @@
 #include "librpc/gen_ndr/ndr_epmapper.h"
 #include "lib/socket/socket.h"
 #include "lib/stream/packet.h"
+#include "libcli/composite/composite.h"
 
 /* transport private information used by general socket pipe transports */
 struct sock_private {
@@ -190,70 +191,73 @@
        return sock->server_name;
 }
 
-/* 
-   open a rpc connection using the generic socket library
-*/
-static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *c, 
-                                       const char *server,
-                                       uint32_t port, 
-                                       const char *type,
-                                       enum dcerpc_transport_t transport)
+
+struct pipe_open_socket_state {
+       struct dcerpc_connection *conn;
+       struct socket_context *socket_ctx;
+       struct sock_private *sock;
+       const char *server;
+       uint32_t port;
+       enum dcerpc_transport_t transport;
+};
+
+
+static void continue_socket_connect(struct composite_context *ctx)
 {
+       struct dcerpc_connection *conn;
        struct sock_private *sock;
-       struct socket_context *socket_ctx;
-       NTSTATUS status;
+       struct composite_context *c = talloc_get_type(ctx->async.private_data,
+                                                     struct composite_context);
+       struct pipe_open_socket_state *s = talloc_get_type(c->private_data,
+                                                          struct 
pipe_open_socket_state);
 
-       sock = talloc(c, struct sock_private);
-       if (!sock) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       /* make it easier to write a function calls */
+       conn = s->conn;
+       sock = s->sock;
 
-       status = socket_create(type, SOCKET_TYPE_STREAM, &socket_ctx, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(sock);
-               return status;
+       c->status = socket_connect_recv(ctx);
+       if (!NT_STATUS_IS_OK(c->status)) {
+               DEBUG(0, ("Failed to connect host %s on port %d - %s\n", 
s->server, s->port,
+                         nt_errstr(c->status)));
+               composite_error(c, c->status);
+               return;
        }
-       talloc_steal(sock, socket_ctx);
 
-       status = socket_connect_ev(socket_ctx, NULL, 0, server, port, 0, 
c->event_ctx);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(sock);
-               return status;
-       }
-
        /*
          fill in the transport methods
        */
-       c->transport.transport = transport;
-       c->transport.private = NULL;
+       conn->transport.transport     = s->transport;
+       conn->transport.private       = NULL;
 
-       c->transport.send_request = sock_send_request;
-       c->transport.send_read = sock_send_read;
-       c->transport.recv_data = NULL;
+       conn->transport.send_request  = sock_send_request;
+       conn->transport.send_read     = sock_send_read;
+       conn->transport.recv_data     = NULL;
 
-       c->transport.shutdown_pipe = sock_shutdown_pipe;
-       c->transport.peer_name = sock_peer_name;
-       
-       sock->sock = socket_ctx;
+       conn->transport.shutdown_pipe = sock_shutdown_pipe;
+       conn->transport.peer_name     = sock_peer_name;
+
+       sock->sock          = s->socket_ctx;
        sock->pending_reads = 0;
-       sock->server_name = strupper_talloc(sock, server);
+       sock->server_name   = strupper_talloc(sock, s->server);
 
-       sock->fde = event_add_fd(c->event_ctx, sock->sock, 
socket_get_fd(sock->sock),
-                                0, sock_io_handler, c);
+       sock->fde = event_add_fd(conn->event_ctx, sock->sock, 
socket_get_fd(sock->sock),
+                                0, sock_io_handler, conn);
+       
+       conn->transport.private = sock;
 
-       c->transport.private = sock;
-
        sock->packet = packet_init(sock);
        if (sock->packet == NULL) {
+               composite_error(c, NT_STATUS_NO_MEMORY);
                talloc_free(sock);
-               return NT_STATUS_NO_MEMORY;
+               return;
        }
-       packet_set_private(sock->packet, c);
+
+       packet_set_private(sock->packet, conn);
        packet_set_socket(sock->packet, sock->sock);
        packet_set_callback(sock->packet, sock_process_recv);
        packet_set_full_request(sock->packet, sock_complete_packet);
        packet_set_error_handler(sock->packet, sock_error_handler);
-       packet_set_event_context(sock->packet, c->event_ctx);
+       packet_set_event_context(sock->packet, conn->event_ctx);
        packet_set_fde(sock->packet, sock->fde);
        packet_set_serialise(sock->packet);
        packet_recv_disable(sock->packet);
@@ -262,10 +266,97 @@
        /* ensure we don't get SIGPIPE */
        BlockSignals(True,SIGPIPE);
 
-       return NT_STATUS_OK;
+       composite_done(c);
 }
 
+
+struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx,
+                                                      struct dcerpc_connection 
*cn,
+                                                      const char *server,
+                                                      uint32_t port, 
+                                                      const char *type,
+                                                      enum dcerpc_transport_t 
transport)
+{
+       NTSTATUS status;
+       struct composite_context *c;
+       struct pipe_open_socket_state *s;
+       struct composite_context *conn_req;
+
+       c = talloc_zero(mem_ctx, struct composite_context);
+       if (c == NULL) return NULL;
+
+       s = talloc_zero(c, struct pipe_open_socket_state);
+       if (s == NULL) {
+               composite_error(c, NT_STATUS_NO_MEMORY);
+               goto done;
+       }
+
+       c->state = COMPOSITE_STATE_IN_PROGRESS;
+       c->private_data = s;
+       c->event_ctx = cn->event_ctx;
+
+       s->conn      = cn;
+       s->transport = transport;
+       s->port      = port;
+       s->server    = talloc_strdup(c, server);
+       if (s->server == NULL) {
+               composite_error(c, NT_STATUS_NO_MEMORY);
+               goto done;
+       }
+
+       s->sock = talloc(cn, struct sock_private);
+       if (s->sock == NULL) {
+               composite_error(c, NT_STATUS_NO_MEMORY);
+               goto done;
+       }
+
+       status = socket_create(type, SOCKET_TYPE_STREAM, &s->socket_ctx, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               composite_error(c, status);
+               talloc_free(s->sock);
+               goto done;
+       }
+       talloc_steal(s->sock, s->socket_ctx);
+
+       conn_req = socket_connect_send(s->socket_ctx, NULL, 0, s->server, 
s->port, 0, c->event_ctx);
+       if (conn_req == NULL) {
+               composite_error(c, NT_STATUS_NO_MEMORY);
+               goto done;
+       }
+       
+       composite_continue(c, conn_req, continue_socket_connect, c);
+
+done:
+       return c;
+}
+
+
+NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c)
+{
+       NTSTATUS status = composite_wait(c);
+
+       talloc_free(c);
+       return status;
+}
+
 /* 
+   open a rpc connection using the generic socket library
+*/
+NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *conn,
+                                const char *server,
+                                uint32_t port, 
+                                const char *type,
+                                enum dcerpc_transport_t transport)
+{
+       struct composite_context *c;
+       
+       c = dcerpc_pipe_open_socket_send(conn, conn, server, port,
+                                        type, transport);
+       return dcerpc_pipe_open_socket_recv(c);
+}
+
+
+/* 
    open a rpc connection using tcp
 */
 NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *c, const char *server, 
uint32_t port)

Reply via email to