r11596: switched the libcli/raw/ code over to using the lib/stream/ generic
authorAndrew Tridgell <tridge@samba.org>
Wed, 9 Nov 2005 08:13:41 +0000 (08:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:45:56 +0000 (13:45 -0500)
packet parsing code. This simplifies the logic in the raw client
library a fair bit

source/lib/basic.mk
source/lib/tls/tls.h
source/libcli/config.mk
source/libcli/raw/clitransport.c
source/libcli/raw/libcliraw.h
source/ntvfs/cifs/vfs_cifs.c

index 383892eb9c6291f335e345db961f7a5db2f5322d..a5311450600dd7ee54c8b370a21ec234309d9a9f 100644 (file)
@@ -15,6 +15,7 @@ include cmdline/config.mk
 include socket_wrapper/config.mk
 include appweb/config.mk
 include replace/config.mk
+include stream/config.mk
 
 ##############################
 # Start SUBSYSTEM LIBNETIF
index a046b916377b137900e79b7d2b3aaf4ff1d7fc16..df67bad0e41b646471233c2d132fe5283d4d3cff 100644 (file)
@@ -20,6 +20,9 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#ifndef _TLS_H_
+#define _TLS_H_
+
 /*
   call tls_initialise() once per task to startup the tls subsystem
 */
@@ -72,3 +75,4 @@ BOOL tls_support(struct tls_params *parms);
 */
 NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending);
 
+#endif
index a7a2862da5fa65652fd1420744a7fb1e4ccf07df..ea93b12a03c685814d2189bc7dfaaf0ab40dc4d5 100644 (file)
@@ -121,3 +121,4 @@ OBJ_FILES = raw/rawfile.o \
                raw/rawacl.o \
                raw/rawdate.o \
                raw/rawlpq.o
+REQUIRED_SUBSYSTEMS = LIBPACKET
index b07bd630e9a17ca57d494775acc4fde62b2a47a6..15959ce272c17a35dc92626e66a964735bef204d 100644 (file)
@@ -25,9 +25,9 @@
 #include "lib/socket/socket.h"
 #include "dlinklist.h"
 #include "lib/events/events.h"
+#include "lib/stream/packet.h"
 
 
-static void smbcli_transport_process_recv(struct smbcli_transport *transport);
 static void smbcli_transport_process_send(struct smbcli_transport *transport);
 
 /*
@@ -40,7 +40,7 @@ static void smbcli_transport_event_handler(struct event_context *ev,
        struct smbcli_transport *transport = talloc_get_type(private,
                                                             struct smbcli_transport);
        if (flags & EVENT_FD_READ) {
-               smbcli_transport_process_recv(transport);
+               packet_recv(transport->packet);
                return;
        }
        if (flags & EVENT_FD_WRITE) {
@@ -59,6 +59,18 @@ static int transport_destructor(void *ptr)
        return 0;
 }
 
+
+/*
+  handle receive errors
+*/
+static void smbcli_transport_error(void *private, NTSTATUS status)
+{
+       struct smbcli_transport *transport = talloc_get_type(private, struct smbcli_transport);
+       smbcli_transport_dead(transport);
+}
+
+static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob);
+
 /*
   create a transport structure based on an established socket
 */
@@ -82,7 +94,20 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
        transport->options.request_timeout = SMB_REQUEST_TIMEOUT;
 
        transport->negotiate.max_xmit = transport->options.max_xmit;
-       
+
+       /* setup the stream -> packet parser */
+       transport->packet = packet_init(transport);
+       if (transport->packet == NULL) {
+               talloc_free(transport);
+               return NULL;
+       }
+       packet_set_private(transport->packet, transport);
+       packet_set_socket(transport->packet, transport->socket->sock);
+       packet_set_callback(transport->packet, smbcli_transport_finish_recv);
+       packet_set_full_request(transport->packet, packet_full_request_nbt);
+       packet_set_error_handler(transport->packet, smbcli_transport_error);
+       packet_set_event_context(transport->packet, transport->socket->event.ctx);
+
        smbcli_init_signing(transport);
 
        ZERO_STRUCT(transport->called);
@@ -381,17 +406,17 @@ static void smbcli_transport_process_send(struct smbcli_transport *transport)
   we have a full request in our receive buffer - match it to a pending request
   and process
  */
