diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2011-08-15 17:46:04 +0200 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2011-08-15 15:21:18 -0400 |
commit | 5bf2314b9f64099cd4e88b8f3498d986d97e1ac6 (patch) | |
tree | e9b1aa6f15b09b6da395438cf2711ed7db0ad3fa /src | |
parent | 0e27817133b931dcbe9d196e9ed0d737164ba613 (diff) | |
download | sssd-5bf2314b9f64099cd4e88b8f3498d986d97e1ac6.tar.gz sssd-5bf2314b9f64099cd4e88b8f3498d986d97e1ac6.tar.xz sssd-5bf2314b9f64099cd4e88b8f3498d986d97e1ac6.zip |
Handle timeout during sss_ldap_init_send
In some cases, where there would be no response from the LDAP server,
there would be no R/W events on the LDAP fd, so
sdap_async_sys_connect_done would never be called.
This patch adds a tevent timer that cancels the connection after
SDAP_NETWORK_TIMEOUT seconds.
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/ldap/sdap_async_connection.c | 6 | ||||
-rw-r--r-- | src/util/sss_ldap.c | 36 | ||||
-rw-r--r-- | src/util/sss_ldap.h | 2 |
3 files changed, 41 insertions, 3 deletions
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index db39be19c..6f67700db 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -89,6 +89,7 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx, struct tevent_req *subreq; struct sdap_connect_state *state; int ret; + int timeout; req = tevent_req_create(memctx, &state, struct sdap_connect_state); if (!req) return NULL; @@ -112,8 +113,11 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx, state->sh->page_size = dp_opt_get_int(state->opts->basic, SDAP_PAGE_SIZE); + timeout = dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT); + subreq = sss_ldap_init_send(state, ev, uri, sockaddr, - sizeof(struct sockaddr_storage)); + sizeof(struct sockaddr_storage), + timeout); if (subreq == NULL) { ret = ENOMEM; DEBUG(1, ("sss_ldap_init_send failed.\n")); diff --git a/src/util/sss_ldap.c b/src/util/sss_ldap.c index bff7c8dca..de4bebf88 100644 --- a/src/util/sss_ldap.c +++ b/src/util/sss_ldap.c @@ -285,12 +285,19 @@ static errno_t set_fd_flags_and_opts(int fd) extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, LDAP **ld); static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq); +static void sdap_async_sys_connect_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, void *pvt); #endif struct sss_ldap_init_state { LDAP *ldap; int sd; const char *uri; + +#ifdef HAVE_LDAP_INIT_FD + struct tevent_timer *connect_timeout; +#endif }; @@ -298,7 +305,7 @@ struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *uri, struct sockaddr_storage *addr, - int addr_len) + int addr_len, int timeout) { int ret = EOK; struct tevent_req *req; @@ -315,6 +322,7 @@ struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, #ifdef HAVE_LDAP_INIT_FD struct tevent_req *subreq; + struct timeval tv; state->sd = socket(addr->ss_family, SOCK_STREAM, 0); if (state->sd == -1) { @@ -339,6 +347,18 @@ struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, goto fail; } + DEBUG(6, ("Setting %d seconds timeout for connecting\n", timeout)); + tv = tevent_timeval_current_ofs(timeout, 0); + + state->connect_timeout = tevent_add_timer(ev, subreq, tv, + sdap_async_sys_connect_timeout, + subreq); + if (state->connect_timeout == NULL) { + DEBUG(1, ("tevent_add_timer failed.\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, sss_ldap_init_sys_connect_done, req); return req; @@ -369,6 +389,18 @@ fail: } #ifdef HAVE_LDAP_INIT_FD +static void sdap_async_sys_connect_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, void *pvt) +{ + struct tevent_req *connection_request; + + DEBUG(4, ("The LDAP connection timed out\n")); + + connection_request = talloc_get_type(pvt, struct tevent_req); + tevent_req_error(connection_request, ETIMEDOUT); +} + static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, @@ -378,6 +410,8 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq) int ret; int lret; + talloc_zfree(state->connect_timeout); + ret = sdap_async_sys_connect_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { diff --git a/src/util/sss_ldap.h b/src/util/sss_ldap.h index ab890293c..4b4d9c1bd 100644 --- a/src/util/sss_ldap.h +++ b/src/util/sss_ldap.h @@ -53,7 +53,7 @@ struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *uri, struct sockaddr_storage *addr, - int addr_len); + int addr_len, int timeout); int sss_ldap_init_recv(struct tevent_req *req, LDAP **ldap, int *sd); #endif /* __SSS_LDAP_H__ */ |