/*
  destroy a pending request
*/
static int nbt_name_request_destructor(struct nbt_name_request *req)
{	
	if (req->state == NBT_REQUEST_SEND) {
		DLIST_REMOVE(req->nbtsock->send_queue, req);
	}
	if (req->state == NBT_REQUEST_WAIT) {
		req->nbtsock->num_pending--;
	}
	if (req->name_trn_id != 0 && !req->is_reply) {
		idr_remove(req->nbtsock->idr, req->name_trn_id);
		req->name_trn_id = 0;
	}
	if (req->te) {
		req->te = NULL;
	}
	if (req->nbtsock->send_queue == NULL) {
		EVENT_FD_NOT_WRITEABLE(req->nbtsock->fde);
	}
	if (req->nbtsock->num_pending == 0 && 
	    req->nbtsock->incoming.handler == NULL) {
		EVENT_FD_NOT_READABLE(req->nbtsock->fde);
	}

	/* once this has been called for this req, don't call again */
	talloc_set_destructor(req, NULL);

	return 0;
}
Exemple #2
0
/*
  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,
				       req->dest);
		if (NT_STATUS_IS_ERR(status)) {
			DEBUG(3,("Failed to send datagram of length %u to %s:%d: %s\n",
				 (unsigned)req->encoded.length, req->dest->addr, req->dest->port, 
				 nt_errstr(status)));
			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 send events on a nbt name socket
*/
static void nbt_name_socket_send(struct nbt_name_socket *nbtsock)
{
	struct nbt_name_request *req = nbtsock->send_queue;
	TALLOC_CTX *tmp_ctx = talloc_new(nbtsock);
	NTSTATUS status;

	while ((req = nbtsock->send_queue)) {
		size_t len;
		
		len = req->encoded.length;
		status = socket_sendto(nbtsock->sock, &req->encoded, &len, 
				       req->dest);
		if (NT_STATUS_IS_ERR(status)) goto failed;		

		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(tmp_ctx);
			return;
		}

		DLIST_REMOVE(nbtsock->send_queue, req);
		req->state = NBT_REQUEST_WAIT;
		if (req->is_reply) {
			talloc_free(req);
		} else {
			EVENT_FD_READABLE(nbtsock->fde);
			nbtsock->num_pending++;
		}
	}

	EVENT_FD_NOT_WRITEABLE(nbtsock->fde);
	talloc_free(tmp_ctx);
	return;

failed:
	DLIST_REMOVE(nbtsock->send_queue, req);
	nbt_name_request_destructor(req);
	req->status = status;
	req->state = NBT_REQUEST_ERROR;
	talloc_free(tmp_ctx);
	if (req->async.fn) {
		req->async.fn(req);
	}
	return;
}
Exemple #4
0
/*
  called when an incoming connection is writeable
*/
static void queue_io_write(struct ctdb_queue *queue)
{
	while (queue->out_queue) {
		struct ctdb_queue_pkt *pkt = queue->out_queue;
		ssize_t n;
		if (queue->ctdb->flags & CTDB_FLAG_TORTURE) {
			n = write(queue->fd, pkt->data, 1);
		} else {
			n = write(queue->fd, pkt->data, pkt->length);
		}

		if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
			if (pkt->length != pkt->full_length) {
				/* partial packet sent - we have to drop it */
				DLIST_REMOVE(queue->out_queue, pkt);
				queue->out_queue_length--;
				talloc_free(pkt);
			}
			talloc_free(queue->fde);
			queue->fde = NULL;
			queue->fd = -1;
			tevent_schedule_immediate(queue->im, queue->ctdb->ev,
						  queue_dead, queue);
			return;
		}
		if (n <= 0) return;
		
		if (n != pkt->length) {
			pkt->length -= n;
			pkt->data += n;
			return;
		}

		DLIST_REMOVE(queue->out_queue, pkt);
		queue->out_queue_length--;
		talloc_free(pkt);
	}

	EVENT_FD_NOT_WRITEABLE(queue->fde);
}
Exemple #5
0
/*
  handle fd send events on a KDC socket
*/
static void kdc_send_handler(struct kdc_socket *kdc_socket)
{
	while (kdc_socket->send_queue) {
		struct kdc_reply *rep = kdc_socket->send_queue;
		NTSTATUS status;
		size_t sendlen;

		status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen,
				       rep->dest);
		if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
			break;
		}
		if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_BUFFER_SIZE)) {
			/* Replace with a krb err, response to big */
		}
		
		DLIST_REMOVE(kdc_socket->send_queue, rep);
		talloc_free(rep);
	}

	if (kdc_socket->send_queue == NULL) {
		EVENT_FD_NOT_WRITEABLE(kdc_socket->fde);
	}
}