2009-12-03 186 views
2

我们最近在测试LDAP服务器时遇到问题 - 它已挂起,不会响应请求。因此,我们的应用程序永远挂起*,而试图绑定它。这只发生在Unix机器上 - 在Windows上,约30秒后ldap_simple_bind_s调用超时。如何导致ldap_simple_bind_s超时?

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

我将呼叫加到ldap_set_option,尝试LDAP_OPT_TIMEOUTLDAP_OPT_NETWORK_TIMEOUT,但绑定呼叫仍然挂起。在我选择的一段时间后,有没有办法让ldap_simple_bind_s超时?

回答

1

这里发生了一些事情。

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

您可以通过使用ldap_simple_bind()来解决此问题,然后调用ldap_result()几次。如果您不希望在超时内得到结果,则可以调用ldap_abandon_ext()告知SDK放弃。

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

希望这会有所帮助。

+0

谢谢 - 我不知道为什么使用功能的异步版本并没有出现我但解决了这一问题。 – 2009-12-10 16:00:10

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连接方法的代码摘录:

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; 
      } 
     }