[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[minion-cvs] Documentation cleanups throughout the code; remove some...
Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv30050/lib/mixminion
Modified Files:
BuildMessage.py ClientDirectory.py ClientMain.py
ClientUtils.py Config.py Fragments.py MMTPClient.py Main.py
NetUtils.py Packet.py ServerInfo.py TLSConnection.py
ThreadUtils.py test.py
Log Message:
Documentation cleanups throughout the code; remove some obsolete stuff; kill bad whitespace; update copyright dates
Index: BuildMessage.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/BuildMessage.py,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- BuildMessage.py 21 Feb 2004 00:02:09 -0000 1.71
+++ BuildMessage.py 6 Mar 2004 00:04:37 -0000 1.72
@@ -99,10 +99,10 @@
path2: Sequence of ServerInfo objects for the 2nd leg of the path
paddingPRNG: random number generator used to generate padding.
If None, a new PRNG is initialized.
+ suppressTag: if true, do not include a decodind handle in the
+ routingInfo for this packet.
Neither path1 nor path2 may be empty. If one is, MixError is raised.
-
- suppressTag DOCDOC
"""
if paddingPRNG is None:
paddingPRNG = Crypto.getCommonPRNG()
@@ -257,6 +257,7 @@
# XXXX007 switch to Host info. We need to use IPV4 for reply blocks
# XXXX007 for now, since we don't know which servers will support HOST.
+ # XXXX007 (Do this after all hosts have upgraded to 0.0.6 or later.)
return ReplyBlock(header, expiryTime,
SWAP_FWD_IPV4_TYPE,
path[0].getIPV4Info().pack(), sharedKey), secrets, tag
@@ -301,11 +302,11 @@
def checkPathLength(path1, path2, exitType, exitInfo, explicitSwap=0,
suppressTag=0):
"""Given two path legs, an exit type and an exitInfo, raise an error
- if we can't build a hop with the provided legs.
+ if we can't build a hop with the provided legs. If suppressTag is
+ true, no decoding handle will be included.
The leg "path1" may be null.
-
- DOCDOC suppressTag"""
+ """
err = 0 # 0: no error. 1: 1st leg too big. 2: 1st leg okay, 2nd too big.
if path1 is not None:
try:
Index: ClientDirectory.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientDirectory.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- ClientDirectory.py 2 Mar 2004 05:40:14 -0000 1.33
+++ ClientDirectory.py 6 Mar 2004 00:04:37 -0000 1.34
@@ -1376,7 +1376,8 @@
nickname = desc.getNickname()
if self.headers:
- #XXXX008 remove this eventually.
+ #XXXX007 remove this eventually, once all servers have upgraded
+ #XXXX007 to 0.0.6 or later.
sware = desc['Server'].get("Software","")
if (sware.startswith("Mixminion 0.0.4") or
sware.startswith("Mixminion 0.0.5alpha1")):
@@ -1473,7 +1474,9 @@
return rt, ri, self.lastHop
def suppressTag(self):
- """DOCDOC"""
+ """Return true iff we should suppress the decoding handle when
+ generating packets for this address.
+ """
if self.isSSFragmented:
return 1
elif self.exitType == 'drop':
@@ -1683,22 +1686,15 @@
return "%s:%s"%(",".join(p1s), ",".join(p2s))
#----------------------------------------------------------------------
-WARN_STAR = 1 #XXXX007 remove
-
-def parsePath(config, path, nHops=None, isReply=0, isSURB=0,
- defaultNHops=None):
+def parsePath(config, path, isReply=0, isSURB=0):
"""Resolve a path as specified on the command line. Returns a
PathSpecifier object.
config -- unused for now.
- path -- the path, in a format described below. If the path is
- None, all servers are chosen as if the path were '*<nHops>'.
- nHops -- the number of hops to use. Defaults to defaultNHops.
+ path -- the path, in a format described below.
startAt/endAt -- A time range during which all servers must be valid.
- isSURB -- Boolean: is this a path for a reply block?
isReply -- Boolean: is this a path for a reply?
- defaultNHops -- The default path length to use when we encounter a
- wildcard in the path. Defaults to 6.
+ isSURB -- Boolean: is this a path for a reply block?
Paths are ordinarily comma-separated lists of server nicknames or
server descriptor filenames, as in:
@@ -1730,8 +1726,6 @@
star on the path, nHops must be >= the path length.
"""
halfPath = isReply or isSURB
- if not path:
- path = "*%d"%(nHops or defaultNHops or 6)
# Break path into a list of entries of the form:
# string
# or "<swap>"
@@ -1776,7 +1770,9 @@
elif re.match(r'\~(\d+)', ent):
pathEntries.append(RandomServersPathElement(approx=int(ent[1:])))
elif ent == '*':
- pathEntries.append("*")
+ #XXXX008 remove entirely; we gave a warning in 0.0.6 and
+ #XXXX008 stopped supporting it in 0.0.7.
+ raise UIError("* without a number is no longer supported.")
elif ent == '<swap>':
pathEntries.append("<swap>")
elif ent == '?':
@@ -1784,25 +1780,6 @@
else:
pathEntries.append(ServerPathElement(ent))
- # If there's a variable-length wildcard...
- if "*" in pathEntries:
- # Find out where it is...
- starPos = pathEntries.index("*")
- if "*" in pathEntries[starPos+1:]:
- raise UIError("Only one '*' is permitted in a single path")
- # Figure out how many hops we expect to have...
- approxHops = reduce(operator.add,
- [ ent.getAvgLength() for ent in pathEntries
- if ent not in ("*", "<swap>") ], 0)
- # Replace the '*' with the number of additional hops we want.
- myNHops = nHops or defaultNHops or 6
- extraHops = max(myNHops-approxHops, 0)
- pathEntries[starPos:starPos+1] =[RandomServersPathElement(n=extraHops)]
-
- if WARN_STAR:
- LOG.warn("'*' without a number is deprecated. Try '*%d' instead.",
- extraHops)
-
# Figure out how long the first leg should be.
lateSplit = 0
if "<swap>" in pathEntries:
Index: ClientMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientMain.py,v
retrieving revision 1.163
retrieving revision 1.164
diff -u -d -r1.163 -r1.164
--- ClientMain.py 2 Mar 2004 18:55:32 -0000 1.163
+++ ClientMain.py 6 Mar 2004 00:04:37 -0000 1.164
@@ -77,7 +77,8 @@
passwordManager = mixminion.ClientUtils.CLIPasswordManager()
createPrivateDir(keyDir)
- # XXXX008 remove this.
+ # XXXX008 remove this; we haven't used the old format since 0.0.5.
+
# We used to store our keys in a different format. At this point,
# it's easier to change the filename.
obsoleteFn = os.path.join(keyDir, "keyring")
@@ -180,6 +181,15 @@
## For reply blocks
#SURBPath: ?,?,?,FavoriteExit
+### If there are servers that you never want to include in automatically
+### generated paths, you can list them here.
+## These servers will never begin a path:
+#BlockEntries: example1,example2
+## These servers will never end a path:
+#BlockExits: example3,example4
+## These servers will never appear in a path at all:
+#BlockServers: example5,example6,example7
+
[Network]
ConnectionTimeout: 60 seconds
""" % fields)
@@ -538,10 +548,9 @@
def flushQueue(self, maxPackets=None, handles=None):
"""Try to send packets in the queue to their destinations. Do not try
- to send more than maxPackets packets. If not all packets will be
- sent, choose the ones to try at random.
-
- DOCDOC nicknames
+ to send more than maxPackets packets. If 'handles' is provided,
+ try only to send the packets whose handles are listed in 'handles;
+ otherwise, choose the ones to try at random.
"""
#XXXX write unit tests
class PacketProxy:
@@ -658,6 +667,7 @@
if not msg.isEncrypted():
if msg.isFragment():
+ foundAFragment = 1
self.pool.addFragment(msg.getContents(), "---")
else:
results.append(msg.getContents())
@@ -677,6 +687,7 @@
if p.isSingleton():
results.append(p.getUncompressedContents())
else:
+ foundAFragment = 1
self.pool.addFragment(p,nym)
else:
raise UIError("Unable to decode message")
@@ -684,6 +695,8 @@
for p in results:
if not isPrintingAscii(p,allowISO=1):
raise UIError("Not writing binary message to terminal: Use -F to do it anyway.")
+ if foundAFragment:
+ self.pool.process()
return results
def readConfigFile(configFile):
@@ -766,7 +779,7 @@
# nHops: number of hops, or None.
# address: exit address, or None.
# lifetime: SURB lifetime, or None.
- # replyBlockFiles: list of SURB filenames. DOCDOC
+ # replyBlockSources: list of SURB filenames (string), or SURB fds (int).
# configFile: Filename of configuration file, or None.
# forceQueue: true if "--queue" is set.
# forceNoQueue: true if "--no-queue" is set.
@@ -827,7 +840,7 @@
self.nHops = None
self.exitAddress = None
self.lifetime = None
- self.replyBlockSources = [] #DOCDOC int is fd, str is filename
+ self.replyBlockSources = []
self.forceQueue = None
self.forceNoQueue = None
@@ -897,7 +910,6 @@
except ValueError:
raise UsageError("%s expects an integer"%o)
elif o in ('--passphrase-fd',):
- #DOCDOC
try:
self.password_fileno = int(v)
except ValueError:
@@ -1024,15 +1036,12 @@
isSURB = isReply = 0
if self.wantReplyPath:
p = 'SURBPath'; isSURB = 1
- defHops = self.config['Security'].get("SURBPathLength", 4)
elif useRB:
p = 'ReplyPath'; isReply = 1
- defHops = self.config['Security'].get("PathLength", 6)
else:
p = 'ForwardPath'
- defHops = self.config['Security'].get("PathLength", 6)
if self.path is None:
- self.path = self.config['Security'].get(p, "*")
+ self.path = self.config['Security'].get(p, "*5")
if isSURB:
if self.lifetime is not None:
@@ -1046,8 +1055,7 @@
self.endAt = previousMidnight(self.startAt+duration)
self.pathSpec = mixminion.ClientDirectory.parsePath(
- self.config, self.path, self.nHops, isReply=isReply, isSURB=isSURB,
- defaultNHops=defHops)
+ self.config, self.path, isReply=isReply, isSURB=isSURB)
self.directory.validatePath(self.pathSpec, self.exitAddress,
self.startAt, self.endAt)
@@ -1078,7 +1086,7 @@
packet, then deliver multiple fragmented packets
to the recipient instead of having the server
reassemble the message.
- --reply-block-fd=<N> DOCDOC
+ --reply-block-fd=<N> Read reply blcoks from file descriptor <N>.
%(extra)s
EXAMPLES:
@@ -1775,7 +1783,7 @@
surblog.close()
_FLUSH_QUEUE_USAGE = """\
-Usage: %(cmd)s [options]
+Usage: %(cmd)s [options] [servername] ...
-h, --help Print this usage message and exit.
-v, --verbose Display extra debugging messages.
-f <file>, --config=<file> Use a configuration file other than ~.mixminionrc
@@ -1785,7 +1793,12 @@
EXAMPLES:
Try to send all currently queued packets.
%(cmd)s
-DOCDOC
+ Try to send at most 10 currently queued packets, chosen at random.
+ %(cmd)s -n 10
+ Try to send all currently queued packets for the server named 'Example1', or
+ for the server whose hostname is 'minion.example.com'.
+ %(cmd)s Example1 minion.example.com
+
""".strip()
def flushQueue(cmd, args):
@@ -1830,7 +1843,8 @@
EXAMPLES:
Remove all pending packets older than one week.
%(cmd)s -d 7
-DOCDODC
+ Remove all pending packets for the server 'Example1'.
+ %(cmd)s Example1
""".strip()
def cleanQueue(cmd, args):
Index: ClientUtils.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientUtils.py,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- ClientUtils.py 2 Mar 2004 07:06:14 -0000 1.23
+++ ClientUtils.py 6 Mar 2004 00:04:37 -0000 1.24
@@ -129,7 +129,7 @@
if not chunk:
break
pw += chunk
- # Strip trailing endline from password, if any.
+ # Strip trailing endline from password, if any.
if pw.endswith("\n"): pw = pw[:-1]
return pw
@@ -725,6 +725,8 @@
mixminion.ClientMain.clientUnlock()
def getHandlesByAge(self, notAfter):
+ """Return a list of all handles for messages that were inserted into
+ the queue before 'notAfter'."""
self.loadMetadata()
result = []
for h in self.store.getAllMessages():
@@ -734,7 +736,18 @@
def getHandlesByDestAndAge(self, destList, directory, notAfter=None,
warnUnused=1):
- """DOCDOC destset: set of hostnames, ips, or keyids"""
+ """Return a list of handles for all messages queued for servers in a
+ given list before a given date.
+
+ destList -- A list of hostnames, ips, keyids, or nicknames
+ for servers whose messages should be included in the result.
+ directory -- An instance of ClientDirectory used to resolve
+ nicknames. This may be None if no nicknames are included.
+ notAfter -- If provided, a time such that no messages queued
+ later should be included
+ warnUnused -- If true, we log a message for every element in
+ destList that has no matching messages in the queue.
+ """
destSet = {}
reverse = {}
for d in destList:
@@ -860,26 +873,34 @@
# ----------------------------------------------------------------------
class ClientFragmentPool:
- """DOCDOC"""
+ """Wrapper around FragmentPool to provide a good interface for client-side
+ fragment reassembly."""
def __init__(self, directory):
+ """Create a new FragmentPool storing its messages in 'directory'."""
createPrivateDir(directory)
self.dir = directory
self.pool = None
def __getPool(self):
+ """Helper: initialize self.pool and return it."""
if self.pool is None:
import mixminion.Fragments
self.pool = mixminion.Fragments.FragmentPool(self.dir)
return self.pool
def close(self):
+ """Finalize self.pool."""
if self.pool is not None:
self.pool.close()
self.pool = None
def addFragment(self, fragment, nym=None):
- """fragment is instance of fragmentPayload or is a string payload
- DOCDOC"""
+ """Add a fragment to the pool, logging appropriate messages. Return
+ the messageID which was updated, if any.
+
+ fragment -- an instance of FragmentPayload or a string payload.
+ nym -- the identity which received this message.
+ """
pool = self.__getPool()
if isinstance(fragment, types.StringType):
try:
@@ -892,20 +913,24 @@
assert isinstance(fragment, mixminion.Packet.FragmentPayload)
r = pool.addFragment(fragment, nym=nym, verbose=1)
- pool.unchunkMessages(); print "UNCHUNK"
return r
def process(self):
+ """Unchunk any messages that are ready for reassembly."""
pool = self.__getPool()
pool.unchunkMessages()
pool.cleanQueue()
def expireMessages(self, cutoff):
+ """Clean up any stale fragments from the pool that have been there
+ since before 'cutoff'."""
pool = self.__getPool()
pool.expireMessages(cutoff)
self.cleanQueue()
def getMessage(self, msgid):
+ """Return the string value of the reassembled message with ID 'msgid',
+ or raise an error explaining why we can't."""
pool = self.__getPool()
state = pool.getStateByMsgID(msgid)
msg = pool.getReadyMessage(state.messageid)
@@ -921,10 +946,13 @@
%msgid)
def removeMessages(self, msgids):
+ """Remove all the messages whose IDs are in the list 'msgIDs'. If the
+ messages were reassembled, mark them as 'COMPLETED'; else mark them
+ as 'REJECTED'."""
pool = self.__getPool()
idSet = {}
for i in msgids:
- state = pool.getStateByMsgID(i)
+ state = pool.getStateByMsgID(i)
if state is None:
raise UIError("No such message as %s")
idSet[state.messageid] = 1
@@ -932,10 +960,13 @@
pool.cleanQueue()
def listMessages(self):
+ """Return a list of pretty-printed IDs for the messages in the pool."""
pool = self.__getPool()
return pool.listMessages()
def formatMessageList(self):
+ """Return a list of strings suitable for display explaining the status
+ of the messages in the pool, sorted by pretty-printed ID."""
msgs = self.listMessages()
result = []
msgids = msgs.keys()
Index: Config.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Config.py,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- Config.py 2 Mar 2004 05:40:14 -0000 1.78
+++ Config.py 6 Mar 2004 00:04:37 -0000 1.79
@@ -363,7 +363,8 @@
raise ConfigError("Invalid exponent on public key")
return key
-# FFFF007/8 stop accepting YYYY/MM/DD
+# FFFF008 stop accepting YYYY/MM/DD. We've generated the right thing
+# FFFF008 since 0.0.6.
# Regular expression to match YYYY/MM/DD or YYYY-MM-DD
_date_re = re.compile(r"^(\d\d\d\d)([/-])(\d\d)([/-])(\d\d)$")
def _parseDate(s):
@@ -383,7 +384,7 @@
raise ConfigError("Invalid date %r"%s)
return calendar.timegm((yyyy,MM,dd,0,0,0,0,0,0))
-# FFFF007/8 stop accepting YYYY/MM/DD
+# FFFF008 stop accepting YYYY/MM/DD
# Regular expression to match YYYY/MM/DD HH:MM:SS
_time_re = re.compile(r"^(\d\d\d\d)([/-])(\d\d)([/-])(\d\d)\s+"
r"(\d\d):(\d\d):(\d\d)((?:\.\d\d\d)?)$")
@@ -978,14 +979,11 @@
'MaxSkew' : ('ALLOW', "interval", "10 minutes"),
'DirectoryTimeout' : ('ALLOW', "interval", "1 minute") },
'User' : { 'UserDir' : ('ALLOW', "filename", DEFAULT_USER_DIR) },
- 'Security' : { 'PathLength' : ('ALLOW', "int", "8"),
- 'SURBAddress' : ('ALLOW', None, None),
- 'SURBPathLength' : ('ALLOW', "int", "4"),
+ 'Security' : { 'SURBAddress' : ('ALLOW', None, None),
'SURBLifetime' : ('ALLOW', "interval", "7 days"),
'ForwardPath' : ('ALLOW', None, "*6"),
'ReplyPath' : ('ALLOW', None, "*4"),
'SURBPath' : ('ALLOW', None, "*4"),
- #DOCDOC and add to .mixminionrc
'BlockServers' : ('ALLOW*', 'list', ""),
'BlockEntries' : ('ALLOW*', 'list', ""),
'BlockExits' : ('ALLOW*', 'list', ""),
@@ -1013,12 +1011,6 @@
_validateHostSection(self['Host'])
security = self['Security']
- p = security.get('PathLength', 8)
- if not 0 < p <= 16:
- raise ConfigError("Path length must be between 1 and 16")
- if p < 4:
- LOG.warn("Your default path length is frighteningly low."
- " I'll trust that you know what you're doing.")
t = self['Network'].get('ConnectionTimeout')
if t:
Index: Fragments.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Fragments.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- Fragments.py 2 Mar 2004 07:06:14 -0000 1.13
+++ Fragments.py 6 Mar 2004 00:04:37 -0000 1.14
@@ -148,7 +148,8 @@
def addFragment(self, fragmentPacket, nym=None, now=None, verbose=0):
"""Given an instance of mixminion.Packet.FragmentPayload, record
the fragment if appropriate and update the state of the
- fragment pool if necessary.
+ fragment pool if necessary. Returns the message ID that was
+ updated, or None if the fragment was redundant or misformed.
fragmentPacket -- the new fragment to add.
nym -- a string representing the identity that received this
@@ -156,8 +157,8 @@
attack where we send 2 fragments to 'MarkTwain' and 2
fragments to 'SClemens', and see that the message is
reconstructed.]
-
- DOCDOC return, verbose
+ verbose -- if true, log information at the INFO level;
+ otherwise, log at DEBUG.
"""
if verbose:
say = LOG.info
@@ -183,7 +184,7 @@
chunkNum=None,
overhead=fragmentPacket.getOverhead(),
insertedDate=today,
- nym=nym,
+ nym=nym,
digest=sha1(fragmentPacket.data))
# ... and allocate or find the MessageState for this message.
state = self._getState(meta)
@@ -342,7 +343,7 @@
for mid in messageIDSet.keys():
if why == "?":
state = self.states[mid]
- if state.isDone:
+ if state.isDone:
whythis = "COMPLETED"
else:
whythis = "REJECTED"
@@ -372,7 +373,10 @@
return state
def getStateByMsgID(self, msgid):
- """DOCDOC"""
+ """Given a message ID (either a 20-byte full ID or a 12-byte
+ pretty-printed ID prefix), return a MessageState object for
+ the corresponding message, or None if the message is not
+ recognized."""
if len(msgid) == 20:
return self.state.get(msgid,None)
elif len(msgid) == 12:
@@ -383,8 +387,11 @@
return None
def listMessages(self):
- """DOCDOC
- pretty-id => { 'size':x, 'nym':x, 'have':x, 'need':x }
+ """Return a map from pretty-printed message ID to dicts mapping:
+ 'size' to the size of the message, in bytes
+ 'nym' to the pseudonym receiving the message
+ 'have' to the number of packets we have so far
+ 'need' to the number of additional packets we need.
"""
result = {}
for msgid in self.states.keys():
@@ -509,7 +516,9 @@
return [ self.chunks[i][0] for i in xrange(self.params.nChunks) ]
def getCompleteness(self):
- """(have,need) DOCDOC"""
+ """Return a tuple of (have,need), where 'need' is the final number
+ of packets needed to reconstruct the message, and 'have' is the
+ number we have so far."""
need = self.params.k * self.params.nChunks
have = self.params.k * len(self.chunks)
for d in self.fragmentsByChunk:
Index: MMTPClient.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/MMTPClient.py,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- MMTPClient.py 16 Feb 2004 22:50:38 -0000 1.55
+++ MMTPClient.py 6 Mar 2004 00:04:38 -0000 1.56
@@ -113,7 +113,7 @@
raise e
tls = context.sock(sock)
- mixminion.TLSConnection.TLSConnection.__init__(self, tls, sock,
+ mixminion.TLSConnection.TLSConnection.__init__(self, tls, sock,
serverName)
if targetKeyID != '\x00' * 20:
Index: Main.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Main.py,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- Main.py 2 Mar 2004 07:06:14 -0000 1.71
+++ Main.py 6 Mar 2004 00:04:38 -0000 1.72
@@ -1,5 +1,5 @@
#!/usr/bin/python2
-# Copyright 2002-2003 Nick Mathewson. See LICENSE for licensing information.
+# Copyright 2002-2004 Nick Mathewson. See LICENSE for licensing information.
# $Id$
#"""Code to correct the python path, and multiplex between the various
@@ -197,7 +197,7 @@
def printVersion(cmd,args):
import mixminion
print "Mixminion version %s" % mixminion.__version__
- print ("Copyright 2002-2003 Nick Mathewson. "+
+ print ("Copyright 2002-2004 Nick Mathewson. "+
"See LICENSE for licensing information.")
print "NOTE: This software is for testing only. The user set is too small"
print " to be anonymous, and the code is too alpha to be reliable."
@@ -285,7 +285,7 @@
print "Interrupted."
def getUIError():
- """DOCDOC"""
+ """Return the UIError class from mixminion.Common"""
commonModule = __import__('mixminion.Common', {}, {}, ['UIError'])
return commonModule.UIError
Index: NetUtils.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/NetUtils.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- NetUtils.py 2 Feb 2004 07:05:49 -0000 1.11
+++ NetUtils.py 6 Mar 2004 00:04:38 -0000 1.12
@@ -86,7 +86,7 @@
found.
"""
_,haveIP6 = getProtocolSupport()
- if not haveIP6: haveIP4 = 1
+ if not haveIP6: haveIP4 = 1
try:
r = getIPs(name)
inet4 = [ addr for addr in r if addr[0] == AF_INET ]
@@ -95,7 +95,7 @@
LOG.warn("getIP returned no inet addresses for %r",name)
return ("NOENT", "No inet addresses returned", time.time())
if inet6 and not inet4 and not haveIP6:
- return ("NOENT",
+ return ("NOENT",
"All addresses were IPv6, and this host has no IPv6 support",
time.time())
best4=best6=None
Index: Packet.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Packet.py,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -d -r1.74 -r1.75
--- Packet.py 21 Feb 2004 00:02:09 -0000 1.74
+++ Packet.py 6 Mar 2004 00:04:38 -0000 1.75
@@ -198,9 +198,11 @@
def getExitAddress(self, tagged=1):
"""Return the part of the routingInfo that contains the delivery
- address. (Requires that routingType is an exit type.)"""
+ address. (Requires that routingType is an exit type.) If
+ 'tagged' is true, ignore the first TAG_LEN bytes of the
+ routingInfo.
+ """
assert self.routingtype >= MIN_EXIT_TYPE
- #XXXX007 This interface is completely insane. Change it.
if not tagged:
return self.routinginfo
else:
@@ -591,7 +593,7 @@
Fields: ip (a dotted quad string), port (an int from 0..65535),
and keyinfo (a digest)."""
- #XXXX007/8 phase this out.
+ #XXXX008 phase this out: we have supported hostnames since 0.0.6.
def __init__(self, ip, port, keyinfo):
"""Construct a new IPV4Info"""
assert 0 <= port <= 65535
@@ -996,7 +998,7 @@
_ZLIB_LIBRARY_OK = 0.5
if ver in ("1.1.2", "1.1.3", "1.1.4", "1.2.0", "1.2.0.1", "1.2.0.2",
- "1.2.0.3", "1.2.0.4", "1.2.0.5", "1.2.0.6", "1.2.0.7",
+ "1.2.0.3", "1.2.0.4", "1.2.0.5", "1.2.0.6", "1.2.0.7",
"1.2.0.8", "1.2.1"):
_ZLIB_LIBRARY_OK = 1
return
Index: ServerInfo.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ServerInfo.py,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -r1.81 -r1.82
--- ServerInfo.py 7 Feb 2004 17:52:49 -0000 1.81
+++ ServerInfo.py 6 Mar 2004 00:04:38 -0000 1.82
@@ -123,13 +123,15 @@
"Published": ("REQUIRE", "time", None),
"Valid-After": ("REQUIRE", "date", None),
"Valid-Until": ("REQUIRE", "date", None),
- #XXXX008 change this to 'require'.
+ #XXXX008 change this to 'require': servers have all
+ #XXXX008 had it since 007.
"Contact": ("ALLOW", None, None),
"Comments": ("ALLOW", None, None),
"Packet-Key": ("REQUIRE", "publicKey", None),
"Contact-Fingerprint": ("ALLOW", None, None),
- "Packet-Formats": ("ALLOW", None, None),#XXXX007 remove
- # XXXX008 change these next few to "REQUIRE".
+ "Packet-Formats": ("ALLOW", None, None),#XXXX008 remove
+ # XXXX008 change these next few to "REQUIRE"; servers
+ # XXXX008 have had them all since 0.0.5
"Packet-Versions": ("ALLOW", "list", '0.3'),
"Software": ("ALLOW", None, None),
"Secure-Configuration": ("ALLOW", "boolean", None),
@@ -137,10 +139,10 @@
},
"Incoming/MMTP" : {
"Version": ("REQUIRE", None, None),
- "IP": ("ALLOW", "IP", None),#XXXX007/8 remove
- "Hostname": ("ALLOW", "host", None),#XXXX008 require
+ "IP": ("ALLOW", "IP", None),#XXXX008 remove
+ "Hostname": ("ALLOW", "host", None),#XXXX008 require;since 0.0.6
"Port": ("REQUIRE", "int", None),
- "Key-Digest": ("ALLOW", "base64", None),#XXXX007/8 rmv
+ "Key-Digest": ("ALLOW", "base64", None),#XXXX008 rmv; not used since 0.0.5
"Protocols": ("REQUIRE", "list", None),
"Allow": ("ALLOW*", "addressSet_allow", None),
"Deny": ("ALLOW*", "addressSet_deny", None),
@@ -153,14 +155,14 @@
},
"Delivery/MBOX" : {
"Version": ("REQUIRE", None, None),
- # XXXX007 change to 'REQUIRE'
+ # XXXX008 change to 'REQUIRE'; since 0.0.6
"Maximum-Size": ("ALLOW", "int", "32"),
- # XXXX007 change to 'REQUIRE'
+ # XXXX008 change to 'REQUIRE'; since 0.0.6
"Allow-From": ("ALLOW", "boolean", "yes"),
},
"Delivery/SMTP" : {
"Version": ("REQUIRE", None, None),
- # XXXX007 change to 'REQUIRE'
+ # XXXX008 change to 'REQUIRE'; since 0.0.6
"Maximum-Size": ("ALLOW", "int", "32"),
"Allow-From": ("ALLOW", "boolean", "yes"),
},
@@ -321,10 +323,6 @@
def getHostname(self):
"""Return this server's Hostname. (Returns None for servers running
version 0.0.5 or earlier.)"""
- #XXXX006 remove this. 0.0.6alpha1 could crash when it got hostnames.
- #XXXX006 Sadly, some people installed it anyway.
- if self['Server'].get("Software","").endswith("0.0.6alpha1"):
- return None
return self['Incoming/MMTP'].get("Hostname")
def getPort(self):
Index: TLSConnection.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/TLSConnection.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- TLSConnection.py 16 Feb 2004 22:50:38 -0000 1.13
+++ TLSConnection.py 6 Mar 2004 00:04:38 -0000 1.14
@@ -401,7 +401,7 @@
return cap
else:
# We got some data; add it to the inbuf.
- LOG.trace("Read got %s bytes from %s",
+ LOG.trace("Read got %s bytes from %s",
len(s), self.address)
self.inbuf.append(s)
self.inbuflen += len(s)
Index: ThreadUtils.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ThreadUtils.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ThreadUtils.py 8 Jan 2004 22:33:31 -0000 1.1
+++ ThreadUtils.py 6 Mar 2004 00:04:38 -0000 1.2
@@ -3,7 +3,7 @@
"""mixminion.ThreadUtils
- Helper code for threading-related operations, including queues and
+ Helper code for threading-related operations, including queues and
RW-locks.
"""
@@ -100,7 +100,7 @@
class RWLock:
"""A lock that allows multiple readers at a time, but only one writer."""
- # Changes from sync.mrsw:
+ # Changes from sync.mrsw:
# * Use threading.Condition instead of sync.condition.
# * Document everything.
# * Don't hold on to rwOK forever when there's an error.
@@ -119,7 +119,7 @@
self.nw = 0 # number writers either waiting to write or writing
self.writing = 0 # 1 iff some thread is writing
# map from each current reader's thread_ident to recursion depth.
- self.readers = {}
+ self.readers = {}
# conditions
self.readOK = threading.Condition(self.rwOK) # OK to unblock readers
Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.188
retrieving revision 1.189
diff -u -d -r1.188 -r1.189
--- test.py 2 Mar 2004 18:52:24 -0000 1.188
+++ test.py 6 Mar 2004 00:04:38 -0000 1.189
@@ -6076,7 +6076,7 @@
'bar' : '18:0FFF::4:1',
'baz.com': '10.99.22.8'},
delay=DELAY)
- # Override getProtocolSupport so we don't convert IPv6 addrs to
+ # Override getProtocolSupport so we don't convert IPv6 addrs to
# an error if we're running on a host with no IPv6 support.
mixminion.NetUtils._PROTOCOL_SUPPORT = (1,1)
@@ -6809,13 +6809,13 @@
self.assertEquals(3, s.count("Only one relay known"))
# wrap path parsing and verification and generation.
- def ppath(dir, cfg, path, addr, nHops=None, startAt=None, endAt=None,
- halfPath=0, defaultNHops=None, nPaths=1):
+ def ppath(dir, cfg, path, addr, startAt=None, endAt=None,
+ halfPath=0, nPaths=1):
isReply = halfPath and (addr is None)
isSURB = halfPath and (addr is not None)
pathSpec = mixminion.ClientDirectory.parsePath(
- cfg, path, nHops=nHops, isReply=isReply,
- isSURB=isSURB, defaultNHops=defaultNHops)
+ cfg, path, isReply=isReply,
+ isSURB=isSURB)
dir.validatePath(pathSpec, addr, startAt=startAt, endAt=endAt)
paths = dir.generatePaths(nPaths, pathSpec, addr, startAt, endAt)
if nPaths == 1:
@@ -6824,9 +6824,6 @@
else:
return paths
- #XXXX008a remove
- mixminion.ClientDirectory.WARN_STAR = 0
-
paddr = mixminion.ClientDirectory.parseAddress
email = paddr("smtp:lloyd@dobler.com")
mboxWithServer = paddr("mbox:Granola@Lola")
@@ -6865,7 +6862,7 @@
fredfile = os.path.join(impdirname, "Fred1")
p1,p2 = ppath(ks, None, "Alice,%r,Bob,Joe"%fredfile, email)
pathIs((p1,p2), ((alice,fred),(bob,joe)))
- p1,p2 = ppath(ks, None, "Alice,Fred,Bob,Lola,Joe", email, nHops=5)
+ p1,p2 = ppath(ks, None, "Alice,Fred,Bob,Lola,Joe", email)
pathIs((p1,p2), ((alice,fred,bob),(lola,joe)))
p1,p2 = ppath(ks, None, "Alice,Fred,Bob", mboxWithServer)
pathIs((p1,p2), ((alice,fred),(bob,lola)))
@@ -6899,83 +6896,31 @@
p1,p2 = ppath(ks, None, "Alice,Bob,?:Joe", email)
eq((len(p1),len(p2)), (3,1))
pathIs((p1[:-1],p2), ((alice,bob),(joe,)))
- p1,p2 = ppath(ks, None, "Alice,Bob,Fred:Joe", email, nHops=4)
+ p1,p2 = ppath(ks, None, "Alice,Bob,Fred:Joe", email)
pathIs((p1,p2), ((alice,bob,fred),(joe,)))
p1,p2 = ppath(ks, None, "Alice,Bob,Fred:Joe", mboxWithServer)
pathIs((p1,p2), ((alice,bob,fred),(joe,lola)))
p1,p2 = ppath(ks, None, "Alice,Bob,Fred:Lola", mboxWithoutServer)
pathIs((p1,p2), ((alice,bob,fred),(lola,)))
- # 1c. Star, no colon
- p1,p2 = ppath(ks, None, 'Alice,*,Joe', email, nHops=5)
- pathIs((p1[0],p2[-1]), (alice, joe))
- eq((len(p1),len(p2)), (3,2))
-
- p1,p2 = ppath(ks, None, 'Alice,Bob,*,Joe', email, nHops=6)
- pathIs((p1[0],p1[1],p2[-1]), (alice, bob, joe))
- eq((len(p1),len(p2)), (3,3))
-
- p1,p2 = ppath(ks, None, 'Alice,Bob,*', email, nHops=6)
- pathIs((p1[0],p1[1],p2[-1]), (alice, bob, joe))
- eq((len(p1),len(p2)), (3,3))
-
- p1,p2 = ppath(ks, None, '*,Bob,Joe', email) #default nHops=6
- pathIs((p2[-2],p2[-1]), (bob, joe))
- eq((len(p1),len(p2)), (3,3))
-
- p1,p2 = ppath(ks, None, 'Bob,*,Alice', mboxWithServer, nHops=5)
- pathIs((p1[0],p2[-2],p2[-1]), (bob, alice, lola))
- eq((len(p1),len(p2)), (3,3))
-
- p1,p2 = ppath(ks, None, 'Bob,*,Alice,Lola', mboxWithoutServer)
- pathIs((p1[0],p2[-2],p2[-1]), (bob, alice, lola))
- eq((len(p1),len(p2)), (3,3))
-
- # 1d. Star and colon
- p1,p2 = ppath(ks, None, 'Bob:*,Alice', mboxWithServer, nHops=5)
- pathIs((p1[0],p2[-2],p2[-1]), (bob, alice, lola))
- eq((len(p1),len(p2)), (1,5))
-
- p1,p2 = ppath(ks, None, 'Bob,*:Alice', mboxWithServer, nHops=5)
- pathIs((p1[0],p2[-2],p2[-1]), (bob, alice, lola))
- eq((len(p1),len(p2)), (4,2))
-
- p1,p2 = ppath(ks, None, 'Bob,*,Joe:Alice', mboxWithServer, nHops=5)
- pathIs((p1[0],p1[-1],p2[-2],p2[-1]), (bob, joe, alice, lola))
- eq((len(p1),len(p2)), (4,2))
-
- p1,p2 = ppath(ks, None, 'Bob,*,Lola:Alice,Joe', email)
- pathIs((p1[0],p1[-1],p2[-2],p2[-1]), (bob, lola, alice, joe))
- eq((len(p1),len(p2)), (4,2))
-
- p1,p2 = ppath(ks, None, '*,Lola:Alice,Joe', email)
- pathIs((p1[-1],p2[-2],p2[-1]), (lola, alice, joe))
- eq((len(p1),len(p2)), (4,2))
-
- p1,p2 = ppath(ks, None, 'Lola:Alice,*', email)
- pathIs((p1[0],p2[0],p2[-1]), (lola, alice, joe))
- eq((len(p1),len(p2)), (1,5))
-
- p1,p2 = ppath(ks, None, 'Bob:Alice,*', mboxWithServer, nHops=5)
- pathIs((p1[0],p2[0],p2[-1]), (bob, alice, lola))
- eq((len(p1),len(p2)), (1,5))
+ # 1c, 1c': Stars, no longer used.
# 1d'. Tilde
p1,p2 = ppath(ks, None, '~2', email)
self.assert_(p1 and p2)
- p1,p2 = ppath(ks, None, '?,~4,Bob,Joe', email) #default nHops=6
+ p1,p2 = ppath(ks, None, '?,~4,Bob,Joe', email)
p = p1+p2
pathIs((p2[-1], p2[-2],), (joe, bob))
total = 0
for _ in xrange(1000):
- p1,p2 = ppath(ks, None, '~2,Bob,Joe', email) #default nHops=6
+ p1,p2 = ppath(ks, None, '~2,Bob,Joe', email)
total += len(p1+p2)
self.assert_(3.4 <= total/1000.0 <= 4.6)
# 1e. Complex.
try:
suspendLog()
- p1,p2 = ppath(ks, None, '?,Bob,*:Joe,*2,Joe', email, nHops=9)
+ p1,p2 = ppath(ks, None, '?,Bob,*3:Joe,*2,Joe', email)
finally:
resumeLog()
pathIs((p1[1],p2[0],p2[-1]), (bob, joe, joe))
@@ -6998,16 +6943,16 @@
# 2. Failing cases
raises = self.assertRaises
# Nonexistent server
- raises(MixError, ppath, ks, None, "Pierre:Alice,*", email)
+ raises(MixError, ppath, ks, None, "Pierre:Alice,*2", email)
# Two swap points
raises(MixError, ppath, ks, None, "Alice:Bob:Joe", email)
# Last hop doesn't support exit type
raises(MixError, ppath, ks, None, "Alice:Bob,Fred", email)
raises(MixError, ppath, ks, None, "Alice:Bob,Fred", mboxWithoutServer)
- # Two stars.
- raises(MixError, ppath, ks, None, "Alice,*,Bob,*,Joe", email)
+ # Old star syntax.
+ raises(MixError, ppath, ks, None, "Alice,*,Bob,Joe", email)
# Nonexistent file
- raises(MixError, ppath, ks, None, "./Pierre:Alice,*", email)
+ raises(MixError, ppath, ks, None, "./Pierre:Alice,*2", email)
## Try 'expungeByNickname'.
# Zapping 'Lisa' does nothing, since she's in the directory...