Starting to draw a distinction between clean-close and abrupt-halt. At least,
if we're in the connected state, wormhole.close() should take its time and
free up server-side resources (nameplate/mailbox) right away, rather than
relying on GC/timeouts to release them.
It might be useful to make separate "clean" wormhole.close() and "abrupt"
wormhole.halt() API calls, except that really when would you ever call halt?
To be realistic, only one of two things will happen:
* connection happens normally, app finishes, calls "clean" close()
* app terminates suddenly, via exception or SIGINT
The problem with defining .close() is that I have to make it work sensibly
from any state, not just the one plausible "connected" state. Providing
.halt() requires defining its behavior from everywhere else.
Starting on defining manager state machines for nameplates, mailboxes, the
PAKE key-establishment process, and the bit that knows it can drop the
connection when both nameplates and mailboxes have been released.
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes#64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes#97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.