[or-cvs] r24237: {arm} Displaying ports and common usage for exit connections. This (in arm/trunk: . src src/interface src/interface/connections src/util)

Damian Johnson atagar1 at gmail.com
Fri Feb 18 17:30:11 UTC 2011


Author: atagar
Date: 2011-02-18 17:30:11 +0000 (Fri, 18 Feb 2011)
New Revision: 24237

Modified:
   arm/trunk/TODO
   arm/trunk/src/interface/connections/connPanel.py
   arm/trunk/src/interface/connections/listings.py
   arm/trunk/src/interface/controller.py
   arm/trunk/src/settings.cfg
   arm/trunk/src/util/conf.py
   arm/trunk/src/util/connections.py
   arm/trunk/src/util/torTools.py
Log:
Displaying ports and common usage for exit connections. This will be toggleable in the future and might be off by default depending on feelings about the feature (thus far I've seen slightly warm feelings to the idea from a couple people, but I'm aware that this is a sensetive area). This is only with the new connection panel, so it's still unavailable unless you set the source flag to display the new panel.

added: dropping the label for DNS connections and explicitely noting which are exits
change: displaying the port and usage for exit connections
fix: config error messages didn't have the proper case



Modified: arm/trunk/TODO
===================================================================
--- arm/trunk/TODO	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/TODO	2011-02-18 17:30:11 UTC (rev 24237)
@@ -35,6 +35,7 @@
           myInternal --> myExternal --> foreign
           idea and initial patch by Fabian Keil
         - give a warning if family relays don't name us
+        - use SAVECONF instead when overwriting the current torrc
       * classify config options as useful (defaultly shown), standard, and
         deprecated (configured to be hidden by default)
       * check tor source for deprecated options like 'group' (are they
@@ -182,6 +183,8 @@
       instance 'SETEVENTS')
     * 'safe' option that restricts to read-only access (start with this)
     * issue sighup reset