-static void smbcli_transport_finish_recv(struct smbcli_transport *transport)
+static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob)
 {
+       struct smbcli_transport *transport = talloc_get_type(private, 
+                                                            struct smbcli_transport);
        uint8_t *buffer, *hdr, *vwv;
        int len;
        uint16_t wct=0, mid = 0, op = 0;
        struct smbcli_request *req;
 
-       buffer = transport->recv_buffer.buffer;
-       len = transport->recv_buffer.req_size;
-
-       ZERO_STRUCT(transport->recv_buffer);
+       buffer = blob.data;
+       len = blob.length;
 
        hdr = buffer+NBT_HDR_SIZE;
        vwv = hdr + HDR_VWV;
@@ -399,7 +424,7 @@ static void smbcli_transport_finish_recv(struct smbcli_transport *transport)
        /* see if it could be an oplock break request */
        if (handle_oplock_break(transport, len, hdr, vwv)) {
                talloc_free(buffer);
-               return;
+               return NT_STATUS_OK;
        }
 
        /* at this point we need to check for a readbraw reply, as
@@ -514,77 +539,14 @@ async:
        if (req->async.fn) {
                req->async.fn(req);
        }
-       return;
+       return NT_STATUS_OK;
 
 error:
        if (req) {
                DLIST_REMOVE(transport->pending_recv, req);
                req->state = SMBCLI_REQUEST_ERROR;
        }
-}
-
-/*
-  process some pending receives
-*/
-static void smbcli_transport_process_recv(struct smbcli_transport *transport)
-{
-       /* a incoming packet goes through 2 stages - first we read the
-          4 byte header, which tells us how much more is coming. Then
-          we read the rest */
-       if (transport->recv_buffer.received < NBT_HDR_SIZE) {
-               NTSTATUS status;
-               size_t nread;
-               status = smbcli_sock_read(transport->socket, 
-                                         transport->recv_buffer.header + 
-                                         transport->recv_buffer.received,
-                                         NBT_HDR_SIZE - transport->recv_buffer.received,
-                                         &nread);
-               if (NT_STATUS_IS_ERR(status)) {
-                       smbcli_transport_dead(transport);
-                       return;
-               }
-               if (!NT_STATUS_IS_OK(status)) {
-                       return;
-               }
-
-               transport->recv_buffer.received += nread;
-
-               if (transport->recv_buffer.received == NBT_HDR_SIZE) {
-                       /* we've got a full header */
-                       transport->recv_buffer.req_size = smb_len(transport->recv_buffer.header) + NBT_HDR_SIZE;
-                       transport->recv_buffer.buffer = talloc_size(transport,
-                                                                   NBT_HDR_SIZE+transport->recv_buffer.req_size);
-                       if (transport->recv_buffer.buffer == NULL) {
-                               smbcli_transport_dead(transport);
-                               return;
-                       }
-                       memcpy(transport->recv_buffer.buffer, transport->recv_buffer.header, NBT_HDR_SIZE);
-               }
-       }
-
-       if (transport->recv_buffer.received < transport->recv_buffer.req_size) {
-               NTSTATUS status;
-               size_t nread;
-               status = smbcli_sock_read(transport->socket, 
-                                         transport->recv_buffer.buffer + 
-                                         transport->recv_buffer.received,
-                                         transport->recv_buffer.req_size - 
-                                         transport->recv_buffer.received,
-                                         &nread);
-               if (NT_STATUS_IS_ERR(status)) {
-                       smbcli_transport_dead(transport);
-                       return;
-               }
-               if (!NT_STATUS_IS_OK(status)) {
-                       return;
-               }
-               transport->recv_buffer.received += nread;
-       }
-
-       if (transport->recv_buffer.received != 0 &&
-           transport->recv_buffer.received == transport->recv_buffer.req_size) {
-               smbcli_transport_finish_recv(transport);
-       }
+       return NT_STATUS_OK;
 }
 
 /*
@@ -593,8 +555,18 @@ static void smbcli_transport_process_recv(struct smbcli_transport *transport)
 */
 BOOL smbcli_transport_process(struct smbcli_transport *transport)
 {
+       NTSTATUS status;
+       size_t npending;
+
        smbcli_transport_process_send(transport);
-       smbcli_transport_process_recv(transport);
+       if (transport->socket->sock == NULL) {
+               return False;
+       }
+
+       status = socket_pending(transport->socket->sock, &npending);
+       if (NT_STATUS_IS_OK(status) && npending > 0) {
+               packet_recv(transport->packet);
+       }
        if (transport->socket->sock == NULL) {
                return False;
        }
index bb13210e747fa8966ba4302f4e7205e55a4301f7..a853bd177c116a1cd6b3d19936b90db60f0d8513 100644 (file)
@@ -154,13 +154,8 @@ struct smbcli_transport {
           know the server name */
        struct nbt_name called;
 
-       /* a buffer for partially received SMB packets. */
-       struct {
-               uint8_t header[NBT_HDR_SIZE];
-               size_t req_size;
-               size_t received;
-               uint8_t *buffer;
-       } recv_buffer;
+       /* context of the stream -> packet parser */
+       struct packet_context *packet;
 };
 
 /* this is the context for the user */
index 44c31d91adbbeab6a1ec35a85002b3d8e9cbd222..b0d0d0655227d007a39d9dbb019f3d6487a56846 100644 (file)
@@ -63,21 +63,6 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin
        return req_send_oplock_break(private->tcon, fnum, level);
 }
 
- /*
-  a handler for read events on a connection to a backend server
-*/
-static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, 
-                               uint16_t flags, void *private)
-{
-       struct cvfs_private *cvfs = talloc_get_type(private, struct cvfs_private);
-       struct smbsrv_tcon *tcon = cvfs->tcon;
-       
-       if (!smbcli_transport_process(cvfs->transport)) {
-               /* the connection to our server is dead */
-               talloc_free(tcon);
-       }
-}
-
 /*
   connect to a share - used when a tree_connect operation comes in.
 */
@@ -90,7 +75,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
        const char *host, *user, *pass, *domain, *remote_share;
        struct smb_composite_connect io;
        struct composite_context *creq;
-       struct fd_event *fde;
 
        struct cli_credentials *credentials;
        BOOL machine_account;
@@ -180,17 +164,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
        /* we need to receive oplock break requests from the server */
        smbcli_oplock_handler(private->transport, oplock_handler, private);
 
-       /* take over event handling for this socket */
-       talloc_free(private->transport->socket->event.fde);
-       fde = event_add_fd(private->transport->socket->event.ctx,
-                          private,
-                          socket_get_fd(private->transport->socket->sock),
-                          EVENT_FD_READ | EVENT_FD_WRITE,
-                          cifs_socket_handler,
-                          private);
-       private->transport->socket->event.fde = fde;
-
-
        private->map_generic = lp_parm_bool(req->tcon->service, 
                                            "cifs", "mapgeneric", False);