summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2011-08-15 17:46:04 +0200
committerStephen Gallagher <sgallagh@redhat.com>2011-12-13 08:40:08 -0500
commit48d1565a58de4ca58b36aef2ae65392ac97d16e8 (patch)
treef6107dc70d15859c7627e1635d577bccd7739bcb
parent8f9336b0e7e13d4d133555cc98d46a28397d82e4 (diff)
downloadsssd-48d1565a58de4ca58b36aef2ae65392ac97d16e8.tar.gz
sssd-48d1565a58de4ca58b36aef2ae65392ac97d16e8.tar.xz
sssd-48d1565a58de4ca58b36aef2ae65392ac97d16e8.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.
-rw-r--r--src/providers/ldap/sdap_async_connection.c6
-rw-r--r--src/util/sss_ldap.c36
-rw-r--r--src/util/sss_ldap.h2
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 58e5a0f6c..7bce2cdf8 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -87,6 +87,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;
@@ -110,8 +111,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 ddaf9b686..c7ed04b15 100644
--- a/src/util/sss_ldap.c
+++ b/src/util/sss_ldap.c
@@ -301,12 +301,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
};
@@ -314,7 +321,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;
@@ -331,6 +338,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) {
@@ -355,6 +363,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;
@@ -385,6 +405,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,
@@ -394,6 +426,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 599559604..b60d05cdb 100644
--- a/src/util/sss_ldap.h
+++ b/src/util/sss_ldap.h
@@ -43,7 +43,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__ */