sdap_id_op.c revision 10922e0293f3ebf056708acacce35e93fe07747e
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom LDAP ID backend operation retry logic and connection cache
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom Eugene Indenbom <eindenbom@gmail.com>
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom Copyright (C) 2008-2010 Red Hat
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom This program is free software; you can redistribute it and/or modify
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom it under the terms of the GNU General Public License as published by
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom the Free Software Foundation; either version 3 of the License, or
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom (at your option) any later version.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom This program is distributed in the hope that it will be useful,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom but WITHOUT ANY WARRANTY; without even the implied warranty of
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom GNU General Public License for more details.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom You should have received a copy of the GNU General Public License
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom along with this program. If not, see <http://www.gnu.org/licenses/>.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* LDAP async connection cache */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* list of all open connections */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* cached (current) connection */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* LDAP async operation tracker:
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * - keeps track of connection usage
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * - keeps track of operation retries */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* ID backend context */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* double linked list pointers */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* current connection */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* number of reconnects for this operation */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* connection request
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * It is required as we need to know which requests to notify
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * when shared connection request to sdap_handle completes.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * This member is cleared when sdap_id_op_connect_state
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * associated with request is destroyed */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* LDAP connection cache connection attempt/established connection data */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* LDAP connection cache */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* double linked list pointers */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* sdap handle */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* connection request */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* timer for connection expiration */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* number of running connection notifies */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* list of operations using connect */
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny /* A flag which is signalizing that this
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny * connection will be disconnected and should
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny * not be used any more */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_conn_cache_be_offline_cb(void *pvt);
10922e0293f3ebf056708acacce35e93fe07747eJan Zelenystatic void sdap_id_conn_cache_fo_reconnect_cb(void *pvt);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_conn_data_destroy(struct sdap_id_conn_data *conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_is_connection_expired(struct sdap_id_conn_data *conn_data, int timeout);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_can_reuse_connection(struct sdap_id_conn_data *conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_conn_data_expire_handler(struct tevent_context *ev,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_conn_data_set_expire_timer(struct sdap_id_conn_data *conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_hook_conn_data(struct sdap_id_op *op, struct sdap_id_conn_data *conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_id_op_can_reconnect(struct sdap_id_op *op);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_connect_req_complete(struct sdap_id_op *op, int dp_error, int ret);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_op_connect_state_destroy(void *pvt);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_op_connect_step(struct tevent_req *req);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_connect_done(struct tevent_req *subreq);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Create a connection cache */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_cache *conn_cache = talloc_zero(memctx, struct sdap_id_conn_cache);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(1, ("talloc_zero(struct sdap_id_conn_cache) failed.\n"));
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny ret = be_add_reconnect_cb(conn_cache, id_ctx->be,
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny DEBUG(SSSDBG_CRIT_FAILURE, ("be_add_reconnect_cb failed.\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Callback on BE going offline */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_conn_cache_be_offline_cb(void *pvt)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_cache *conn_cache = talloc_get_type(pvt, struct sdap_id_conn_cache);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_data *cached_connection = conn_cache->cached_connection;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* Release any cached connection on going offline */
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny/* Callback for attempt to reconnect to primary server */
10922e0293f3ebf056708acacce35e93fe07747eJan Zelenystatic void sdap_id_conn_cache_fo_reconnect_cb(void *pvt)
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny struct sdap_id_conn_cache *conn_cache = talloc_get_type(pvt, struct sdap_id_conn_cache);
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny struct sdap_id_conn_data *cached_connection = conn_cache->cached_connection;
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny /* Release any cached connection on going offline */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Release sdap_id_conn_data and destroy it if no longer needed */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom if (!conn_data || conn_data->ops || conn_data->notify_lock) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* connection is in use */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Destructor for struct sdap_id_conn_data */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_conn_data_destroy(struct sdap_id_conn_data *conn_data)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* we clean out list of ops to make sure that order of destruction does not matter */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Check whether connection will expire after timeout seconds */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_is_connection_expired(struct sdap_id_conn_data *conn_data, int timeout)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom if (!conn_data || !conn_data->sh || !conn_data->sh->connected) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom return true;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom if ((expire_time != 0) && (expire_time < time( NULL ) + timeout) ) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom return true;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom return false;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Check whether connection can be reused for next LDAP ID operation */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_can_reuse_connection(struct sdap_id_conn_data *conn_data)
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny !conn_data->sh->connected || conn_data->disconnecting) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom return false;
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce timeout = dp_opt_get_int(conn_data->conn_cache->id_ctx->opts->basic,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom return !sdap_is_connection_expired(conn_data, timeout);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Set expiration timer for connection if needed */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_conn_data_set_expire_timer(struct sdap_id_conn_data *conn_data)
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce timeout = dp_opt_get_int(conn_data->conn_cache->id_ctx->opts->basic,
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce tevent_add_timer(conn_data->conn_cache->id_ctx->be->ev,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Handler for connection expiration timer */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_conn_data_expire_handler(struct tevent_context *ev,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_data *conn_data = talloc_get_type(pvt,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(3, ("connection is about to expire, releasing it\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Create an operation object */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstruct sdap_id_op *sdap_id_op_create(TALLOC_CTX *memctx, struct sdap_id_conn_cache *conn_cache)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_op *op = talloc_zero(memctx, struct sdap_id_op);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom talloc_set_destructor((void*)op, sdap_id_op_destroy);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Attach/detach connection to sdap_id_op */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_hook_conn_data(struct sdap_id_op *op, struct sdap_id_conn_data *conn_data)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_data *current = op->conn_data;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DLIST_ADD_END(conn_data->ops, op, struct sdap_id_op*);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Destructor for sdap_id_op */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_op *op = talloc_get_type(pvt, struct sdap_id_op);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Check whether retry with reconnect can be performed for the operation */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic bool sdap_id_op_can_reconnect(struct sdap_id_op *op)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* we allow 2 retries for failover server configured:
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * - one for connection broken during request execution
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * - one for the following (probably failed) reconnect attempt */
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce count = be_fo_get_server_count(op->conn_cache->id_ctx->be,
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce/* state of connect request */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Destructor for operation connection request */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_op_connect_state_destroy(void *pvt)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_op_connect_state *state = talloc_get_type(pvt,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* clear destroyed connection request */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Begin to connect to LDAP server */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstruct tevent_req *sdap_id_op_connect_send(struct sdap_id_op *op,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* Connection already in progress, invalid operation */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(1, ("Bug: connection request is already running or completed and leaked.\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom req = tevent_req_create(memctx, &state, struct sdap_id_op_connect_state);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom talloc_set_destructor((void*)state, sdap_id_op_connect_state_destroy);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* If the operation is already connected,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * reuse existing connection regardless of its status */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom } else if (op->conn_data && !op->conn_data->connect_req) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* Connection is already established */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Begin a connection retry to LDAP server */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic int sdap_id_op_connect_step(struct tevent_req *req)
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce tevent_req_data(req, struct sdap_id_op_connect_state);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_cache *conn_cache = op->conn_cache;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* Try to reuse context cached connection */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("waiting for connection to complete\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("releasing expired cached connection\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom conn_data = talloc_zero(conn_cache, struct sdap_id_conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom talloc_set_destructor(conn_data, sdap_id_conn_data_destroy);
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce subreq = sdap_cli_connect_send(conn_data, state->ev,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom tevent_req_set_callback(subreq, sdap_id_op_connect_done, conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Subrequest callback for connection completion */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_connect_done(struct tevent_req *subreq)
1d9eec9e868fbc2d996f1030a43675be9a840133Simo Sorce tevent_req_callback_data(subreq, struct sdap_id_conn_data);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache;
743475e5d730f1438bff4bb086600186adfe8311Jan Zeleny struct sdap_server_opts *current_srv_opts = NULL;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom bool can_retry = false;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom bool is_offline = false;
1d9eec9e868fbc2d996f1030a43675be9a840133Simo Sorce ret = sdap_cli_connect_recv(subreq, conn_data, &can_retry,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(0, ("Authentication mechanism not Supported by server\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom if (ret == EOK && (!conn_data->sh || !conn_data->sh->connected)) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(0, ("sdap_cli_connect_recv returned bogus connection\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* be is going offline as there is no more servers to try */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(1, ("Failed to connect, going offline (%d [%s])\n",
743475e5d730f1438bff4bb086600186adfe8311Jan Zeleny DEBUG(8, ("Old USN: %lu, New USN: %lu\n", current_srv_opts->last_usn, srv_opts->last_usn));
743475e5d730f1438bff4bb086600186adfe8311Jan Zeleny if (strcmp(srv_opts->server_id, current_srv_opts->server_id) == 0 &&
743475e5d730f1438bff4bb086600186adfe8311Jan Zeleny current_srv_opts->last_usn > srv_opts->last_usn) {
743475e5d730f1438bff4bb086600186adfe8311Jan Zeleny DEBUG(5, ("Server was probably re-initialized\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom ret = sdap_id_conn_data_set_expire_timer(conn_data);
85abff7f43e8006de2c2fa35612884d377b9a036Simo Sorce sdap_steal_server_opts(conn_cache->id_ctx, &srv_opts);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* do not attempt to retry on errors like ENOMEM */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* Notify about connection */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("connection was broken after %d notifies\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* another operation to notify */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* failed to connect or connection got broken during notify */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom bool retry = false;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* drop connection from cache now */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* determining whether retry is possible */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* be is offline, no retry possible */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("skipping automatic retry on op #%d as be is offline\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("attempting automatic retry on op #%d\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("attempting failover retry on op #%d\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom int retry_ret = sdap_id_op_connect_step(op->connect_req);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom sdap_id_op_connect_req_complete(op, DP_ERR_FATAL, retry_ret);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("notify connected to op #%d\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom sdap_id_op_connect_req_complete(op, DP_ERR_OK, ret);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom } else if (is_offline) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("notify offline to op #%d\n", notify_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom sdap_id_op_connect_req_complete(op, DP_ERR_OFFLINE, EAGAIN);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("notify error to op #%d: %d [%s]\n", notify_count, ret, strerror(ret)));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom sdap_id_op_connect_req_complete(op, DP_ERR_FATAL, ret);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* all operations notified */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("caching successful connection after %d notifies\n", notify_count));
1639954090616f9e868a083f358c87e381b3fb78eindenbom /* Run any post-connection routines */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Mark operation connection request as complete */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstatic void sdap_id_op_connect_req_complete(struct sdap_id_op *op, int dp_error, int ret)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom state = tevent_req_data(req, struct sdap_id_op_connect_state);
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Get the result of an asynchronous connect operation on sdap_id_op
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * In dp_error data provider error code is returned:
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_OK - connection established
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_FATAL - operation failed
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomint sdap_id_op_connect_recv(struct tevent_req *req, int *dp_error)
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom struct sdap_id_op_connect_state *state = tevent_req_data(req,
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Report completion of LDAP operation and release associated connection.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * Returns operation result (possible updated) passed in ret parameter.
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * In dp_error data provider error code is returned:
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_OK (operation result = EOK) - operation completed
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_OK (operation result != EOK) - operation can be retried
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom * DP_ERR_FATAL - operation failed */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomint sdap_id_op_done(struct sdap_id_op *op, int retval, int *dp_err_out)
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny struct sdap_id_conn_data *current_conn = op->conn_data;
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* this currently the only possible communication error after connection is established */
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny && current_conn == op->conn_cache->cached_connection) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* do not reuse failed connection */
54577e54d1b6300aeb348087372c14ed72530f88eindenbom DEBUG(5, ("communication error on cached connection, moving to next server\n"));
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce be_fo_try_next_server(op->conn_cache->id_ctx->be,
cf1cf7b96d38c8b481a90d800cf53546ac15ce8aSimo Sorce } else if (be_is_offline(op->conn_cache->id_ctx->be)) {
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* if backend is already offline, just report offline, do not duplicate errors */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* communication error, can try to reconnect */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("too many communication failures, giving up...\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* reconnect retry */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom DEBUG(9, ("advising for connection retry #%i\n", op->reconnect_retry_count));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom /* end of request */
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny if (current_conn->ops == NULL || current_conn->disconnecting) {
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny DEBUG(SSSDBG_TRACE_FUNC, ("Connection is marked for "
10922e0293f3ebf056708acacce35e93fe07747eJan Zeleny "disconnection, executing ...\n"));
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbom/* Get SDAP handle associated with operation by sdap_id_op_connect */
2d7a7b0140a4d3fcef9148900276e24f82e33866eindenbomstruct sdap_handle *sdap_id_op_handle(struct sdap_id_op *op)