digraph { /* could shave a RTT by committing to the nameplate early, before finishing the rest of the code input. While the user is still typing/completing the code, we claim the nameplate, open the mailbox, and retrieve the peer's PAKE message. Then as soon as the user finishes entering the code, we build our own PAKE message, send PAKE, compute the key, send VERSION. Starting from the Return, this saves two round trips. OTOH it adds consequences to hitting Tab. */ WM_start [label="Wormhole\nMachine" style="dotted"] WM_start -> WM_S_nothing [style="invis"] WM_S_nothing [label="know\nnothing"] WM_S_nothing -> WM_P_queue1 [label="API_send" style="dotted"] WM_P_queue1 [shape="box" style="dotted" label="queue\noutbound msg"] WM_P_queue1 -> WM_S_nothing [style="dotted"] WM_S_nothing -> WM_P_build_and_post_pake [label="WM_set_code()"] WM_P_build_and_post_pake [label="M_set_nameplate()\nbuild_pake()\nM_send(pake)" shape="box"] WM_P_build_and_post_pake -> WM_S_know_code WM_S_know_code [label="know code\n"] WM_S_know_code -> WM_P_queue2 [label="API_send" style="dotted"] WM_P_queue2 [shape="box" style="dotted" label="queue\noutbound msg"] WM_P_queue2 -> WM_S_know_code [style="dotted"] WM_S_know_code -> WM_P_compute_key [label="WM_rx_pake"] WM_S_know_code -> WM_P_mood_lonely [label="close"] WM_P_compute_key [label="compute_key()" shape="box"] WM_P_compute_key -> WM_P_post_version [label="pake ok"] WM_P_compute_key -> WM_P_mood_scary [label="pake bad"] WM_P_mood_scary [shape="box" label="M_close()\nmood=scary"] WM_P_mood_scary -> WM_P_notify_failure WM_P_notify_failure [shape="box" label="notify_failure()" color="red"] WM_P_notify_failure -> WM_S_closed WM_P_post_version [label="M_send(version)\nnotify_verifier()" shape="box"] WM_P_post_version -> WM_S_know_key WM_S_know_key [label="know_key\nunverified" color="orange"] WM_S_know_key -> WM_P_queue3 [label="API_send" style="dotted"] WM_P_queue3 [shape="box" style="dotted" label="queue\noutbound msg"] WM_P_queue3 -> WM_S_know_key [style="dotted"] WM_S_know_key -> WM_P_verify [label="WM_rx_msg()"] /* version or phase */ WM_S_know_key -> WM_P_mood_lonely [label="close"] /* more like impatient */ WM_P_verify [label="verify(msg)" shape="box"] WM_P_verify -> WM_P_accept_msg [label="verify good"] WM_P_verify -> WM_P_mood_scary [label="verify bad"] WM_P_accept_msg [label="deliver\ninbound\nmsg()" shape="box"] WM_P_accept_msg -> WM_P_send_queued WM_P_send_queued [shape="box" label="M_send()\nqueued"] WM_P_send_queued -> WM_S_verified_key WM_S_verified_key [color="green"] WM_S_verified_key -> WM_P_verify [label="WM_rx_msg()"] /* probably phase */ WM_S_verified_key -> WM_P_mood_happy [label="close"] WM_S_verified_key -> WM_P_send [label="API_send"] WM_P_mood_happy [shape="box" label="M_close()\nmood=happy"] WM_P_mood_happy -> WM_S_closed WM_P_mood_lonely [shape="box" label="M_close()\nmood=lonely"] WM_P_mood_lonely -> WM_S_closed WM_P_send [shape="box" label="M_send(msg)"] WM_P_send -> WM_S_verified_key WM_S_closed [label="closed"] WCM_start [label="Wormhole Code\nMachine" style="dotted"] WCM_start -> WCM_S_unknown [style="invis"] WCM_S_unknown [label="unknown"] WCM_S_unknown -> WCM_P_set_code [label="set"] WCM_P_set_code [shape="box" label="WM_set_code()"] WCM_P_set_code -> WCM_S_known WCM_S_known [label="known" color="green"] WCM_S_unknown -> WCM_P_list_nameplates [label="input"] WCM_S_typing_nameplate [label="typing\nnameplate"] WCM_S_typing_nameplate -> WCM_P_nameplate_completion [label=""] WCM_P_nameplate_completion [shape="box" label="completion?"] WCM_P_nameplate_completion -> WCM_P_list_nameplates WCM_P_list_nameplates [shape="box" label="NLM_update_nameplates()"] WCM_P_list_nameplates -> WCM_S_typing_nameplate WCM_S_typing_nameplate -> WCM_P_got_nameplates [label="C_rx_nameplates()"] WCM_P_got_nameplates [shape="box" label="stash nameplates\nfor completion"] WCM_P_got_nameplates -> WCM_S_typing_nameplate WCM_S_typing_nameplate -> WCM_P_finish_nameplate [label="finished\nnameplate"] WCM_P_finish_nameplate [shape="box" label="lookup wordlist\nfor completion"] WCM_P_finish_nameplate -> WCM_S_typing_code WCM_S_typing_code [label="typing\ncode"] WCM_S_typing_code -> WCM_P_code_completion [label=""] WCM_P_code_completion [shape="box" label="completion"] WCM_P_code_completion -> WCM_S_typing_code WCM_S_typing_code -> WCM_P_set_code [label="finished\ncode"] WCM_S_unknown -> WCM_P_allocate [label="allocate"] WCM_P_allocate [shape="box" label="C_allocate_nameplate()"] WCM_P_allocate -> WCM_S_allocate_waiting WCM_S_allocate_waiting [label="waiting"] WCM_S_allocate_waiting -> WCM_P_allocate_generate [label="WCM_rx_allocation()"] WCM_P_allocate_generate [shape="box" label="generate\nrandom code"] WCM_P_allocate_generate -> WCM_P_set_code /* NM_start [label="Nameplate\nMachine" style="dotted"] NM_start -> NM_S_unclaimed [style="invis"] NM_S_unclaimed [label="no nameplate"] NM_S_unclaimed -> NM_S_unclaimed [label="NM_release()"] NM_P_set_nameplate [shape="box" label="post_claim()"] NM_S_unclaimed -> NM_P_set_nameplate [label="NM_set_nameplate()"] NM_S_claiming [label="claim pending"] NM_P_set_nameplate -> NM_S_claiming NM_S_claiming -> NM_P_rx_claimed [label="rx claimed"] NM_P_rx_claimed [label="MM_set_mailbox()" shape="box"] NM_P_rx_claimed -> NM_S_claimed NM_S_claimed [label="claimed"] NM_S_claimed -> NM_P_release [label="NM_release()"] NM_P_release [shape="box" label="post_release()"] NM_P_release -> NM_S_releasing NM_S_releasing [label="release pending"] NM_S_releasing -> NM_S_releasing [label="NM_release()"] NM_S_releasing -> NM_S_released [label="rx released"] NM_S_released [label="released"] NM_S_released -> NM_S_released [label="NM_release()"] */ /* MM_start [label="Mailbox\nMachine" style="dotted"] MM_start -> MM_S_want_mailbox [style="invis"] MM_S_want_mailbox [label="want mailbox"] MM_S_want_mailbox -> MM_P_queue1 [label="MM_send()" style="dotted"] MM_P_queue1 [shape="box" style="dotted" label="queue message"] MM_P_queue1 -> MM_S_want_mailbox [style="dotted"] MM_P_open_mailbox [shape="box" label="post_open()"] MM_S_want_mailbox -> MM_P_open_mailbox [label="set_mailbox()"] MM_P_send_queued [shape="box" label="post add() for\nqueued messages"] MM_P_open_mailbox -> MM_P_send_queued MM_P_send_queued -> MM_S_open MM_S_open [label="open\n(unused)"] MM_S_open -> MM_P_send1 [label="MM_send()"] MM_P_send1 [shape="box" label="post add()\nfor message"] MM_P_send1 -> MM_S_open MM_S_open -> MM_P_release1 [label="MM_close()"] MM_P_release1 [shape="box" label="NM_release()"] MM_P_release1 -> MM_P_close MM_S_open -> MM_P_rx [label="rx message"] MM_P_rx [shape="box" label="WM_rx_pake()\nor WM_rx_msg()"] MM_P_rx -> MM_P_release2 MM_P_release2 [shape="box" label="NM_release()"] MM_P_release2 -> MM_S_used MM_S_used [label="open\n(used)"] MM_S_used -> MM_P_rx [label="rx message"] MM_S_used -> MM_P_send2 [label="MM_send()"] MM_P_send2 [shape="box" label="post add()\nfor message"] MM_P_send2 -> MM_S_used MM_S_used -> MM_P_close [label="MM_close()"] MM_P_close [shape="box" label="post_close(mood)"] MM_P_close -> MM_S_closing MM_S_closing [label="waiting"] MM_S_closing -> MM_S_closing [label="MM_close()"] MM_S_closing -> MM_S_closed [label="rx closed"] MM_S_closed [label="closed"] MM_S_closed -> MM_S_closed [label="MM_close()"] */ /* upgrading to new PAKE algorithm, the slower form (the faster form puts the pake_abilities record in the nameplate_info message) */ /* P2_start [label="(PAKE\nupgrade)\nstart"] P2_start -> P2_P_send_abilities [label="set_code()"] P2_P_send_abilities [shape="box" label="send pake_abilities"] P2_P_send_abilities -> P2_wondering P2_wondering [label="waiting\nwondering"] P2_wondering -> P2_P_send_pakev1 [label="rx pake_v1"] P2_P_send_pakev1 [shape="box" label="send pake_v1"] P2_P_send_pakev1 -> P2_P_process_v1 P2_P_process_v1 [shape="box" label="process v1"] P2_wondering -> P2_P_find_max [label="rx pake_abilities"] P2_P_find_max [shape="box" label="find max"] P2_P_find_max -> P2_P_send_pakev2 P2_P_send_pakev2 P2_P_send_pakev2 [shape="box" label="send pake_v2"] P2_P_send_pakev2 -> P2_P_process_v2 [label="rx pake_v2"] P2_P_process_v2 [shape="box" label="process v2"] */ /* ConnectionMachine */ C_start [label="Connection\nMachine" style="dotted"] C_start -> C_S_connecting [label="C_start()"] C_S_connecting [label="connecting"] C_S_connecting -> C_S_connected [label="connected"] C_S_connecting -> C_P_stop_connecting [label="C_stop()"] C_P_stop_connecting [shape="box" label="cancel\nconnection\nattempt"] C_P_stop_connecting -> C_S_stopped C_S_connected [label="connected" color="green"] C_S_connected -> C_S_waiting [label="lost"] C_S_waiting [label="waiting"] C_S_waiting -> C_S_connecting [label="expire"] C_S_waiting -> C_S_stopped [label="C_stop()"] C_S_connected -> C_S_stopping [label="C_stop()"] C_S_stopping [label="stopping"] C_S_stopping -> C_S_stopped [label="stopped"] C_S_stopped [label="stopped"] }