[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[minion-cvs] Lots of documentation, lots of usage messages, minor pa...



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

Modified Files:
	Modules.py PacketHandler.py ServerKeys.py ServerMain.py 
	ServerQueue.py 
Log Message:
Lots of documentation, lots of usage messages, minor patches.

EVERYWHERE: 
	- documentation.

ClientMain:
	- Improves usage messages
	- Improved errors
	- Move UIError, UsageError to Common.
	- Finish s/keystore/directory/
	- Finish s/firstHop/routing/ as appropriate
	- Make sure that the last node before a reply block can relay.
	- If the user's password is "", don't bother requesting it.
	- Fix getpass behavior when stdout is redirected to a file.
	- Make SURBLog always grab clientLock
	- Debug SURBLog's behavior with 'LAST_CLEANED'
	- Print a helpful message when inspecting an empty pool.
	- Debug SURBLog location.
	- Allow multiple '-R' arguments.
	- Give an error on 'send -D yes -D no'
	- Give an error on 'send -t alice -t bob'
	- Give an error on '--swap-at=1 --swap-at=2'
	- Give an error on '-H 1 -H 2'
	- Give an error on '-P alice,bob -P bob,alice'
	- Give an error on '--lifetime=3 --lifetime=4'
	- Give a better error on 'decode foo'.
	- Display info on whether surbs have been used when 'inspect-surbs'
	  is called.

Main:
	- Centralized handling of UIError and UsageError.
	- Add plausible plural/singulars for generate-surb(s) and 
          inspect-surb(s).

Common:
	- Fix bugs in LockFile
	- Move UIError, UsageError from ClientMain.

MMTPClient:
	- Refactor sendPacket and sendJunkPacket to both use _sendPacket.

Packet:
	- Quick hack to skip over extraneous whitespace in files of 
          binary reply blocks.
	- Temporary patch to allow 'Decoding handle:' as an alterantive
          spelling of 'Decoding-handle:'.  This allows me to test with
          existing servers.

PacketHandler:
	- Additional asserts

test:
	- Tests for Lockfiles
	- Clean up tests that break because of increased DeliveryPacket 
	  strictness.


Index: Modules.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/Modules.py,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- Modules.py	9 Feb 2003 22:30:58 -0000	1.30
+++ Modules.py	13 Feb 2003 06:30:23 -0000	1.31
@@ -180,18 +180,26 @@
                 self.deliveryFailed(handle, 0)
 
 class DeliveryThread(threading.Thread):
-    "DOCDOC"
-    #DOCDOC
+    """A thread object used by ModuleManager to send messages in the
+       background; delegates to ModuleManager._sendReadyMessages."""
+    ## Fields:
+    # moduleManager -- a ModuleManager object.
+    # event -- an Event that is set when we have messages to deliver, or
+    #    when we're stopping.
+    # __stoppingEvent -- an event that is set when we're shutting down.
     def __init__(self, moduleManager):
+        """Create a new DeliveryThread."""
         threading.Thread.__init__(self)
         self.moduleManager = moduleManager
         self.event = threading.Event()
         self.__stoppingevent = threading.Event()
 
     def beginSending(self):
+        """Tell this thread that there are messages ready to be sent."""
         self.event.set()
 
     def shutdown(self):
+        """Tell this thread to shut down after sending further messages."""
         LOG.info("Telling delivery thread to shut down.")
         self.__stoppingevent.set()
         self.event.set()
@@ -397,6 +405,7 @@
             self.thread.shutdown()
 
     def join(self):
+        """Wait for the delivery thread (if any) to finish shutting down."""
         if self.thread is not None:
             self.thread.join()
 
@@ -460,8 +469,8 @@
                or any parent domain thereof.  "Deny allhosts fred.com" matches
                "bob@fred.com" and "bob@host.fred.com", but not "bob@com".
              pattern: match the email address if the provided regex appears
-               anywhere in it.  "Pattern /./" matches everything;
-               "Pattern /(..)*/" matches all addresses with an even number
+               anywhere in it.  "Deny pattern /./" matches everything;
+               "Deny pattern /(..)*/" matches all addresses with an even number
                of characters.
     """
     ## Fields

Index: PacketHandler.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/PacketHandler.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- PacketHandler.py	9 Feb 2003 22:30:58 -0000	1.9
+++ PacketHandler.py	13 Feb 2003 06:30:23 -0000	1.10
@@ -189,25 +189,53 @@
         return RelayedPacket(address, msg)
         
 class RelayedPacket:
-    """DOCDOC"""
+    """A packet that is to be relayed to another server; returned by
+       returned by PacketHandler.processMessage."""
+    ## Fields:
+    # address -- an instance of IPV4Info
+    # msg -- a 32K packet.
     def __init__(self, address, msg):
+        """Create a new packet, given an instance of IPV4Info and a 32K
+           packet."""
         assert isinstance(address, Packet.IPV4Info)
+        assert len(msg) == 1<<15
         self.address = address
         self.msg = msg
 
     def isDelivery(self):
+        """Return true iff this packet is a delivery (non-relay) packet."""
         return 0
 
     def getAddress(self):
+        """Return an instance of IPV4Info indicating the address where this
+           packet is to be delivered."""
         return self.address
 
     def getPacket(self):
+        """Returns the 32K contents of this packet."""
         return self.msg
 
 class DeliveryPacket:
-    """DOCDOC"""
+    """A packet that is to be delivered via some exit module; returned by
+       PacketHandler.processMessage"""
+    ##Fields:
+    # exitType -- a 2-byte integer indicating which exit module to use.
+    # address -- a string encoding the address to deliver to.
+    # key -- the 16-byte application key
+    # tag -- the 20-byte delivery handle
+    # payload -- the unencoded 28K payload
+    # contents -- until decode is called, None.  After decode is called,
+    #     the actual contents of this message as delivered.
+    # type -- until decode is called, None.  After decode is called,
+    #     one of 'plain' (plaintext message), 'long' (overcompressed message),
+    #     'enc' (encrypted message), or 'err' (malformed message).
     def __init__(self, routingType, routingInfo, applicationKey,
                  tag, payload):
+        """Construct a new DeliveryPacket."""
+        assert 0 <= routingType <= 0xFFFF
+        assert len(applicationKey) == 16
+        assert len(tag) == 20
+        assert len(payload) == 28*1024
         self.exitType = routingType
         self.address = routingInfo
         self.key = applicationKey
@@ -217,6 +245,7 @@
         self.type = None
 
     def isDelivery(self):
+        """Return true iff this packet is a delivery (non-relay) packet."""
         return 1
 
     def getExitType(self): return self.exitType
@@ -226,30 +255,40 @@
     def getPayload(self): return self.payload
 
     def getContents(self):
+        """Return the decoded contents of this packet."""
         if self.type is None: self.decode()
         return self.contents
 
     def isPlaintext(self):
+        """Return true iff this packet is a plaintext, forward packet."""
         if self.type is None: self.decode()
         return self.type == 'plain'
 
     def isOvercompressed(self):
+        """Return true iff this packet is an overcompressed, plaintext, forward
+           packet."""
         if self.type is None: self.decode()
         return self.type == 'long'
 
     def isEncrypted(self):
+        """Return true iff this packet may be an encrypted forward or
+           reply packet."""
         if self.type is None: self.decode()
         return self.type == 'enc'
 
     def isPrintingAscii(self):
+        """Return true iff this packets contents are printing characters
+           suitable for inclusion in a text transport medium."""
         if self.type is None: self.decode()
         return isPrintingAscii(self.contents, allowISO=1)
 
     def isError(self):
+        """Return true iff this packet is malformed."""
         if self.type is None: self.decode()
         return self.type == 'err'
 
     def decode(self):
+        """Helper method: Determines this message's type and contents."""
         if self.payload is None:
             return
         message = self.payload
@@ -276,6 +315,8 @@
         self.payload = None
 
     def getAsciiContents(self):
+        """Return the contents of this message, encoded in base64 if they are
+           not already printable."""
         if self.type is None:
             self.decode()
 
@@ -285,9 +326,11 @@
             return base64.encodestring(self.contents)
 
     def getAsciiTag(self):
+        """Return a base64-representation of this message's decoding handle."""
         return base64.encodestring(self.tag).strip()
 
     def getTextEncodedMessage(self):
+        """Return a Packet.TextEncodedMessage object for this packet."""
         tag = None
         if self.isOvercompressed():
             tp = 'LONG'

Index: ServerKeys.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerKeys.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ServerKeys.py	9 Feb 2003 22:30:58 -0000	1.11
+++ ServerKeys.py	13 Feb 2003 06:30:23 -0000	1.12
@@ -382,8 +382,8 @@
 CERTIFICATE_EXPIRY_SLOPPINESS = 5*60
 
 def generateServerDescriptorAndKeys(config, identityKey, keydir, keyname,
-                                    hashdir, validAt=None, now=None,
-                                    useServerKeys=None):
+                                    hashdir, validAt=None, now=None):
+                                    ## useServerKeys=None):
     """Generate and sign a new server descriptor, and generate all the keys to
        go with it.
 
@@ -393,11 +393,10 @@
           keyname -- The name of this new key set within keydir
           hashdir -- The root directory for storing hash logs.
           validAt -- The starting time (in seconds) for this key's lifetime.
-
-          DOCDOC  useServerKeys
-          XXXX test useServerKeys
           """
 
