[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[minion-cvs] Make fragmentation and reassembly work in practise.



Update of /home/minion/cvsroot/src/minion/lib/mixminion/server
In directory moria.mit.edu:/tmp/cvs-serv28685/lib/mixminion/server

Modified Files:
	Modules.py PacketHandler.py ServerMain.py 
Log Message:
Make fragmentation and reassembly work in practise.

BuildMessage, Packet:
- Use symbolic constants instead of '20'.
- Note insanity in exceptions to tag length checking.


BuildMessage:
- Allow decodeMessage to work properly with no tag.
- Make _checkPayload work properly on fragment payloads, instead of rejecting
  them all.

ClientMain:
- Fix typo.

Common:
- Add a 'display base 64' function.

Fragments:
- Better logging
- Make backward compatible with Python2.0 syntax.
- Fix bug in getUnneededFragmentHandles

Main:
- Print version on startup.

test:
- More tests for fragmentation

Modules:
- Seriously debug handling of fragmented messages

PacketHandler:
- Handle instances of DeliveryPacket generated by old versions of the
  code.

ServerMain:
- Logging tweak.


Index: Modules.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/Modules.py,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- Modules.py	25 Aug 2003 23:44:30 -0000	1.52
+++ Modules.py	28 Aug 2003 01:40:08 -0000	1.53
@@ -563,10 +563,12 @@
         if packet.isError():
             LOG.warn("Dropping FRAGMENT packet with decoding error: %s",
                      packet.error)
+            return
         elif not packet.isFragment():
             LOG.warn("Dropping FRAGMENT packet with non-fragment payload.")
+            print packet.type, packet.isfrag
             return
-        if packet.getAddress():
+        elif packet.getAddress():
             LOG.warn("Dropping FRAGMENT packet with spurious addressing info.")
             return
         # Should be instance of FragmentPayload.
@@ -610,27 +612,29 @@
         """Create a _FragmentedDeliveryMessage object from an instance of
            mixminion.Packet.ServerSideFragmentedMessage."""
         self.m = ssfm
+        self.exitType = self.m.routingtype
+        self.address = self.m.routinginfo
         self.contents = None
-    def __getstate__(self):
-        return ( self.m , )
-    def __setstate__(self, s):
-        self.m = s[0]
-        self.contents = None
+        self.tp = None
+        self.headers = None
+
     def isDelivery(self): return 1
-    def getExitType(self): return self.m.routingtype
-    def getAddress(self): return self.m.exitinfo
+    def getExitType(self): return self.exitType
+    def getAddress(self): return self.address
     def getContents(self):
         if self.contents is None: self.decode()
         return self.contents
-    def isPlaintext(self): return 1
+    def isPlaintext(self): 
+        if self.contents is None: self.decode()
+        return self.tp == 'plain'
     def isFragment(self): return 0
     def isEncrypted(self): return 0
-    def isError(self):
+    def isError(self): 
         if self.contents is None: self.decode()
-        return self.isError
+        return self.tp == 'err'
     def isOvercompressed(self):
         if self.contents is None: self.decode()
-        return self.isOvercompressed
+        return self.tp == 'long'
     def isPrintingAscii(self):
         if self.contents is None: self.decode()
         return isPrintingAscii(self.contents, allowISO=1)
@@ -656,13 +660,20 @@
     def decode(self):
         maxLen = 20*len(self.m.compressedContents)
         try:
-            c = uncompressData(self.m.uncompressedContents, maxLen)
+            c = uncompressData(self.m.compressedContents, maxLen)
+            self.contents, self.headers = \
+                           mixminion.Packet.parseMessageAndHeaders(c)
+            self.tp = 'plain'
         except CompressedDataTooLong:
             self.contents = self.m.uncompressedContents
+            self.tp = 'long'
             self.headers = {}
             return
-        self.contents, self.headers = \
-                       mixminion.Packet.parseMessageAndHeaders(c)
+        except MixError, e:
+            self.contents = str(e)
+            self.headers = {}
+            self.tp = 'err'
+        del self.m
         
 #----------------------------------------------------------------------
 class EmailAddressSet:

Index: PacketHandler.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/PacketHandler.py,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- PacketHandler.py	25 Aug 2003 23:44:30 -0000	1.23
+++ PacketHandler.py	28 Aug 2003 01:40:08 -0000	1.24
@@ -146,7 +146,7 @@
         keys = Crypto.Keyset(subh.secret)
 
         # Replay prevention
-        replayhash = keys.get(Crypto.REPLAY_PREVENTION_MODE, 20)
+        replayhash = keys.get(Crypto.REPLAY_PREVENTION_MODE, Crypto.DIGEST_LEN)
         if hashlog.seenHash(replayhash):
             raise ContentError("Duplicate message detected.")
         else:
@@ -273,7 +273,8 @@
         """Construct a new DeliveryPacket."""
         assert 0 <= routingType <= 0xFFFF
         assert len(applicationKey) == 16
-        #assert len(tag) == 20 #XXXX make tag system sane.
+        #assert len(tag) == 20 #XXXX006 make tag system sane.
+        assert len(tag) == 20 or routingType == Packet.FRAGMENT_TYPE
         assert len(payload) == 28*1024
         self.exitType = routingType
         self.address = routingInfo
@@ -285,6 +286,17 @@
         self.headers = None
         self.isfrag = 0
         self.dPayload = None
+        self.error = None #DOCDOC
+
+    def __setstate__(self, state):
+        self.__dict__.update(state)
+        # XXXX006 remove
+        if not hasattr(self, 'isfrag'):
+            self.isfrag = 0
+        if not hasattr(self, 'dPayload'):
+            self.dPayload = None
+        if not hasattr(self, 'error'):
+            self.error = None
 
     def isDelivery(self):
         """Return true iff this packet is a delivery (non-relay) packet."""

Index: ServerMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerMain.py,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- ServerMain.py	25 Aug 2003 23:44:30 -0000	1.90
+++ ServerMain.py	28 Aug 2003 01:40:08 -0000	1.91
@@ -63,7 +63,7 @@
 
 from bisect import insort
 from mixminion.Common import LOG, LogStream, MixError, MixFatalError,\
-     UIError, ceilDiv, createPrivateDir, formatBase64, formatTime, \
+     UIError, ceilDiv, createPrivateDir, disp64, formatTime, \
      installSIGCHLDHandler, Lockfile, LockfileLocked, readFile, secureDelete, \
      tryUnlink, waitForChildren, writeFile
 
@@ -260,8 +260,11 @@
             packet = self.queue.getObject(h)
             if packet.isDelivery():
                 h2 = self.moduleManager.queueDecodedMessage(packet)
-                LOG.debug("  (sending message MIX:%s to exit modules as MOD:%s)"
-                          , h, h2)
+                if h2:
+                    LOG.debug("  (sending message MIX:%s to exit modules as MOD:%s)"
+                              , h, h2)
+                else:
+                    LOG.debug("  (exit modules received message MIX:%s without queueing.)", h)
             else:
                 address = packet.getAddress()
                 h2 = self.outgoingQueue.queueDeliveryMessage(packet, address)