2009-12-03 120 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; 
      } 
     }