+    useServerKeys = None #XXXX004
+    
     if useServerKeys is None:
         # First, we generate both of our short-term keys...
         packetKey = mixminion.Crypto.pk_generate(PACKET_KEY_BYTES*8)

Index: ServerMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerMain.py,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- ServerMain.py	9 Feb 2003 22:30:58 -0000	1.37
+++ ServerMain.py	13 Feb 2003 06:30:23 -0000	1.38
@@ -35,13 +35,15 @@
      createPrivateDir, formatBase64, formatTime, installSIGCHLDHandler, \
      Lockfile, secureDelete, waitForChildren
 
-#DOCDOC Re-check fields and args for all classes, methods here!
-
 class IncomingQueue(mixminion.server.ServerQueue.Queue):
     """A DeliveryQueue to accept packets from incoming MMTP connections,
        and hold them until they can be processed.  As packets arrive, and
        are stored to disk, we notify a message queue so that another thread
        can read them."""
+    ## Fields:
+    # packetHandler -- an instance of PacketHandler.
+    # mixPool -- an instance of MixPool
+    # processingThread -- an instance of ProcessingThread
     def __init__(self, location, packetHandler):
         """Create an IncomingQueue that stores its messages in <location>
            and processes them through <packetHandler>."""
@@ -112,6 +114,10 @@
 
        All methods on this class are invoked from the main thread.
     """
+    ## Fields:
+    # queue -- underlying *MixQueue
+    # outgoingQueue -- instance of OutgoingQueue
+    # moduleManager -- instance of ModuleManager.
     def __init__(self, config, queueDir):
         """Create a new MixPool, based on this server's configuration and
            queue location."""
@@ -138,9 +144,11 @@
         self.moduleManager = None
 
     def lock(self):
+        """Acquire the lock on the underlying queue"""
         self.queue.lock()
 
     def unlock(self):
+        """Release the lock on the underlying queue"""
         self.queue.unlock()
 
     def queueObject(self, obj):
@@ -169,7 +177,7 @@
         
         for h in handles:
             packet = self.queue.getObject(h)
-            #XXXX remove the first case after 0.0.3
+            #XXXX004 remove the first case after 0.0.3
             if type(packet) == type(()):
                 LOG.debug("  (skipping message %s in obsolete format)", h)
             elif packet.isDelivery():
@@ -180,6 +188,7 @@
                 LOG.debug("  (sending message %s to MMTP server)",
                           formatBase64(packet.getPacket()[:8]))
                 self.outgoingQueue.queueDeliveryMessage(packet)
+            # In any case, we're through with this message now.
             self.queue.removeMessage(h)
 
     def getNextMixTime(self, now):
@@ -194,6 +203,8 @@
 
        All methods in this class are run from the main thread.
     """
