Skip to content

Commit

Permalink
Merge branch 'endpoints-hints' into endpoints
Browse files Browse the repository at this point in the history
Conflicts:
	foolscap/referenceable.py
  • Loading branch information
david415 committed Jan 20, 2014
2 parents c193bf8 + e14c248 commit 759aced
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 41 deletions.
6 changes: 2 additions & 4 deletions foolscap/negotiate.py
Expand Up @@ -1279,7 +1279,6 @@ def buildProtocol(self, addr):
def clientConnectionFailed(self, connector, reason):
self.tc.clientConnectionFailed(self, reason)


class TubConnector(object):
"""I am used to make an outbound connection. I am given a target TubID
and a list of locationHints, and I try all of them until I establish a
Expand Down Expand Up @@ -1313,7 +1312,7 @@ def __init__(self, parent, tubref):
self.target = tubref
hints = []

self.remainingEndpoints = map(lambda x:"%s:%s:%s" % x, self.target.getLocations())
self.remainingEndpoints = self.target.getLocations()

# attemptedLocations keeps track of where we've already tried to
# connect, so we don't try them twice.
Expand Down Expand Up @@ -1377,9 +1376,8 @@ def connectToAll(self):
continue
self.attemptedEndpoints.append(endpointDesc)

host = endpointDesc.split(':')[1]
lp = self.log("connectTCP to %s" % (endpointDesc,))
f = TubConnectorClientFactory(self, host, lp)
f = TubConnectorClientFactory(self, endpointDesc, lp)
endpoint = clientFromString(reactor, endpointDesc)

self.pendingConnections[f] = endpoint.connect(f)
Expand Down
46 changes: 19 additions & 27 deletions foolscap/referenceable.py
Expand Up @@ -782,11 +782,6 @@ class BadFURLError(Exception):
OLD_STYLE_HINT_RE=re.compile(r"^(%s|%s):(\d+){1,5}$" % (DOTTED_QUAD_RESTR,
DNS_NAME_RESTR))

def encode_location_hint(hint):
assert hint[0] == "tcp"
host, port = hint[1:]
return "%s:%d" % (host, port)

# Each location hint must start with "TYPE:" (where TYPE is alphanumeric) and
# then can contain any characters except "," and "/". These are expected to
# look like Twisted endpoint descriptors, or contain other ":"-separated
Expand All @@ -795,17 +790,22 @@ def encode_location_hint(hint):
# as an old-style hint, the part after TYPE: may not consist of only 1-5
# digits (so "type:123" will be treated as type="tcp" and hostname="type").

# Future versions of foolscap may put hints in their FURLs which we do not
# understand. We will ignore such hints. This version understands two types
# of hints:
# foolscap no longer needs to understand the hints in the the FURL.
# Endpoint creation will be handled by clientFromString and the IStreamClientEndpointStringParser plugins:
# https://twistedmatrix.com/documents/13.2.0/api/twisted.internet.endpoints.html#clientFromString
# https://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IStreamClientEndpointStringParser.html
#
# We will continue support the old style connection hints by converting them
# to be a valid twisted tcp endpoint descriptor.
#
# Convert this old style:
# HOST:PORT (implicit tcp)
# tcp:host=HOST:port=PORT }
# tcp:HOST:PORT } (endpoint syntax for TCP connections
# tcp:host=HOST:PORT } in full, compact and mixed forms)
# tcp:HOST:port=PORT }
#
# To this:
# tcp:host:port
#

def decode_location_hints(hints_s):
def convert_old_location_hints(hints_s):
hints = []
if hints_s:
for hint_s in hints_s.split(","):
Expand All @@ -815,14 +815,8 @@ def decode_location_hints(hints_s):

mo = OLD_STYLE_HINT_RE.search(hint_s)
if mo:
hint = ( "tcp", mo.group(1), int(mo.group(2)) )
hints.append(hint)
else:

pieces = hint_s.split(':')
fields = dict([f.split("=") for f in pieces])
hint = (fields["type"], fields["host"], int(fields["port"]))
hints.append(hint)
hint_s = "tcp:%s:%s" % ( mo.group(1), mo.group(2) )
hints.append(hint_s)

return hints

Expand All @@ -848,23 +842,22 @@ def decode_furl(furl):
if not base32.is_base32(tubID):
raise BadFURLError("'%s' is not a valid tubid" % (tubID,))
hints = mo_auth_furl.group(2)
location_hints = decode_location_hints(hints)
location_hints = convert_old_location_hints(hints)
name = mo_auth_furl.group(3)

elif mo_nonauth_furl:
encrypted = False
tubID = None
hints = mo_nonauth_furl.group(1)
location_hints = decode_location_hints(hints)
location_hints = convert_old_location_hints(hints)
name = mo_nonauth_furl.group(2)

else:
raise ValueError("unknown FURL prefix in %r" % (furl,))
return (encrypted, tubID, location_hints, name)

def encode_furl(encrypted, tubID, location_hints, name):
location_hints_s = ",".join([encode_location_hint(hint)
for hint in location_hints])
location_hints_s = ",".join(location_hints)
if encrypted:
return "pb://" + tubID + "@" + location_hints_s + "/" + name
else:
Expand Down Expand Up @@ -975,8 +968,7 @@ def getShortTubID(self):
return "<unauth>"

def __str__(self):
return "pbu://" + ",".join([encode_location_hint(location)
for location in self.locations])
return "pbu://" + ",".join(self.locations)

def _distinguishers(self):
"""This serves the same purpose as SturdyRef._distinguishers."""
Expand Down
4 changes: 2 additions & 2 deletions foolscap/test/test_gifts.py
Expand Up @@ -452,7 +452,7 @@ def _introduce(adave):
(encrypted, tubid, location_hints, name) = \
decode_furl(adave.tracker.url)
# highly unlikely that there's anything listening on this port
location_hints = [ ("tcp", "127.0.0.1", 2) ]
locations_hints = [ "tcp:host=127.0.0.1:port=2" ]
adave.tracker.url = encode_furl(encode_furl, tubid,
location_hints, name)
return self.shouldFail(ConnectionRefusedError, "Bad.test_location",
Expand All @@ -477,7 +477,7 @@ def _introduce(adave):
# connection timeout.
(encrypted, tubid, location_hints, name) = \
decode_furl(adave.tracker.url)
location_hints = [ ("tcp", "127.0.0.1", p.getHost().port) ]
location_hints = [ "tcp:host=127.0.0.1:port=" + p.getHost().port ]
adave.tracker.url = encode_furl(encode_furl, tubid,
location_hints, name)
self.tubD.options['connect_timeout'] = 2
Expand Down
16 changes: 8 additions & 8 deletions foolscap/test/test_sturdyref.py
Expand Up @@ -10,21 +10,21 @@ def testURL(self):
sr = SturdyRef("pb://%s@127.0.0.1:9900/name" % TUB1)
self.failUnlessEqual(sr.tubID, TUB1)
self.failUnlessEqual(sr.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:host=127.0.0.1:port=9900" ])
self.failUnlessEqual(sr.name, "name")

def testEndpointsURLTcp(self):
sr = SturdyRef("pb://%s@tcp:host=127.0.0.1:port=9900/name" % TUB1)
self.failUnlessEqual(sr.tubID, TUB1)
self.failUnlessEqual(sr.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:127.0.0.1:9900" ])
self.failUnlessEqual(sr.name, "name")

def testEndpointsURLTcpCompact(self):
sr = SturdyRef("pb://%s@tcp:127.0.0.1:9900/name" % TUB1)
self.failUnlessEqual(sr.tubID, TUB1)
self.failUnlessEqual(sr.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:127.0.0.1:9900" ])
self.failUnlessEqual(sr.name, "name")

def testEndpointsURLTcpMixed(self):
Expand All @@ -33,11 +33,11 @@ def testEndpointsURLTcpMixed(self):
self.failUnlessEqual(sr1, sr2)
self.failUnlessEqual(sr1.tubID, TUB1)
self.failUnlessEqual(sr1.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:127.0.0.1:9900" ])
self.failUnlessEqual(sr1.name, "name")
self.failUnlessEqual(sr2.tubID, TUB1)
self.failUnlessEqual(sr2.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:127.0.0.1:9900" ])
self.failUnlessEqual(sr2.name, "name")

def testTubIDExtensions(self):
Expand All @@ -51,7 +51,7 @@ def testLocationHintExtensions(self):
furl = "pb://%s@127.0.0.1:9900,udp:127.0.0.1:7700/name" % TUB1
sr = SturdyRef(furl)
self.failUnlessEqual(sr.locationHints,
[ ("tcp", "127.0.0.1", 9900) ])
[ "tcp:127.0.0.1:9900" ])
self.failUnlessEqual(sr.getURL(), furl)

furl = "pb://%s@udp:127.0.0.1:7700/name" % TUB1
Expand Down Expand Up @@ -81,8 +81,8 @@ def testLocationHints(self):
sr = SturdyRef(url)
self.failUnlessEqual(sr.tubID, TUB1)
self.failUnlessEqual(sr.locationHints,
[ ("tcp", "127.0.0.1", 9900),
("tcp", "remote", 8899) ])
[ "tcp:127.0.0.1:9900",
"tcp:remote:8899" ])
self.failUnlessEqual(sr.name, "name")

def testBrokenHints(self):
Expand Down

0 comments on commit 759aced

Please sign in to comment.