* add util to get onion address from private key
* PR comments: added test, using go-ricochet errors, function argument a privateKey
* remove unnecesary cast and variable
After the last round of fixes in Do, there was still one major issue
making it impossible to use Do or Break safely: closing connections.
Connections can be closed spontaneously, and this causes Process to
return. At that moment any ongoing call to Do or Break has deadlocked;
nothing will ever read those channels again. To prevent this, we have to
ensure that Do or Break won't try to send to Process' channels once it
has stopped reading from them. Doing that without other races is tricky.
The solution here, briefly, is to acquire a mutex in Do and Break before
checking the `closed` boolean, and hold that mutex for the entire
operation (including any blocking channel operations). When Process is
closing down the connection, it uses a separate goroutine to acquire the
same mutex and change the boolean, while still handling channel reads.
Once the boolean has changed, the mutex guarantees that nothing will try
to send to these channels again.
I've tried to document the problems and solutions in the code, because
it is subtle in some places and this is definitely critical code.
ChatChannel didn't return the message ID for sent messages, which made
using the returned ACKs impossible. The SendMessage method now returns
the uin32 messageID.
Also, SendMessage didn't support the TimeDelta field for messages, which
is used for queued or resent messages. This is now available as
SendMessageWithTime.
And finally, the ChatMessageAck callback didn't indicate if mesasges
were accepted or not, which is part of the protocol. That was added as a
field, which is unfortunately a breaking API change, but I've made
enough of those lately to not feel guilty about it.
SendRicochetPacket now has error handling, correctly encodes channel
ids, accepts any io.Writer, and ensures that all data is written. All
callers should be changed at some point to handle errors also.
RecvRicochetPackets is refactored to return only one packet per call and
avoid reading more data than it will consume, which simplifies the logic
and fixes a number of problems with short reads or large packets. Also
fixed an error in bounds checking that caused a remote panic for invalid
packet sizes. It also now accepts any io.Reader.
Tests are updated and expanded, and now pass.
Changes to Ricochet.processConnection are whitespace-only, because of
the removal of the inner packets loop.