]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add lock to rfc2136 handling to fix deadlock issue
authorRuben d'Arco <cyclops@prof-x.net>
Sun, 3 Mar 2013 07:01:41 +0000 (08:01 +0100)
committermind04 <mind04@monshouwer.org>
Fri, 12 Jul 2013 15:26:18 +0000 (17:26 +0200)
We receive
Mar 03 07:40:06 UPDATE (9044) from 127.0.0.3 for test.dyndns: Caught SSqlException: Failed to execute mysql_query, perhaps connection died? Err=1: Deadlock found when trying to get lock; try restarting transaction; Sending ServFail!

if we don't.

pdns/packethandler.hh
pdns/rfc2136handler.cc

index c49bd6199b910ba3504c02d1763aa7c8c74f7e2a..1a00c11967b8a8f1562a19950274908bf091f02f 100755 (executable)
@@ -122,6 +122,7 @@ private:
   void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target);
   
   static AtomicCounter s_count;
+  static pthread_mutex_t s_rfc2136lock;
   bool d_doFancyRecords;
   bool d_doRecursion;
   bool d_doCNAME;
index 2aa8139146b1d6b4588fbc923a5d9b87e8f3f054..87c6c4c4aeab9565e4e5ba27ebf284f12aca23c3 100755 (executable)
@@ -13,6 +13,8 @@
 
 extern PacketCache PC;
 
+pthread_mutex_t PacketHandler::s_rfc2136lock=PTHREAD_MUTEX_INITIALIZER;
+
 // Implement section 3.2.1 and 3.2.2 of RFC2136
 int PacketHandler::checkUpdatePrerequisites(const DNSRecord *rr, DomainInfo *di) {
   if (rr->d_ttl != 0)
@@ -534,7 +536,7 @@ int PacketHandler::processUpdate(DNSPacket *p) {
     }
   }
 
-  //TODO: Start a lock here, to make section 3.7 correct???
+  Lock l(&s_rfc2136lock);
   L<<Logger::Info<<msgPrefix<<"starting transaction."<<endl;
   if (!di.backend->startTransaction(p->qdomain, -1)) { // Not giving the domain_id means that we do not delete the records.
     L<<Logger::Error<<msgPrefix<<"Backend for domain "<<p->qdomain<<" does not support transaction. Can't do Update packet."<<endl;
@@ -691,11 +693,21 @@ int PacketHandler::processUpdate(DNSPacket *p) {
       increaseSerial(msgPrefix, &di, haveNSEC3, narrow, &ns3pr);
 
   }
+  catch (DBException &e) {
+    L<<Logger::Error<<msgPrefix<<"Caught DBException: "<<e.reason<<"; Sending ServFail!"<<endl;
+    di.backend->abortTransaction();
+    return RCode::ServFail;
+  }
   catch (AhuException &e) {
     L<<Logger::Error<<msgPrefix<<"Caught AhuException: "<<e.reason<<"; Sending ServFail!"<<endl;
     di.backend->abortTransaction();
     return RCode::ServFail;
   }
+  catch (SSqlException &e) {
+    L<<Logger::Error<<msgPrefix<<"Caught SSqlException: "<<e.txtReason()<<"; Sending ServFail!"<<endl;
+    di.backend->abortTransaction();
+    return RCode::ServFail;
+  }  
   catch (...) {
     L<<Logger::Error<<msgPrefix<<"Caught unknown exception when performing update. Sending ServFail!"<<endl;
     di.backend->abortTransaction();