如何使ldap_simple_bind_s超时?

时间:2009-12-03 20:24:49

标签: c linux unix ldap

我们最近遇到了测试LDAP服务器的问题 - 它已挂起并且不会响应请求。结果,我们的应用程序永远挂起*尝试绑定它。这只发生在Unix机器上 - 在Windows上,ldap_simple_bind_s呼叫在大约30秒后超时。

*我不知道它是否真的永远,但它至少是几分钟。

我添加了对ldap_set_option的调用,同时尝试LDAP_OPT_TIMEOUTLDAP_OPT_NETWORK_TIMEOUT,但绑定调用仍然挂起。在我选择一段时间后,有没有办法让ldap_simple_bind_s超时?

2 个答案:

答案 0 :(得分:1)

这里发生了一些事情。

基本上,LDAP SDK已损坏;基于规范,它应该根据您在ldap_set_option中发送的值超时。不幸的是,它没有做到这一点。你的绑定可能最终会超时,但直到操作系统返回失败时才会出现,这将来自TCP超时或该超时的某个倍数。

您可以使用ldap_simple_bind(),然后多次调用ldap_result()来解决此问题。如果你没有在你想要的超时时间内得到结果,你可以调用ldap_abandon_ext()告诉SDK放弃。

当然,因为你试图绑定它几乎肯定会使连接处于不可用的状态,所以你需要立即解除绑定。

希望这有帮助。

答案 1 :(得分:0)

更新:以下代码仅适用于openldap 2.4+。 openLdap 2.3不支持LDAP_OPT_TIMEOUT,否则无论你设置什么,ldap_simple_bind_s都不会超时。以下是openLdap论坛的link

我在LDAP身份验证服务中使用ldap_simple_bind_s,并设置了LDAP_OPT_TIMEOUT,LDAP_OPT_TIMELIMIT和LDAP_OPT_NETWORK_TIMEOUT;如果LDAP服务器不可用,它会成功超时。

以下是我的LDAP Connect方法的代码摘录:

  int opt_timeout     = 4;               // LDAP_OPT_TIMEOUT
  int timelimit       = 4;               // LDAP_OPT_TIMELIMIT
  int network_timeout = 4;               // LDAP_OPT_NETWORK_TIMEOUT
  int status = 0;

      // Set LDAP operation timeout(synchronous operations)

      if ( opt_timeout > 0 )
      {

          struct timeval optTimeout;
          optTimeout.tv_usec = 0;
          optTimeout.tv_sec = opt_timeout;

          status = ldap_set_option(connection, LDAP_OPT_TIMEOUT, (void *)&optTimeout);
          if ( status != LDAP_OPT_SUCCESS )
          {
              return false;
          }
      }

      // Set LDAP operation timeout
      if ( timelimit > 0 )
      {
          status = ldap_set_option(connection, LDAP_OPT_TIMELIMIT, (void *)&timelimit);
          if ( status != LDAP_OPT_SUCCESS )
          {
              return false;
          }
      }

      // Set LDAP network operation timeout(connection attempt)
      if ( network_timeout > 0 )
      {
          struct timeval networkTimeout;
          networkTimeout.tv_usec = 0;
          networkTimeout.tv_sec = network_timeout;

          status = ldap_set_option(connection, LDAP_OPT_NETWORK_TIMEOUT, (void *)&networkTimeout);
          if ( status != LDAP_OPT_SUCCESS )
          {
              return false;
          }
      }