tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2011
- 18 participants
- 883 discussions

26 Apr '11
commit 8dc1fcaa32e2aef8dfd5b018709844b4c582f388
Author: Damian Johnson <atagar(a)torproject.org>
Date: Tue Apr 26 09:50:14 2011 -0700
Dropping deprecated conn panel from the codebase
Now that we have feature parity between the new and old connection panels we
can drop the old version. This change removes it, and all the confusing
controller hacks in place to allow us to have either or both panels be visible.
---
armrc.sample | 6 -
src/interface/connPanel.py | 997 --------------------------------------
src/interface/controller.py | 421 ++---------------
src/interface/descriptorPopup.py | 20 +-
4 files changed, 48 insertions(+), 1396 deletions(-)
diff --git a/armrc.sample b/armrc.sample
index 4cda197..58fe5c2 100644
--- a/armrc.sample
+++ b/armrc.sample
@@ -157,10 +157,6 @@ features.graph.bw.accounting.isTimeLong false
# Parameters for connection display
# ---------------------------------
-# oldPanel
-# includes the old connection panel in the interface
-# newPanel
-# includes the new connection panel in the interface
# listingType
# the primary category of information shown by default, options including:
# 0 -> IP Address / Port 1 -> Hostname
@@ -187,8 +183,6 @@ features.graph.bw.accounting.isTimeLong false
# showColumn.*
# toggles the visability of the connection table columns
-features.connection.oldPanel false
-features.connection.newPanel true
features.connection.listingType 0
features.connection.order 0, 2, 1
features.connection.refreshRate 5
diff --git a/src/interface/connPanel.py b/src/interface/connPanel.py
deleted file mode 100644
index e4d4be6..0000000
--- a/src/interface/connPanel.py
+++ /dev/null
@@ -1,997 +0,0 @@
-#!/usr/bin/env python
-# connPanel.py -- Lists network connections used by tor.
-# Released under the GPL v3 (http://www.gnu.org/licenses/gpl.html)
-
-import time
-import socket
-import curses
-from threading import RLock
-from TorCtl import TorCtl
-
-from util import log, connections, hostnames, panel, torTools, uiTools
-
-# Scrubs private data from any connection that might belong to client or exit
-# traffic. This is a little overly conservative, hiding anything that isn't
-# identified as a relay and meets the following criteria:
-# - Connection is inbound and relay's either a bridge (BridgeRelay is set) or
-# guard (making it a probable client connection)
-# - Outbound connection permitted by the exit policy (probable exit connection)
-#
-# Note that relay etiquette says these are bad things to look at (ie, DON'T
-# CHANGE THIS UNLESS YOU HAVE A DAMN GOOD REASON!)
-SCRUB_PRIVATE_DATA = True
-
-# directory servers (IP, port) for tor version 0.2.1.24
-# this comes from the dirservers array in src/or/config.c
-DIR_SERVERS = [("86.59.21.38", "80"), # tor26
- ("128.31.0.39", "9031"), # moria1
- ("216.224.124.114", "9030"), # ides
- ("80.190.246.100", "8180"), # gabelmoo
- ("194.109.206.212", "80"), # dizum
- ("193.23.244.244", "80"), # dannenberg
- ("208.83.223.34", "443"), # urras
- ("82.94.251.203", "80")] # Tonga
-
-# enums for listing types
-LIST_IP, LIST_HOSTNAME, LIST_FINGERPRINT, LIST_NICKNAME = range(4)
-LIST_LABEL = {LIST_IP: "IP Address", LIST_HOSTNAME: "Hostname", LIST_FINGERPRINT: "Fingerprint", LIST_NICKNAME: "Nickname"}
-
-# attributes for connection types
-TYPE_COLORS = {"inbound": "green", "outbound": "blue", "client": "cyan", "directory": "magenta", "control": "red", "family": "magenta", "localhost": "yellow"}
-TYPE_WEIGHTS = {"inbound": 0, "outbound": 1, "client": 2, "directory": 3, "control": 4, "family": 5, "localhost": 6} # defines ordering
-
-# enums for indexes of ConnPanel 'connections' fields
-CONN_TYPE, CONN_L_IP, CONN_L_PORT, CONN_F_IP, CONN_F_PORT, CONN_COUNTRY, CONN_TIME, CONN_PRIVATE = range(8)
-
-# labels associated to 'connectionCount'
-CONN_COUNT_LABELS = ["inbound", "outbound", "client", "directory", "control"]
-
-# enums for sorting types (note: ordering corresponds to SORT_TYPES for easy lookup)
-# TODO: add ORD_BANDWIDTH -> (ORD_BANDWIDTH, "Bandwidth", lambda x, y: ???)
-ORD_TYPE, ORD_FOREIGN_LISTING, ORD_SRC_LISTING, ORD_DST_LISTING, ORD_COUNTRY, ORD_FOREIGN_PORT, ORD_SRC_PORT, ORD_DST_PORT, ORD_TIME = range(9)
-SORT_TYPES = [(ORD_TYPE, "Connection Type",
- lambda x, y: TYPE_WEIGHTS[x[CONN_TYPE]] - TYPE_WEIGHTS[y[CONN_TYPE]]),
- (ORD_FOREIGN_LISTING, "Listing (Foreign)", None),
- (ORD_SRC_LISTING, "Listing (Source)", None),
- (ORD_DST_LISTING, "Listing (Dest.)", None),
- (ORD_COUNTRY, "Country Code",
- lambda x, y: cmp(x[CONN_COUNTRY], y[CONN_COUNTRY])),
- (ORD_FOREIGN_PORT, "Port (Foreign)",
- lambda x, y: int(x[CONN_F_PORT]) - int(y[CONN_F_PORT])),
- (ORD_SRC_PORT, "Port (Source)",
- lambda x, y: int(x[CONN_F_PORT] if x[CONN_TYPE] == "inbound" else x[CONN_L_PORT]) - int(y[CONN_F_PORT] if y[CONN_TYPE] == "inbound" else y[CONN_L_PORT])),
- (ORD_DST_PORT, "Port (Dest.)",
- lambda x, y: int(x[CONN_L_PORT] if x[CONN_TYPE] == "inbound" else x[CONN_F_PORT]) - int(y[CONN_L_PORT] if y[CONN_TYPE] == "inbound" else y[CONN_F_PORT])),
- (ORD_TIME, "Connection Time",
- lambda x, y: cmp(-x[CONN_TIME], -y[CONN_TIME]))]
-
-# provides bi-directional mapping of sorts with their associated labels
-def getSortLabel(sortType, withColor = False):
- """
- Provides label associated with a type of sorting. Throws ValueEror if no such
- sort exists. If adding color formatting this wraps with the following mappings:
- Connection Type red
- Listing * blue
- Port * green
- Bandwidth cyan
- Country Code yellow
- """
-
- for (type, label, func) in SORT_TYPES:
- if sortType == type:
- color = None
-
- if withColor:
- if label == "Connection Type": color = "red"
- elif label.startswith("Listing"): color = "blue"
- elif label.startswith("Port"): color = "green"
- elif label == "Bandwidth": color = "cyan"
- elif label == "Country Code": color = "yellow"
- elif label == "Connection Time": color = "magenta"
-
- #if color: return "<%s>%s</%s>" % (color, label, color)
- if color: return (label, color)
- else: return label
-
- raise ValueError(sortType)
-
-def getSortType(sortLabel):
- """
- Provides sort type associated with a given label. Throws ValueEror if label
- isn't recognized.
- """
-
- for (type, label, func) in SORT_TYPES:
- if sortLabel == label: return type
- raise ValueError(sortLabel)
-
-def ipAddressIsPrivate(ipAddr):
- """
- Provides true if the IP address belongs on the local network or belongs to
- loopback, false otherwise. These include:
- Private ranges: 10.*, 172.16.* - 172.31.*, 192.168.*
- Loopback: 127.*
-
- Arguments:
- ipAddr - IP address to be checked
- """
-
- # TODO: being lazy right now and just declaring all of 172.* as private
- return ipAddr.startswith("10.") or ipAddr.startswith("192.168.") or ipAddr.startswith("172.") or ipAddr.startswith("127.")
-
-class ConnPanel(TorCtl.PostEventListener, panel.Panel):
- """
- Lists tor related connection data.
- """
-
- def __init__(self, stdscr, conn, isDisabled):
- TorCtl.PostEventListener.__init__(self)
- panel.Panel.__init__(self, stdscr, "conn", 0)
- self.scroll = 0
- self.conn = conn # tor connection for querrying country codes
- self.listingType = LIST_IP # information used in listing entries
- self.allowDNS = False # permits hostname resolutions if true
- self.showLabel = True # shows top label if true, hides otherwise
- self.showingDetails = False # augments display to accomidate details window if true
- self.lastUpdate = -1 # time last stats was retrived
- self.localhostEntry = None # special connection - tuple with (entry for this node, fingerprint)
- self.sortOrdering = [ORD_TYPE, ORD_FOREIGN_LISTING, ORD_FOREIGN_PORT]
- self.fingerprintLookupCache = {} # cache of (ip, port) -> fingerprint
- self.nicknameLookupCache = {} # cache of (ip, port) -> nickname
- self.fingerprintMappings = _getFingerprintMappings(self.conn) # mappings of ip -> [(port, fingerprint, nickname), ...]
- self.providedGeoipWarning = False
- self.orconnStatusCache = [] # cache for 'orconn-status' calls
- self.orconnStatusCacheValid = False # indicates if cache has been invalidated
- self.clientConnectionCache = None # listing of nicknames for our client connections
- self.clientConnectionLock = RLock() # lock for clientConnectionCache
- self.isDisabled = isDisabled # prevent panel from updating entirely
- self.lastConnResults = None # used to check if connection results have changed
-
- self.isCursorEnabled = True
- self.cursorSelection = None
- self.cursorLoc = 0 # fallback cursor location if selection disappears
-
- # parameters used for pausing
- self.isPaused = False
- self.pauseTime = 0 # time when paused
- self.connectionsBuffer = [] # location where connections are stored while paused
- self.connectionCountBuffer = []
- self.familyResolutionsBuffer = {}
-
- # mapping of ip/port to fingerprint of family entries, used in hack to short circuit (ip / port) -> fingerprint lookups
- self.familyResolutions = {}
-
- # mapping of family entries to fingerprints
- self.familyFingerprints = {}
-
- self.address = ""
- self.nickname = ""
- self.listenPort = "0" # port used to identify inbound/outbound connections (from ORListenAddress if defined, otherwise ORPort)
- self.orPort = "0"
- self.dirPort = "0"
- self.controlPort = "0"
- self.socksPort = "0"
- self.family = [] # fingerpints of family entries
- self.isBridge = False # true if BridgeRelay is set
- self.exitPolicy = ""
- self.exitRejectPrivate = True # true if ExitPolicyRejectPrivate is 0
-
- self.resetOptions()
-
- # connection results are tuples of the form:
- # (type, local IP, local port, foreign IP, foreign port, country code)
- self.connections = []
- self.connectionsLock = RLock() # limits modifications of connections
-
- # count of total inbound, outbound, client, directory, and control connections
- self.connectionCount = [0] * 5
-
- self.reset()
-
- def resetOptions(self):
- self.familyResolutions = {}
- self.familyFingerprints = {}
-
- try:
- self.address = "" # fetched when needed if unset
- self.nickname = self.conn.get_option("Nickname")[0][1]
- if self.nickname == None: self.nickname = "Unnamed"
-
- self.orPort = self.conn.get_option("ORPort")[0][1]
- self.dirPort = self.conn.get_option("DirPort")[0][1]
- self.controlPort = self.conn.get_option("ControlPort")[0][1]
-
- # uses ports to identify type of connections (ORListenAddress port overwrites ORPort if set)
- listenAddr = self.conn.get_option("ORListenAddress")[0][1]
- if listenAddr and ":" in listenAddr:
- self.listenPort = listenAddr[listenAddr.find(":") + 1:]
- else: self.listenPort = self.orPort
-
- self.socksPort = torTools.getConn().getOption("SocksPort", "0")
-
- # entry is None if not set, otherwise of the format "$<fingerprint>,$<fingerprint>"
- familyEntry = self.conn.get_option("MyFamily")[0][1]
- if familyEntry: self.family = familyEntry.split(",")
- else: self.family = []
-
- self.isBridge = self.conn.get_option("BridgeRelay")[0][1] == "1"
-
- policyEntries = torTools.getConn().getOption("ExitPolicy", multiple=True)
- if not policyEntries: policyEntries = [] # if ExitPolicy is undefined, policyEntries is None
- self.exitPolicy = ",".join(policyEntries)
- self.exitPolicy = self.exitPolicy.replace("\\t", " ").replace("\"", "")
-
- if self.exitPolicy: self.exitPolicy += "," + self.conn.get_info("exit-policy/default")["exit-policy/default"]
- else: self.exitPolicy = self.conn.get_info("exit-policy/default")["exit-policy/default"]
-
- self.exitRejectPrivate = self.conn.get_option("ExitPolicyRejectPrivate")[0][1] == "1"
-
- self._resolveFamilyEntries()
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed):
- self.nickname = ""
- self.listenPort = None
- self.orPort = "0"
- self.dirPort = "0"
- self.controlPort = "0"
- self.socksPort = "0"
- self.family = []
- self.isBridge = False
- self.exitPolicy = ""
- self.exitRejectPrivate = True
-
- # change in client circuits
- def circ_status_event(self, event):
- self.clientConnectionLock.acquire()
- self.clientConnectionCache = None
- self.clientConnectionLock.release()
-
- # when consensus changes update fingerprint mappings
- # TODO: should also be taking NS events into account
- def new_consensus_event(self, event):
- self.orconnStatusCacheValid = False
- self.fingerprintLookupCache.clear()
- self.nicknameLookupCache.clear()
- self.fingerprintMappings = _getFingerprintMappings(self.conn, event.nslist)
- if self.listingType != LIST_HOSTNAME: self.sortConnections()
-
- def new_desc_event(self, event):
- self.orconnStatusCacheValid = False
- self._resolveFamilyEntries()
-
- for fingerprint in event.idlist:
- # clears entries with this fingerprint from the cache
- if fingerprint in self.fingerprintLookupCache.values():
- invalidEntries = set(k for k, v in self.fingerprintLookupCache.iteritems() if v == fingerprint)
- for k in invalidEntries:
- # nicknameLookupCache keys are a subset of fingerprintLookupCache
- del self.fingerprintLookupCache[k]
- if k in self.nicknameLookupCache.keys(): del self.nicknameLookupCache[k]
-
- # gets consensus data for the new description
- try: nsData = self.conn.get_network_status("id/%s" % fingerprint)
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): return
-
- if len(nsData) > 1:
- # multiple records for fingerprint (shouldn't happen)
- log.log(log.WARN, "Multiple consensus entries for fingerprint: %s" % fingerprint)
- return
- nsEntry = nsData[0]
-
- # updates fingerprintMappings with new data
- if nsEntry.ip in self.fingerprintMappings.keys():
- # if entry already exists with the same orport, remove it
- orportMatch = None
- for entryPort, entryFingerprint, entryNickname in self.fingerprintMappings[nsEntry.ip]:
- if entryPort == nsEntry.orport:
- orportMatch = (entryPort, entryFingerprint, entryNickname)
- break
-
- if orportMatch: self.fingerprintMappings[nsEntry.ip].remove(orportMatch)
-
- # add new entry
- self.fingerprintMappings[nsEntry.ip].append((nsEntry.orport, nsEntry.idhex, nsEntry.nickname))
- else:
- self.fingerprintMappings[nsEntry.ip] = [(nsEntry.orport, nsEntry.idhex, nsEntry.nickname)]
- if self.listingType != LIST_HOSTNAME: self.sortConnections()
-
- def reset(self):
- """
- Reloads connection results.
- """
-
- if self.isDisabled: return
-
- # inaccessable during startup so might need to be refetched
- try:
- if not self.address: self.address = self.conn.get_info("address")["address"]
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass
-
- self.connectionsLock.acquire()
- self.clientConnectionLock.acquire()
-
- # temporary variables for connections and count
- connectionsTmp = []
- connectionCountTmp = [0] * 5
- familyResolutionsTmp = {}
-
- # used (with isBridge) to determine if inbound connections should be scrubbed
- isGuard = False
- try:
- myFingerprint = self.conn.get_info("fingerprint")
- nsCall = self.conn.get_network_status("id/%s" % myFingerprint)
- if nsCall: isGuard = "Guard" in nsCall[0].flags
- else: raise TorCtl.ErrorReply # network consensus couldn't be fetched
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass
-
- try:
- if self.clientConnectionCache == None:
- # client connection cache was invalidated
- self.clientConnectionCache = _getClientConnections(self.conn)
-
- connTimes = {} # mapping of ip/port to connection time
- for entry in (self.connections if not self.isPaused else self.connectionsBuffer):
- connTimes[(entry[CONN_F_IP], entry[CONN_F_PORT])] = entry[CONN_TIME]
-
- results = connections.getResolver("tor").getConnections()
- if results == self.lastConnResults: return # contents haven't changed
-
- for lIp, lPort, fIp, fPort in results:
- fingerprint = self.getFingerprint(fIp, fPort)
-
- isPrivate = False
- if lPort in (self.listenPort, self.dirPort):
- type = "inbound"
- connectionCountTmp[0] += 1
- if SCRUB_PRIVATE_DATA and fIp not in self.fingerprintMappings.keys(): isPrivate = isGuard or self.isBridge
- elif lPort == self.socksPort:
- type = "client"
- connectionCountTmp[2] += 1
- elif lPort == self.controlPort:
- type = "control"
- connectionCountTmp[4] += 1
- else:
- nickname = self.getNickname(fIp, fPort)
-
- isClient = False
- for clientName in self.clientConnectionCache:
- if nickname == clientName or (len(clientName) > 1 and clientName[0] == "$" and fingerprint == clientName[1:]):
- isClient = True
- break
-
- if isClient:
- type = "client"
- connectionCountTmp[2] += 1
- elif (fIp, fPort) in DIR_SERVERS:
- type = "directory"
- connectionCountTmp[3] += 1
- else:
- type = "outbound"
- connectionCountTmp[1] += 1
- if SCRUB_PRIVATE_DATA and fIp not in self.fingerprintMappings.keys(): isPrivate = isExitAllowed(fIp, fPort, self.exitPolicy, self.exitRejectPrivate)
-
- # replace nat address with external version if available and the
- # external address isn't a private IP
- isPrivateIp = ipAddressIsPrivate(fIp)
- if self.address and type != "control" and not isPrivateIp: lIp = self.address
-
- if isPrivateIp:
- countryCode = "??"
- else:
- try:
- countryCodeQuery = "ip-to-country/%s" % fIp
- countryCode = self.conn.get_info(countryCodeQuery)[countryCodeQuery]
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed):
- countryCode = "??"
- if not self.providedGeoipWarning:
- log.log(log.WARN, "Tor geoip database is unavailable.")
- self.providedGeoipWarning = True
-
- if (fIp, fPort) in connTimes: connTime = connTimes[(fIp, fPort)]
- else: connTime = time.time()
-
- connectionsTmp.append((type, lIp, lPort, fIp, fPort, countryCode, connTime, isPrivate))
-
- # appends localhost connection to allow user to look up their own consensus entry
- selfFingerprint = None
- try:
- selfFingerprint = self.conn.get_info("fingerprint")["fingerprint"]
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass
-
- if self.address and selfFingerprint:
- try:
- countryCodeQuery = "ip-to-country/%s" % self.address
- selfCountryCode = self.conn.get_info(countryCodeQuery)[countryCodeQuery]
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed):
- selfCountryCode = "??"
-
- if (self.address, self.orPort) in connTimes: connTime = connTimes[(self.address, self.orPort)]
- else: connTime = time.time()
-
- self.localhostEntry = (("localhost", self.address, self.orPort, self.address, self.orPort, selfCountryCode, connTime, False), selfFingerprint)
- connectionsTmp.append(self.localhostEntry[0])
- else:
- self.localhostEntry = None
-
- # appends family connections
- tmpCounter = 0 # used for unique port of unresolved family entries (funky hack)
- for familyEntry in self.family:
- # TODO: turns out that "ns/name/<OR nickname>" accpets fingerprint
- # identifiers, so all this nickname -> fingerprint work is unnecessary,
- # but used for fingerprint lookup performance in draw... this could be
- # improved (might be completely unnecessary due to the fingerprint
- # lookup cache)
- fingerprint = None
- if familyEntry in self.familyFingerprints:
- fingerprint = self.familyFingerprints[familyEntry]
-
- try:
- if fingerprint: nsCall = self.conn.get_network_status("id/%s" % fingerprint)
- else: nsCall = self.conn.get_network_status("name/%s" % familyEntry)
- if nsCall: familyAddress, familyPort = nsCall[0].ip, nsCall[0].orport
- else: raise TorCtl.ErrorReply # network consensus couldn't be fetched
-
- countryCodeQuery = "ip-to-country/%s" % familyAddress
- familyCountryCode = self.conn.get_info(countryCodeQuery)[countryCodeQuery]
-
- if (familyAddress, familyPort) in connTimes: connTime = connTimes[(familyAddress, familyPort)]
- else: connTime = time.time()
-
- if fingerprint: familyResolutionsTmp[(familyAddress, familyPort)] = fingerprint
- connectionsTmp.append(("family", familyAddress, familyPort, familyAddress, familyPort, familyCountryCode, connTime, False))
- except (socket.error, TorCtl.ErrorReply):
- # use dummy entry for sorting - the draw function notes that entries are unknown
- portIdentifier = str(65536 + tmpCounter)
- if fingerprint: familyResolutionsTmp[("256.255.255.255", portIdentifier)] = fingerprint
- connectionsTmp.append(("family", "256.255.255.255", portIdentifier, "256.255.255.255", portIdentifier, "??", time.time(), False))
- tmpCounter += 1
- except TorCtl.TorCtlClosed:
- pass # connections aren't shown when control port is unavailable
-
- self.lastUpdate = time.time()
-
- # assigns results
- if self.isPaused:
- self.connectionsBuffer = connectionsTmp
- self.connectionCountBuffer = connectionCountTmp
- self.familyResolutionsBuffer = familyResolutionsTmp
- else:
- self.connections = connectionsTmp
- self.connectionCount = connectionCountTmp
- self.familyResolutions = familyResolutionsTmp
-
- # hostnames are sorted at draw - otherwise now's a good time
- if self.listingType != LIST_HOSTNAME: self.sortConnections()
- self.lastConnResults = results
- finally:
- self.connectionsLock.release()
- self.clientConnectionLock.release()
-
- def handleKey(self, key):
- # cursor or scroll movement
-
- #if key in (curses.KEY_UP, curses.KEY_DOWN, curses.KEY_PPAGE, curses.KEY_NPAGE):
- if uiTools.isScrollKey(key):
- pageHeight = self.getPreferredSize()[0] - 1
- if self.showingDetails: pageHeight -= 8
-
- self.connectionsLock.acquire()
- try:
- # determines location parameter to use
- if self.isCursorEnabled:
- try: currentLoc = self.connections.index(self.cursorSelection)
- except ValueError: currentLoc = self.cursorLoc # fall back to nearby entry
- else: currentLoc = self.scroll
-
- # location offset
- if key == curses.KEY_UP: shift = -1
- elif key == curses.KEY_DOWN: shift = 1
- elif key == curses.KEY_PPAGE: shift = -pageHeight + 1 if self.isCursorEnabled else -pageHeight
- elif key == curses.KEY_NPAGE: shift = pageHeight - 1 if self.isCursorEnabled else pageHeight
- elif key == curses.KEY_HOME: shift = -currentLoc
- elif key == curses.KEY_END: shift = len(self.connections) # always below the lower bound
- newLoc = currentLoc + shift
-
- # restricts to valid bounds
- maxLoc = len(self.connections) - 1 if self.isCursorEnabled else len(self.connections) - pageHeight
- newLoc = max(0, min(newLoc, maxLoc))
-
- # applies to proper parameter
- if self.isCursorEnabled and self.connections:
- self.cursorSelection, self.cursorLoc = self.connections[newLoc], newLoc
- else: self.scroll = newLoc
- finally:
- self.connectionsLock.release()
- elif key == ord('r') or key == ord('R'):
- self.allowDNS = not self.allowDNS
- if not self.allowDNS: hostnames.setPaused(True)
- elif self.listingType == LIST_HOSTNAME: hostnames.setPaused(False)
- else: return # skip following redraw
- self.redraw(True)
-
- def draw(self, width, height):
- self.connectionsLock.acquire()
- try:
- # hostnames frequently get updated so frequent sorting needed
- if self.listingType == LIST_HOSTNAME: self.sortConnections()
-
- if self.showLabel:
- # notes the number of connections for each type if above zero
- countLabel = ""
- for i in range(len(self.connectionCount)):
- if self.connectionCount[i] > 0: countLabel += "%i %s, " % (self.connectionCount[i], CONN_COUNT_LABELS[i])
- if countLabel: countLabel = " (%s)" % countLabel[:-2] # strips ending ", " and encases in parentheses
- self.addstr(0, 0, "Connections%s:" % countLabel, curses.A_STANDOUT)
-
- if self.connections:
- listingHeight = height - 1
- currentTime = time.time() if not self.isPaused else self.pauseTime
-
- if self.showingDetails:
- listingHeight -= 8
- isScrollBarVisible = len(self.connections) > height - 9
- if width > 80: self.win.hline(8, 80, curses.ACS_HLINE, width - 81)
- else:
- isScrollBarVisible = len(self.connections) > height - 1
- xOffset = 3 if isScrollBarVisible else 0 # content offset for scroll bar
-
- # ensure cursor location and scroll top are within bounds
- self.cursorLoc = max(min(self.cursorLoc, len(self.connections) - 1), 0)
- self.scroll = max(min(self.scroll, len(self.connections) - listingHeight), 0)
-
- if self.isCursorEnabled:
- # update cursorLoc with selection (or vice versa if selection not found)
- if self.cursorSelection not in self.connections:
- self.cursorSelection = self.connections[self.cursorLoc]
- else: self.cursorLoc = self.connections.index(self.cursorSelection)
-
- # shift scroll if necessary for cursor to be visible
- if self.cursorLoc < self.scroll: self.scroll = self.cursorLoc
- elif self.cursorLoc - listingHeight + 1 > self.scroll: self.scroll = self.cursorLoc - listingHeight + 1
-
- lineNum = (-1 * self.scroll) + 1
- for entry in self.connections:
- if lineNum >= 1:
- type = entry[CONN_TYPE]
- isPrivate = entry[CONN_PRIVATE]
- color = TYPE_COLORS[type]
-
- # adjustments to measurements for 'xOffset' are to account for scroll bar
- if self.listingType == LIST_IP:
- # base data requires 73 characters
- src = "%s:%s" % (entry[CONN_L_IP], entry[CONN_L_PORT])
- dst = "%s:%s" % (entry[CONN_F_IP], entry[CONN_F_PORT])
- if not ipAddressIsPrivate(entry[CONN_F_IP]):
- dst += " (%s)" % entry[CONN_COUNTRY]
-
- if isPrivate: dst = "<scrubbed>"
-
- src, dst = "%-21s" % src, "%-26s" % dst
-
- etc = ""
- if width > 115 + xOffset:
- # show fingerprint (column width: 42 characters)
- etc += "%-40s " % self.getFingerprint(entry[CONN_F_IP], entry[CONN_F_PORT])
-
- if width > 127 + xOffset:
- # show nickname (column width: remainder)
- nickname = self.getNickname(entry[CONN_F_IP], entry[CONN_F_PORT])
- nicknameSpace = width - 118 - xOffset
-
- # truncates if too long
- if len(nickname) > nicknameSpace: nickname = "%s..." % nickname[:nicknameSpace - 3]
-
- etc += ("%%-%is " % nicknameSpace) % nickname
- elif self.listingType == LIST_HOSTNAME:
- # base data requires 80 characters
- src = "localhost:%-5s" % entry[CONN_L_PORT]
-
- # space available for foreign hostname (stretched to claim any free space)
- foreignHostnameSpace = width - 42 - xOffset
-
- etc = ""
- if width > 102 + xOffset:
- # shows ip/locale (column width: 22 characters)
- foreignHostnameSpace -= 22
-
- if isPrivate: ipEntry = "<scrubbed>"
- else:
- ipEntry = "%s:%s" % (entry[CONN_F_IP], entry[CONN_F_PORT])
- if ipAddressIsPrivate(entry[CONN_F_IP]):
- ipEntry += " (%s)" % entry[CONN_COUNTRY]
-
- etc += "%-20s " % ipEntry
- if width > 134 + xOffset:
- # show fingerprint (column width: 42 characters)
- foreignHostnameSpace -= 42
- etc += "%-40s " % self.getFingerprint(entry[CONN_F_IP], entry[CONN_F_PORT])
-
- if width > 151 + xOffset:
- # show nickname (column width: min 17 characters, uses half of the remainder)
- nickname = self.getNickname(entry[CONN_F_IP], entry[CONN_F_PORT])
- nicknameSpace = 15 + (width - xOffset - 151) / 2
- foreignHostnameSpace -= (nicknameSpace + 2)
-
- if len(nickname) > nicknameSpace: nickname = "%s..." % nickname[:nicknameSpace - 3]
- etc += ("%%-%is " % nicknameSpace) % nickname
-
- if isPrivate: dst = "<scrubbed>"
- else:
- try: hostname = hostnames.resolve(entry[CONN_F_IP])
- except ValueError: hostname = None
-
- # truncates long hostnames
- portDigits = len(str(entry[CONN_F_PORT]))
- if hostname and (len(hostname) + portDigits) > foreignHostnameSpace - 1:
- hostname = hostname[:(foreignHostnameSpace - portDigits - 4)] + "..."
-
- dst = "%s:%s" % (hostname if hostname else entry[CONN_F_IP], entry[CONN_F_PORT])
-
- dst = ("%%-%is" % foreignHostnameSpace) % dst
- elif self.listingType == LIST_FINGERPRINT:
- # base data requires 75 characters
- src = "localhost"
- if entry[CONN_TYPE] == "control": dst = "localhost"
- else: dst = self.getFingerprint(entry[CONN_F_IP], entry[CONN_F_PORT])
- dst = "%-40s" % dst
-
- etc = ""
- if width > 92 + xOffset:
- # show nickname (column width: min 17 characters, uses remainder if extra room's available)
- nickname = self.getNickname(entry[CONN_F_IP], entry[CONN_F_PORT])
- nicknameSpace = width - 78 - xOffset if width < 126 else width - 106 - xOffset
- if len(nickname) > nicknameSpace: nickname = "%s..." % nickname[:nicknameSpace - 3]
- etc += ("%%-%is " % nicknameSpace) % nickname
-
- if width > 125 + xOffset:
- # shows ip/port/locale (column width: 28 characters)
- if isPrivate: ipEntry = "<scrubbed>"
- else:
- ipEntry = "%s:%s" % (entry[CONN_F_IP], entry[CONN_F_PORT])
- if ipAddressIsPrivate(entry[CONN_F_IP]):
- ipEntry += " (%s)" % entry[CONN_COUNTRY]
-
- etc += "%-26s " % ipEntry
- else:
- # base data uses whatever extra room's available (using minimun of 50 characters)
- src = self.nickname
- if entry[CONN_TYPE] == "control": dst = self.nickname
- else: dst = self.getNickname(entry[CONN_F_IP], entry[CONN_F_PORT])
-
- # space available for foreign nickname
- foreignNicknameSpace = width - len(self.nickname) - 27 - xOffset
-
- etc = ""
- if width > 92 + xOffset:
- # show fingerprint (column width: 42 characters)
- foreignNicknameSpace -= 42
- etc += "%-40s " % self.getFingerprint(entry[CONN_F_IP], entry[CONN_F_PORT])
-
- if width > 120 + xOffset:
- # shows ip/port/locale (column width: 28 characters)
- foreignNicknameSpace -= 28
-
- if isPrivate: ipEntry = "<scrubbed>"
- else:
- ipEntry = "%s:%s" % (entry[CONN_F_IP], entry[CONN_F_PORT])
- if ipAddressIsPrivate(entry[CONN_F_IP]):
- ipEntry += " (%s)" % entry[CONN_COUNTRY]
-
- etc += "%-26s " % ipEntry
-
- dst = ("%%-%is" % foreignNicknameSpace) % dst
-
- timeLabel = uiTools.getTimeLabel(currentTime - entry[CONN_TIME], 1)
- if type == "inbound": src, dst = dst, src
- elif type == "family" and int(entry[CONN_L_PORT]) > 65535:
- # this belongs to an unresolved family entry - replaces invalid data with "UNKNOWN"
- timeLabel = "---"
-
- if self.listingType == LIST_IP:
- src = "%-21s" % "UNKNOWN"
- dst = "%-26s" % "UNKNOWN"
- elif self.listingType == LIST_HOSTNAME:
- src = "%-15s" % "UNKNOWN"
- dst = ("%%-%is" % len(dst)) % "UNKNOWN"
- if len(etc) > 0: etc = etc.replace("256.255.255.255 (??)", "UNKNOWN" + " " * 13)
- else:
- ipStart = etc.find("256")
- if ipStart > -1: etc = etc[:ipStart] + ("%%-%is" % len(etc[ipStart:])) % "UNKNOWN"
-
- padding = width - (len(src) + len(dst) + len(etc) + 27) - xOffset # padding needed to fill full line
- lineEntry = "<%s>%s --> %s %s%s%5s (<b>%s</b>)%s</%s>" % (color, src, dst, etc, " " * padding, timeLabel, type.upper(), " " * (9 - len(type)), color)
-
- if self.isCursorEnabled and entry == self.cursorSelection:
- lineEntry = "<h>%s</h>" % lineEntry
-
- yOffset = 0 if not self.showingDetails else 8
- self.addfstr(lineNum + yOffset, xOffset, lineEntry)
- lineNum += 1
-
- if isScrollBarVisible:
- topY = 9 if self.showingDetails else 1
- bottomEntry = self.scroll + height - 9 if self.showingDetails else self.scroll + height - 1
- self.addScrollBar(self.scroll, bottomEntry, len(self.connections), topY)
- finally:
- self.connectionsLock.release()
-
- def getFingerprint(self, ipAddr, port):
- """
- Makes an effort to match connection to fingerprint - if there's multiple
- potential matches or the IP address isn't found in the discriptor then
- returns "UNKNOWN".
- """
-
- # checks to see if this matches the localhost entry
- if self.localhostEntry and ipAddr == self.localhostEntry[0][CONN_L_IP] and port == self.localhostEntry[0][CONN_L_PORT]:
- return self.localhostEntry[1]
-
- # checks if this belongs to a family entry
- if (ipAddr, port) in self.familyResolutions.keys():
- return self.familyResolutions[(ipAddr, port)]
-
- port = int(port)
- if (ipAddr, port) in self.fingerprintLookupCache:
- return self.fingerprintLookupCache[(ipAddr, port)]
- else:
- match = None
-
- # orconn-status provides a listing of Tor's current connections - used to
- # eliminated ambiguity for outbound connections
- if not self.orconnStatusCacheValid:
- self.orconnStatusCache, isOdd = [], True
- self.orconnStatusCacheValid = True
- try:
- for entry in self.conn.get_info("orconn-status")["orconn-status"].split():
- if isOdd: self.orconnStatusCache.append(entry)
- isOdd = not isOdd
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): self.orconnStatusCache = None
-
- if ipAddr in self.fingerprintMappings.keys():
- potentialMatches = self.fingerprintMappings[ipAddr]
-
- if len(potentialMatches) == 1: match = potentialMatches[0][1]
- else:
- # multiple potential matches - look for exact match with port
- for (entryPort, entryFingerprint, entryNickname) in potentialMatches:
- if entryPort == port:
- match = entryFingerprint
- break
-
- if not match:
- # still haven't found it - use trick from Mike's ConsensusTracker,
- # excluding possiblities that have...
- # ... lost their Running flag
- # ... list a bandwidth of 0
- # ... have 'opt hibernating' set
- operativeMatches = list(potentialMatches)
- for entryPort, entryFingerprint, entryNickname in potentialMatches:
- # gets router description to see if 'down' is set
- toRemove = False
- try:
- nsCall = self.conn.get_network_status("id/%s" % entryFingerprint)
- if not nsCall: raise TorCtl.ErrorReply() # network consensus couldn't be fetched
- else: nsEntry = nsCall[0]
-
- descLookupCmd = "desc/id/%s" % entryFingerprint
- descEntry = TorCtl.Router.build_from_desc(self.conn.get_info(descLookupCmd)[descLookupCmd].split("\n"), nsEntry)
- toRemove = descEntry.down
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass # ns or desc lookup fails... also weird
-
- # eliminates connections not reported by orconn-status -
- # this has *very* little impact since few ips have multiple relays
- if self.orconnStatusCache and not toRemove: toRemove = entryNickname not in self.orconnStatusCache
-
- if toRemove: operativeMatches.remove((entryPort, entryFingerprint, entryNickname))
-
- if len(operativeMatches) == 1: match = operativeMatches[0][1]
-
- if not match: match = "UNKNOWN"
-
- self.fingerprintLookupCache[(ipAddr, port)] = match
- return match
-
- def getNickname(self, ipAddr, port):
- """
- Attempts to provide the nickname for an ip/port combination, "UNKNOWN"
- if this can't be determined.
- """
-
- if (ipAddr, port) in self.nicknameLookupCache:
- return self.nicknameLookupCache[(ipAddr, port)]
- else:
- match = self.getFingerprint(ipAddr, port)
-
- try:
- if match != "UNKNOWN":
- nsCall = self.conn.get_network_status("id/%s" % match)
- if nsCall: match = nsCall[0].nickname
- else: raise TorCtl.ErrorReply # network consensus couldn't be fetched
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): return "UNKNOWN" # don't cache result
-
- self.nicknameLookupCache[(ipAddr, port)] = match
- return match
-
- def setPaused(self, isPause):
- """
- If true, prevents connection listing from being updated.
- """
-
- if isPause == self.isPaused: return
-
- self.isPaused = isPause
- if isPause:
- self.pauseTime = time.time()
- self.connectionsBuffer = list(self.connections)
- self.connectionCountBuffer = list(self.connectionCount)
- self.familyResolutionsBuffer = dict(self.familyResolutions)
- else:
- self.connections = list(self.connectionsBuffer)
- self.connectionCount = list(self.connectionCountBuffer)
- self.familyResolutions = dict(self.familyResolutionsBuffer)
-
- # pause buffer connections may be unsorted
- if self.listingType != LIST_HOSTNAME: self.sortConnections()
-
- def sortConnections(self):
- """
- Sorts connections according to currently set ordering. This takes into
- account secondary and tertiary sub-keys in case of ties.
- """
-
- # Current implementation is very inefficient, but since connection lists
- # are decently small (count get up to arounk 1k) this shouldn't be a big
- # whoop. Suggestions for improvements are welcome!
-
- sorts = []
-
- # wrapper function for using current listed data (for 'LISTING' sorts)
- if self.listingType == LIST_IP:
- listingWrapper = lambda ip, port: _ipToInt(ip)
- elif self.listingType == LIST_HOSTNAME:
- # alphanumeric hostnames followed by unresolved IP addresses
- listingWrapper = lambda ip, port: _getHostname(ip).upper() if _getHostname(ip) else "zzzzz%099i" % _ipToInt(ip)
- elif self.listingType == LIST_FINGERPRINT:
- # alphanumeric fingerprints followed by UNKNOWN entries
- listingWrapper = lambda ip, port: self.getFingerprint(ip, port) if self.getFingerprint(ip, port) != "UNKNOWN" else "zzzzz%099i" % _ipToInt(ip)
- elif self.listingType == LIST_NICKNAME:
- # alphanumeric nicknames followed by Unnamed then UNKNOWN entries
- listingWrapper = lambda ip, port: self.getNickname(ip, port) if self.getNickname(ip, port) not in ("UNKNOWN", "Unnamed") else "zzzzz%i%099i" % (0 if self.getNickname(ip, port) == "Unnamed" else 1, _ipToInt(ip))
-
- for entry in self.sortOrdering:
- if entry == ORD_FOREIGN_LISTING:
- sorts.append(lambda x, y: cmp(listingWrapper(x[CONN_F_IP], x[CONN_F_PORT]), listingWrapper(y[CONN_F_IP], y[CONN_F_PORT])))
- elif entry == ORD_SRC_LISTING:
- sorts.append(lambda x, y: cmp(listingWrapper(x[CONN_F_IP] if x[CONN_TYPE] == "inbound" else x[CONN_L_IP], x[CONN_F_PORT]), listingWrapper(y[CONN_F_IP] if y[CONN_TYPE] == "inbound" else y[CONN_L_IP], y[CONN_F_PORT])))
- elif entry == ORD_DST_LISTING:
- sorts.append(lambda x, y: cmp(listingWrapper(x[CONN_L_IP] if x[CONN_TYPE] == "inbound" else x[CONN_F_IP], x[CONN_F_PORT]), listingWrapper(y[CONN_L_IP] if y[CONN_TYPE] == "inbound" else y[CONN_F_IP], y[CONN_F_PORT])))
- else: sorts.append(SORT_TYPES[entry][2])
-
- self.connectionsLock.acquire()
- try: self.connections.sort(lambda x, y: _multisort(x, y, sorts))
- finally: self.connectionsLock.release()
-
- def _resolveFamilyEntries(self):
- """
- Populates mappings of the torrc family entries to their fingerprints.
- """
-
- self.familyFingerprints = {}
-
- for familyEntry in self.family:
- if not familyEntry: continue
-
- if familyEntry[0] == "$":
- # relay identified by fingerprint
- self.familyFingerprints[familyEntry] = familyEntry[1:]
- else:
- # relay identified by nickname
- descEntry = torTools.getConn().getInfo("desc/name/%s" % familyEntry)
-
- if descEntry:
- fingerprintStart = descEntry.find("opt fingerprint") + 16
- fingerprintEnd = descEntry.find("\n", fingerprintStart)
- fingerprint = descEntry[fingerprintStart:fingerprintEnd].replace(" ", "")
-
- self.familyFingerprints[familyEntry] = fingerprint
-
-# recursively checks primary, secondary, and tertiary sorting parameter in ties
-def _multisort(conn1, conn2, sorts):
- comp = sorts[0](conn1, conn2)
- if comp or len(sorts) == 1: return comp
- else: return _multisort(conn1, conn2, sorts[1:])
-
-def _getHostname(ipAddr):
- try: return hostnames.resolve(ipAddr)
- except ValueError: return None
-
-# provides comparison int for sorting IP addresses
-def _ipToInt(ipAddr):
- total = 0
- for comp in ipAddr.split("."):
- total *= 255
- total += int(comp)
- return total
-
-# uses consensus data to map IP addresses to port / fingerprint combinations
-def _getFingerprintMappings(conn, nsList = None):
- ipToFingerprint = {}
-
- if not nsList:
- try: nsList = conn.get_network_status()
- except (socket.error, TorCtl.TorCtlClosed, TorCtl.ErrorReply): nsList = []
- except TypeError: nsList = [] # TODO: temporary workaround for a TorCtl bug, remove when fixed
-
- for entry in nsList:
- if entry.ip in ipToFingerprint.keys(): ipToFingerprint[entry.ip].append((entry.orport, entry.idhex, entry.nickname))
- else: ipToFingerprint[entry.ip] = [(entry.orport, entry.idhex, entry.nickname)]
-
- return ipToFingerprint
-
-# provides client relays we're currently attached to (first hops in circuits)
-# this consists of the nicknames and ${fingerprint} if unnamed
-def _getClientConnections(conn):
- clients = []
-
- try:
- for line in conn.get_info("circuit-status")["circuit-status"].split("\n"):
- components = line.split()
- if len(components) > 3: clients += [components[2].split(",")[0]]
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass
-
- return clients
-
-def isExitAllowed(ip, port, exitPolicy, isPrivateRejected):
- """
- Determines if a given connection is a permissable exit with the given
- policy or not (True if it's allowed to be an exit connection, False
- otherwise).
-
- NOTE: this is a little tricky and liable to need some tweaks
- """
-
- # might not be set when first starting up
- if not exitPolicy: return True
-
- # TODO: move into a utility and craft some unit tests (this is very error
- # prone...)
-
- # TODO: currently doesn't consider ExitPolicyRejectPrivate (which prevents
- # connections to private networks and local ip)
- for entry in exitPolicy.split(","):
- entry = entry.strip()
-
- isAccept = entry.startswith("accept")
- entry = entry[7:] # strips off "accept " or "reject "
-
- # parses ip address (with mask if provided) and port
- if ":" in entry:
- entryIP = entry[:entry.find(":")]
- entryPort = entry[entry.find(":") + 1:]
- else:
- entryIP = entry
- entryPort = "*"
-
- #raise AssertionError(str(exitPolicy) + " - " + entryIP + ":" + entryPort)
- isIPMatch = entryIP == ip or entryIP[0] == "*"
-
- if not "-" in entryPort:
- # single port
- isPortMatch = entryPort == str(port) or entryPort[0] == "*"
- else:
- # port range
- minPort = int(entryPort[:entryPort.find("-")])
- maxPort = int(entryPort[entryPort.find("-") + 1:])
- isPortMatch = port >= minPort and port <= maxPort
-
- # TODO: Currently being lazy and considering subnet masks or 'private'
- # keyword to be equivilant to wildcard if it would reject, and none
- # if it would accept (ie, being conservative with acceptance). Would be
- # nice to fix at some point.
- if not isAccept: isIPMatch |= "/" in entryIP or entryIP == "private"
-
- if isIPMatch and isPortMatch: return isAccept
-
- # we shouldn't ever fall through due to default exit policy
- log.log(log.WARN, "Exit policy left connection uncategorized: %s:%i" % (ip, port))
- return False
-
diff --git a/src/interface/controller.py b/src/interface/controller.py
index b88152f..5060188 100644
--- a/src/interface/controller.py
+++ b/src/interface/controller.py
@@ -18,7 +18,6 @@ from TorCtl import TorCtl
import headerPanel
import graphing.graphPanel
import logPanel
-import connPanel
import configPanel
import torrcPanel
import descriptorPopup
@@ -43,17 +42,14 @@ PAGE_S = ["header", "control", "popup"] # sticky (ie, always available) page
PAGES = [
["graph", "log"],
["conn"],
- ["conn2"],
["config"],
["torrc"]]
-PAUSEABLE = ["header", "graph", "log", "conn", "conn2"]
+PAUSEABLE = ["header", "graph", "log", "conn"]
CONFIG = {"log.torrc.readFailed": log.WARN,
"features.graph.type": 1,
"features.config.prepopulateEditValues": True,
- "features.connection.oldPanel": False,
- "features.connection.newPanel": True,
"queries.refreshRate.rate": 5,
"log.torEventTypeUnrecognized": log.NOTICE,
"features.graph.bw.prepopulate": True,
@@ -119,11 +115,7 @@ class ControlPanel(panel.Panel):
currentPage = self.page
pageCount = len(PAGES)
- if not CONFIG["features.connection.newPanel"]:
- if currentPage >= 3: currentPage -= 1
- pageCount -= 1
-
- if self.isBlindMode or not CONFIG["features.connection.oldPanel"]:
+ if self.isBlindMode:
if currentPage >= 2: currentPage -= 1
pageCount -= 1
@@ -562,17 +554,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
# before being positioned - the following is a quick hack til rewritten
panels["log"].setPaused(True)
- if CONFIG["features.connection.oldPanel"]:
- panels["conn"] = connPanel.ConnPanel(stdscr, conn, isBlindMode)
- else:
- panels["conn"] = panel.Panel(stdscr, "blank", 0, 0, 0)
- PAUSEABLE.remove("conn")
-
- if CONFIG["features.connection.newPanel"]:
- panels["conn2"] = interface.connections.connPanel.ConnectionPanel(stdscr, config)
- else:
- panels["conn2"] = panel.Panel(stdscr, "blank", 0, 0, 0)
- PAUSEABLE.remove("conn2")
+ panels["conn"] = interface.connections.connPanel.ConnectionPanel(stdscr, config)
panels["control"] = ControlPanel(stdscr, isBlindMode)
panels["config"] = configPanel.ConfigPanel(stdscr, configPanel.State.TOR, config)
@@ -599,8 +581,6 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
conn.add_event_listener(panels["graph"].stats["bandwidth"])
conn.add_event_listener(panels["graph"].stats["system resources"])
if not isBlindMode: conn.add_event_listener(panels["graph"].stats["connections"])
- if CONFIG["features.connection.oldPanel"]:
- conn.add_event_listener(panels["conn"])
conn.add_event_listener(sighupTracker)
# prepopulates bandwidth values from state file
@@ -627,8 +607,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
# tells revised panels to run as daemons
panels["header"].start()
panels["log"].start()
- if CONFIG["features.connection.newPanel"]:
- panels["conn2"].start()
+ panels["conn"].start()
# warns if tor isn't updating descriptors
#try:
@@ -687,8 +666,6 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
#panels["header"]._updateParams(True)
# other panels that use torrc data
- if CONFIG["features.connection.oldPanel"]:
- panels["conn"].resetOptions()
#if not isBlindMode: panels["graph"].stats["connections"].resetOptions(conn)
#panels["graph"].stats["bandwidth"].resetOptions()
@@ -749,9 +726,6 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
isUnresponsive = False
log.log(log.NOTICE, "Relay resumed")
- if CONFIG["features.connection.oldPanel"]:
- panels["conn"].reset()
-
# TODO: part two of hack to prevent premature drawing by log panel
if page == 0 and not isPaused: panels["log"].setPaused(False)
@@ -844,11 +818,11 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
# stops panel daemons
panels["header"].stop()
- if CONFIG["features.connection.newPanel"]: panels["conn2"].stop()
+ panels["conn"].stop()
panels["log"].stop()
panels["header"].join()
- if CONFIG["features.connection.newPanel"]: panels["conn2"].join()
+ panels["conn"].join()
panels["log"].join()
# joins on utility daemon threads - this might take a moment since
@@ -871,15 +845,10 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
if key == curses.KEY_LEFT: page = (page - 1) % len(PAGES)
else: page = (page + 1) % len(PAGES)
- # skip connections listings if it's disabled
- while True:
- if page == 1 and (isBlindMode or not CONFIG["features.connection.oldPanel"]):
- if key == curses.KEY_LEFT: page = (page - 1) % len(PAGES)
- else: page = (page + 1) % len(PAGES)
- elif page == 2 and (isBlindMode or not CONFIG["features.connection.newPanel"]):
- if key == curses.KEY_LEFT: page = (page - 1) % len(PAGES)
- else: page = (page + 1) % len(PAGES)
- else: break
+ # skip connections listing if it's disabled
+ if page == 1 and isBlindMode:
+ if key == curses.KEY_LEFT: page = (page - 1) % len(PAGES)
+ else: page = (page + 1) % len(PAGES)
# pauses panels that aren't visible to prevent events from accumilating
# (otherwise they'll wait on the curses lock which might get demanding)
@@ -977,37 +946,11 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
popup.addfstr(1, 41, "<b>down arrow</b>: scroll down a line")
popup.addfstr(2, 2, "<b>page up</b>: scroll up a page")
popup.addfstr(2, 41, "<b>page down</b>: scroll down a page")
- popup.addfstr(3, 2, "<b>enter</b>: connection details")
- popup.addfstr(3, 41, "<b>d</b>: raw consensus descriptor")
-
- listingType = connPanel.LIST_LABEL[panels["conn"].listingType].lower()
- popup.addfstr(4, 2, "<b>l</b>: listed identity (<b>%s</b>)" % listingType)
-
- resolverUtil = connections.getResolver("tor").overwriteResolver
- if resolverUtil == None: resolverUtil = "auto"
- popup.addfstr(4, 41, "<b>u</b>: resolving utility (<b>%s</b>)" % resolverUtil)
-
- if CONFIG["features.connection.oldPanel"]:
- allowDnsLabel = "allow" if panels["conn"].allowDNS else "disallow"
- else: allowDnsLabel = "disallow"
- popup.addfstr(5, 2, "<b>r</b>: permit DNS resolution (<b>%s</b>)" % allowDnsLabel)
-
- popup.addfstr(5, 41, "<b>s</b>: sort ordering")
- popup.addfstr(6, 2, "<b>c</b>: client circuits")
-
- #popup.addfstr(5, 41, "c: toggle cursor (<b>%s</b>)" % ("on" if panels["conn"].isCursorEnabled else "off"))
-
- pageOverrideKeys = (ord('d'), ord('l'), ord('s'), ord('c'))
- elif page == 2:
- popup.addfstr(1, 2, "<b>up arrow</b>: scroll up a line")
- popup.addfstr(1, 41, "<b>down arrow</b>: scroll down a line")
- popup.addfstr(2, 2, "<b>page up</b>: scroll up a page")
- popup.addfstr(2, 41, "<b>page down</b>: scroll down a page")
popup.addfstr(3, 2, "<b>enter</b>: edit configuration option")
popup.addfstr(3, 41, "<b>d</b>: raw consensus descriptor")
- listingType = panels["conn2"]._listingType.lower()
+ listingType = panels["conn"]._listingType.lower()
popup.addfstr(4, 2, "<b>l</b>: listed identity (<b>%s</b>)" % listingType)
popup.addfstr(4, 41, "<b>s</b>: sort ordering")
@@ -1017,7 +960,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
popup.addfstr(5, 2, "<b>u</b>: resolving utility (<b>%s</b>)" % resolverUtil)
pageOverrideKeys = (ord('d'), ord('l'), ord('s'), ord('u'))
- elif page == 3:
+ elif page == 2:
popup.addfstr(1, 2, "<b>up arrow</b>: scroll up a line")
popup.addfstr(1, 41, "<b>down arrow</b>: scroll down a line")
popup.addfstr(2, 2, "<b>page up</b>: scroll up a page")
@@ -1031,7 +974,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
popup.addfstr(4, 2, "<b>r</b>: reload torrc")
popup.addfstr(4, 41, "<b>x</b>: reset tor (issue sighup)")
- elif page == 4:
+ elif page == 3:
popup.addfstr(1, 2, "<b>up arrow</b>: scroll up a line")
popup.addfstr(1, 41, "<b>down arrow</b>: scroll down a line")
popup.addfstr(2, 2, "<b>page up</b>: scroll up a page")
@@ -1292,220 +1235,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
setPauseState(panels, isPaused, page)
finally:
panel.CURSES_LOCK.release()
- elif CONFIG["features.connection.oldPanel"] and key == 27 and panels["conn"].listingType == connPanel.LIST_HOSTNAME and panels["control"].resolvingCounter != -1:
- # canceling hostname resolution (esc on any page)
- panels["conn"].listingType = connPanel.LIST_IP
- panels["control"].resolvingCounter = -1
- hostnames.setPaused(True)
- panels["conn"].sortConnections()
- elif page == 1 and panels["conn"].isCursorEnabled and uiTools.isSelectionKey(key):
- # TODO: deprecated when migrated to the new connection panel, thought as
- # well keep around until there's a counterpart for hostname fetching
-
- # provides details on selected connection
- panel.CURSES_LOCK.acquire()
- try:
- setPauseState(panels, isPaused, page, True)
- popup = panels["popup"]
-
- # reconfigures connection panel to accomidate details dialog
- panels["conn"].showLabel = False
- panels["conn"].showingDetails = True
- panels["conn"].redraw(True)
-
- hostnames.setPaused(not panels["conn"].allowDNS)
- relayLookupCache = {} # temporary cache of entry -> (ns data, desc data)
-
- curses.cbreak() # wait indefinitely for key presses (no timeout)
- key = 0
-
- while not uiTools.isSelectionKey(key):
- popup.clear()
- popup.win.box()
- popup.addstr(0, 0, "Connection Details:", curses.A_STANDOUT)
-
- selection = panels["conn"].cursorSelection
- if not selection or not panels["conn"].connections: break
- selectionColor = connPanel.TYPE_COLORS[selection[connPanel.CONN_TYPE]]
- format = uiTools.getColor(selectionColor) | curses.A_BOLD
-
- selectedIp = selection[connPanel.CONN_F_IP]
- selectedPort = selection[connPanel.CONN_F_PORT]
- selectedIsPrivate = selection[connPanel.CONN_PRIVATE]
-
- addrLabel = "address: %s:%s" % (selectedIp, selectedPort)
-
- if selection[connPanel.CONN_TYPE] == "family" and int(selection[connPanel.CONN_L_PORT]) > 65535:
- # unresolved family entry - unknown ip/port
- addrLabel = "address: unknown"
-
- if selectedIsPrivate: hostname = None
- else:
- try: hostname = hostnames.resolve(selectedIp)
- except ValueError: hostname = "unknown" # hostname couldn't be resolved
-
- if hostname == None:
- if hostnames.isPaused() or selectedIsPrivate: hostname = "DNS resolution disallowed"
- else:
- # if hostname is still being resolved refresh panel every half-second until it's completed
- curses.halfdelay(5)
- hostname = "resolving..."
- elif len(hostname) > 73 - len(addrLabel):
- # hostname too long - truncate
- hostname = "%s..." % hostname[:70 - len(addrLabel)]
-
- if selectedIsPrivate:
- popup.addstr(1, 2, "address: <scrubbed> (unknown)", format)
- popup.addstr(2, 2, "locale: ??", format)
- popup.addstr(3, 2, "No consensus data found", format)
- else:
- popup.addstr(1, 2, "%s (%s)" % (addrLabel, hostname), format)
-
- locale = selection[connPanel.CONN_COUNTRY]
- popup.addstr(2, 2, "locale: %s" % locale, format)
-
- # provides consensus data for selection (needs fingerprint to get anywhere...)
- fingerprint = panels["conn"].getFingerprint(selectedIp, selectedPort)
-
- if fingerprint == "UNKNOWN":
- if selectedIp not in panels["conn"].fingerprintMappings.keys():
- # no consensus entry for this ip address
- popup.addstr(3, 2, "No consensus data found", format)
- else:
- # couldn't resolve due to multiple matches - list them all
- popup.addstr(3, 2, "Muliple matches, possible fingerprints are:", format)
- matchings = panels["conn"].fingerprintMappings[selectedIp]
-
- line = 4
- for (matchPort, matchFingerprint, matchNickname) in matchings:
- popup.addstr(line, 2, "%i. or port: %-5s fingerprint: %s" % (line - 3, matchPort, matchFingerprint), format)
- line += 1
-
- if line == 7 and len(matchings) > 4:
- popup.addstr(8, 2, "... %i more" % len(matchings) - 3, format)
- break
- else:
- # fingerprint found - retrieve related data
- lookupErrored = False
- if selection in relayLookupCache.keys(): nsEntry, descEntry = relayLookupCache[selection]
- else:
- try:
- nsCall = conn.get_network_status("id/%s" % fingerprint)
- if len(nsCall) == 0: raise TorCtl.ErrorReply() # no results provided
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed):
- # ns lookup fails or provides empty results - can happen with
- # localhost lookups if relay's having problems (orport not
- # reachable) and this will be empty if network consensus
- # couldn't be fetched
- lookupErrored = True
-
- if not lookupErrored and nsCall:
- if len(nsCall) > 1:
- # multiple records for fingerprint (shouldn't happen)
- log.log(log.WARN, "Multiple consensus entries for fingerprint: %s" % fingerprint)
-
- nsEntry = nsCall[0]
-
- try:
- descLookupCmd = "desc/id/%s" % fingerprint
- descEntry = TorCtl.Router.build_from_desc(conn.get_info(descLookupCmd)[descLookupCmd].split("\n"), nsEntry)
- relayLookupCache[selection] = (nsEntry, descEntry)
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): lookupErrored = True # desc lookup failed
-
- if lookupErrored:
- popup.addstr(3, 2, "Unable to retrieve consensus data", format)
- else:
- popup.addstr(2, 15, "fingerprint: %s" % fingerprint, format)
-
- nickname = panels["conn"].getNickname(selectedIp, selectedPort)
- dirPortLabel = "dirport: %i" % nsEntry.dirport if nsEntry.dirport else ""
- popup.addstr(3, 2, "nickname: %-25s orport: %-10i %s" % (nickname, nsEntry.orport, dirPortLabel), format)
-
- popup.addstr(4, 2, "published: %-24s os: %-14s version: %s" % (descEntry.published, descEntry.os, descEntry.version), format)
- popup.addstr(5, 2, "flags: %s" % ", ".join(nsEntry.flags), format)
-
- exitLine = ", ".join([str(k) for k in descEntry.exitpolicy])
- if len(exitLine) > 63: exitLine = "%s..." % exitLine[:60]
- popup.addstr(6, 2, "exit policy: %s" % exitLine, format)
-
- if descEntry.contact:
- # clears up some common obscuring
- contactAddr = descEntry.contact
- obscuring = [(" at ", "@"), (" AT ", "@"), ("AT", "@"), (" dot ", "."), (" DOT ", ".")]
- for match, replace in obscuring: contactAddr = contactAddr.replace(match, replace)
- if len(contactAddr) > 67: contactAddr = "%s..." % contactAddr[:64]
- popup.addstr(7, 2, "contact: %s" % contactAddr, format)
-
- popup.refresh()
- key = stdscr.getch()
-
- if key == curses.KEY_RIGHT: key = curses.KEY_DOWN
- elif key == curses.KEY_LEFT: key = curses.KEY_UP
-
- if key in (curses.KEY_DOWN, curses.KEY_UP, curses.KEY_PPAGE, curses.KEY_NPAGE):
- panels["conn"].handleKey(key)
- elif key in (ord('d'), ord('D')):
- descriptorPopup.showDescriptorPopup(panels["popup"], stdscr, panels["conn"])
- panels["conn"].redraw(True)
-
- panels["conn"].showLabel = True
- panels["conn"].showingDetails = False
- hostnames.setPaused(not panels["conn"].allowDNS and panels["conn"].listingType == connPanel.LIST_HOSTNAME)
- setPauseState(panels, isPaused, page)
- curses.halfdelay(REFRESH_RATE * 10) # reset normal pausing behavior
- finally:
- panel.CURSES_LOCK.release()
- elif page == 1 and panels["conn"].isCursorEnabled and key in (ord('d'), ord('D')):
- # presents popup for raw consensus data
- panel.CURSES_LOCK.acquire()
- try:
- setPauseState(panels, isPaused, page, True)
- curses.cbreak() # wait indefinitely for key presses (no timeout)
- panels["conn"].showLabel = False
- panels["conn"].redraw(True)
-
- descriptorPopup.showDescriptorPopup(panels["popup"], stdscr, panels["conn"])
-
- setPauseState(panels, isPaused, page)
- curses.halfdelay(REFRESH_RATE * 10) # reset normal pausing behavior
- panels["conn"].showLabel = True
- finally:
- panel.CURSES_LOCK.release()
- elif page == 1 and (key == ord('l') or key == ord('L')):
- # provides menu to pick identification info listed for connections
- optionTypes = [connPanel.LIST_IP, connPanel.LIST_HOSTNAME, connPanel.LIST_FINGERPRINT, connPanel.LIST_NICKNAME]
- options = [connPanel.LIST_LABEL[sortType] for sortType in optionTypes]
- initialSelection = panels["conn"].listingType # enums correspond to index
-
- # hides top label of conn panel and pauses panels
- panels["conn"].showLabel = False
- panels["conn"].redraw(True)
- setPauseState(panels, isPaused, page, True)
-
- selection = showMenu(stdscr, panels["popup"], "List By:", options, initialSelection)
-
- # reverts changes made for popup
- panels["conn"].showLabel = True
- setPauseState(panels, isPaused, page)
-
- # applies new setting
- if selection != -1 and optionTypes[selection] != panels["conn"].listingType:
- panels["conn"].listingType = optionTypes[selection]
-
- if panels["conn"].listingType == connPanel.LIST_HOSTNAME:
- curses.halfdelay(10) # refreshes display every second until done resolving
- panels["control"].resolvingCounter = hostnames.getRequestCount() - hostnames.getPendingCount()
-
- hostnames.setPaused(not panels["conn"].allowDNS)
- for connEntry in panels["conn"].connections:
- try: hostnames.resolve(connEntry[connPanel.CONN_F_IP])
- except ValueError: pass
- else:
- panels["control"].resolvingCounter = -1
- hostnames.setPaused(True)
-
- panels["conn"].sortConnections()
- elif page in (1, 2) and (key == ord('u') or key == ord('U')):
+ elif page == 1 and (key == ord('u') or key == ord('U')):
# provides menu to pick identification resolving utility
options = ["auto"] + connections.Resolver.values()
@@ -1514,7 +1244,8 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
else: initialSelection = options.index(currentOverwrite)
# hides top label of conn panel and pauses panels
- panels["conn"].showLabel = False
+ panelTitle = panels["conn"]._title
+ panels["conn"]._title = ""
panels["conn"].redraw(True)
setPauseState(panels, isPaused, page, True)
@@ -1522,133 +1253,67 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
selectedOption = options[selection] if selection != "auto" else None
# reverts changes made for popup
- panels["conn"].showLabel = True
+ panels["conn"]._title = panelTitle
setPauseState(panels, isPaused, page)
# applies new setting
if selection != -1 and selectedOption != connections.getResolver("tor").overwriteResolver:
connections.getResolver("tor").overwriteResolver = selectedOption
- elif page == 1 and (key == ord('s') or key == ord('S')):
- # set ordering for connection listing
- titleLabel = "Connection Ordering:"
- options = [connPanel.getSortLabel(i) for i in range(9)]
- oldSelection = [connPanel.getSortLabel(entry) for entry in panels["conn"].sortOrdering]
- optionColors = dict([connPanel.getSortLabel(i, True) for i in range(9)])
- results = showSortDialog(stdscr, panels, isPaused, page, titleLabel, options, oldSelection, optionColors)
-
- if results:
- # converts labels back to enums
- resultEnums = [connPanel.getSortType(entry) for entry in results]
- panels["conn"].sortOrdering = resultEnums
- panels["conn"].sortConnections()
-
- # TODO: not necessary until the connection panel rewrite
- #panels["conn"].redraw(True)
- elif page == 1 and (key == ord('c') or key == ord('C')):
- # displays popup with client circuits
- clientCircuits = None
- try:
- clientCircuits = conn.get_info("circuit-status")["circuit-status"].split("\n")
- except (socket.error, TorCtl.ErrorReply, TorCtl.TorCtlClosed): pass
-
- maxEntryLength = 0
- if clientCircuits:
- for clientEntry in clientCircuits: maxEntryLength = max(len(clientEntry), maxEntryLength)
-
- panel.CURSES_LOCK.acquire()
- try:
- setPauseState(panels, isPaused, page, True)
-
- # makes sure there's room for the longest entry
- popup = panels["popup"]
- if clientCircuits and maxEntryLength + 4 > popup.getPreferredSize()[1]:
- popup.height = max(popup.height, len(clientCircuits) + 3)
- popup.recreate(stdscr, maxEntryLength + 4)
-
- # lists commands
- popup.clear()
- popup.win.box()
- popup.addstr(0, 0, "Client Circuits:", curses.A_STANDOUT)
-
- if clientCircuits == None:
- popup.addstr(1, 2, "Unable to retireve current circuits")
- elif len(clientCircuits) == 1 and clientCircuits[0] == "":
- popup.addstr(1, 2, "No active client circuits")
- else:
- line = 1
- for clientEntry in clientCircuits:
- popup.addstr(line, 2, clientEntry)
- line += 1
-
- popup.addstr(popup.height - 2, 2, "Press any key...")
- popup.refresh()
-
- curses.cbreak()
- stdscr.getch()
- curses.halfdelay(REFRESH_RATE * 10)
-
- # reverts popup dimensions
- popup.height = 9
- popup.recreate(stdscr, 80)
-
- setPauseState(panels, isPaused, page)
- finally:
- panel.CURSES_LOCK.release()
- elif page == 2 and key in (ord('d'), ord('D')):
+ elif page == 1 and key in (ord('d'), ord('D')):
# presents popup for raw consensus data
panel.CURSES_LOCK.acquire()
try:
setPauseState(panels, isPaused, page, True)
curses.cbreak() # wait indefinitely for key presses (no timeout)
- panelTitle = panels["conn2"]._title
- panels["conn2"]._title = ""
- panels["conn2"].redraw(True)
+ panelTitle = panels["conn"]._title
+ panels["conn"]._title = ""
+ panels["conn"].redraw(True)
- descriptorPopup.showDescriptorPopup(panels["popup"], stdscr, panels["conn2"], True)
+ descriptorPopup.showDescriptorPopup(panels["popup"], stdscr, panels["conn"])
- panels["conn2"]._title = panelTitle
+ panels["conn"]._title = panelTitle
setPauseState(panels, isPaused, page)
curses.halfdelay(REFRESH_RATE * 10) # reset normal pausing behavior
finally:
panel.CURSES_LOCK.release()
- elif page == 2 and (key == ord('l') or key == ord('L')):
+ elif page == 1 and (key == ord('l') or key == ord('L')):
# provides a menu to pick the primary information we list connections by
options = interface.connections.entries.ListingType.values()
# dropping the HOSTNAME listing type until we support displaying that content
options.remove(interface.connections.entries.ListingType.HOSTNAME)
- initialSelection = options.index(panels["conn2"]._listingType)
+ initialSelection = options.index(panels["conn"]._listingType)
# hides top label of connection panel and pauses the display
- panelTitle = panels["conn2"]._title
- panels["conn2"]._title = ""
- panels["conn2"].redraw(True)
+ panelTitle = panels["conn"]._title
+ panels["conn"]._title = ""
+ panels["conn"].redraw(True)
setPauseState(panels, isPaused, page, True)
selection = showMenu(stdscr, panels["popup"], "List By:", options, initialSelection)
# reverts changes made for popup
- panels["conn2"]._title = panelTitle
+ panels["conn"]._title = panelTitle
setPauseState(panels, isPaused, page)
# applies new setting
- if selection != -1 and options[selection] != panels["conn2"]._listingType:
- panels["conn2"].setListingType(options[selection])
- panels["conn2"].redraw(True)
- elif page == 2 and (key == ord('s') or key == ord('S')):
+ if selection != -1 and options[selection] != panels["conn"]._listingType:
+ panels["conn"].setListingType(options[selection])
+ panels["conn"].redraw(True)
+ elif page == 1 and (key == ord('s') or key == ord('S')):
# set ordering for connection options
titleLabel = "Connection Ordering:"
options = interface.connections.entries.SortAttr.values()
- oldSelection = panels["conn2"]._sortOrdering
+ oldSelection = panels["conn"]._sortOrdering
optionColors = dict([(attr, interface.connections.entries.SORT_COLORS[attr]) for attr in options])
results = showSortDialog(stdscr, panels, isPaused, page, titleLabel, options, oldSelection, optionColors)
if results:
- panels["conn2"].setSortOrder(results)
+ panels["conn"].setSortOrder(results)
- panels["conn2"].redraw(True)
- elif page == 3 and (key == ord('c') or key == ord('C')) and False:
+ panels["conn"].redraw(True)
+ elif page == 2 and (key == ord('c') or key == ord('C')) and False:
# TODO: disabled for now (probably gonna be going with separate pages
# rather than popup menu)
# provides menu to pick config being displayed
@@ -1671,7 +1336,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
if selection != -1: panels["torrc"].setConfigType(selection)
selectiveRefresh(panels, page)
- elif page == 3 and (key == ord('w') or key == ord('W')):
+ elif page == 2 and (key == ord('w') or key == ord('W')):
# display a popup for saving the current configuration
panel.CURSES_LOCK.acquire()
try:
@@ -1800,7 +1465,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
panel.CURSES_LOCK.release()
panels["config"].redraw(True)
- elif page == 3 and (key == ord('s') or key == ord('S')):
+ elif page == 2 and (key == ord('s') or key == ord('S')):
# set ordering for config options
titleLabel = "Config Option Ordering:"
options = [configPanel.FIELD_ATTR[field][0] for field in configPanel.Field.values()]
@@ -1821,7 +1486,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
panels["config"].setSortOrder(resultEnums)
panels["config"].redraw(True)
- elif page == 3 and uiTools.isSelectionKey(key):
+ elif page == 2 and uiTools.isSelectionKey(key):
# let the user edit the configuration value, unchanged if left blank
panel.CURSES_LOCK.acquire()
try:
@@ -1877,7 +1542,7 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
setPauseState(panels, isPaused, page)
finally:
panel.CURSES_LOCK.release()
- elif page == 4 and key == ord('r') or key == ord('R'):
+ elif page == 3 and key == ord('r') or key == ord('R'):
# reloads torrc, providing a notice if successful or not
loadedTorrc = torConfig.getTorrc()
loadedTorrc.getLock().acquire()
@@ -1907,10 +1572,8 @@ def drawTorMonitor(stdscr, startTime, loggedEvents, isBlindMode):
elif page == 1:
panels["conn"].handleKey(key)
elif page == 2:
- panels["conn2"].handleKey(key)
- elif page == 3:
panels["config"].handleKey(key)
- elif page == 4:
+ elif page == 3:
panels["torrc"].handleKey(key)
def startTorMonitor(startTime, loggedEvents, isBlindMode):
diff --git a/src/interface/descriptorPopup.py b/src/interface/descriptorPopup.py
index 7d51ee5..cdc959d 100644
--- a/src/interface/descriptorPopup.py
+++ b/src/interface/descriptorPopup.py
@@ -8,7 +8,6 @@ import curses
from TorCtl import TorCtl
import controller
-import connPanel
import connections.connEntry
from util import panel, torTools, uiTools
@@ -69,7 +68,7 @@ class PopupProperties:
elif key == curses.KEY_PPAGE: self.scroll = max(self.scroll - height, 0)
elif key == curses.KEY_NPAGE: self.scroll = max(0, min(self.scroll + height, len(self.text) - height))
-def showDescriptorPopup(popup, stdscr, connectionPanel, isNewPanel=False):
+def showDescriptorPopup(popup, stdscr, connectionPanel):
"""
Presents consensus descriptor in popup window with the following controls:
Up, Down, Page Up, Page Down - scroll descriptor
@@ -83,18 +82,11 @@ def showDescriptorPopup(popup, stdscr, connectionPanel, isNewPanel=False):
if not panel.CURSES_LOCK.acquire(False): return
try:
while isVisible:
- if isNewPanel:
- selection = connectionPanel._scroller.getCursorSelection(connectionPanel._entryLines)
- if not selection: break
- fingerprint = selection.foreign.getFingerprint()
- entryColor = connections.connEntry.CATEGORY_COLOR[selection.getType()]
- properties.reset(fingerprint, entryColor)
- else:
- selection = connectionPanel.cursorSelection
- if not selection or not connectionPanel.connections: break
- fingerprint = connectionPanel.getFingerprint(selection[connPanel.CONN_F_IP], selection[connPanel.CONN_F_PORT])
- entryColor = connPanel.TYPE_COLORS[selection[connPanel.CONN_TYPE]]
- properties.reset(fingerprint, entryColor)
+ selection = connectionPanel._scroller.getCursorSelection(connectionPanel._entryLines)
+ if not selection: break
+ fingerprint = selection.foreign.getFingerprint()
+ entryColor = connections.connEntry.CATEGORY_COLOR[selection.getType()]
+ properties.reset(fingerprint, entryColor)
# constrains popup size to match text
width, height = 0, 0
1
0

26 Apr '11
commit 47f472510fab2bc2c06e53ee932b13cfe1bdcbe4
Merge: 6a726d3 bb6d45a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 12:49:58 2011 -0400
Merge remote-tracking branch 'origin/maint-0.2.2'
Conflicts:
src/or/rephist.c
changes/bug2899 | 4 ++++
src/or/rephist.c | 42 ++++++++++++++++++++++--------------------
src/or/routerlist.c | 4 ++--
3 files changed, 28 insertions(+), 22 deletions(-)
1
0

26 Apr '11
commit bb6d45af1fc738b9f71e798cde6c7564172b6e04
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 12:46:07 2011 -0400
Downgrade notice to info when downloading a cert.
---
changes/bug2899 | 4 ++++
src/or/routerlist.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/changes/bug2899 b/changes/bug2899
new file mode 100644
index 0000000..6af86d0
--- /dev/null
+++ b/changes/bug2899
@@ -0,0 +1,4 @@
+ - Minor bugfixes:
+ o Downgrade "no current certificates known for authority" message from
+ Notice to Info. Bugfix on 0.2.0.10-alpha; fixes bug 2899.
+
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 4deff53..c02654f 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -531,8 +531,8 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
if (!found &&
download_status_is_ready(&cl->dl_status, now,MAX_CERT_DL_FAILURES) &&
!digestmap_get(pending, ds->v3_identity_digest)) {
- log_notice(LD_DIR, "No current certificate known for authority %s; "
- "launching request.", ds->nickname);
+ log_info(LD_DIR, "No current certificate known for authority %s; "
+ "launching request.", ds->nickname);
smartlist_add(missing_digests, ds->v3_identity_digest);
}
} SMARTLIST_FOREACH_END(ds);
1
0

26 Apr '11
commit 9d673dcd206289bceb8f5ff527e63336ef0a50b9
Author: Roger Dingledine <arma(a)torproject.org>
Date: Tue Apr 26 11:28:49 2011 -0400
fix some comments before they create conflicts
---
src/or/rephist.c | 44 +++++++++++++++++++++++---------------------
1 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 524cd1d..5703e3e 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -992,10 +992,10 @@ find_next_with(smartlist_t *sl, int i, const char *prefix)
return -1;
}
-/** How many bad times has parse_possibly_bad_iso_time parsed? */
+/** How many bad times has parse_possibly_bad_iso_time() parsed? */
static int n_bogus_times = 0;
/** Parse the ISO-formatted time in <b>s</b> into *<b>time_out</b>, but
- * rounds any pre-1970 date to Jan 1, 1970. */
+ * round any pre-1970 date to Jan 1, 1970. */
static int
parse_possibly_bad_iso_time(const char *s, time_t *time_out)
{
@@ -1288,7 +1288,7 @@ commit_max(bw_array_t *b)
b->total_in_period = 0;
}
-/** Shift the current observation time of 'b' forward by one second. */
+/** Shift the current observation time of <b>b</b> forward by one second. */
static INLINE void
advance_obs(bw_array_t *b)
{
@@ -1318,16 +1318,16 @@ advance_obs(bw_array_t *b)
static INLINE void
add_obs(bw_array_t *b, time_t when, uint64_t n)
{
- /* Don't record data in the past. */
- if (when<b->cur_obs_time)
- return;
+ if (when < b->cur_obs_time)
+ return; /* Don't record data in the past. */
+
/* If we're currently adding observations for an earlier second than
* 'when', advance b->cur_obs_time and b->cur_obs_idx by an
- * appropriate number of seconds, and do all the other housekeeping */
- while (when>b->cur_obs_time) {
+ * appropriate number of seconds, and do all the other housekeeping. */
+ while (when > b->cur_obs_time) {
/* Doing this one second at a time is potentially inefficient, if we start
with a state file that is very old. Fortunately, it doesn't seem to
- show up in profiles, so we can just ignore it for now. */
+ show up in profiles, so we can just ignore it for now. */
advance_obs(b);
}
@@ -1375,7 +1375,7 @@ bw_arrays_init(void)
dir_write_array = bw_array_new();
}
-/** We read <b>num_bytes</b> more bytes in second <b>when</b>.
+/** Remember that we read <b>num_bytes</b> bytes in second <b>when</b>.
*
* Add num_bytes to the current running total for <b>when</b>.
*
@@ -1396,7 +1396,7 @@ rep_hist_note_bytes_written(size_t num_bytes, time_t when)
add_obs(write_array, when, num_bytes);
}
-/** We wrote <b>num_bytes</b> more bytes in second <b>when</b>.
+/** Remember that we wrote <b>num_bytes</b> bytes in second <b>when</b>.
* (like rep_hist_note_bytes_written() above)
*/
void
@@ -1406,8 +1406,8 @@ rep_hist_note_bytes_read(size_t num_bytes, time_t when)
add_obs(read_array, when, num_bytes);
}
-/** We wrote <b>num_bytes</b> more directory bytes in second <b>when</b>.
- * (like rep_hist_note_bytes_written() above)
+/** Remember that we wrote <b>num_bytes</b> directory bytes in second
+ * <b>when</b>. (like rep_hist_note_bytes_written() above)
*/
void
rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when)
@@ -1415,8 +1415,8 @@ rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when)
add_obs(dir_write_array, when, num_bytes);
}
-/** We read <b>num_bytes</b> more directory bytes in second <b>when</b>.
- * (like rep_hist_note_bytes_written() above)
+/** Remember that we read <b>num_bytes</b> directory bytes in second
+ * <b>when</b>. (like rep_hist_note_bytes_written() above)
*/
void
rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when)
@@ -1511,7 +1511,8 @@ rep_hist_fill_bandwidth_history(char *buf, size_t len, const bw_array_t *b)
}
/** Allocate and return lines for representing this server's bandwidth
- * history in its descriptor.
+ * history in its descriptor. We publish these lines in our extra-info
+ * descriptor.
*/
char *
rep_hist_get_bandwidth_lines(void)
@@ -1559,7 +1560,7 @@ rep_hist_get_bandwidth_lines(void)
}
/** Write a single bw_array_t into the Values, Ends, Interval, and Maximum
- * entries of an or_state_t. */
+ * entries of an or_state_t. Done before writing out a new state file. */
static void
rep_hist_update_bwhist_state_section(or_state_t *state,
const bw_array_t *b,
@@ -1619,7 +1620,8 @@ rep_hist_update_bwhist_state_section(or_state_t *state,
smartlist_add(*s_maxima, cp);
}
-/** Update <b>state</b> with the newest bandwidth history. */
+/** Update <b>state</b> with the newest bandwidth history. Done before
+ * writing out a new state file. */
void
rep_hist_update_state(or_state_t *state)
{
@@ -1643,7 +1645,7 @@ rep_hist_update_state(or_state_t *state)
}
/** Load a single bw_array_t from its Values, Ends, Maxima, and Interval
- * entries in an or_state_t. */
+ * entries in an or_state_t. Done while reading the state file. */
static int
rep_hist_load_bwhist_state_section(bw_array_t *b,
const smartlist_t *s_values,
@@ -1718,7 +1720,7 @@ rep_hist_load_bwhist_state_section(bw_array_t *b,
return retval;
}
-/** Set bandwidth history from our saved state. */
+/** Set bandwidth history from the state file we just loaded. */
int
rep_hist_load_state(or_state_t *state, char **err)
{
@@ -1766,7 +1768,7 @@ static smartlist_t *predicted_ports_times=NULL;
static void
add_predicted_port(time_t now, uint16_t port)
{
- /* XXXX we could just use uintptr_t here, I think. */
+ /* XXXX we could just use uintptr_t here, I think. -NM */
uint16_t *tmp_port = tor_malloc(sizeof(uint16_t));
time_t *tmp_time = tor_malloc(sizeof(time_t));
*tmp_port = port;
1
0

[tor/maint-0.2.2] Downgrade notice to info when downloading a cert.
by nickm@torproject.org 26 Apr '11
by nickm@torproject.org 26 Apr '11
26 Apr '11
commit bb6d45af1fc738b9f71e798cde6c7564172b6e04
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 12:46:07 2011 -0400
Downgrade notice to info when downloading a cert.
---
changes/bug2899 | 4 ++++
src/or/routerlist.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/changes/bug2899 b/changes/bug2899
new file mode 100644
index 0000000..6af86d0
--- /dev/null
+++ b/changes/bug2899
@@ -0,0 +1,4 @@
+ - Minor bugfixes:
+ o Downgrade "no current certificates known for authority" message from
+ Notice to Info. Bugfix on 0.2.0.10-alpha; fixes bug 2899.
+
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 4deff53..c02654f 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -531,8 +531,8 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
if (!found &&
download_status_is_ready(&cl->dl_status, now,MAX_CERT_DL_FAILURES) &&
!digestmap_get(pending, ds->v3_identity_digest)) {
- log_notice(LD_DIR, "No current certificate known for authority %s; "
- "launching request.", ds->nickname);
+ log_info(LD_DIR, "No current certificate known for authority %s; "
+ "launching request.", ds->nickname);
smartlist_add(missing_digests, ds->v3_identity_digest);
}
} SMARTLIST_FOREACH_END(ds);
1
0

26 Apr '11
commit 12077adddb88f1a2e7ae2f8e0078c54ce3e70fd2
Author: Damian Johnson <atagar(a)torproject.org>
Date: Tue Apr 26 08:32:50 2011 -0700
fix: Accounting for multiple results from lsof
When querying lsof from the python process this can provide multiple results
with the same pid. The second is from the lsof query itself (this was observed
with an earlier change for querying our own process). Accounting for this by
checking all pid results from the query to see if they're in agreement.
---
src/util/torTools.py | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/util/torTools.py b/src/util/torTools.py
index 08b04c0..f4a29af 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -224,8 +224,20 @@ def getPid(controlPort=9051, pidFilePath=None):
try:
results = sysTools.call("lsof -wnPi | egrep \"^tor.*:%i\"" % controlPort)
- if len(results) == 1 and len(results[0].split()) > 1:
- pid = results[0].split()[1]
+
+ # This can result in multiple entries with the same pid (maybe from the
+ # query itself?). Checking all lines to see if they have the same pid.
+
+ if results:
+ pid = ""
+
+ for line in results:
+ lineComp = line.split()
+
+ if len(lineComp) >= 2 and (not pid or lineComp[1] == pid):
+ pid = lineComp[1]
+ else: raise IOError
+
if pid.isdigit(): return pid
except IOError: pass
1
0

26 Apr '11
commit 9d673dcd206289bceb8f5ff527e63336ef0a50b9
Author: Roger Dingledine <arma(a)torproject.org>
Date: Tue Apr 26 11:28:49 2011 -0400
fix some comments before they create conflicts
---
src/or/rephist.c | 44 +++++++++++++++++++++++---------------------
1 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 524cd1d..5703e3e 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -992,10 +992,10 @@ find_next_with(smartlist_t *sl, int i, const char *prefix)
return -1;
}
-/** How many bad times has parse_possibly_bad_iso_time parsed? */
+/** How many bad times has parse_possibly_bad_iso_time() parsed? */
static int n_bogus_times = 0;
/** Parse the ISO-formatted time in <b>s</b> into *<b>time_out</b>, but
- * rounds any pre-1970 date to Jan 1, 1970. */
+ * round any pre-1970 date to Jan 1, 1970. */
static int
parse_possibly_bad_iso_time(const char *s, time_t *time_out)
{
@@ -1288,7 +1288,7 @@ commit_max(bw_array_t *b)
b->total_in_period = 0;
}
-/** Shift the current observation time of 'b' forward by one second. */
+/** Shift the current observation time of <b>b</b> forward by one second. */
static INLINE void
advance_obs(bw_array_t *b)
{
@@ -1318,16 +1318,16 @@ advance_obs(bw_array_t *b)
static INLINE void
add_obs(bw_array_t *b, time_t when, uint64_t n)
{
- /* Don't record data in the past. */
- if (when<b->cur_obs_time)
- return;
+ if (when < b->cur_obs_time)
+ return; /* Don't record data in the past. */
+
/* If we're currently adding observations for an earlier second than
* 'when', advance b->cur_obs_time and b->cur_obs_idx by an
- * appropriate number of seconds, and do all the other housekeeping */
- while (when>b->cur_obs_time) {
+ * appropriate number of seconds, and do all the other housekeeping. */
+ while (when > b->cur_obs_time) {
/* Doing this one second at a time is potentially inefficient, if we start
with a state file that is very old. Fortunately, it doesn't seem to
- show up in profiles, so we can just ignore it for now. */
+ show up in profiles, so we can just ignore it for now. */
advance_obs(b);
}
@@ -1375,7 +1375,7 @@ bw_arrays_init(void)
dir_write_array = bw_array_new();
}
-/** We read <b>num_bytes</b> more bytes in second <b>when</b>.
+/** Remember that we read <b>num_bytes</b> bytes in second <b>when</b>.
*
* Add num_bytes to the current running total for <b>when</b>.
*
@@ -1396,7 +1396,7 @@ rep_hist_note_bytes_written(size_t num_bytes, time_t when)
add_obs(write_array, when, num_bytes);
}
-/** We wrote <b>num_bytes</b> more bytes in second <b>when</b>.
+/** Remember that we wrote <b>num_bytes</b> bytes in second <b>when</b>.
* (like rep_hist_note_bytes_written() above)
*/
void
@@ -1406,8 +1406,8 @@ rep_hist_note_bytes_read(size_t num_bytes, time_t when)
add_obs(read_array, when, num_bytes);
}
-/** We wrote <b>num_bytes</b> more directory bytes in second <b>when</b>.
- * (like rep_hist_note_bytes_written() above)
+/** Remember that we wrote <b>num_bytes</b> directory bytes in second
+ * <b>when</b>. (like rep_hist_note_bytes_written() above)
*/
void
rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when)
@@ -1415,8 +1415,8 @@ rep_hist_note_dir_bytes_written(size_t num_bytes, time_t when)
add_obs(dir_write_array, when, num_bytes);
}
-/** We read <b>num_bytes</b> more directory bytes in second <b>when</b>.
- * (like rep_hist_note_bytes_written() above)
+/** Remember that we read <b>num_bytes</b> directory bytes in second
+ * <b>when</b>. (like rep_hist_note_bytes_written() above)
*/
void
rep_hist_note_dir_bytes_read(size_t num_bytes, time_t when)
@@ -1511,7 +1511,8 @@ rep_hist_fill_bandwidth_history(char *buf, size_t len, const bw_array_t *b)
}
/** Allocate and return lines for representing this server's bandwidth
- * history in its descriptor.
+ * history in its descriptor. We publish these lines in our extra-info
+ * descriptor.
*/
char *
rep_hist_get_bandwidth_lines(void)
@@ -1559,7 +1560,7 @@ rep_hist_get_bandwidth_lines(void)
}
/** Write a single bw_array_t into the Values, Ends, Interval, and Maximum
- * entries of an or_state_t. */
+ * entries of an or_state_t. Done before writing out a new state file. */
static void
rep_hist_update_bwhist_state_section(or_state_t *state,
const bw_array_t *b,
@@ -1619,7 +1620,8 @@ rep_hist_update_bwhist_state_section(or_state_t *state,
smartlist_add(*s_maxima, cp);
}
-/** Update <b>state</b> with the newest bandwidth history. */
+/** Update <b>state</b> with the newest bandwidth history. Done before
+ * writing out a new state file. */
void
rep_hist_update_state(or_state_t *state)
{
@@ -1643,7 +1645,7 @@ rep_hist_update_state(or_state_t *state)
}
/** Load a single bw_array_t from its Values, Ends, Maxima, and Interval
- * entries in an or_state_t. */
+ * entries in an or_state_t. Done while reading the state file. */
static int
rep_hist_load_bwhist_state_section(bw_array_t *b,
const smartlist_t *s_values,
@@ -1718,7 +1720,7 @@ rep_hist_load_bwhist_state_section(bw_array_t *b,
return retval;
}
-/** Set bandwidth history from our saved state. */
+/** Set bandwidth history from the state file we just loaded. */
int
rep_hist_load_state(or_state_t *state, char **err)
{
@@ -1766,7 +1768,7 @@ static smartlist_t *predicted_ports_times=NULL;
static void
add_predicted_port(time_t now, uint16_t port)
{
- /* XXXX we could just use uintptr_t here, I think. */
+ /* XXXX we could just use uintptr_t here, I think. -NM */
uint16_t *tmp_port = tor_malloc(sizeof(uint16_t));
time_t *tmp_time = tor_malloc(sizeof(time_t));
*tmp_port = port;
1
0
commit 6fde2b46d2cc2345ec955b1ed9674a777e5e8716
Author: Sebastian Hahn <sebastian(a)torproject.org>
Date: Tue Apr 26 15:33:08 2011 +0200
Fix more of bug 2704
The last entry of the *Maxima values in the state file was inflated by a
factor of NUM_SECS_ROLLING_MEASURE (currently 10). This could lead to
a wrong maximum value propagating through the state file history.
---
changes/bug2704 | 5 +++++
src/or/rephist.c | 3 ++-
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/changes/bug2704 b/changes/bug2704
new file mode 100644
index 0000000..821b38b
--- /dev/null
+++ b/changes/bug2704
@@ -0,0 +1,5 @@
+ o Major bugfixes:
+ - When writing our maximum bw for the current interval to the state
+ file, don't wrongly inflate that value by a factor of 10 anymore.
+ Fixes more of bug 2704.
+
diff --git a/src/or/rephist.c b/src/or/rephist.c
index fb091d5..9146fce 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -1614,7 +1614,8 @@ rep_hist_update_bwhist_state_section(or_state_t *state,
}
tor_asprintf(&cp, U64_FORMAT, U64_PRINTF_ARG(b->total_in_period & ~0x3ff));
smartlist_add(*s_values, cp);
- tor_asprintf(&cp, U64_FORMAT, U64_PRINTF_ARG(b->max_total & ~0x3ff));
+ maxval = b->max_total / NUM_SECS_ROLLING_MEASURE;
+ tor_asprintf(&cp, U64_FORMAT, U64_PRINTF_ARG(maxval & ~0x3ff));
smartlist_add(*s_maxima, cp);
}
1
0

26 Apr '11
commit 6a726d34e175e40cbf86617f9f9c761b52929f96
Merge: 075d904 1cff525
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 11:15:03 2011 -0400
Merge remote-tracking branch 'origin/maint-0.2.2'
changes/bug2704 | 5 +++++
src/or/rephist.c | 5 +++--
2 files changed, 8 insertions(+), 2 deletions(-)
1
0
commit 1cff525973c9e3934a4e1661b721b8a13d20ff72
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Apr 26 11:14:46 2011 -0400
Fix compilation in last patch
---
src/or/rephist.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 9146fce..524cd1d 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -1570,6 +1570,7 @@ rep_hist_update_bwhist_state_section(or_state_t *state,
{
char *cp;
int i,j;
+ uint64_t maxval;
if (*s_values) {
SMARTLIST_FOREACH(*s_values, char *, val, tor_free(val));
@@ -1603,7 +1604,6 @@ rep_hist_update_bwhist_state_section(or_state_t *state,
/* Set i to first position in circular array */
i = (b->num_maxes_set <= b->next_max_idx) ? 0 : b->next_max_idx;
for (j=0; j < b->num_maxes_set; ++j,++i) {
- uint64_t maxval;
if (i >= NUM_TOTALS)
i = 0;
tor_asprintf(&cp, U64_FORMAT, U64_PRINTF_ARG(b->totals[i] & ~0x3ff));
1
0