+    ## Fields:
+    # server -- an instance of _MMTPServer
     def __init__(self, location):
         """Create a new OutgoingQueue that stores its messages in a given
            location."""
@@ -201,6 +212,7 @@
         self.server = None
 
     def configure(self, config):
+        """Set up this queue according to a ServerConfig object."""
         retry = config['Outgoing/MMTP']['Retry']
         self.setRetrySchedule(retry)
 
@@ -233,6 +245,9 @@
 
        All methods in this class are run from the main thread.
        """
+    ## Fields:
+    # incomingQueue -- a Queue to hold messages we receive
+    # outgoingQueue -- a DeliveryQueue to hold messages to be sent.
     def __init__(self, config, tls):
         mixminion.server.MMTPServer.MMTPAsyncServer.__init__(self, config, tls)
 
@@ -248,6 +263,7 @@
 
     def onMessageUndeliverable(self, msg, handle, retriable):
         self.outgoingQueue.deliveryFailed(handle, retriable)
+        
 #----------------------------------------------------------------------
 class CleaningThread(threading.Thread):
     """Thread that handles file deletion.  Some methods of secure deletion
@@ -298,11 +314,14 @@
                           "Exception while cleaning; shutting down thread.")
 
 class ProcessingThread(threading.Thread):
-    """Background thread to handle CPU-intensive functions."""
+    """Background thread to handle CPU-intensive functions.
+
+       Currently used to process packets in the background."""
     # Fields:
     #   mqueue: a MessageQueue of callable objects.
