[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[minion-cvs] Print useful server names for incoming connections.
Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv11868/lib/mixminion
Modified Files:
ClientDirectory.py ClientMain.py ClientUtils.py MMTPClient.py
NetUtils.py Packet.py ServerInfo.py test.py
Log Message:
Print useful server names for incoming connections.
Index: ClientDirectory.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientDirectory.py,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- ClientDirectory.py 27 Jan 2004 05:55:54 -0000 1.29
+++ ClientDirectory.py 2 Feb 2004 07:05:49 -0000 1.30
@@ -60,7 +60,9 @@
# byNickname: Map from nickname.lower() to list of (ServerInfo, source)
# tuples.
# byKeyID: Map from desc.getKeyDigest() to list of (ServerInfo,source)
- # allServers: DOCDOC
+ # blockedNickname: Map from nickname to list of '*' (blocked in every
+ # position), 'entry' (blocked as entry node), 'exit' (blocked as exit
+ # node).
# __scanning: Flag to prevent recursive invocation of self.rescan().
# __downloading: Flag to prevent simultaneous invocation of
# downloadDirectory()
@@ -99,7 +101,7 @@
self.__downloading = 0
self._lock = RWLock()
self.config = None
- self.blockedNicknames = {} #nickname->['*','entry','exit']
+ self.blockedNicknames = {}
if diskLock is None:
self._diskLock = threading.RLock()
else:
@@ -112,7 +114,7 @@
self._diskLock.release()
def configure(self, config):
- """DOCDOC"""
+ """Adjust this ClientDirectory to account for blocked servers."""
sec = config.get("Security", {})
blocked = {}
for lst in sec.get("BlockServers", []):
@@ -127,6 +129,7 @@
self._lock.write_in()
try:
self.blockedNicknames = blocked
+ self.__rebuildTables()
finally:
self._lock.write_out()
@@ -388,8 +391,9 @@
def _installAsKeyIDResolver(self):
"""Use this ClientDirectory to identify servers in calls to
- ServerInfo.displayServer."""
+ ServerInfo.displayServer*."""
mixminion.ServerInfo._keyIDToNicknameFn = self.getNicknameByKeyID
+ mixminion.ServerInfo._addressToNicknameFn = self.getNicknameByAddress
def importFromFile(self, filename):
"""Import a new server descriptor stored in 'filename'"""
@@ -484,18 +488,15 @@
return len(badSources)
def __rebuildTables(self):
- """Helper method. Reconstruct byNickname, byKeyID, and allServers
- from the internal state of this object. Caller must hold write
- lock."""
+ """Helper method. Reconstruct byNickname and byKeyIDk from the
+ internal state of this object. Caller must hold write lock.
+ """
self.byNickname = {}
self.byKeyID = {}
- self.allServers = []
- self.byCapability = { } #DOCDOC disused
self.goodServerNicknames = {}
for info, where in self.serverList:
nn = info.getNickname().lower()
- self.allServers.append((info,where))
self.goodServerNicknames[nn] = 1
for info, where in self.fullServerList:
@@ -600,7 +601,10 @@
return u.values()
def __nicknameIsBlocked(self, nn, isEntry=0, isExit=0):
- """DOCDOC"""
+ """Return true iff 'nn' is blocked. By default, check for nicknames
+ blocked in every position. If isEntry is true, also check for
+ nicknames blocked as entries; and if isExit is true, also check
+ for nicknames blocked as exits."""
b = self.blockedNicknames.get(nn.lower(), None)
if b is None:
return 0
@@ -614,20 +618,26 @@
return 0
def __excludeBlocked(self, lst, isEntry=0, isExit=0):
- """DOCDOC"""
+ """Given a list of ServerInfo, return a new list with all the
+ blocked servers removed. 'isEntry' and 'isExit' are as for
+ __nicknameIsBlocked.
+ """
res = []
for info in lst:
if not self.__nicknameIsBlocked(info.getNickname(),isEntry,isExit):
res.append(info)
return res
- def getNicknameByIP(self, ip):
- """DOCDOC"""
+ def getNicknameByAddress(self, addr):
+ """Given an address (IP or hostname) return the nickname of
+ the server with that hostname. Return None if no such
+ server is known, and a slash-separated string if multiple
+ servers are known."""
self._lock.read_in()
try:
nicknames = []
for desc,where in self.fullServerList:
- if desc.getIP() == ip:
+ if addr in (desc.getIP(), desc.getHostname()):
if desc.getNickname() not in nicknames:
nicknames.append(desc.getNickname())
return "/".join(nicknames)
@@ -635,8 +645,9 @@
self._lock.read_out()
def getNicknameByKeyID(self, keyid):
- """Given a keyid, return the nickname of the server with that keyid.
- Return None if no such server is known."""
+ """Given a keyid, return the nickname of the server with that
+ keyid. Return None if no such server is known, and a
+ slash-separated string if multiple servers are known."""
self._lock.read_in()
try:
s = self.byKeyID.get(keyid)
@@ -651,7 +662,8 @@
self._lock.read_out()
def getKeyIDByNickname(self, nickname):
- """DOCDOC"""
+ """Given the nickname of the server, return the corresponding
+ keyid, or None if the nickname is not recognized."""
self._lock.read_in()
try:
s = self.byNickname.get(nickname.lower())
@@ -677,9 +689,10 @@
def getLiveServers(self, startAt=None, endAt=None, isEntry=0, isExit=0):
"""Return a list of all server desthat are live from startAt through
endAt. The list is in the standard (ServerInfo,where) format,
- as returned by __find.
- DOCDOC no blocked or notrecommended
- """
+ as returned by __find. If 'isEntry' or 'isExit' is true, return
+ servers suitable as entries or exits. Exclude servers in
+ the not-recommended or blocked lists.
+ """
if startAt is None:
startAt = time.time()
if endAt is None:
@@ -687,7 +700,7 @@
self._lock.read_in()
try:
return self.__excludeBlocked(
- self.__find(self.allServers, startAt, endAt),
+ self.__find(self.serverList, startAt, endAt),
isEntry=isEntry, isExit=isExit)
finally:
self._lock.read_out()
@@ -739,7 +752,7 @@
LOG.info("Couldn't remove %s: %s", s[2:], e)
finally:
self._diskLock.release()
- for field in 'fullServerList', 'serverList', 'allServers':
+ for field in 'fullServerList', 'serverList':
val = getattr(self, field)
val = [ (i,w) for i,w in val if not badSources.has_key(w) ]
setattr(self,field,val)
@@ -931,7 +944,7 @@
servers.append(self.getServerInfo(name, startAt, endAt, 1))
# Now figure out which relays we haven't used yet.
- relays = self.__find(self.allServers, startAt, endAt)
+ relays = self.__find(self.serverList, startAt, endAt)
relays = self.__excludeBlocked(relays)
if not relays:
raise UIError("No relays known")
Index: ClientMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientMain.py,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- ClientMain.py 27 Jan 2004 05:57:59 -0000 1.152
+++ ClientMain.py 2 Feb 2004 07:05:49 -0000 1.153
@@ -30,7 +30,7 @@
parseReplyBlocks, parseSMTPInfo, parseTextEncodedMessages, \
parseTextReplyBlocks, ReplyBlock, parseMessageAndHeaders
-from mixminion.ServerInfo import displayServer, ServerInfo
+from mixminion.ServerInfo import displayServerByRouting, ServerInfo
#----------------------------------------------------------------------
# Global variable; holds an instance of Common.Lockfile used to prevent
@@ -572,13 +572,13 @@
sentSome = 0; sentAll = 1
for routing, packets in self._sortPackets(packets):
LOG.info("Sending %s packets to %s...",
- len(packets), displayServer(routing))
+ len(packets), displayServerByRouting(routing))
try:
self.sendPackets(packets, routing, noQueue=1, warnIfLost=0)
sentSome = 1
except MixError, e:
LOG.error("Can't deliver packets to %s: %s; leaving in queue",
- displayServer(routing), str(e))
+ displayServerByRouting(routing), str(e))
sentAll = 0
if sentAll:
@@ -596,7 +596,8 @@
byRouting = self._sortPackets(
[ (h, self.queue.getRouting(h)) for h in handles ],
shuffle = 0)
- byName = [ (displayServer(ri), lst) for ri,lst in byRouting ]
+ byName = [ (displayServerByRouting(ri), lst)
+ for ri,lst in byRouting ]
byName.sort()
if not byName:
LOG.info("No packets removed.")
@@ -1868,7 +1869,7 @@
print "(No packets in queue)"
return
- res_items = [ (displayServer(ri),count,date)
+ res_items = [ (displayServerByRouting(ri),count,date)
for ri,(count,date) in res.items() ]
res_items.sort()
now = time.time()
Index: ClientUtils.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ClientUtils.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- ClientUtils.py 17 Jan 2004 04:24:57 -0000 1.18
+++ ClientUtils.py 2 Feb 2004 07:05:49 -0000 1.19
@@ -25,7 +25,6 @@
succeedingMidnight, writeFile, armorText, unarmorText
from mixminion.Crypto import sha1, ctr_crypt, DIGEST_LEN, AES_KEY_LEN, \
getCommonPRNG, trng
-from mixminion.ServerInfo import displayServer
#----------------------------------------------------------------------
class BadPassword(MixError):
Index: MMTPClient.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/MMTPClient.py,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- MMTPClient.py 27 Jan 2004 05:58:46 -0000 1.51
+++ MMTPClient.py 2 Feb 2004 07:05:49 -0000 1.52
@@ -90,7 +90,7 @@
if context is None:
context = _ml.TLSContext_new()
if serverName is None:
- serverName = mixminion.ServerInfo.displayServer(
+ serverName = mixminion.ServerInfo.displayServerByRouting(
IPV4Info(targetAddr, targetPort, targetKeyID))
if certCache is None:
certCache = PeerCertificateCache()
@@ -393,7 +393,7 @@
after each successful packet delivery.
"""
# Find out where we're connecting to.
- serverName = mixminion.ServerInfo.displayServer(routing)
+ serverName = mixminion.ServerInfo.displayServerByRouting(routing)
if isinstance(routing, IPV4Info):
family, addr = socket.AF_INET, routing.ip
else:
Index: NetUtils.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/NetUtils.py,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- NetUtils.py 12 Jan 2004 04:48:16 -0000 1.10
+++ NetUtils.py 2 Feb 2004 07:05:49 -0000 1.11
@@ -40,8 +40,8 @@
#======================================================================
def optimizeThroughput(sock):
- """DOCDOC"""
- if not IPTOS_THROUGHPUT:
+ """Set the socket options on 'sock' to maximize throughput."""
+ if not IPTOS_THROUGHPUT:
return
if sys.platform in ('cygwin', 'dgux', 'sni-sysv'):
# According to rumor, these platforms handle socket.IP_TOS
Index: Packet.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Packet.py,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- Packet.py 7 Jan 2004 02:50:08 -0000 1.72
+++ Packet.py 2 Feb 2004 07:05:49 -0000 1.73
@@ -530,7 +530,7 @@
self.encryptionKey = key
def format(self):
- from mixminion.ServerInfo import displayServer
+ import mixminion.ServerInfo
digest = binascii.b2a_hex(sha1(self.pack()))
expiry = formatTime(self.timestamp)
if self.routingType == SWAP_FWD_IPV4_TYPE:
@@ -539,9 +539,10 @@
routing = parseMMTPHostInfo(self.routingInfo)
else:
routing = None
+ server = mixminion.ServerInfo.displayServerByRouting(routing)
return """Reply block hash: %s
Expires at: %s GMT
-First server is: %s""" % (digest, expiry, displayServer(routing))
+First server is: %s""" % (digest, expiry, server)
def pack(self):
"""Returns the external representation of this reply block"""
Index: ServerInfo.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/ServerInfo.py,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- ServerInfo.py 27 Jan 2004 05:55:54 -0000 1.78
+++ ServerInfo.py 2 Feb 2004 07:05:49 -0000 1.79
@@ -8,7 +8,7 @@
descriptors.
"""
-__all__ = [ 'ServerInfo', 'ServerDirectory', 'displayServer' ]
+__all__ = [ 'ServerInfo', 'ServerDirectory', 'displayServerByRouting' ]
import re
import time
@@ -40,55 +40,65 @@
MMTP_KEY_BYTES = 1024 >> 3
# ----------------------------------------------------------------------
-def displayServer(s):
- """Return the best possible human-readable name for a server 's'.
- 's' must be one of: None, IPV4Info, MMTPHostInfo, ServerInfo,
- string.
+def displayServerByRouting(s):
+ """Return the best possible human-readable name for a server with
+ routinginfo 's'. 's' must be one of: IPV4Info, MMTPHostInfo.
"""
- if isinstance(s, types.StringType):
- return s
- elif isinstance(s, ServerInfo):
- if s.getHostname():
- addr = "%s:%s" % (s.getHostname(), s.getPort())
- else:
- addr = "%s:%s" % (s.getIP(), s.getPort())
- nickname = "'%s'" % s.getNickname()
- elif (isinstance(s, mixminion.Packet.IPV4Info) or
- isinstance(s, mixminion.Packet.MMTPHostInfo)):
- nickname = getNicknameByKeyID(s.keyinfo)
- if nickname:
- nickname = "'%s'" % nickname
- else:
- nickname = 'server'
- if isinstance(s, mixminion.Packet.IPV4Info):
- addr = "%s:%s" % (s.ip, s.port)
- else:
- addr = "%s:%s" % (s.hostname, s.port)
- elif s is None:
- return "unknown server"
+ assert (isinstance(s, mixminion.Packet.IPV4Info) or
+ isinstance(s, mixminion.Packet.MMTPHostInfo))
+ nickname = getNicknameByKeyID(s.keyinfo)
+ if isinstance(s, mixminion.Packet.IPV4Info):
+ addr = "%s:%s" % (s.ip, s.port)
else:
- raise AssertionError # unreached
-
+ addr = "%s:%s" % (s.hostname, s.port)
+ if nickname:
+ nickname = "'%s'"%nickname
+ else:
+ nickname = "server"
return "%s at %s" % (nickname, addr)
+def displayServerByAddress(ip, port, hostname=None):
+ """Return the best human-reasable name for a server at IP 'ip', hostname
+ 'hostname', connecting from port 'port'. Note that because reverse
+ caching is unreliable, and IP-based authentication is a lie, any
+ inferred nicknames are displayed as questionable.
+ """
+ nickname = None
+ if hostname is not None:
+ nickname = getNicknameByAddress(hostname)
+ if nickname is None:
+ nickname = getNicknameByAddress(ip)
+ if nickname is None:
+ nickname = ""
+ else:
+ nickname = " ('%s'?)" % nickname
+ return "server at %s:%s%s" %(ip, port, nickname)
+
def getNicknameByKeyID(keyid):
"""Given a 20-byte keyid, look up the nickname of the corresponding
- server. Return the nickname on success and None if we don't recognize
- the server.
-
- FFFF Right now, this is not supported for servers, since they don't
- FFFF download directories.
+ server. Return the nickname on success and None if we don't
+ recognize the server. If multiple servers match, return their
+ nicknames separated by slashes.
"""
#FFFF Be cleverer with all-zero keyids.
- if _keyIDToNicknameFn:
+ if _keyIDToNicknameFn is not None:
return _keyIDToNicknameFn(keyid)
else:
return None
-# This variable should hold None, or a function that maps from keyids to
-# nicknames, and returns None on failure. Currently set by
-# ClientDirectory.ClientDirectory._installAsKeyIDResolver().
+def getNicknameByAddress(address):
+ """Given an IP or hostname, look up the nickname of the corresponding
+ server. Returns as for getNicknameByKeyID.
+ """
+ if _addressToNicknameFn is not None:
+ return _addressToNicknameFn(address)
+ else:
+ return None
+
+# These variables should hold None, or functions that implement getNicknameBy*.
+# Currently set by ClientDirectory.ClientDirectory._installAsKeyIDResolver().
_keyIDToNicknameFn = None
+_addressToNicknameFn = None
# ----------------------------------------------------------------------
Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.180
retrieving revision 1.181
diff -u -d -r1.180 -r1.181
--- test.py 27 Jan 2004 05:14:31 -0000 1.180
+++ test.py 2 Feb 2004 07:05:49 -0000 1.181
@@ -4461,38 +4461,44 @@
class ServerInfoTests(TestCase):
def test_displayServer(self):
- ds = mixminion.ServerInfo.displayServer
+ dsbr = mixminion.ServerInfo.displayServerByRouting
+ dsba = mixminion.ServerInfo.displayServerByAddress
eq = self.assertEquals
- eq(ds(None), "unknown server")
- eq(ds("Fred"), "Fred")
# Test without keyid resolver
- eq(ds(IPV4Info("1.2.3.4", 48099, "x"*20)),
+ eq(dsbr(IPV4Info("1.2.3.4", 48099, "x"*20)),
"server at 1.2.3.4:48099")
-
- eq(ds(MMTPHostInfo("a.b.com", 48099, "x"*20)),
+ eq(dsbr(MMTPHostInfo("a.b.com", 48099, "x"*20)),
"server at a.b.com:48099")
+ eq(dsba("1.2.3.4",48099), "server at 1.2.3.4:48099")
+ eq(dsba("1.2.3.4",48099, "X.Y"), "server at 1.2.3.4:48099")
# Test with keyid resolver
def resolver(keyid):
if keyid[0] == 'a': return "Kenichi"
elif keyid[1] == 'b': return "Tima"
else: return None
+ def reverseResolver(addr):
+ if addr == "1.2.3.4": return "Each"
+ elif addr == "a.b.c.d": return "Peach"
+ else: return None
try:
mixminion.ServerInfo._keyIDToNicknameFn = resolver
- eq(ds(IPV4Info("1.2.3.4", 48099, "b"*20)),
+ mixminion.ServerInfo._addressToNicknameFn = reverseResolver
+ eq(dsbr(IPV4Info("1.2.3.4", 48099, "b"*20)),
"'Tima' at 1.2.3.4:48099")
- eq(ds(IPV4Info("1.2.3.4", 48099, "x"*20)),
+ eq(dsbr(IPV4Info("1.2.3.4", 48099, "x"*20)),
"server at 1.2.3.4:48099")
- eq(ds(MMTPHostInfo("ken.com", 48099, "a"*20)),
+ eq(dsbr(MMTPHostInfo("ken.com", 48099, "a"*20)),
"'Kenichi' at ken.com:48099")
+ eq(dsba("1.2.3.4",48099), "server at 1.2.3.4:48099 ('Each'?)")
+ eq(dsba("1.2.3.4",48099,"a.b.c.d"),
+ "server at 1.2.3.4:48099 ('Peach'?)")
+ eq(dsba("3.4.5.6",48099,"x.y.z"),
+ "server at 3.4.5.6:48099")
finally:
mixminion.ServerInfo._keyIDToNicknameFn = None
-
- # Test serverinfos
- examples = getExampleServerDescriptors()
- eq(ds(mixminion.ServerInfo.ServerInfo(string=examples["Fred"][0])),
- "'Fred' at Fred:48099")
+ mixminion.ServerInfo._addressToNicknameFn = None
def test_ServerInfo(self):
# Try generating a serverinfo and see if its values are as expected.
@@ -7537,7 +7543,7 @@
tc = loader.loadTestsFromTestCase
if 0:
- suite.addTest(tc(MMTPTests))
+ suite.addTest(tc(ServerInfoTests))
return suite
testClasses = [MiscTests,
MinionlibCryptoTests,