[tor-commits] [bridgedb/develop] Teach Bridge._getTransportForRequest() to filter blocked addresses.

isis at torproject.org isis at torproject.org
Thu Jun 25 07:10:54 UTC 2015


commit b77e0126da7132c02453111310231d4912818a66
Author: Isis Lovecruft <isis at torproject.org>
Date:   Sat Apr 18 06:25:49 2015 +0000

    Teach Bridge._getTransportForRequest() to filter blocked addresses.
---
 lib/bridgedb/bridges.py |   52 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py
index 8f4f853..dc5b78d 100644
--- a/lib/bridgedb/bridges.py
+++ b/lib/bridgedb/bridges.py
@@ -1040,6 +1040,13 @@ class Bridge(BridgeBackwardsCompatibility):
         :term:`Bridge Line` based upon the client identifier in the
         **bridgeRequest**.
 
+        .. warning:: If this bridge doesn't have any of the requested
+            pluggable transport type (optionally, not blocked in whichever
+            countries the user doesn't want their bridges to be blocked in),
+            then this method returns ``None``.  This should only happen
+            rarely, because the bridges are filtered into the client's
+            hashring based on the **bridgeRequest** options.
+
         :type bridgeRequest: :class:`bridgedb.bridgerequest.BridgeRequestBase`
         :param bridgeRequest: A ``BridgeRequest`` which stores all of the
             client-specified options for which type of bridge they want to
@@ -1056,29 +1063,40 @@ class Bridge(BridgeBackwardsCompatibility):
             return a :term:`Bridge Line` for the requested pluggable transport
             type.
         """
+        desired = bridgeRequest.justOnePTType()
         addressClass = bridgeRequest.addressClass
-        desiredTransport = bridgeRequest.justOnePTType()
-        hashringPosition = bridgeRequest.getHashringPlacement(bridgeRequest.client,
-                                                              'Order-Or-Addresses')
 
         logging.info("Bridge %s answering request for %s transport..." %
-                     (safelog.logSafely(self.fingerprint), desiredTransport))
+                     (self, desired))
+
         # Filter all this Bridge's ``transports`` according to whether or not
-        # their ``methodname`` matches the requested transport, i.e. only
-        # 'obfs3' transports, or only 'scramblesuit' transports:
-        transports = filter(lambda pt: desiredTransport == pt.methodname,
-                            self.transports)
+        # their ``methodname`` matches the requested transport:
+        transports = filter(lambda pt: pt.methodname == desired, self.transports)
         # Filter again for whichever of IPv4 or IPv6 was requested:
         transports = filter(lambda pt: isinstance(pt.address, addressClass),
                             transports)
 
-        if transports:
-            return transports[hashringPosition % len(transports)]
-        else:
+        if not transports:
             raise PluggableTransportUnavailable(
-                ("Client requested transport %s from bridge %s, but this "
-                 "bridge doesn't have any of that transport!") %
-                (desiredTransport, self.fingerprint))
+                ("Client requested transport %s, but bridge %s doesn't "
+                "have any of that transport!") % (desired, self))
+
+
+        unblocked = []
+        for pt in transports:
+            if not sum([self.transportIsBlockedIn(cc, pt.methodname)
+                        for cc in bridgeRequest.notBlockedIn]):
+                unblocked.append(pt)
+
+        if unblocked:
+            position = bridgeRequest.getHashringPlacement('Order-Or-Addresses')
+            return transports[position % len(unblocked)]
+        else:
+            logging.warn(("Client requested transport %s%s, but bridge %s "
+                          "doesn't have any of that transport!") %
+                         (desired, " not blocked in %s" %
+                          " ".join(bridgeRequest.notBlockedIn)
+                          if bridgeRequest.notBlockedIn else "", self))
 
     def _getVanillaForRequest(self, bridgeRequest):
         """If vanilla bridges were requested, return the assigned
@@ -1235,9 +1253,13 @@ class Bridge(BridgeBackwardsCompatibility):
             logging.info("Bridge request was not valid. Dropping request.")
             return  # XXX raise error perhaps?
 
+        bridgeLine = None
+
         if bridgeRequest.transports:
             pt = self._getTransportForRequest(bridgeRequest)
-            bridgeLine = pt.getTransportLine(includeFingerprint, bridgePrefix)
+            if pt:
+                bridgeLine = pt.getTransportLine(includeFingerprint,
+                                                 bridgePrefix)
         else:
             addrport = self._getVanillaForRequest(bridgeRequest)
             bridgeLine = self._constructBridgeLine(addrport,





More information about the tor-commits mailing list