Author: atagar
Date: 2011-02-28 17:11:26 +0000 (Mon, 28 Feb 2011)
New Revision: 24276
Modified:
arm/trunk/src/util/torTools.py
Log:
Adding a method for fetching the currently used guards, and allowing for empty cache results.
Modified: arm/trunk/src/util/torTools.py
===================================================================
--- arm/trunk/src/util/torTools.py 2011-02-28 13:30:28 UTC (rev 24275)
+++ arm/trunk/src/util/torTools.py 2011-02-28 17:11:26 UTC (rev 24276)
@@ -55,7 +55,7 @@
"config/names", "info/names", "features/names", "events/names",
"nsEntry", "descEntry", "address", "bwRate", "bwBurst",
"bwObserved", "bwMeasured", "flags", "pid", "pathPrefix",
- "startTime", "authorities")
+ "startTime", "authorities", "usedGuards")
# Tor has a couple messages (in or/router.c) for when our ip address changes:
# "Our IP Address has changed from <previous> to <current>; rebuilding
@@ -263,7 +263,7 @@
self._pathPrefixLogging = True
# cached GETINFO parameters (None if unset or possibly changed)
- self._cachedParam = dict([(arg, "") for arg in CACHE_ARGS])
+ self._cachedParam = dict([(arg, None) for arg in CACHE_ARGS])
# cached GETCONF parameters, entries consisting of:
# (option, fetch_type) => value
@@ -691,6 +691,16 @@
return self._getRelayAttr("flags", default)
+ def getMyUsedGuards(self, default = None):
+ """
+ Provides the guards that we're currently using.
+
+ Arguments:
+ default - results if the query fails
+ """
+
+ return self._getRelayAttr("usedGuards", default)
+
def getMyPid(self):
"""
Provides the pid of the attached tor process (None if no controller exists
@@ -716,10 +726,7 @@
jail's path.
"""
- result = self._getRelayAttr("pathPrefix", "")
-
- if result == UNKNOWN: return ""
- else: return result
+ return self._getRelayAttr("pathPrefix", "")
def getStartTime(self):
"""
@@ -727,10 +734,7 @@
can't be determined then this provides None.
"""
- result = self._getRelayAttr("startTime", None)
-
- if result == UNKNOWN: return None
- else: return result
+ return self._getRelayAttr("startTime", None)
def getStatus(self):
"""
@@ -1100,7 +1104,7 @@
if not issueSighup:
try:
self.conn.send_signal("RELOAD")
- self._cachedParam = dict([(arg, "") for arg in CACHE_ARGS])
+ self._cachedParam = dict([(arg, None) for arg in CACHE_ARGS])
self._cachedConf = {}
except Exception, exc:
# new torrc parameters caused an error (tor's likely shut down)
@@ -1145,7 +1149,7 @@
if errorLine: raise IOError(" ".join(errorLine.split()[3:]))
else: raise IOError("failed silently")
- self._cachedParam = dict([(arg, "") for arg in CACHE_ARGS])
+ self._cachedParam = dict([(arg, None) for arg in CACHE_ARGS])
self._cachedConf = {}
except IOError, exc:
raisedException = exc
@@ -1258,6 +1262,8 @@
# CIRC events aren't required, but if one's received then flush this cache
# since it uses circuit-status results.
self._fingerprintsAttachedCache = None
+
+ self._cachedParam["usedGuards"] = None
def buildtimeout_set_event(self, event):
self._updateHeartbeat()
@@ -1448,14 +1454,14 @@
"""
currentVal = self._cachedParam[key]
- if currentVal:
+ if currentVal != None:
if currentVal == UNKNOWN: return default
else: return currentVal
self.connLock.acquire()
currentVal, result = self._cachedParam[key], None
- if not currentVal and self.isAlive():
+ if currentVal == None and self.isAlive():
# still unset - fetch value
if key in ("nsEntry", "descEntry"):
myFingerprint = self.getInfo("fingerprint")
@@ -1580,16 +1586,30 @@
locationComp = entry.split()[-2] # address:port component
result.append(tuple(locationComp.split(":", 1)))
else: result = list(DIR_SERVERS)
+ elif key == "usedGuards":
+ # Checks our circuit-status entry and provides the first hops. Results
+ # tend to be one or three hops, for instance:
+ # 91 BUILT $E4AE6E2FE320FBBD31924E8577F3289D4BE0B4AD=Qwerty PURPOSE=GENERAL
+ circStatusResults = self.getInfo("circuit-status")
+
+ if circStatusResults == "":
+ result = [] # we don't have any client circuits
+ elif circStatusResults != None:
+ for line in circStatusResults.split("\n"):
+ fpStart = line.find("$")
+ fpEnd = line.find("=", fpStart)
+ guardFp = line[fpStart + 1:fpEnd]
+
+ if not guardFp in result: result.append(guardFp)
# cache value
- if result: self._cachedParam[key] = result
+ if result != None: self._cachedParam[key] = result
elif cacheUndefined: self._cachedParam[key] = UNKNOWN
- elif currentVal == UNKNOWN: result = currentVal
self.connLock.release()
- if result: return result
- else: return default
+ if result == None or result == UNKNOWN: return default
+ else: return result
def _notifyStatusListeners(self, eventType):
"""
@@ -1601,7 +1621,7 @@
"""
# resets cached GETINFO and GETCONF parameters
- self._cachedParam = dict([(arg, "") for arg in CACHE_ARGS])
+ self._cachedParam = dict([(arg, None) for arg in CACHE_ARGS])
self._cachedConf = {}
# gives a notice that the control port has closed