r11605: added handling of the send queue to the generic packet handling code
authorAndrew Tridgell <tridge@samba.org>
Wed, 9 Nov 2005 13:33:53 +0000 (13:33 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:45:57 +0000 (13:45 -0500)
(This used to be commit f98d499b2ef93cf2d060acafbc424754add322a8)

source4/lib/stream/packet.c
source4/lib/stream/packet.h

index 50687d18fa0b8b1d1c18f9515f51f99945eef13e..3a7a938249e4612d0b82ea4136f36b20550db570 100644 (file)
@@ -44,6 +44,12 @@ struct packet_context {
        struct fd_event *fde;
        BOOL serialise;
        BOOL processing;
+
+       struct send_element {
+               struct send_element *next, *prev;
+               DATA_BLOB blob;
+               size_t nsent;
+       } *send_queue;
 };
 
 /*
@@ -323,6 +329,61 @@ next_partial:
 }
 
 
+/*
+  trigger a run of the send queue
+*/
+void packet_queue_run(struct packet_context *pc)
+{
+       while (pc->send_queue) {
+               struct send_element *el = pc->send_queue;
+               NTSTATUS status;
+               size_t nwritten;
+               DATA_BLOB blob = data_blob_const(el->blob.data + el->nsent,
+                                                el->blob.length - el->nsent);
+
+               if (pc->tls) {
+                       status = tls_socket_send(pc->tls, &blob, &nwritten);
+               } else {
+                       status = socket_send(pc->sock, &blob, &nwritten, 0);
+               }
+               if (NT_STATUS_IS_ERR(status)) {
+                       packet_error(pc, NT_STATUS_NET_WRITE_FAULT);
+                       return;
+               }
+               if (!NT_STATUS_IS_OK(status)) {
+                       return;
+               }
+               el->nsent += nwritten;
+               if (el->nsent == el->blob.length) {
+                       DLIST_REMOVE(pc->send_queue, el);
+                       talloc_free(el);
+               }
+       }
+
+       /* we're out of requests to send, so don't wait for write
+          events any more */
+       EVENT_FD_NOT_WRITEABLE(pc->fde);
+}
+
+/*
+  put a packet in the send queue
+*/
+NTSTATUS packet_send(struct packet_context *pc, DATA_BLOB blob)
+{
+       struct send_element *el;
+       el = talloc(pc, struct send_element);
+       NT_STATUS_HAVE_NO_MEMORY(el);
+
+       DLIST_ADD_END(pc->send_queue, el, struct send_element *);
+       el->blob = blob;
+       el->nsent = 0;
+       talloc_steal(el, blob.data);
+
+       EVENT_FD_WRITEABLE(pc->fde);
+
+       return NT_STATUS_OK;
+}
+
 
 /*
   a full request checker for NBT formatted packets (first 3 bytes are length)
@@ -338,3 +399,5 @@ NTSTATUS packet_full_request_nbt(void *private, DATA_BLOB blob, size_t *packet_s
        }
        return NT_STATUS_OK;
 }
+
+
index b6ed8d6598f9a867e0014f2461242b88f22857e3..196e20a378725dff0a996f0d9b96723b6e5fb89b 100644 (file)
@@ -40,6 +40,8 @@ void packet_set_socket(struct packet_context *pc, struct socket_context *sock);
 void packet_set_event_context(struct packet_context *pc, struct event_context *ev);
 void packet_set_serialise(struct packet_context *pc, struct fd_event *fde);
 void packet_recv(struct packet_context *pc);
+NTSTATUS packet_send(struct packet_context *pc, DATA_BLOB blob);
+void packet_queue_run(struct packet_context *pc);
 
 /*
   pre-canned handlers