diff --git foolscap/negotiate.py foolscap/negotiate.py
index f74daba..ac8e9cb 100644
--- foolscap/negotiate.py
+++ foolscap/negotiate.py
@@ -329,13 +329,18 @@ class Negotiation(protocol.Protocol):
         # we are using an encrypted Tub is separate, and expressed in our
         # Hello block.
         req = []
+        proxyPrefix = ''
+        if 'http-proxy' in self.tub.options:
+            proxyPrefix = 'http://' + self.targetHost
+            self.log("sendPlaintextClient: using HTTP Proxy %s"
+                % self.tub.options['http-proxy'])
         if self.target.encrypted:
             self.log("sendPlaintextClient: GET for tubID %s" %
                      self.target.tubID)
-            req.append("GET /id/%s HTTP/1.1" % self.target.tubID)
+            req.append("GET %s/id/%s HTTP/1.1" % (proxyPrefix, self.target.tubID))
         else:
             self.log("sendPlaintextClient: GET for no tubID")
-            req.append("GET /id/ HTTP/1.1")
+            req.append("GET %s/id/ HTTP/1.1" % proxyPrefix)
         req.append("Host: %s" % self.targetHost)
         self.log("sendPlaintextClient: wantEncryption=%s" % self.wantEncryption)
         if self.wantEncryption:
@@ -1353,10 +1358,15 @@ class TubConnector(object):
             if location in self.attemptedLocations:
                 continue
             self.attemptedLocations.append(location)
-            host, port = location
+            if 'http-proxy' in self.tub.options:
+                host, port = self.tub.options['http-proxy'].split(':')
+                destination = location[0]
+            else:
+                host, port = location
+                destination = host
             lp = self.log("connectTCP to %s" % (location,))
-            f = TubConnectorClientFactory(self, host, lp)
-            c = reactor.connectTCP(host, port, f)
+            f = TubConnectorClientFactory(self, destination, lp)
+            c = reactor.connectTCP(host, int(port), f)
             self.pendingConnections[f] = c
             # the tcp.Connector that we get back from reactor.connectTCP will
             # retain a reference to the transport that it creates, so we can
diff --git foolscap/pb.py foolscap/pb.py
index 83a3e06..d742ff4 100644
--- foolscap/pb.py
+++ foolscap/pb.py
@@ -205,6 +205,7 @@ class Tub(service.MultiService):
                     connection negotiation. Currently defined keys are:
                      - debug_slow: if True, wait half a second between
                                    each negotiation response
+                     - http-proxy: if set, connect using this HTTP proxy
 
     @ivar brokers: maps TubIDs to L{Broker} instances
 
@@ -359,6 +360,8 @@ class Tub(service.MultiService):
             self.setLogGathererFURL(value)
         elif name == "log-gatherer-furlfile":
             self.setLogGathererFURLFile(value)
+        elif name == "http-proxy":
+            self.options['http-proxy'] = value
         elif name == "bridge-twisted-logs":
             assert value is not False, "cannot unbridge twisted logs"
             if value is True:
diff --git foolscap/referenceable.py foolscap/referenceable.py
index 8af48d7..ca044e1 100644
--- foolscap/referenceable.py
+++ foolscap/referenceable.py
@@ -775,6 +775,13 @@ def decode_location_hints(hints_s):
         if mo:
             hint = ( "ipv4", mo.group(1), int(mo.group(2)) )
             hints.append(hint)
+        elif hint_s.startswith("i2p:"):
+            (protocol, destination) = hints_s.split(":", 2)
+            hint = ( "ipv4", destination, 0) # I2P destinations have no port
+            hints.append(hint)
+        elif hint_s.endswith(".b32.i2p"): # For compatibility, to be removed in a future version
+            hint = ( "ipv4", hint_s, 0)
+            hints.append(hint)
         else:
             # some extension from the future that we will ignore
             pass
