Skip to content

Commit d965d44

Browse files
committed
feat: Improve protocol availability
1 parent f3e1736 commit d965d44

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed

logic/background_worker.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from core.trad_crypto import (
1919
decrypt_xchacha20poly1305
2020
)
21-
from base64 import urlsafe_b64encode
21+
from base64 import b64decode, urlsafe_b64encode
2222
import copy
2323
import logging
2424

@@ -67,17 +67,43 @@ def parse_blobs(blobs: list[bytes]) -> dict:
6767
return parsed_messages
6868

6969
def background_worker(user_data, user_data_lock, ui_queue, stop_flag):
70-
# Incase we received a SMP question request last time and user did not answer it.
71-
# NOTE: this is not needed anymore, as we have implemented acknowlegements
72-
# smp_unanswered_questions(user_data, user_data_lock, ui_queue)
7370

7471
# Acknowledgements
7572
acks = {}
7673

7774
while not stop_flag.is_set():
75+
7876
with user_data_lock:
7977
server_url = user_data["server_url"]
8078
auth_token = user_data["token"]
79+
session_headers = user_data["tmp"]["session_headers"]
80+
81+
user_data_copied = copy.deepcopy(user_data)
82+
83+
84+
for i, v in user_data_copied["contacts"].items():
85+
for msg_payload in v["staged_messages"]:
86+
try:
87+
http_request(f"{server_url}/data/send", "POST", metadata = {
88+
"recipient": i
89+
},
90+
blob = b64decode(msg_payload),
91+
headers = session_headers,
92+
auth_token = auth_token
93+
)
94+
logger.info("Successfuly recovered and sent the message to contact (%s)", i)
95+
96+
with user_data_lock:
97+
user_data["contacts"][i]["staged_messages"].pop(0)
98+
99+
if not user_data["contacts"][i]["staged_messages"]:
100+
user_data["contacts"][i]["locked"] = False
101+
102+
except Exception as e:
103+
logger.error("Failed to send recovered message to contact (%s), error: %s", i, str(e))
104+
break
105+
106+
81107

82108
try:
83109
# Random longpoll number to help obfsucate traffic against analysis
@@ -109,20 +135,28 @@ def background_worker(user_data, user_data_lock, ui_queue, stop_flag):
109135
sender = message["sender"]
110136
blob = message["blob"]
111137

112-
ack_id = urlsafe_b64encode(message["ack_id"]).decode().rstrip("=")
113-
if "acks" not in acks:
114-
acks["acks"] = [ack_id]
115-
else:
116-
acks["acks"].append(ack_id)
117-
118138
with user_data_lock:
119139
try:
120-
user_data["contacts"][sender]["locked"] = True
140+
141+
if user_data["contacts"][sender]["locked"] is False:
142+
user_data["contacts"][sender]["locked"] = True
143+
else:
144+
logger.info("Skipping data message from contact (%s) as contact is locked.", contact_id)
145+
continue
146+
121147
except Exception:
122148
pass
123149

124150
user_data_copied = copy.deepcopy(user_data)
125151

152+
153+
154+
ack_id = urlsafe_b64encode(message["ack_id"]).decode().rstrip("=")
155+
if "acks" not in acks:
156+
acks["acks"] = [ack_id]
157+
else:
158+
acks["acks"].append(ack_id)
159+
126160
# Everything from here is not validated by server
127161

128162
blob_plaintext = None

logic/contacts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def save_contact(user_data: dict, user_data_lock, contact_id: str) -> None:
9797

9898
}
9999
},
100+
"staged_messages": [],
100101
"our_next_strand_key": None,
101102
"contact_next_strand_key": None,
102103
"our_next_strand_nonce": None,

logic/message.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
XCHACHA20POLY1305_NONCE_LEN
4141

4242
)
43+
from base64 import b64encode
4344
import secrets
4445
import logging
4546

@@ -145,6 +146,8 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
145146

146147
if user_data["contacts"][contact_id]["locked"]:
147148
return
149+
else:
150+
user_data["contacts"][contact_id]["locked"] = True
148151

149152

150153
if contact_kyber_public_key is None or contact_mceliece_public_key is None:
@@ -216,20 +219,24 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
216219
)
217220

218221
try:
219-
http_request(f"{server_url}/data/send", "POST", metadata = {
222+
http_request(f"{server_url}/data/sendd", "POST", metadata = {
220223
"recipient": contact_id
221224
},
222225
blob = ciphertext_blob,
223226
headers = session_headers,
224227
auth_token = auth_token
225228
)
226-
except Exception:
227-
ui_queue.put({"type": "showerror", "title": "Error", "message": "Failed to send our message to the server"})
228-
return False
229-
229+
logger.info("Successfuly sent the message to contact (%s)", contact_id)
230+
with user_data_lock:
231+
user_data["contacts"][contact_id]["locked"] = False
232+
except Exception as e:
233+
logger.error("Could not send new message to contact (%s), server gave us error: %s", contact_id, str(e))
234+
ui_queue.put({"type": "showerror", "title": "Error", "message": "Failed to send our message to the server. You do NOT need to resent it, we will resent it automatically once you regain internet connectivity."})
230235

231-
logger.info("Successfuly sent the message to contact (%s)", contact_id)
236+
with user_data_lock:
237+
user_data["contacts"][contact_id]["staged_messages"].append(b64encode(ciphertext_blob).decode())
232238

239+
save_account_data(user_data, user_data_lock)
233240

234241
return True
235242

0 commit comments

Comments
 (0)