Exemplo n.º 1
0
static
void ldap_connection_abort_request(struct ldap_op_queue_entry *req)
{
	struct ldap_result res;

	/* too bad */
	if (req->to_abort != NULL)
		timeout_remove(&req->to_abort);
	if (req->msgid > -1)
		ldap_abandon_ext(req->conn->conn, req->msgid, NULL, NULL);

	memset(&res, 0, sizeof(res));
	res.openldap_ret = LDAP_TIMEOUT;
	res.error_string = "Aborting LDAP request after timeout";
	if (req->result_callback != NULL)
		req->result_callback(&res, req->result_callback_ctx);

	unsigned int n = aqueue_count(req->conn->request_queue);
	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(req->conn->request_array),
				  aqueue_idx(req->conn->request_queue, i));
		if (req == *reqp) {
			aqueue_delete(req->conn->request_queue, i);
			ldap_connection_request_destroy(&req);
			return;
		}
	}
	i_unreached();
}
Exemplo n.º 2
0
static
void ldap_connection_send_next(struct ldap_connection *conn)
{
	unsigned int i = 0, n;
	struct ldap_op_queue_entry *req;

	if (conn->to_reconnect != NULL)
		timeout_remove(&(conn->to_reconnect));

	if (conn->state == LDAP_STATE_DISCONNECT) {
		if (ldap_connection_connect(conn) == -1)
			conn->to_reconnect = timeout_add(1000, ldap_connection_send_next, conn);
		return;
	}

	if (conn->state != LDAP_STATE_CONNECT) {
		return;
	}

	if (conn->pending > 10) return; /* try again later */

	req = NULL;
	/* get next request */
	n = aqueue_count(conn->request_queue);

	for(i=0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->msgid > -1)
			break;
		req = *reqp;
	}

	i--;

	/* nothing to actually send */
	if (req == NULL) return;

	i_assert(req->msgid == -1);

	const char *error;
	int ret;
	if ((ret = req->send_request_cb(conn, req, &error)) != LDAP_SUCCESS) {
		/* did not succeed */
		struct ldap_result res;

		memset(&res, 0, sizeof(res));
		res.openldap_ret = ret;
		if (req->result_callback != NULL)
			req->result_callback(&res, req->result_callback_ctx);

		ldap_connection_request_destroy(&req);
		aqueue_delete(conn->request_queue, i);
	} else conn->pending++;
}
Exemplo n.º 3
0
static const char *test_aqueue2(unsigned int initial_size)
{
	ARRAY(unsigned int) aqueue_array;
	unsigned int i, j, k;

	for (i = 0; i < N_ELEMENTS(aqueue_input); i++) {
		for (k = 0; k < N_ELEMENTS(aqueue_input); k++) {
			struct aqueue *aqueue;

			t_array_init(&aqueue_array, initial_size);
			aqueue = aqueue_init(&aqueue_array.arr);
			aqueue->head = aqueue->tail = initial_size - 1;
			for (j = 0; j < k; j++) {
				aqueue_append(aqueue, &aqueue_input[j]);
				if (aqueue_count(aqueue) != j + 1) {
					return t_strdup_printf("Wrong count after append %u vs %u)",
							       aqueue_count(aqueue), j + 1);
				}
				if (!aqueue_is_ok(aqueue, UINT_MAX))
					return "Invalid data after append";
			}

			if (k != 0 && i < k) {
				aqueue_delete(aqueue, i);
				if (aqueue_count(aqueue) != k - 1)
					return "Wrong count after delete";
				if (!aqueue_is_ok(aqueue, i))
					return "Invalid data after delete";
			}
			aqueue_clear(aqueue);
			if (aqueue_count(aqueue) != 0)
				return "aqueue_clear() broken";
			aqueue_deinit(&aqueue);
		}
	}
	return NULL;
}
Exemplo n.º 4
0
void aqueue_delete_tail(struct aqueue *aqueue)
{
	aqueue_delete(aqueue, 0);
}
Exemplo n.º 5
0
static int
ldap_connection_handle_message(struct ldap_connection *conn,
			       LDAPMessage *message)
{
	struct ldap_op_queue_entry *req;
	unsigned int i = 0;
	bool finished = FALSE;
	int err = LDAP_SUCCESS;

	/* we need to look at who it was for */
	req = ldap_connection_find_req_by_msgid(conn, ldap_msgid(message), &i);
	if (req != NULL)
		err = req->internal_response_cb(conn, req, message, &finished);
	ldap_msgfree(message);

	switch(err) {
	case LDAP_SUCCESS:
		break;
	case LDAP_SERVER_DOWN:
#ifdef LDAP_CONNECT_ERROR
	case LDAP_CONNECT_ERROR:
#endif
	case LDAP_UNAVAILABLE:
	case LDAP_OPERATIONS_ERROR:
	case LDAP_BUSY:
		/* requeue */
		ldap_connection_kill(conn);
		ldap_connection_send_next(conn);
		finished = FALSE;
		break;
	case LDAP_INVALID_CREDENTIALS: {
		/* fail everything */
		ldap_connection_kill(conn);
		ldap_connection_abort_all_requests(conn);
		return 0;
	}
	case LDAP_SIZELIMIT_EXCEEDED:
	case LDAP_TIMELIMIT_EXCEEDED:
	case LDAP_NO_SUCH_ATTRIBUTE:
	case LDAP_UNDEFINED_TYPE:
	case LDAP_INAPPROPRIATE_MATCHING:
	case LDAP_CONSTRAINT_VIOLATION:
	case LDAP_TYPE_OR_VALUE_EXISTS:
	case LDAP_INVALID_SYNTAX:
	case LDAP_NO_SUCH_OBJECT:
	case LDAP_ALIAS_PROBLEM:
	case LDAP_INVALID_DN_SYNTAX:
	case LDAP_IS_LEAF:
	case LDAP_ALIAS_DEREF_PROBLEM:
	case LDAP_FILTER_ERROR:
	case LDAP_LOCAL_ERROR:
		finished = TRUE;
		break;
	default:
		/* ignore */
		break;
	}

	if (finished) {
		i_assert(req != NULL);
		ldap_connection_request_destroy(&req);
		conn->pending--;
		aqueue_delete(conn->request_queue, i);
		return 1;
	}
	return 0;
}