[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[minion-cvs] A few minor changes, one of them with little tentacles ...
Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv2215/lib/mixminion
Modified Files:
BuildMessage.py ClientDirectory.py ClientMain.py Common.py
Main.py Packet.py test.py
Log Message:
A few minor changes, one of them with little tentacles throughout the code.
- Make the presence/absence of a tag decided by users of
DeliverableMessage/Subheader, not (as before) by DM/S on the basis of
exit types. This allows extension types to exist without deliverhandles.
- Add a 'mixminiond' script and entrypoint. Should work.
- Fix a bug: when no workable exit server is found, we shouldn't crash.
Index: BuildMessage.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/BuildMessage.py,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- BuildMessage.py 16 Feb 2004 22:50:38 -0000 1.70
+++ BuildMessage.py 21 Feb 2004 00:02:09 -0000 1.71
@@ -89,7 +89,7 @@
return paddingPRNG.getBytes(PAYLOAD_LEN)
def buildForwardPacket(payload, exitType, exitInfo, path1, path2,
- paddingPRNG=None):
+ paddingPRNG=None, suppressTag=0):
"""Construct a forward message.
payload: The payload to deliver. Must be exactly 28K. If the
payload is None, 28K of random data is sent.
@@ -101,6 +101,8 @@
If None, a new PRNG is initialized.
Neither path1 nor path2 may be empty. If one is, MixError is raised.
+
+ suppressTag DOCDOC
"""
if paddingPRNG is None:
paddingPRNG = Crypto.getCommonPRNG()
@@ -109,11 +111,6 @@
if not path2:
raise MixError("Second leg of path is empty")
- suppressTag = 0
- #XXXX refactor _TYPES_WITHOUT_TAGS
- if exitType == DROP_TYPE or mixminion.Packet._TYPES_WITHOUT_TAGS.get(exitType):
- suppressTag = 1
-
assert len(payload) == PAYLOAD_LEN
LOG.debug(" Using path %s:%s",
@@ -126,7 +123,7 @@
tag = _getRandomTag(paddingPRNG)
exitInfo = tag + exitInfo
return _buildPacket(payload, exitType, exitInfo, path1, path2,
- paddingPRNG)
+ paddingPRNG,suppressTag=suppressTag)
def buildEncryptedForwardPacket(payload, exitType, exitInfo, path1, path2,
@@ -301,11 +298,14 @@
return _buildReplyBlockImpl(path, exitType, exitInfo, expiryTime, prng,
seed)[0]
-def checkPathLength(path1, path2, exitType, exitInfo, explicitSwap=0):
+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.
- The leg "path1" may be null."""
+ 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:
@@ -314,8 +314,7 @@
except MixError:
err = 1
# Add a dummy tag as needed to last exitinfo.
- if (exitType != DROP_TYPE
- and not mixminion.Packet._TYPES_WITHOUT_TAGS.get(exitType)
+ if (not suppressTag
and exitInfo is not None):
exitInfo += "X"*20
else:
@@ -466,7 +465,8 @@
#----------------------------------------------------------------------
def _buildPacket(payload, exitType, exitInfo,
- path1, path2, paddingPRNG=None, paranoia=0):
+ path1, path2, paddingPRNG=None, paranoia=0,
+ suppressTag=0):
"""Helper method to create a message.
The following fields must be set:
@@ -498,7 +498,7 @@
reply = path2
path2 = None
else:
- if len(exitInfo) < TAG_LEN and exitType != DROP_TYPE and not mixminion.Packet._TYPES_WITHOUT_TAGS.get(exitType):
+ if len(exitInfo) < TAG_LEN and not suppressTag:
raise MixError("Implausibly short exit info: %r"%exitInfo)
if exitType < MIN_EXIT_TYPE and exitType != DROP_TYPE:
raise MixError("Invalid exit type: %4x"%exitType)
@@ -547,7 +547,7 @@
each of the subheaders.
exitType: The routing type for the last node in the header
exitInfo: The routing info for the last node in the header.
- (Must include 20-byte decoding tag.)
+ (Must include 20-byte decoding tag, if any.)
paddingPRNG: A pseudo-random number generator to generate padding
"""
assert len(path) == len(secrets)
Index: ClientDirectory.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientDirectory.py,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- ClientDirectory.py 2 Feb 2004 07:15:18 -0000 1.31
+++ ClientDirectory.py 21 Feb 2004 00:02:09 -0000 1.32
@@ -1082,6 +1082,13 @@
raise UIError("%s exit type expects a fixed exit server." %
exitAddress.getPrettyExitType())
+ if fs is None and lh is None:
+ for desc in self.getLiveServers(startAt, endAt, isExit=1):
+ if exitAddress.isSupportedByServer(desc):
+ break
+ else:
+ raise UIError("No recommended server supports delivery type.")
+
# Check for unrecommended servers
if not warnUnrecommended:
return
@@ -1466,6 +1473,15 @@
rt = self.exitType
return rt, ri, self.lastHop
+ def suppressTag(self):
+ """DOCDOC"""
+ if self.isSSFragmented:
+ return 1
+ elif self.exitType == 'drop':
+ return 1
+ else:
+ return 0
+
def parseAddress(s):
"""Parse and validate an address; takes a string, and returns an
ExitAddress object.
Index: ClientMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientMain.py,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -d -r1.155 -r1.156
--- ClientMain.py 16 Feb 2004 22:30:03 -0000 1.155
+++ ClientMain.py 21 Feb 2004 00:02:09 -0000 1.156
@@ -369,7 +369,7 @@
pkt = mixminion.BuildMessage.buildForwardPacket(
p, routingType, routingInfo, path1, path2,
- self.prng)
+ self.prng, suppressTag=address.suppressTag())
r.append( (pkt, path1[0]) )
return r
Index: Common.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Common.py,v
retrieving revision 1.130
retrieving revision 1.131
diff -u -d -r1.130 -r1.131
--- Common.py 6 Feb 2004 23:14:28 -0000 1.130
+++ Common.py 21 Feb 2004 00:02:09 -0000 1.131
@@ -571,7 +571,7 @@
finally:
f.close()
-def writeFile(fn, contents, mode=0600, binary=0):
+def writeFile(fn, contents, mode=0600, binary=0, fsync=0):
"""Atomically write a string <contents> into a file <file> with mode
<mode>. If <binary>, binary mode will be used.
@@ -579,12 +579,16 @@
If two processes attempt to writeFile the same file at once,
the one finishing last wins.
+
+ If fsync is true, we call fsync on the file before closing it.
"""
tmpname = fn+".tmp"
f, tmpname = openUnique(tmpname, ['w','wb'][binary], mode)
try:
try:
f.write(contents)
+ if fsync:
+ os.fsync(f.fileno())
finally:
f.close()
except:
Index: Main.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Main.py,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- Main.py 15 Jan 2004 21:03:26 -0000 1.67
+++ Main.py 21 Feb 2004 00:02:09 -0000 1.68
@@ -141,6 +141,8 @@
"dir": ( 'mixminion.directory.DirMain', 'main'),
"shell": ( 'mixminion.Main', 'commandShell' ),
+
+ "__d": ( 'mixminion.Main', 'mixminiondMain' ),
}
_USAGE = (
@@ -177,6 +179,18 @@
"For help on sending a message, run 'mixminion send --help'"
)
+_SERVER_USAGE = (
+ "Usage: mixminiond <command> [arguments]\n"+
+ " start [Begin running a Mixminion server]\n"+
+ " stop [Halt a running Mixminion server]\n"+
+ " reload [Make running Mixminion server reload its config\n"+
+ " (Not implemented yet; only restarts logging.)]\n"+
+ " republish [Re-send all keys to directory server]\n"+
+ " DELKEYS [Remove generated keys for a Mixminion server]\n"+
+ " stats [List as-yet-unlogged statistics for this server]\n"+
+ " upgrade [Upgrade a pre-0.0.4 server homedir]\n"
+ )
+
def printVersion(cmd,args):
import mixminion
print "Mixminion version %s" % mixminion.__version__
@@ -199,8 +213,11 @@
sys.exit(1)
-def printUsage():
- print _USAGE
+def printUsage(daemon=0):
+ if daemon:
+ print _SERVER_USAGE
+ else:
+ print _USAGE
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."
@@ -242,7 +259,7 @@
except SystemExit:
pass
-def main(args):
+def main(args,daemon=0):
"Use <args> to fix path, pick a command and pass it arguments."
# Specifically, args[0] is used to fix sys.path so we can import
# mixminion.*; args[1] is used to select a command name from _COMMANDS,
@@ -250,16 +267,14 @@
correctPath(args[0])
-## if len(args) > 2 and args[1] == 'mixminiond':
-## if _COMMANDS.has_key("server-"+args[2]):
-## args[1:3] = "server-"+args[2]
-## else:
-## printUsage()
-## sys.exit(1)
+ if daemon:
+ prefix = "server-"
+ else:
+ prefix = ""
# Check whether we have a recognized command.
- if len(args) == 1 or not _COMMANDS.has_key(args[1]):
- printUsage()
+ if len(args) == 1 or not _COMMANDS.has_key(prefix+args[1]):
+ printUsage(daemon)
sys.exit(1)
if args[1] not in ('unittests', 'benchmarks', 'version') and \
@@ -276,7 +291,7 @@
filePermissionErrorClass = commonModule.MixFilePermissionError
# Read the module and function.
- command_module, command_fn = _COMMANDS[args[1]]
+ command_module, command_fn = _COMMANDS[prefix+args[1]]
mod = __import__(command_module, {}, {}, [command_fn])
func = getattr(mod, command_fn)
Index: Packet.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Packet.py,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- Packet.py 2 Feb 2004 07:05:49 -0000 1.73
+++ Packet.py 21 Feb 2004 00:02:09 -0000 1.74
@@ -94,12 +94,6 @@
FRAGMENT_TYPE = 0x0103 # Find the actual delivery info in the message payload
MAX_EXIT_TYPE = 0xFFFF
-# Set of exit types that don't get tag fields.
-# XXXX007 This interface is really brittle; it needs to change. I added it
-# XXXX007 in order to allow 'fragment' to be an exit type without adding a
-# XXXX007 needless tag field to every fragment routing info.
-_TYPES_WITHOUT_TAGS = { FRAGMENT_TYPE : 1 }
-
def typeIsSwap(tp):
return tp in (SWAP_FWD_IPV4_TYPE,SWAP_FWD_HOST_TYPE)
@@ -162,8 +156,8 @@
underflow = ""
if rlen < len(ri):
ri, underflow = ri[:rlen], ri[rlen:]
- if rt >= MIN_EXIT_TYPE and not _TYPES_WITHOUT_TAGS.get(rt) and rlen < TAG_LEN:
- raise ParseError("Subheader missing tag")
+## if rt >= MIN_EXIT_TYPE and not _TYPES_WITHOUT_TAGS.get(rt) and rlen < TAG_LEN:
+## raise ParseError("Subheader missing tag")
return Subheader(major,minor,secret,digest,rt,ri,rlen,underflow)
class Subheader:
@@ -202,27 +196,25 @@
"routingtype=%(routingtype)r, routinginfo=%(routinginfo)r, "+
"routinglen=%(routinglen)r)")% self.__dict__
- def getExitAddress(self):
+ def getExitAddress(self, tagged=1):
"""Return the part of the routingInfo that contains the delivery
address. (Requires that routingType is an exit type.)"""
assert self.routingtype >= MIN_EXIT_TYPE
#XXXX007 This interface is completely insane. Change it.
- if _TYPES_WITHOUT_TAGS.get(self.routingtype):
+ if not tagged:
return self.routinginfo
else:
- assert len(self.routinginfo) >= TAG_LEN
+ if len(self.routinginfo) < TAG_LEN:
+ raise ParseError("Missing tag")
return self.routinginfo[TAG_LEN:]
def getTag(self):
"""Return the part of the routingInfo that contains the decoding
tag. (Requires that routingType is an exit type.)"""
assert self.routingtype >= MIN_EXIT_TYPE
- #XXXX007 This interface is completely insane. Change it.
- if _TYPES_WITHOUT_TAGS.get(self.routingtype):
- return ""
- else:
- assert len(self.routinginfo) >= TAG_LEN
- return self.routinginfo[:TAG_LEN]
+ if len(self.routinginfo) < TAG_LEN:
+ raise ParseError("Missing tag")
+ return self.routinginfo[:TAG_LEN]
def setRoutingInfo(self, info):
"""Change the routinginfo, and the routinglength to correspond."""
Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.184
retrieving revision 1.185
diff -u -d -r1.184 -r1.185
--- test.py 15 Feb 2004 23:25:33 -0000 1.184
+++ test.py 21 Feb 2004 00:02:09 -0000 1.185
@@ -2580,6 +2580,7 @@
else:
self.assert_(res.isDelivery())
self.assertEquals(res.getExitType(), rt)
+ res.setTagged(res.getExitType() not in (DROP_TYPE,FRAGMENT_TYPE))
self.assertEquals(res.getAddress(), ri)
if appkey:
self.assertEquals(res.getApplicationKey(), appkey)
@@ -5385,16 +5386,18 @@
class FakeDeliveryPacket(mixminion.server.PacketHandler.DeliveryPacket):
"""Stub version of DeliveryPacket used for testing modules"""
- def __init__(self, type, exitType, exitAddress, contents, tag=None,
+ def __init__(self, type, exitType, exitAddress, contents, tag="",
headers = {}):
- if tag is None:
+ if tag == "" and exitType not in (DROP_TYPE, FRAGMENT_TYPE):
tag = "-="*10
mixminion.server.PacketHandler.DeliveryPacket.__init__(self,
- exitType, exitAddress, "Z"*16, tag, "Q"*(28*1024))
+ exitType, tag+exitAddress, "Z"*16, "Q"*(28*1024))
self.type = type
self.headers = headers
self.payload = None
self.contents = contents
+ if tag:
+ self.setTagged(1)
class ModuleTests(TestCase):
def testEmailAddressSet(self):
@@ -5850,7 +5853,7 @@
"pirates@sea","").pack())
deliv = [ mixminion.server.PacketHandler.DeliveryPacket(
routingType=FRAGMENT_TYPE, routingInfo="", applicationKey="X"*16,
- tag="", payload=p) for p in payloads ]
+ payload=p) for p in payloads ]
self.assertEquals(len(deliv), 11)
replaceFunction(mixminion.server.Modules, 'sendSMTPMessage',
@@ -7543,7 +7546,7 @@
tc = loader.loadTestsFromTestCase
if 0:
- suite.addTest(tc(MMTPTests))
+ suite.addTest(tc(ModuleTests))
return suite
testClasses = [MiscTests,
MinionlibCryptoTests,