summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/basic.mk1
-rw-r--r--source4/lib/tls/tls.h4
-rw-r--r--source4/libcli/config.mk1
-rw-r--r--source4/libcli/raw/clitransport.c122
-rw-r--r--source4/libcli/raw/libcliraw.h9
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c27
6 files changed, 55 insertions, 109 deletions
diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk
index 383892eb9c..a531145060 100644
--- a/source4/lib/basic.mk
+++ b/source4/lib/basic.mk
@@ -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
diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h
index a046b91637..df67bad0e4 100644
--- a/source4/lib/tls/tls.h
+++ b/source4/lib/tls/tls.h
@@ -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
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index a7a2862da5..ea93b12a03 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -121,3 +121,4 @@ OBJ_FILES = raw/rawfile.o \
raw/rawacl.o \
raw/rawdate.o \
raw/rawlpq.o
+REQUIRED_SUBSYSTEMS = LIBPACKET
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index b07bd630e9..15959ce272 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -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;
}
diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h
index bb13210e74..a853bd177c 100644
--- a/source4/libcli/raw/libcliraw.h
+++ b/source4/libcli/raw/libcliraw.h
@@ -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 */
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index 44c31d91ad..b0d0d06552 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -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);