From 5686a7c58f58f8c6374e6bf17c2d5b1ea63a5efa Mon Sep 17 00:00:00 2001 From: Edouard Tisserant Date: Wed, 30 Nov 2016 02:56:53 +0100 Subject: [PATCH] ENGINE-133 timeout in retrieve_next_sync_msg - tested --- src/pEpmodule.cc | 24 +++++++------- src/sync_mixin.cc | 26 ++++++++------- src/sync_mixin.hh | 2 +- test/mp_sync_test.py | 22 +++++++++++++ test/multipEp.py | 77 +++++++++++++++++++++++++++----------------- 5 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/pEpmodule.cc b/src/pEpmodule.cc index aaf61de..33033d2 100644 --- a/src/pEpmodule.cc +++ b/src/pEpmodule.cc @@ -76,12 +76,12 @@ BOOST_PYTHON_MODULE(pEp) " lang ISO 639-1 language code for language being preferred\n" " on this communication channel\n" ) - .def(boost::python::init()) - .def(boost::python::init()) - .def(boost::python::init()) - .def(boost::python::init()) - .def(boost::python::init()) - .def(boost::python::init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) .def("__repr__", &Identity::_repr) .def("__str__", &Identity::_str, "string representation of this identity\n" @@ -128,9 +128,9 @@ BOOST_PYTHON_MODULE(pEp) " data bytes-like object\n" " mime_type MIME type for the data\n" " filename filename to store the data\n" , - boost::python::init< object, char const*, char const* >(args("data", "mime_type", "filename"))) - .def(boost::python::init()) - .def(boost::python::init()) + init< object, char const*, char const* >(args("data", "mime_type", "filename"))) + .def(init()) + .def(init()) .def("__repr__", &Message::Blob::_repr) .def("__len__", &Message::Blob::size, "size of Blob data in bytes") .def("decode", (string(Message::Blob::*)()) &Message::Blob::decode) @@ -165,9 +165,9 @@ BOOST_PYTHON_MODULE(pEp) "\n" " mime_text text in Multipurpose Internet Mail Extensions format\n" ) - .def(boost::python::init()) - .def(boost::python::init()) - .def(boost::python::init()) + .def(init()) + .def(init()) + .def(init()) .def("__str__", &Message::_str, "the string representation of a Message is it's MIME text" ) diff --git a/src/sync_mixin.cc b/src/sync_mixin.cc index 89b9785..967fdbe 100644 --- a/src/sync_mixin.cc +++ b/src/sync_mixin.cc @@ -69,9 +69,9 @@ namespace pEp { #endif jmp_buf SyncMixIn::env; - jmp_buf SyncMixIn::env_timeout; void *SyncMixIn::_msg; bool SyncMixIn::running_timeout = false; + bool SyncMixIn::expiring_timeout = false; int SyncMixIn::inject_sync_msg(void *msg, void *management) { @@ -94,21 +94,19 @@ namespace pEp { { static int twice = 1; twice = !twice; - if (!twice) - return (void *) _msg; - if (*timeout != 0){ - int val = setjmp(env_timeout); - if (!val){ + + if (!twice){ + if (expiring_timeout){ + *timeout = 1; + expiring_timeout = true; + } else if (_msg != NULL && *timeout != 0){ // call python timeout timer start auto that = dynamic_cast< SyncMixIn_callback * >( static_cast< SyncMixIn * > (management)); that->setTimeout(*timeout); running_timeout = true; - }else{ - running_timeout = false; - // this will inject tiemout event - return NULL; } + return (void *) _msg; } longjmp(env, 1); return (void *) 23; @@ -116,7 +114,13 @@ namespace pEp { // to be called from python timeout timer - may GIL protect us void SyncMixIn::onTimeout(){ - longjmp(env_timeout, 1); + _msg = NULL; + int val = setjmp(env); + if (!val){ + expiring_timeout = true; + do_sync_protocol(session, (void*)this); + running_timeout = false; + } } void SyncMixIn_callback::messageToSend(Message msg) diff --git a/src/sync_mixin.hh b/src/sync_mixin.hh index 19ae388..73b30b6 100644 --- a/src/sync_mixin.hh +++ b/src/sync_mixin.hh @@ -38,8 +38,8 @@ namespace pEp { pEp_identity *me, pEp_identity *partner); static jmp_buf env; - static jmp_buf env_timeout; static bool running_timeout; + static bool expiring_timeout; static void *_msg; static int inject_sync_msg(void *msg, void *management); static void *retrieve_next_sync_msg(void *management, time_t *timeout); diff --git a/test/mp_sync_test.py b/test/mp_sync_test.py index 3be8444..12a623e 100644 --- a/test/mp_sync_test.py +++ b/test/mp_sync_test.py @@ -144,6 +144,27 @@ def not_for_sync_in_a_group_of_3_members(pre_actions=[]): ("GroupA1", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_have_no_key)), ] : yield action +def timeout_while_group_on_keygen(): + for action in [ + ("GroupA1", [disable_auto_handshake, []]), + ("GroupA2", [disable_auto_handshake, []]) + ] : yield action + enc_msg = yield from pre_existing_peers_with_encrypted_mail() + for action in [ + ("GroupA2", [create_account, ["first@group.a", "GroupA First"]]), + (cycle_until_no_change, ["GroupA1", "GroupA2"], expect(3)), + ("GroupA1", [simulate_timeout, []]), + ("GroupA2", [simulate_timeout, []]), + (flush_all_mails,), + ("GroupA1", [enable_auto_handshake, []]), + ("GroupA2", [enable_auto_handshake, []]), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_have_no_key)), + (cycle_until_no_change, ["GroupA1", "GroupA2"], expect(4)), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)) + ] : yield action + + return enc_msg + if __name__ == "__main__": run_scenario(group_on_keygen) run_scenario(group_on_cannotdecrypt) @@ -152,4 +173,5 @@ if __name__ == "__main__": run_scenario(group_survives_restart) run_scenario(nokey_in_a_group_of_3_members) run_scenario(not_for_sync_in_a_group_of_3_members) + run_scenario(timeout_while_group_on_keygen) diff --git a/test/multipEp.py b/test/multipEp.py index 6d56bb8..d4f493e 100644 --- a/test/multipEp.py +++ b/test/multipEp.py @@ -20,6 +20,7 @@ indent = 0 i_name = "" handshakes_pending = [] handshakes_to_accept = [] +disable_handshake = False pEp = None # manager globals @@ -35,7 +36,7 @@ handshakes_validated = [] msgs_folders = None # ---------------------------------------------------------------------------- -# INSTANCE ACIONS +# INSTANCE ACTIONS # ---------------------------------------------------------------------------- def create_account(address, name, flags=None): @@ -79,8 +80,25 @@ def decrypt_message(msgstr): printi("---") return rating +def disable_auto_handshake(): + global disable_handshake + disable_handshake = True + +def enable_auto_handshake(): + global disable_handshake + disable_handshake = False + del handshakes_pending[:] + del handshakes_to_accept[:] + del handshakes_seen[:] + del handshakes_validated[:] + +def simulate_timeout(): + global sync_handler + sync_handler.onTimeout() + +no_inbox_decrypt = [disable_auto_handshake, enable_auto_handshake, simulate_timeout] # ---------------------------------------------------------------------------- -# MANAGER ACIONS +# MANAGER ACTIONS # ---------------------------------------------------------------------------- def flush_all_mails(): @@ -155,37 +173,39 @@ def printmsg(msg): def execute_order(order): global handshakes_pending, handshakes_to_accept, handshakes_seen - global handshakes_validated, msgs_folders, own_addresses + global handshakes_validated, msgs_folders, own_addresses, sync_handler + global disable_handshake func, args, kwargs, timeoff = order[0:] + [None, [], {}, 0][len(order):] printheader("DECRYPT messages") # decrypt every non-consumed message for all instance accounts - for own_address in own_addresses: - msgs_for_me = msgs_folders.get(own_address, []) - for msgstr in msgs_for_me: - msg = pEp.incoming_message(msgstr) - printi("--- decrypt()") - msg.recv = int(time.time() + timeoff) - printmsg(msg) - msg2, keys, rating, consumed, flags = msg.decrypt() - - if consumed == "MESSAGE_CONSUME": - printi("--- PEP_MESSAGE_CONSUMED") - # folder may have changed in the meantime, - # remove item directly from latest version of it. - folder = msgs_folders[own_address] - folder.remove(msgstr) - msgs_folders[own_address] = folder - elif consumed == "MESSAGE_IGNORE": - printi("--- PEP_MESSAGE_DISCARDED") - else : - printi("->-", rating, "->-") - printmsg(msg2) - printi("---") + if func not in no_inbox_decrypt : + for own_address in own_addresses : + msgs_for_me = msgs_folders.get(own_address, []) + for msgstr in msgs_for_me: + msg = pEp.incoming_message(msgstr) + printi("--- decrypt()") + msg.recv = int(time.time() + timeoff) + printmsg(msg) + msg2, keys, rating, consumed, flags = msg.decrypt() + + if consumed == "MESSAGE_CONSUME": + printi("--- PEP_MESSAGE_CONSUMED") + # folder may have changed in the meantime, + # remove item directly from latest version of it. + folder = msgs_folders[own_address] + folder.remove(msgstr) + msgs_folders[own_address] = folder + elif consumed == "MESSAGE_IGNORE": + printi("--- PEP_MESSAGE_DISCARDED") + else : + printi("->-", rating, "->-") + printmsg(msg2) + printi("---") printheader() - if handshakes_pending: + if handshakes_pending and not disable_handshake: printheader("check pending handshakes accepted on other device") for tple in handshakes_pending: tw, partner = tple @@ -205,7 +225,7 @@ def execute_order(order): printi("function " + func.__name__ + " returned :", res) printheader() - if handshakes_to_accept: + if handshakes_to_accept and not disable_handshake: printheader("apply to-accept-because-already-seen handshakes") for tple in handshakes_to_accept: tw, partner = tple @@ -257,8 +277,7 @@ def pEp_instance_run(iname, _own_addresses, conn, _msgs_folders, _handshakes_see printi("SET TIMEOUT :", timeout) def cancelTimeout(self): - printi("CANCEL TIMEOUT !") - + printi("CANCEL TIMEOUT") sync_handler = Handler()