oxen-io / session-protocol-docs

Documentation for Session
https://getsession.org/
5 stars 3 forks source link

Persistent queue for outgoing messages #5

Open msgmaxim opened 4 years ago

msgmaxim commented 4 years ago

Currently (at least on Desktop) there is only a cache for incoming messages. It allows, for instance, messages that couldn't get decrypted in time (e.g. the app is closed) to be retired after the app is restarted. This is also helpful for groups with sender keys: if the sender key is missing, the app can request the key from the sender and attempt to decrypt the message afterwards. (This is not so useful for regular messages: failure to decrypt a message would probably result in a session reset, rendering the old ciphertext unusable.)

However, there is no such mechanism for outgoing messages. We often find ourselves in a situation where the client wants to send a regular message, but the session does not exist, or it might exist for some but not all devices or group members (relevant for small groups mostly). There does not seem to be a clear way to delay message sending until the session is established. So until now the "solution" has often been to replace the current message with a message that triggers a new session creation (e.g. a friend request), which is clearly suboptimal. It might not be a big issue if this happens to a regular text message, but a control message (for example, a group update) should probably have stronger delivery guaranties.

This document proposes creating a database backed queue for outgoing messages, so that any failed message could be retried later on, even if the app has been restarted. This would allow us to build abstractions like "send a message establishing a session if necessary", which would put a message in the queue, request a new session, and send the message as soon as the session is established. This should simplify our existing codebase and make our app more robust.

neuroscr commented 4 years ago

For user generated messages, sure. A group of users is busy piling up messages but no session, sure, queue them all for when we do have a session. That solves "a clear way to delay message sending until the session is established."

But storing automated ones is an issue. Our software should be able to detect any state and recover from it. You have clients has been dormant for how long? Who knows what state messages have expired on the service node waiting for us? We can't have clients knowing their state with others without communication.

Adding a queue for automated messages is just going to make those issues harder to detect, we'll be sending signals from the past and then still will have to figure out the state. I think this will just be a hinderance instead of us actually fixing our protocol.

Even if you added an expiration to the queue but the truth of the matter is we don't have any form of delivery guarantee on this network (it's a network issue and a clients aren't able to hack around that).

So until now the "solution" has often been to replace the current message with a message that triggers a new session creation (e.g. a friend request), which is clearly suboptimal

Why is this suboptimal?

nielsandriesse commented 4 years ago

Mobile has this actually

msgmaxim commented 4 years ago

Why is this suboptimal?

Becasue the original message is lost. And if you are in a group/multidevice setup, there will be an inconsistent history of messages.

msgmaxim commented 4 years ago

Our software should be able to detect any state and recover from it.

We could have that too, I don't think these things are mutually exclusive.

Like you said, our control messages can already be lost, arrive delayed and so on... Eliminating one error case (no session) should make things easier not harder. It is another question how we should handle potentially conflicting comand messages arriving at the same time (or even out of order), and this is already somehing we have to do.

I have concrete cases in mind where the proposed system would help a lot. One is exchaning sender keys when a medium size group is created. Each client receives the new group info, and needs to send sender keys to everyone else. He might not have sessions with every member, so he would need a way to delay the message until the session is established (which might be after the app has restarted).