+  * options for more deailed control of when bandwidth's contributed
+    https://trac.torproject.org/projects/tor/ticket/1730
   * make use of the new process/* GETINFO options
     They'll be available in the next tor release, as per:
     https://trac.torproject.org/projects/tor/ticket/2291

Modified: arm/trunk/src/interface/connections/connPanel.py
===================================================================
--- arm/trunk/src/interface/connections/connPanel.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/interface/connections/connPanel.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -116,7 +116,8 @@
       entry = self._connections[lineNum]
       drawLine = lineNum + 1 - scrollLoc
       
-      lineFormat = uiTools.getColor(listings.CATEGORY_COLOR[entry.type])
+      entryType = entry.getType()
+      lineFormat = uiTools.getColor(listings.CATEGORY_COLOR[entryType])
       if entry == cursorSelection: lineFormat |= curses.A_STANDOUT
       
       # Lines are split into three components (prefix, category, and suffix)
@@ -133,11 +134,11 @@
       xLoc += len(prefixLabel)
       
       # category
-      self.addstr(drawLine, xLoc, entry.type.upper(), lineFormat | curses.A_BOLD)
-      xLoc += len(entry.type)
+      self.addstr(drawLine, xLoc, entryType.upper(), lineFormat | curses.A_BOLD)
+      xLoc += len(entryType)
       
       # suffix (ending parentheses plus padding so lines are the same length)
-      self.addstr(drawLine, xLoc, ")" + " " * (9 - len(entry.type)), lineFormat)
+      self.addstr(drawLine, xLoc, ")" + " " * (9 - len(entryType)), lineFormat)
       
       if drawLine >= height: break
     
@@ -186,7 +187,7 @@
       # counts the relays in each of the categories
       categoryTypes = listings.Category.values()
       typeCounts = dict((type, 0) for type in categoryTypes)
-      for conn in newConnections: typeCounts[conn.type] += 1
+      for conn in newConnections: typeCounts[conn.getType()] += 1
       
       # makes labels for all the categories with connections (ie,
       # "21 outbound", "1 control", etc)

Modified: arm/trunk/src/interface/connections/listings.py
===================================================================
--- arm/trunk/src/interface/connections/listings.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/interface/connections/listings.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -9,16 +9,16 @@
 # Connection Categories:
 #   Inbound     Relay connection, coming to us.
 #   Outbound    Relay connection, leaving us.
-#   DNS         Relayed dns queries.
+#   Exit        Outbound relay connection leaving the Tor network.
 #   Socks       Application client connection.
 #   Client      Circuits for our client traffic.
 #   Directory   Fetching tor consensus information.
 #   Control     Tor controller (arm, vidalia, etc).
 
 # TODO: add recognizing of CLIENT connection type
-Category = enum.Enum("INBOUND", "OUTBOUND", "DNS", "SOCKS", "CLIENT", "DIRECTORY", "CONTROL")
+Category = enum.Enum("INBOUND", "OUTBOUND", "EXIT", "SOCKS", "CLIENT", "DIRECTORY", "CONTROL")
 CATEGORY_COLOR = {Category.INBOUND: "green", Category.OUTBOUND: "blue",
-                  Category.DNS: "blue",      Category.SOCKS: "cyan",
+                  Category.EXIT: "red",      Category.SOCKS: "cyan",
                   Category.CLIENT: "cyan",   Category.DIRECTORY: "magenta",
                   Category.CONTROL: "red"}
 
@@ -128,42 +128,63 @@
       myOrPort = listenAddr[listenAddr.find(":") + 1:]
     
     if lPort in (myOrPort, myDirPort):
-      self.type = Category.INBOUND
+      self.baseType = Category.INBOUND
       self.local.isORPort = True
     elif lPort == mySocksPort:
-      self.type = Category.SOCKS
+      self.baseType = Category.SOCKS
     elif lPort == myCtlPort:
-      self.type = Category.CONTROL
+      self.baseType = Category.CONTROL
     elif (fIpAddr, fPort) in myAuthorities:
-      self.type = Category.DIRECTORY
-    elif fPort == "53":
-      # TODO: also check if this was a UDP connection (gonna take a bit more work...)
-      self.type = Category.DNS
+      self.baseType = Category.DIRECTORY
     else:
-      self.type = Category.OUTBOUND
+      self.baseType = Category.OUTBOUND
       self.foreign.isORPort = True
   
+  def getType(self):
+    """
+    Provides the category this connection belongs to. This isn't always static
+    since it can rely on dynamic information (like the current consensus).
+    """
+    
+    if self.baseType == Category.OUTBOUND:
+      # Currently the only non-static categories are OUTBOUND vs EXIT (since
+      # this depends on the current consensus). The exitability and
+      # fingerprints are both cached by the torTools util making this a quick
+      # lookup.
+      
+      conn = torTools.getConn()
+      isKnownRelay = self.foreign.getFingerprint() != "UNKNOWN"
+      isExitingAllowed = conn.isExitingAllowed(self.foreign.getIpAddr(), self.foreign.getPort())
+      isExitConnection = isExitingAllowed and not isKnownRelay
+      
+      return Category.EXIT if isExitingAllowed else Category.OUTBOUND
+    else: return self.baseType
+  
   def isPrivate(self):
     """
     Returns true if the endpoint is private, possibly belonging to a client
     connection or exit traffic.
     """
     
-    if self.type == Category.INBOUND:
+    myType = self.getType()
+    
+    if myType == Category.INBOUND:
       # if the connection doesn't belong to a known relay then it might be
       # client traffic
       
       return self.foreign.getFingerprint() == "UNKNOWN"
-    elif self.type == Category.OUTBOUND:
-      # if it's both not a relay and obeys our exit policy then it may belong
-      # to exit traffic
+    elif myType == Category.EXIT:
+      # DNS connections exiting us aren't private (since they're hitting our
+      # resolvers). Everything else, however, is.
       
-      conn = torTools.getConn()
-      isExitingAllowed = conn.isExitingAllowed(self.foreign.getIpAddr(), self.foreign.getPort())
-      return self.foreign.getFingerprint() == "UNKNOWN" and isExitingAllowed
-    else:
-      # for control, application, and directory connections this isn't a concern
-      return False
+      # TODO: Ideally this would also double check that it's a UDP connection
+      # (since DNS is the only UDP connections Tor will relay), however this
+      # will take a bit more work to propagate the information up from the
+      # connection resolver.
+      return self.foreign.getPort() != "53"
+    
+    # for everything else this isn't a concern
+    return False
   
   def getLabel(self, listingType, width):
     """
@@ -206,15 +227,36 @@
       return self._labelCache
     
     conn = torTools.getConn()
+    myType = self.getType()
     
     # destination of the connection
-    dstAddress = "<scrubbed>"
-    if not self.isPrivate():
+    if self.isPrivate():
+      dstAddress = "<scrubbed>:%s" % self.foreign.getPort()
+    else:
       dstAddress = "%s:%s" % (self.foreign.getIpAddr(), self.foreign.getPort())
+    
+    # Appends an extra field which could be...
+    # - the port's purpose for exits
+    # - locale for most other connections
+    # - blank if it's on the local network
+    
+    if myType == Category.EXIT:
+      purpose = connections.getPortUsage(self.foreign.getPort())
       
-      # if this isn't on the local network then also include the country
-      if not connections.isIpAddressPrivate(self.foreign.getIpAddr()):
-        dstAddress += " (%s)" % self.foreign.getLocale()
+      if purpose:
+        spaceAvailable = 26 - len(dstAddress) - 3
+        
+        # BitTorrent is a common protocol to truncate, so just use "Torrent"
+        # if there's not enough room.
+        if len(purpose) > spaceAvailable and purpose == "BitTorrent":
+          purpose = "Torrent"
+        
+        # crops with a hyphen if too long
+        purpose = uiTools.cropStr(purpose, spaceAvailable, endType = uiTools.Ending.HYPHEN)
+        
+        dstAddress += " (%s)" % purpose
+    elif not connections.isIpAddressPrivate(self.foreign.getIpAddr()):
+      dstAddress += " (%s)" % self.foreign.getLocale()
     
     src, dst, etc = "", "", ""
     if listingType == connPanel.Listing.IP:
@@ -279,7 +321,7 @@
     elif listingType == connPanel.Listing.FINGERPRINT:
       # base data requires 75 characters
       src = "localhost"
-      if self.type == Category.CONTROL: dst = "localhost"
+      if myType == Category.CONTROL: dst = "localhost"
       else: dst = self.foreign.getFingerprint()
       dst = "%-40s" % dst
       
@@ -295,7 +337,7 @@
     else:
       # base data uses whatever extra room's available (using minimun of 50 characters)
       src = self.local.getNickname()
-      if self.type == Category.CONTROL: dst = self.local.getNickname()
+      if myType == Category.CONTROL: dst = self.local.getNickname()
       else: dst = self.foreign.getNickname()
       
       # space available for foreign nickname
@@ -313,7 +355,7 @@
       
       dst = ("%%-%is" % nicknameSpace) % dst
     
-    if self.type == Category.INBOUND: src, dst = dst, src
+    if myType == Category.INBOUND: src, dst = dst, src
     padding = width - len(src) - len(dst) - len(etc) - 27
     self._labelCache = "%s  -->  %s  %s%s" % (src, dst, etc, " " * padding)
     self._labelCacheArgs = (listingType, width)

Modified: arm/trunk/src/interface/controller.py
===================================================================
--- arm/trunk/src/interface/controller.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/interface/controller.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -826,9 +826,11 @@
         
         # stops panel daemons
         panels["header"].stop()
+        panels["conn2"].stop()
         panels["log"].stop()
         
         panels["header"].join()
+        panels["conn2"].join()
         panels["log"].join()
         
         # joins on utility daemon threads - this might take a moment since

Modified: arm/trunk/src/settings.cfg
===================================================================
--- arm/trunk/src/settings.cfg	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/settings.cfg	2011-02-18 17:30:11 UTC (rev 24237)
@@ -366,3 +366,287 @@
 torrc.label.time.day day, days
 torrc.label.time.week week, weeks
 
+# Common usages for ports based on:
+# https://secure.wikimedia.org/wikipedia/en/wiki/List_of_TCP_and_UDP_port_numbers
+# http://isc.sans.edu/services.html
+# 
+# Including all the official low ports (< 1024), and higher ones I recognize.
+
+port.label.1 TCPMUX
+port.label.2 CompressNET
+port.label.3 CompressNET
+port.label.5 RJE
+port.label.7 Echo
+port.label.9 Discard
+port.label.11 SYSTAT
+port.label.13 Daytime
+port.label.15 netstat
+port.label.17 QOTD
+port.label.18 MSP
+port.label.19 CHARGEN
+port.label.20 FTP
+port.label.21 FTP
+port.label.22 SSH
+port.label.23 Telnet
+port.label.24 Priv-mail
+port.label.25 SMTP
+port.label.34 RF
+port.label.35 Printer
+port.label.37 TIME
+port.label.39 RLP
+port.label.41 Graphics
+port.label.42 WINS
+port.label.43 WHOIS
+port.label.47 NI FTP
+port.label.49 TACACS
+port.label.50 Remote Mail
+port.label.51 IMP
+port.label.52 XNS
+port.label.53 DNS
+port.label.54 XNS
+port.label.55 ISI-GL
+port.label.56 RAP
+port.label.57 MTP
+port.label.58 XNS
+port.label.67 BOOTP
+port.label.68 BOOTP
+port.label.69 TFTP
+port.label.70 Gopher
+port.label.79 Finger
+port.label.80 HTTP
+port.label.81 Torpark
+port.label.82 Torpark
+port.label.83 MIT ML
+port.label.88 Kerberos
+port.label.90 dnsix
+port.label.99 WIP
+port.label.101 NIC
+port.label.102 ISO-TSAP
+port.label.104 ACR/NEMA
+port.label.105 CCSO
+port.label.107 Telnet
+port.label.108 SNA
+port.label.109 POP2
+port.label.110 POP3
+port.label.111 ONC RPC
+port.label.113 ident
+port.label.115 SFTP
+port.label.117 UUCP
+port.label.118 SQL
+port.label.119 NNTP
+port.label.123 NTP
+port.label.135 DCE
+port.label.137 NetBIOS
+port.label.138 NetBIOS
+port.label.139 NetBIOS
+port.label.143 IMAP
+port.label.152 BFTP
+port.label.153 SGMP
+port.label.156 SQL
+port.label.158 DMSP
+port.label.161 SNMP
+port.label.162 SNMPTRAP
+port.label.170 Print-srv
+port.label.177 XDMCP
+port.label.179 BGP
+port.label.194 IRC
+port.label.199 SMUX
+port.label.201 AppleTalk
+port.label.209 QMTP
+port.label.210 ANSI
+port.label.213 IPX
+port.label.218 MPP
+port.label.220 IMAP
+port.label.256 2DEV
+port.label.259 ESRO
+port.label.264 BGMP
+port.label.308 Novastor
+port.label.311 OSX Admin
+port.label.318 PKIX TSP
+port.label.319 PTP
+port.label.320 PTP
+port.label.323 IMMP
+port.label.350 MATIP
+port.label.351 MATIP
+port.label.366 ODMR
+port.label.369 Rpc2portmap
+port.label.370 codaauth2
+port.label.371 ClearCase
+port.label.383 HP Alarm Mgr
+port.label.384 ARNS
+port.label.387 AURP
+port.label.389 LDAP
+port.label.401 UPS
+port.label.402 Altiris
+port.label.427 SLP
+port.label.443 HTTPS
+port.label.444 SNPP
+port.label.445 SMB
+port.label.464 Kerberos
+port.label.465 SMTP
+port.label.475 tcpnethaspsrv
+port.label.497 Retrospect
+port.label.500 ISAKMP
+port.label.501 STMF
+port.label.502 Modbus
+port.label.504 Citadel
+port.label.510 FirstClass
+port.label.512 Rexec
+port.label.513 rlogin
+port.label.514 rsh
+port.label.515 LPD
+port.label.517 Talk
+port.label.518 NTalk
+port.label.520 efs
+port.label.524 NCP
+port.label.530 RPC
+port.label.531 AIM/IRC
+port.label.532 netnews
+port.label.533 netwall
+port.label.540 UUCP
+port.label.542 commerce
+port.label.543 klogin
+port.label.544 klogin
+port.label.545 OSISoft PI
+port.label.546 DHCPv6
+port.label.547 DHCPv6
+port.label.548 AFP
+port.label.550 new-who
+port.label.554 RTSP
+port.label.556 RFS
+port.label.560 rmonitor
+port.label.561 monitor
+port.label.563 NNTPS
+port.label.587 SMTP
+port.label.591 FileMaker
+port.label.593 HTTP RPC
+port.label.604 TUNNEL
+port.label.623 ASF-RMCP
+port.label.631 CUPS
+port.label.635 RLZ DBase
+port.label.636 LDAPS
+port.label.639 MSDP
+port.label.641 SupportSoft
+port.label.646 LDP
+port.label.647 DHCP
+port.label.648 RRP
+port.label.651 IEEE-MMS
+port.label.652 DTCP
+port.label.653 SupportSoft
+port.label.654 MMS/MMP
+port.label.657 RMC
+port.label.660 OSX Admin
+port.label.665 sun-dr
+port.label.666 Doom
+port.label.674 ACAP
+port.label.691 MS Exchange
+port.label.692 Hyperwave-ISP
+port.label.694 Linux-HA
+port.label.695 IEEE-MMS-SSL
+port.label.698 OLSR
+port.label.699 Access Network
+port.label.700 EPP
+port.label.701 LMP
+port.label.702 IRIS
+port.label.706 SILC
+port.label.711 MPLS
+port.label.712 TBRPF
+port.label.720 SMQP
+port.label.749 Kerberos
+port.label.750 rfile
+port.label.751 pump
+port.label.752 qrh
+port.label.753 rrh
+port.label.754 tell send
+port.label.760 ns
+port.label.782 Conserver
+port.label.783 spamd
+port.label.829 CMP
+port.label.843 Flash
+port.label.847 DHCP
+port.label.860 iSCSI
+port.label.873 rsync
+port.label.888 CDDB
+port.label.901 SWAT
+port.label.902 VMware
+port.label.903 VMware
+port.label.904 VMware
+port.label.911 NCA
+port.label.953 DNS RNDC
+port.label.981 SofaWare
+port.label.989 FTPS
+port.label.990 FTPS
+port.label.991 NAS
+port.label.992 Telnet
+port.label.993 IMAPS
+port.label.995 POP3S
+port.label.999 ScimoreDB
+port.label.1001 JtoMB
+port.label.1002 cogbot
+
+port.label.1080 SOCKS
+port.label.1085 WebObjects
+port.label.1109 KPOP
+port.label.1169 Tripwire
+port.label.1194 OpenVPN
+port.label.1214 Kazaa
+port.label.1220 QuickTime
+port.label.1234 VLC
+port.label.1241 Nessus
+port.label.1270 SCOM
+port.label.1293 IPSec
+port.label.1433 MSSQL
+port.label.1434 MSSQL
+port.label.1503 MSN
+port.label.1512 WINS
+port.label.1521 Oracle
+port.label.1526 Oracle
+port.label.1666 Perforce
+port.label.1725 Steam
+port.label.1863 MSNP
+port.label.2049 NFS
+port.label.2086 GNUnet
+port.label.2401 CVS
+port.label.2525 SMTP
+port.label.2710 BitTorrent
+port.label.3074 XBox LIVE
+port.label.3101 BlackBerry
+port.label.3306 MySQL
+port.label.3690 SVN
+port.label.3723 Battle.net
+port.label.3724 WoW
+port.label.4662 eMule
+port.label.5003 FileMaker
+port.label.5050 Yahoo IM
+port.label.5060 SIP
+port.label.5061 SIP
+port.label.5190 AIM/ICQ
+port.label.5222 Jabber
+port.label.5223 Jabber
+port.label.5269 Jabber
+port.label.5298 Jabber
+port.label.5432 PostgreSQL
+port.label.5500 VNC
+port.label.5556 Freeciv
+port.label.5666 NRPE
+port.label.5667 NSCA
+port.label.5800 VNC
+port.label.5900 VNC
+port.label.6346 gnutella
+port.label.6347 gnutella
+port.label.6660-6669 IRC
+port.label.6679 IRC
+port.label.6697 IRC
+port.label.6881-6999 BitTorrent
+port.label.8008 HTTP
+port.label.8010 XMPP
+port.label.8080 Tomcat
+port.label.8118 Privoxy
+port.label.8123 Polipo
+port.label.9030 Tor
+port.label.9050 Tor
+port.label.9051 Tor
+port.label.23399 Skype
+port.label.30301 BitTorrent
+port.label.33434 traceroute
+

Modified: arm/trunk/src/util/conf.py
===================================================================
--- arm/trunk/src/util/conf.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/util/conf.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -113,7 +113,7 @@
       if val.upper() == "NONE": val = None
       elif val.upper() in log.Runlevel.values(): val = val.upper()
       else:
-        msg = "config entry '%s' is expected to be a runlevel" % key
+        msg = "Config entry '%s' is expected to be a runlevel" % key
         if default != None: msg += ", defaulting to '%s'" % default
         log.log(CONFIG["log.configEntryTypeError"], msg)
         val = default
@@ -121,19 +121,19 @@
       if val.lower() == "true": val = True
       elif val.lower() == "false": val = False
       else:
-        msg = "config entry '%s' is expected to be a boolean, defaulting to '%s'" % (key, str(default))
+        msg = "Config entry '%s' is expected to be a boolean, defaulting to '%s'" % (key, str(default))
         log.log(CONFIG["log.configEntryTypeError"], msg)
         val = default
     elif isinstance(default, int):
       try: val = int(val)
       except ValueError:
-        msg = "config entry '%s' is expected to be an integer, defaulting to '%i'" % (key, default)
+        msg = "Config entry '%s' is expected to be an integer, defaulting to '%i'" % (key, default)
         log.log(CONFIG["log.configEntryTypeError"], msg)
         val = default
     elif isinstance(default, float):
       try: val = float(val)
       except ValueError:
-        msg = "config entry '%s' is expected to be a float, defaulting to '%f'" % (key, default)
+        msg = "Config entry '%s' is expected to be a float, defaulting to '%f'" % (key, default)
         log.log(CONFIG["log.configEntryTypeError"], msg)
         val = default
     elif isinstance(default, list):
@@ -145,7 +145,7 @@
           entryKey, entryVal = entry.split("=>", 1)
           valMap[entryKey.strip()] = entryVal.strip()
         else:
-          msg = "ignoring invalid %s config entry (expected a mapping, but \"%s\" was missing \"=>\")" % (key, entry)
+          msg = "Ignoring invalid %s config entry (expected a mapping, but \"%s\" was missing \"=>\")" % (key, entry)
           log.log(CONFIG["log.configEntryTypeError"], msg)
       val = valMap
     
@@ -170,7 +170,7 @@
       
       # check if the count doesn't match
       if count != None and len(confComp) != count:
-        msg = "config entry '%s' is expected to be %i comma separated values" % (key, count)
+        msg = "Config entry '%s' is expected to be %i comma separated values" % (key, count)
         if default != None and (isinstance(default, list) or isinstance(default, tuple)):
           defaultStr = ", ".join([str(i) for i in default])
           msg += ", defaulting to '%s'" % defaultStr
@@ -200,7 +200,7 @@
     
     # validates the input, setting the errorMsg if there's a problem
     errorMsg = None
-    baseErrorMsg = "config entry '%s' is expected to %%s" % key
+    baseErrorMsg = "Config entry '%s' is expected to %%s" % key
     if default != None and (isinstance(default, list) or isinstance(default, tuple)):
       defaultStr = ", ".join([str(i) for i in default])
       baseErrorMsg += ", defaulting to '%s'" % defaultStr

Modified: arm/trunk/src/util/connections.py
===================================================================
--- arm/trunk/src/util/connections.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/util/connections.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -79,10 +79,40 @@
           "log.connLookupFailed": log.INFO,
           "log.connLookupFailover": log.NOTICE,
           "log.connLookupAbandon": log.WARN,
-          "log.connLookupRateGrowing": None}
+          "log.connLookupRateGrowing": None,
+          "log.configEntryTypeError": log.NOTICE}
 
+PORT_USAGE = {}
+
 def loadConfig(config):
   config.update(CONFIG)
+  
+  for configKey in config.getKeys():
+    # fetches any port.label.* values
+    if configKey.startswith("port.label."):
+      portEntry = configKey[11:]
+      purpose = config.get(configKey)
+      
+      divIndex = portEntry.find("-")
+      if divIndex == -1:
+        # single port
+        if portEntry.isdigit():
+          PORT_USAGE[portEntry] = purpose
+        else:
+          msg = "Port value isn't numeric for entry: %s" % configKey
+          log.log(CONFIG["log.configEntryTypeError"], msg)
+      else:
+        try:
+          # range of ports (inclusive)
+          minPort = int(portEntry[:divIndex])
+          maxPort = int(portEntry[divIndex + 1:])
+          if minPort > maxPort: raise ValueError()
+          
+          for port in range(minPort, maxPort + 1):
+            PORT_USAGE[str(port)] = purpose
+        except ValueError:
+          msg = "Unable to parse port range for entry: %s" % configKey
+          log.log(CONFIG["log.configEntryTypeError"], msg)
 
 def isValidIpAddress(ipStr):
   """
@@ -123,6 +153,17 @@
   
   return False
 
+def getPortUsage(port):
+  """
+  Provides the common use of a given port. If no useage is known then this
+  provides None.
+  
+  Arguments:
+    port - port number to look up
+  """
+  
+  return PORT_USAGE.get(port)
+
 def getResolverCommand(resolutionCmd, processName, processPid = ""):
   """
   Provides the command that would be processed for the given resolver type.

Modified: arm/trunk/src/util/torTools.py
===================================================================
--- arm/trunk/src/util/torTools.py	2011-02-18 02:54:30 UTC (rev 24236)
+++ arm/trunk/src/util/torTools.py	2011-02-18 17:30:11 UTC (rev 24237)
@@ -750,7 +750,10 @@
       # query the policy if it isn't yet cached
       if not (ipAddress, port) in self._exitPolicyLookupCache:
         # If we allow any exiting then this could be relayed DNS queries,
-        # otherwise the policy is checked.
+        # otherwise the policy is checked. Tor still makes DNS connections to
+        # test when exiting isn't allowed, but nothing is relayed over them.
+        # I'm registering these as non-exiting to avoid likely user confusion:
+        # https://trac.torproject.org/projects/tor/ticket/965
         
         if self._isExitingAllowed and port == "53": isAccepted = True
         else: isAccepted = self._exitPolicyChecker.check(ipAddress, port)



More information about the tor-commits mailing list