The return value indicates whether any batch IDs were written.
AckWriter.finish() and Database.removeBatchesToAck() are only called
if at least one batch ID was written.
The initiator flag in the transport protocol makes this unnecessary by
linking the two sides of a stream-mode connection, making it
impossible for an attacker to replay the responder's side of a
different connection.
The flag is used to distinguish between the initiator and responder
directions of a stream-mode connection, allowing them to use the same
connection number without risking IV reuse.
The flag is also raised for batch-mode connections, which only have
one direction.
This should provide acceptable memory usage and database locking
granularity, while making subscription and transport updates large
enough for the incremental update issue to be kicked into the long
grass.
Removed awareness of the serialisation format from the protocol
component wherever possible, and added tests to ensure that the
constants defined in the protocol package's API are compatible with
the serialisation format.
authenticate each frame before parsing its contents. Each connection
starts with a tag, followed by any number of frames, each starting
with the frame number (32 bits) and payload length (16 bits), and
ending with a MAC (256 bits).
Tags have the following format: 32 bits reserved, 16 bits for the
transport ID, 32 bits for the connection number, 32 bits (set to zero
in the tag) for the frame number, and 16 bits (set to zero in the tag)
for the block number. The tag is encrypted with the tag key in
ECB mode.
Frame numbers for each connection must start from zero and must be
contiguous and strictly increasing. Each frame is encrypted with the
frame key in CTR mode, using the plaintext tag with the appropriate
frame number to initialise the counter.
The maximum frame size is 64 KiB, including header and footer. The
maximum amount of data that can be sent over a connection is 2^32
frames - roughly 2^48 bytes, or 8 terabytes, with the maximum frame
size of 64 KiB. If that isn't sufficient we can add another 16 bits to
the frame counter.
acceptable timestamp of subscribed messages. For a new subscription,
the timestamp is initialised to the current time, so a new subscriber
to a group will not immediately receive any messages. (Subscribing to
a group is therefore more like joining a mailing list than joining a
Usenet group - you only receive messages written after you joined.)
Once the database fills up and starts expiring messages, the
timestamps of subscriptions are updated so that contacts need not send
messages that would expire immediately. This is done using the
*approximate* timestamp of the oldest message in the database, to
avoid revealing the presence or absence of any particular message.