In ricochet-qt, contacts were stored with a sequential numeric ID, and
that was used in various places to refer to the contact uniquely. The
habit carried over here in an attempt to keep configuration
compatibility.
These IDs are error prone (particularly over RPC) and unnecessary. This
removes the entire concept and uses addresses to index and refer
uniquely to contacts everywhere.
The existing configuration was partially compatible with Ricochet's,
but not enough to actually be useful. It also required a bunch of
boilerplate code to copy data between configuration data structures,
internal data structures, and RPC data structures.
Protobuf conveniently supports encoding messages to JSON, and we already
need to store most data (e.g. contacts) in protobuf structures. This
commit changes the configuration to be a protobuf JSON serialization of
the Config message, which can directly reuse RPC messages like Contact.
Additionally, the RWMutex-based configuration type was a deadlock
waiting to happen. There is now a read-only clone of the configuration
available atomically at any time. Writers need an exclusive lock on the
ConfigFile object, which commits its changes to disk and readers on
unlock.
This implements a handler for inbound contact request connections,
taking advantage of the synchronous Process API.
This is largely untested code at the moment.
This includes connection management and enough to compile, but doesn't
reimplement most of the protocol messages and functionality yet. There
are problems noted throughout the code, also.
OnionConnector will now reset the backoff timer and try again
immediately when network connection status changes. Connection attempts
now scale up to 15 minutes, instead of waiting only 10 seconds each
time.
The default address will be set from the environment, or fall back to
trying 127.0.0.1:9051. There is now an API to allow this to be
overriden as well.
Improved parts of the conversation implementation, moved the
conversation event monitor to Identity, added event monitor
population, and other minor changes.
Refactor the connection management on contacts to have a goroutine
responsible for tracking the state of a contact's connection, launching
and canceling outbound attempts when appropriate, etc.
A race would cause a call to AddOnionPorts that was blocked waiting for
a control connection to try to publish the service twice, because the
onion republication wasn't done until after the connection status
change.
This is fixed by refactoring the control connection setup to do all
setup before signalling the state change, including copying the list of
onions to publish. The code is slightly cleaner now as well.
Also, slightly refactor Ricochet to be an interface to get the various
top-level components, and let the implementation define it (such as
backend's RicochetCore RPC type)
This is ugly API for now, but it's a simple and relatively safe
solution. It should be cleaned up later.
Data from the Config object can only be accessed by opening the "root"
for reading (OpenRead) or writing (OpenWrite). Multiple readers may be
open simultaneously, but only one writer, which guarantees atomic
behavior. There are ugly edge-cases for save errors and pointer-style
objects in the config tree, so use good behavior.