Browse Source

[1262] Implement the AXFR fallback

Michal 'vorner' Vaner 13 years ago
parent
commit
703cd3ed58
1 changed files with 31 additions and 2 deletions
  1. 31 2
      src/bin/xfrin/xfrin.py.in

+ 31 - 2
src/bin/xfrin/xfrin.py.in

@@ -332,9 +332,38 @@ class XfrinIXFREnd(XfrinState):
         return False
 
 class XfrinAXFR(XfrinState):
+    def __init__(self):
+        self.__diff = None
+
+    def handle_rr(self, conn, rr):
+        """
+        Handle the RR by putting it into the zone.
+        """
+        if self.__diff is None:
+            # This is the first RR there. So create the diff to accumulate
+            # data
+            self.__diff = Diff(conn._datasrc_client, conn._zone_name, True)
+        self.__diff.add_data(rr)
+        if rr.get_type() == RRType.SOA():
+            # Soa means end. We commit the data and move to the final state
+            self.set_xfrstate(conn, XfrinAXFREnd())
+            self.__diff.commit()
+        # Yes, we've eaten this RR.
+        return True
+
+class XfrinAXFREnd(XfrinState):
     def handle_rr(self, conn, rr):
-        raise XfrinException('Falling back from IXFR to AXFR not ' +
-                             'supported yet')
+        raise XfrinProtocolError('Extra data after the end of AXFR: ' +
+                                 rr.to_text())
+
+    def finish_message(self, conn):
+        """
+        Final processing after processing an entire AXFR session.
+
+        There might be more actions here, but for now we simply return False,
+        indicating there will be no more message to receive.
+        """
+        return False
 
 class XfrinConnection(asyncore.dispatcher):
     '''Do xfrin in this class. '''