From 769070d502a95439ea7d6e2c6616cfa08fc5d673 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Apr 2005 08:35:02 +0000 Subject: 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) --- source4/libcli/dgram/dgramsocket.c | 99 +++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 6 deletions(-) (limited to 'source4/libcli/dgram/dgramsocket.c') 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,12 +78,60 @@ 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 */ @@ -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; +} -- cgit