86f246dbdb
Starting to draw a distinction between clean-close and abrupt-halt. At least, if we're in the connected state, wormhole.close() should take its time and free up server-side resources (nameplate/mailbox) right away, rather than relying on GC/timeouts to release them. It might be useful to make separate "clean" wormhole.close() and "abrupt" wormhole.halt() API calls, except that really when would you ever call halt? To be realistic, only one of two things will happen: * connection happens normally, app finishes, calls "clean" close() * app terminates suddenly, via exception or SIGINT The problem with defining .close() is that I have to make it work sensibly from any state, not just the one plausible "connected" state. Providing .halt() requires defining its behavior from everywhere else.
223 lines
10 KiB
Plaintext
223 lines
10 KiB
Plaintext
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="<tab>"]
|
|
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="<tab>"]
|
|
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_P_connected [label="onConnect"]
|
|
C_P_connected [shape="box" label="M_connected()"]
|
|
C_P_connected -> C_S_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_P_lost [label="onClose"]
|
|
C_P_lost [shape="box" label="M_lost()\nstart timer"]
|
|
C_P_lost -> C_S_waiting
|
|
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="onClose"]
|
|
C_S_stopped [label="stopped"]
|
|
|
|
}
|