[tahoe-lafs-trac-stream] [Tahoe-LAFS] #2831: connection-hint incompatibility with tahoe-1.11.0 and current versions?

Tahoe-LAFS trac at tahoe-lafs.org
Thu Sep 15 17:53:14 UTC 2016


#2831: connection-hint incompatibility with tahoe-1.11.0 and current versions?
--------------------------+------------------------
 Reporter:  warner        |          Owner:
     Type:  defect        |         Status:  new
 Priority:  normal        |      Milestone:  1.12.0
Component:  code-network  |        Version:  1.11.0
 Keywords:                |  Launchpad Bug:
--------------------------+------------------------
 IRC user "edi" was using the debian/jesse version of Tahoe (1.11.0) and
 Foolscap (0.6.5), and happened to configure `tub.location` using the
 modern recommendations (so `tub.location = tcp:HOST:PORT`). Unfortunately
 foolscap-0.6.5 can't handle that format: it can handle `HOST:PORT`, and
 `tcp:host=HOST:port=PORT`, but not `tcp:HOST:PORT`.

 0.6.5 is about the time we were experimenting with using client-endpoint
 strings as connection hints. 5 weeks later, we backed away from this in
 0.7.0, which accepts `HOST:PORT` and `tcp:HOST:PORT` but not the kind with
 the equals.

 Unfortunately debian/jesse froze the one foolscap release that behaves
 this way. The symptom is a !ValueError as it tries to look for "=" in the
 connection hint:

 {{{
 File "/usr/lib/python2.7/dist-packages/allmydata/node.py", line 385, in
 _setup_tub
             self.tub.setLocation(location)
           File "/usr/lib/python2.7/dist-packages/foolscap/pb.py", line
 510, in setLocation
             self._maybeCreateLogPortFURLFile()
           File "/usr/lib/python2.7/dist-packages/foolscap/pb.py", line
 450, in _maybeCreateLogPortFURLFile
             ignored = self.getLogPortFURL()
           File "/usr/lib/python2.7/dist-packages/foolscap/pb.py", line
 461, in getLogPortFURL
             furlFile=furlfile)
           File "/usr/lib/python2.7/dist-packages/foolscap/pb.py", line
 712, in registerReference
             sr = SturdyRef(oldfurl)
           File "/usr/lib/python2.7/dist-
 packages/foolscap/referenceable.py", line 897, in __init__
             decode_furl(url)
           File "/usr/lib/python2.7/dist-
 packages/foolscap/referenceable.py", line 850, in decode_furl
             location_hints = decode_location_hints(hints)
           File "/usr/lib/python2.7/dist-
 packages/foolscap/referenceable.py", line 820, in decode_location_hints
             fields = dict([f.split("=") for f in pieces[1:]])
         exceptions.ValueError: dictionary update sequence element #0 has
 length 1; 2 is required
 }}}

 This error could either happen when a client hears one of these FURLs from
 the introducer, when a client or server is configured with an
 introducer.furl in this format, or when any older node is configured with
 `tub.location=tcp:HOST:PORT` and is then booted a second time.

 The second-boot issue is that upon first boot, nodes write some of their
 generated FURLs into a "furlfile". This is where persistent FURLs (like
 the Introducer's `private/introducer.furl`, or a storage server's
 `private/storage.furl`) remember their "swissnum", the secret portion
 after the last slash. These recorded FURLs include `tub.location` as their
 connection hints. The node doesn't immediately care what's in these hints,
 it just advertises the FURLs to the introducer and writes them into the
 furlfiles.

 But on the second boot, if the furlfile exists, the node reads the
 contents back into memory and parses them (to get the swissnum). While
 parsing, as a side-effect, the node passes the connection hints to
 `decode_location_hints()`, which then raises an exception when it sees the
 `tcp:` prefix but not any `=` in the components.

 This exception means anything that is waiting for the Tub to be ready just
 won't get run, which means the Introducer Client isn't started, and the
 storage server isn't announced. And since the node has already daemonized
 by then, the original `tahoe start` doesn't show the error: you have to
 look in twistd.log to find out why we haven't heard anything from the
 introducer (this behavior is much better in current tahoe: `tahoe start`
 prints the traceback to stderr and then exits with an error).

 So even if you fix `tahoe.cfg` to set `tub.location = HOST:PORT`, you must
 also edit (or delete) those furlfiles (`private/introducer.furl`,
 `private/storage.furl`, `private/logport.furl`, maybe others I've missed),
 or the exception will happen again.

 The worst part is that I think this represents an incompatibility between
 Tahoe nodes created under debian/jesse and modern ones. If the modern
 nodes intentionally advertise old-style `HOST:PORT` hints, then they'll
 all work, but if they stick with the default `tcp:HOST:PORT`, then the
 jesse nodes will ignore those servers.

 I was hoping that we'd got the forwards-compatibility right, but Jesse
 captured the wrong version of Foolscap. If only we'd gotten Foolscap-0.7.0
 out a few weeks earlier, this wouldn't be a problem.

 So I guess the resolution for this ticket is to add a note to the docs
 under "Compatibility", pointing out that you have to configure your modern
 introducer or servers with old-style hints if you want them to be useable
 by jesse-based servers or clients.

--
Ticket URL: <https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2831>
Tahoe-LAFS <https://Tahoe-LAFS.org>
secure decentralized storage


More information about the tahoe-lafs-trac-stream mailing list