summaryrefslogtreecommitdiff
path: root/source4/libcli/dgram/dgramsocket.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-04-05 08:35:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:11:26 -0500
commit769070d502a95439ea7d6e2c6616cfa08fc5d673 (patch)
treed8bac8a0d0df76c1a135913288599d9784b0578f /source4/libcli/dgram/dgramsocket.c
parente1e8928840b632297e3cbbd19aeef5e075ff7798 (diff)
downloadsamba-769070d502a95439ea7d6e2c6616cfa08fc5d673.tar.gz
samba-769070d502a95439ea7d6e2c6616cfa08fc5d673.tar.bz2
samba-769070d502a95439ea7d6e2c6616cfa08fc5d673.zip
r6209: started added code to support mailslot requests over UDP/138
datagrams. This adds the IDL to parse mailslot packets, plus mailslot dispatch and listener registration code. mailslots are used for UDP/138 browse and netlogon packets (This used to be commit f20e7e5200de736b3451d748ed716be638f93502)
Diffstat (limited to 'source4/libcli/dgram/dgramsocket.c')
-rw-r--r--source4/libcli/dgram/dgramsocket.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c
index 7f179bc3c3..33734258a3 100644
--- a/source4/libcli/dgram/dgramsocket.c
+++ b/source4/libcli/dgram/dgramsocket.c
@@ -33,15 +33,16 @@
/*
handle recv events on a nbt dgram socket
*/
-static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock)
+static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock)
{
- TALLOC_CTX *tmp_ctx = talloc_new(nbtsock);
+ TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
NTSTATUS status;
const char *src_addr;
int src_port;
DATA_BLOB blob;
size_t nread;
struct nbt_dgram_packet *packet;
+ const char *mailslot_name;
blob = data_blob_talloc(tmp_ctx, NULL, DGRAM_MAX_PACKET_SIZE);
if (blob.data == NULL) {
@@ -49,7 +50,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock)
return;
}
- status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0,
+ status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0,
&src_addr, &src_port);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
@@ -77,13 +78,61 @@ static void dgm_socket_recv(struct nbt_dgram_socket *nbtsock)
return;
}
- NDR_PRINT_DEBUG(nbt_dgram_packet, packet);
+ /* if this is a mailslot message, then see if we can dispatch it to a handler */
+ mailslot_name = dgram_mailslot_name(packet);
+ if (mailslot_name) {
+ struct dgram_mailslot_handler *dgmslot;
+ dgmslot = dgram_mailslot_find(dgmsock, mailslot_name);
+ if (dgmslot) {
+ dgmslot->handler(dgmslot, packet, src_addr, src_port);
+ } else {
+ DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name));
+ }
+ } else {
+ /* dispatch if there is a general handler */
+ if (dgmsock->incoming.handler) {
+ dgmsock->incoming.handler(dgmsock, packet, src_addr, src_port);
+ }
+ }
talloc_free(tmp_ctx);
}
/*
+ handle send events on a nbt dgram socket
+*/
+static void dgm_socket_send(struct nbt_dgram_socket *dgmsock)
+{
+ struct nbt_dgram_request *req;
+ NTSTATUS status;
+
+ while ((req = dgmsock->send_queue)) {
+ size_t len;
+
+ len = req->encoded.length;
+ status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0,
+ req->dest_addr, req->dest_port);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(3,("Failed to send datagram of length %u to %s:%d\n",
+ req->encoded.length, req->dest_addr, req->dest_port));
+ DLIST_REMOVE(dgmsock->send_queue, req);
+ talloc_free(req);
+ continue;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) return;
+
+ DLIST_REMOVE(dgmsock->send_queue, req);
+ talloc_free(req);
+ }
+
+ EVENT_FD_NOT_WRITEABLE(dgmsock->fde);
+ return;
+}
+
+
+/*
handle fd events on a nbt_dgram_socket
*/
static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde,
@@ -92,7 +141,7 @@ static void dgm_socket_handler(struct event_context *ev, struct fd_event *fde,
struct nbt_dgram_socket *dgmsock = talloc_get_type(private,
struct nbt_dgram_socket);
if (flags & EVENT_FD_WRITE) {
- /* nothing at the moment */
+ dgm_socket_send(dgmsock);
} else if (flags & EVENT_FD_READ) {
dgm_socket_recv(dgmsock);
}
@@ -128,6 +177,10 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx,
dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock,
socket_get_fd(dgmsock->sock), 0,
dgm_socket_handler, dgmsock);
+
+ dgmsock->send_queue = NULL;
+ dgmsock->incoming.handler = NULL;
+ dgmsock->mailslot_handlers = NULL;
return dgmsock;
@@ -138,7 +191,7 @@ failed:
/*
- setup a handler for incoming requests
+ setup a handler for generic incoming requests
*/
NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock,
void (*handler)(struct nbt_dgram_socket *,
@@ -151,3 +204,37 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock,
EVENT_FD_READABLE(dgmsock->fde);
return NT_STATUS_OK;
}
+
+
+/*
+ queue a datagram for send
+*/
+NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock,
+ struct nbt_dgram_packet *packet,
+ const char *dest_addr,
+ int dest_port)
+{
+ struct nbt_dgram_request *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+ req = talloc(dgmsock, struct nbt_dgram_request);
+ if (req == NULL) goto failed;
+
+ req->dest_addr = talloc_strdup(req, dest_addr);
+ if (req->dest_addr == NULL) goto failed;
+ req->dest_port = dest_port;
+
+ status = ndr_push_struct_blob(&req->encoded, req, packet,
+ (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ DLIST_ADD_END(dgmsock->send_queue, req, struct nbt_dgram_request *);
+
+ EVENT_FD_WRITEABLE(dgmsock->fde);
+
+ return NT_STATUS_OK;
+
+failed:
+ talloc_free(req);
+ return status;
+}