setArgPrefix( "ldap" + suffix );
m_getdn = false;
+ m_reconnect_attempts = getArgAsNum( "reconnect-attempts" );
m_list_fcnt = &LdapBackend::list_simple;
m_lookup_fcnt = &LdapBackend::lookup_simple;
m_prepare_fcnt = &LdapBackend::prepare_simple;
+bool LdapBackend::reconnect()
+{
+ int attempts = m_reconnect_attempts;
+ bool connected = false;
+ while ( !connected && attempts > 0 ) {
+ L << Logger::Debug << m_myname << " Reconnection attempts left: " << attempts << endl;
+ connected = m_pldap->connect();
+ if ( !connected )
+ Utility::usleep( 250 );
+ --attempts;
+ }
+
+ if ( connected )
+ m_pldap->bind( m_authenticator );
+
+ return connected;
+}
+
+
+
bool LdapBackend::list( const DNSName& target, int domain_id, bool include_disabled )
{
try
L << Logger::Warning << m_myname << " Unable to get zone " << target << " from LDAP directory: " << lt.what() << endl;
throw( DBException( "LDAP server timeout" ) );
}
+ catch( LDAPNoConnection &lnc )
+ {
+ L << Logger::Warning << m_myname << " Connection to LDAP lost, trying to reconnect" << endl;
+ if ( reconnect() )
+ this->list( target, domain_id );
+ else
+ throw PDNSException( "Failed to reconnect to LDAP server" );
+ }
catch( LDAPException &le )
{
L << Logger::Error << m_myname << " Unable to get zone " << target << " from LDAP directory: " << le.what() << endl;
L << Logger::Warning << m_myname << " Unable to search LDAP directory: " << lt.what() << endl;
throw( DBException( "LDAP server timeout" ) );
}
+ catch( LDAPNoConnection &lnc )
+ {
+ L << Logger::Warning << m_myname << " Connection to LDAP lost, trying to reconnect" << endl;
+ if ( reconnect() )
+ this->lookup( qtype, qname, dnspkt, zoneid );
+ else
+ throw PDNSException( "Failed to reconnect to LDAP server" );
+ }
catch( LDAPException &le )
{
L << Logger::Error << m_myname << " Unable to search LDAP directory: " << le.what() << endl;
declare( suffix, "filter-axfr", "LDAP filter for limiting AXFR results", "(:target:)" );
declare( suffix, "filter-lookup", "LDAP filter for limiting IP or name lookups", "(:target:)" );
declare( suffix, "disable-ptrrecord", "Deprecated, use ldap-method=strict instead", "no" );
+ declare( suffix, "reconnect-attempts", "Number of attempts to re-establish a lost LDAP connection", "5" );
}
vector<DNSName>::iterator m_adomain;
vector<DNSName> m_adomains;
QType m_qtype;
+ int m_reconnect_attempts;
bool (LdapBackend::*m_list_fcnt)( const DNSName&, int );
void (LdapBackend::*m_lookup_fcnt)( const QType&, const DNSName&, DNSPacket*, int );
bool getDomainInfo( const string& domain, DomainInfo& di );
+ bool reconnect();
+
public:
LdapBackend( const string &suffix="" );
}
+bool PowerLDAP::connect()
+{
+ try
+ {
+ ensureConnect();
+ return true;
+ }
+ catch( LDAPException &le )
+ {
+ return false;
+ }
+}
+
+
void PowerLDAP::setOption( int option, int value )
{
ldapSetOption( d_ld, option, (void*) &value );
if ( i == -1 ) {
// Error while retrieving the message
- throw LDAPException( "Error when retrieving LDAP result: " + getError() );
+ int err_code;
+ ldapGetOption( d_ld, LDAP_OPT_ERROR_NUMBER, &err_code );
+ if ( err_code == LDAP_SERVER_DOWN || err_code == LDAP_CONNECT_ERROR )
+ throw LDAPNoConnection();
+ else
+ throw LDAPException( "PowerLDAP::getSearchEntry(): Error when retrieving LDAP result: " + getError( err_code ) );
}
if ( i == 0 ) {