-    
     class _Shutdown:
+        """Callable that raises itself when called.  Inserted into the
+           queue when it's time to shut down."""
         def __call__(self):
             raise self
 
@@ -334,14 +353,14 @@
                           "Exception while processing; shutting down thread.")
 
 #----------------------------------------------------------------------
-STOPPING = 0
+STOPPING = 0 # Set to one if we get SIGTERM
 def _sigTermHandler(signal_num, _):
     '''(Signal handler for SIGTERM)'''
     signal.signal(signal_num, _sigTermHandler)
     global STOPPING
     STOPPING = 1
 
-GOT_HUP = 0
+GOT_HUP = 0 # Set to one if we get SIGHUP.
 def _sigHupHandler(signal_num, _):
     '''(Signal handler for SIGTERM)'''
     signal.signal(signal_num, _sigHupHandler)
@@ -376,8 +395,12 @@
     # moduleManager: Instance of ModuleManager.  Map routing types to
     #    outging queues, and processes non-MMTP exit messages.
     # outgoingQueue: Holds messages waiting to be send via MMTP.
-    # DOCDOC cleaningThread, processingthread, incomingQueue
-    
+    # cleaningThread: Thread used to remove packets in the background
+    # processingThread: Thread to handle CPU-intensive activity without
+    #    slowing down network interactivity.
+    # lockFile: An instance of Lockfile to prevent multiple servers from
+    #    running in the same directory
+    # pidFile: Filename in which we store the pid of the running server.
     def __init__(self, config):
         """Create a new server from a ServerConfig."""
         LOG.debug("Initializing server")

Index: ServerQueue.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerQueue.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ServerQueue.py	9 Feb 2003 22:30:58 -0000	1.6
+++ ServerQueue.py	13 Feb 2003 06:30:23 -0000	1.7
@@ -365,7 +365,6 @@
         """ 
         try:
             self._lock.acquire()
-            #DOCDOC nextAttempt 
             handle = self.queueObject( (retry, None, msg, nextAttempt) )
             self.sendable.append(handle)
         finally: