diff --git foolscap/negotiate.py foolscap/negotiate.py
index f74daba..1eade3d 100644
--- foolscap/negotiate.py
+++ foolscap/negotiate.py
@@ -329,13 +329,19 @@ class Negotiation(protocol.Protocol):
         # we are using an encrypted Tub is separate, and expressed in our
         # Hello block.
         req = []
+        # I2P: use HTTP Proxy protocol
+        proxyPrefix = ''
+        if 'httpProxy' in self.tub.options:
+            proxyPrefix = 'http://' + self.targetHost
+            self.log("sendPlaintextClient: using HTTP Proxy %s"
+                % self.tub.options['httpProxy'])
         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 +1359,16 @@ class TubConnector(object):
             if location in self.attemptedLocations:
                 continue
             self.attemptedLocations.append(location)
-            host, port = location
+            # I2P: Connect to HTTP Proxy instead of to destination
+            if 'httpProxy' in self.tub.options:
+                host, port = self.tub.options['httpProxy'].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 35c8981..19b3ed8 100644
--- foolscap/pb.py
+++ foolscap/pb.py
@@ -190,6 +190,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
 
@@ -344,6 +345,8 @@ class Tub(service.MultiService):
             self.setLogGathererFURL(value)
         elif name == "log-gatherer-furlfile":
             self.setLogGathererFURLFile(value)
+        elif name == "httpProxy":
+            self.options['httpProxy'] = 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 7efbcb5..c15d706 100644
--- foolscap/referenceable.py
+++ foolscap/referenceable.py
@@ -763,6 +763,8 @@ AUTH_STURDYREF_RE = re.compile(r"pb://([^@]+)@([^/]+)/(.+)$")
 NONAUTH_STURDYREF_RE = re.compile(r"pbu://([^/]+)/(.+)$")
 
 IPV4_HINT_RE = re.compile(r"^([^:]+):(\d+)$")
+# I2P: Recognize I2P destinations
+I2P_HINT_RE = re.compile(r"^([a-z2-7]{52}\.b32\.i2p)$")
 def encode_location_hint(hint):
     assert hint[0] == "ipv4"
     host, port = hint[1:]
@@ -775,8 +777,14 @@ def decode_location_hints(hints_s):
             hint = ( "ipv4", mo.group(1), int(mo.group(2)) )
             hints.append(hint)
         else:
-            # some extension from the future that we will ignore
-            pass
+            mo = I2P_HINT_RE.search(hint_s)
+            if mo:
+                # I2P: destinations have no port
+                hint = ( "ipv4", mo.group(1), 0)
+                hints.append(hint)
+            else:
+                # some extension from the future that we will ignore
+                pass
     return hints
 
 class BadFURLError(Exception):
