/* create a temporary mailslot handler for a reply mailslot, allocating a new mailslot name using the given base name and a random integer extension */ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, dgram_mailslot_handler_t handler, void *private_data) { char *name; int i; struct dgram_mailslot_handler *dgmslot; /* try a 100 times at most */ for (i=0; i<100; i++) { name = talloc_asprintf(dgmsock, "%s%03u", mailslot_name, generate_random() % 1000); if (name == NULL) return NULL; if (dgram_mailslot_find(dgmsock, name)) { talloc_free(name); return NULL; } dgmslot = dgram_mailslot_listen(dgmsock, name, handler, private_data); talloc_free(name); if (dgmslot != NULL) { return dgmslot; } } DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); return NULL; }
/* handle recv events on a nbt dgram socket */ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); NTSTATUS status; struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct nbt_dgram_packet *packet; const char *mailslot_name; enum ndr_err_code ndr_err; status = socket_pending(dgmsock->sock, &dsize); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } blob = data_blob_talloc(tmp_ctx, NULL, dsize); if ((dsize != 0) && (blob.data == NULL)) { talloc_free(tmp_ctx); return; } status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } blob.length = nread; DEBUG(5,("Received dgram packet of length %d from %s:%d\n", (int)blob.length, src->addr, src->port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); if (packet == NULL) { talloc_free(tmp_ctx); return; } /* parse the request */ ndr_err = ndr_pull_struct_blob(&blob, packet, packet, (ndr_pull_flags_fn_t)ndr_pull_nbt_dgram_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); DEBUG(2,("Failed to parse incoming NBT DGRAM packet - %s\n", nt_errstr(status))); talloc_free(tmp_ctx); return; } /* 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); } 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); } } talloc_free(tmp_ctx); }