/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 8 - 2 0 2 1 ĠNet Found ry ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . open z iti . impl Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . channels . Buffer Overflow Ċ import Ġkotlinx . coroutines . flow .* Ċ import Ġkotlinx . coroutines . future . as Comp letableFuture Ċ import Ġkotlinx . coroutines . select s . select Ċ import Ġorg . open z iti .* Ċ import Ġorg . open z iti . api .* Ċ import Ġorg . open z iti . identity . Identity Ċ import Ġorg . open z iti . net .* Ċ import Ġorg . open z iti . net . dns . Z iti DNS Manager Ċ import Ġorg . open z iti . net . nio . As ych Channel Socket Ċ import Ġorg . open z iti . net . nio . connect Suspend Ċ import Ġorg . open z iti . net . routing . Route Manager Ċ import Ġorg . open z iti . post ure . Posture Service Ċ import Ġorg . open z iti . util . IP Util Ċ import Ġorg . open z iti . util . Logged Ċ import Ġorg . open z iti . util . Z iti Log Ċ import Ġjava . io . Writer Ċ import Ġjava . net .* Ċ import Ġjava . nio . channels . As ynchronous Server SocketChannel Ċ import Ġjava . nio . channels . As ynchronous SocketChannel Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . properties . Deleg ates Ċ import Ġkotlin . random . Random Ċ import Ġorg . open z iti . api . Identity Ġas ĠApi Identity Ċ Ċ /** Ċ Ġ* ĠObject Ġmaintaining Ġcurrent ĠZ iti Ġsession . Ċ Ġ* Ċ Ġ*/ Ċ internal Ġclass ĠZ iti Context Impl ( internal Ġval Ġid : ĠIdentity , Ġenabled : ĠBoolean ) Ġ: ĠZ iti Context , ĠIdentity Ġby Ġid , ĊĠĠĠ ĠCor outine Scope , ĠLog ged Ġby ĠZ iti Log () Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġ_ enabled : ĠBoolean Ġby ĠDeleg ates . observable ( enabled ) Ġ{ Ġ_, Ġ_, Ġis Enabled Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( isEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( status Ch . value Ġ== ĠZ iti Context . Status . Disabled ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ch . value Ġ= ĠZ iti Context . Status . Active ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ch . value Ġ= ĠZ iti Context . Status . Disabled ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġrefresh Delay Ġ= ĠTimeUnit . MIN UTES . to Millis ( 1 ) ĊĊĠĠĠ Ġprivate Ġval Ġsupervisor Ġ= ĠSuper visor Job () ĊĠĠĠ Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠDispatch ers . IO Ġ+ Ġsupervisor ĊĊĠĠĠ Ġprivate Ġval Ġapi Session Ġ= ĠMutable State Flow < Api Session ? >( null ) ĊĠĠĠ Ġprivate Ġval Ġcurrent Edge Rout ers Ġ= ĠMutable State Flow < Collection < Edge Router >>( emptyList ()) ĊĊĠĠĠ Ġprivate Ġval Ġcontroller : ĠController Ġ= ĠController ( URI . create ( id . controller ()). to URL (), Ġssl Context (), Ġtrust Manager ()) ĊĠĠĠ Ġprivate Ġval Ġpost ure Service Ġ= ĠPost ure Service () ĊĊĠĠĠ Ġprivate Ġval Ġstatus Ch : ĠMutable State Flow < Z iti Context . Status > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ= ĠMutable State Flow ( if Ġ( enabled ) ĠZ iti Context . Status . Loading Ġelse ĠZ iti Context . Status . Disabled ) ĊĊĠĠĠ Ġprivate Ġval Ġservice Ch : ĠMutable Shared Flow < Z iti Context . Service Event > Ġ= ĠMutable Shared Flow () ĊĊĠĠĠ Ġprivate Ġval Ġauth Code Ġ= Ġkotlinx . coroutines . channels . Channel < String >( capacity Ġ= Ġ 1 , ĠBuffer Overflow . DROP _ OL DEST ) ĊĊĠĠĠ Ġprivate Ġval Ġservices Loaded Ġ= ĠComp letable Deferred < Unit >() ĊĠĠĠ Ġprivate Ġval Ġservices ByName Ġ= ĠConcurrent HashMap < String , ĠService >() ĊĠĠĠ Ġprivate Ġval Ġservices ById Ġ= Ġmutable Map Of < String , ĠService >() ĊĊĠĠĠ Ġprivate Ġval Ġservices By Addr Ġ= Ġmutable Map Of < Inet Address , ĠMutable Map < Port Range , Service >>() ĊĊĠĠĠ Ġ// ĠTODO Ġprivate Ġval Ġaddr ById Ġ= Ġmutable Map Of < String , ĠInet SocketAddress >() ĊĊĠĠĠ Ġdata Ġclass ĠSession Key Ġ( val Ġservice Id : ĠString , Ġval Ġtype : ĠSession Type ) ĊĠĠĠ Ġprivate Ġval Ġnetwork Sessions Ġ= ĠConcurrent HashMap < Session Key , ĠSession >() ĊĊĠĠĠ Ġprivate Ġval Ġconn Counter Ġ= ĠAtomicInteger ( 0 ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġthis ._ enabled Ġ= Ġenabled ĊĊĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ch . collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd Ġ{ Ġ"${ this @ Z iti Context Impl } Ġtransition ed Ġto Ġ$ it " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== ĠZ iti Context . Status . Disabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġstart () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Identity () Ġ= Ġapi Session . map NotNull { Ġit ?. identity Ġ} ĊĠĠĠ Ġoverride Ġfun ĠgetId (): ĠApi Identity ? Ġ= Ġapi Session . value ?. identity ĊĊĠĠĠ Ġoverride Ġfun ĠgetStatus () Ġ= Ġstatus Ch . value ĊĠĠĠ Ġoverride Ġfun Ġstatus Updates (): ĠState Flow < Z iti Context . Status > Ġ= Ġstatus Ch ĊĊĠĠĠ Ġ//@ Experimental Cor outines Api ĊĠĠĠ Ġoverride Ġfun Ġservice Updates (): ĠFlow < Z iti Context . Service Event > Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġemit All ( services ByName . values . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠZ iti Context . Service Event ( it , ĠZ iti Context . Service Update . Available ) ĊĠĠĠĠĠĠĠ Ġ}. as Flow ()) ĊĊĠĠĠĠĠĠĠ Ġemit All ( service Ch ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Service Termin ators ( service : ĠService ): ĠCollection < Service Termin ator > Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġcontroller . getService Termin ators ( service ). to Collection ( mutable ListOf ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Status ( s : ĠZ iti Context . Status ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( status Ch . value Ġ!= ĠZ iti Context . Status . Disabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ch . value Ġ= Ġs ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġset Enabled ( v : ĠBoolean ) Ġ{ Ġ_ enabled Ġ= Ġv Ġ} ĊĠĠĠ Ġprivate Ġfun Ġcheck Enabled () Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ enabled Ġ|| Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdial ( serviceName : ĠString ): ĠZ iti Connection Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdial ( Z iti Address . Dial ( serviceName )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdial ( dial Addr : ĠZ iti Address . Dial ): ĠZ iti Connection Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrun Blocking Ġ{ Ġdial Suspend ( dial Addr ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġdial Suspend ( dial Addr : ĠZ iti Address . Dial ): ĠZ iti Connection Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Enabled () ĊĠĠĠĠĠĠĠ Ġval Ġconn Ġ= Ġopen () Ġas ĠZ iti SocketChannel ĊĠĠĠĠĠĠĠ Ġconn . connect Suspend ( dial Addr ) ĊĠĠĠĠĠĠĠ Ġreturn Ġconn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdial ById ( service Id : ĠString ): ĠZ iti Connection Ġ= ĊĠĠĠĠĠĠĠ Ġservices ById [ service Id ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdial ( it . name ) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĊĊĠĠĠ Ġinternal Ġfun Ġdial ( host : ĠString , Ġport : ĠInt ): ĠZ iti Connection Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġservice Ġ= Ġget Service ( host , Ġport ) Ġ?: Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdial ( service . name ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdial ( host : ĠInet Address , Ġport : ĠInt ): ĠZ iti Connection Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġports Ġ= Ġservices By Addr . get ( host ) Ġ?: Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ(( range , Ġs ) Ġin Ġports ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( range . contains ( port )) Ġreturn Ġdial ( s . name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġconnect ( host : ĠString , Ġport : ĠInt ): ĠSocket Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Enabled () ĊĠĠĠĠĠĠĠ Ġval Ġch Ġ= Ġopen () ĊĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġget Service ( host , Ġport ) Ġ?: Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ Ġch . connect Suspend ( Z iti Address . Dial ( s . name )) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠAs ych Channel Socket ( ch ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart (): ĠJob Ġ= Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ Ġrunner () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Failure Ġ{ Ġcancel (" z iti Ġcontext Ġfailed ", Ġit ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġrunner () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession Ġ= Ġrun Catch ing Ġ{ Ġlogin () Ġ}. getOrElse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe (" failed Ġto Ġlogin , Ġcannot Ġcontinue ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Status ( Z iti Context . Status . Not Authorized ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġapi Session . value Ġ= Ġsession ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm fa Ġ= Ġsession . auth Queries . find Ġ{ Ġit . type Id Ġ== ĠM FA Type . M FA Ġ&& Ġit . provider Ġ== Ġ" z iti " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m fa Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Status ( Z iti Context . Status . Needs Auth ( m fa . type Id Ġ?: ĠM FA Type . CUSTOM , Ġm fa . provider )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsuccess Ġ= Ġrun Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcode Ġ= Ġauth Code . receive () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller . auth M FA ( code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. getOrElse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Status ( Z iti Context . Status . Not Authorized ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! success ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Status ( Z iti Context . Status . Active ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġapi Session Update Ġ= Ġmaintain Api Session () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġservice Update Ġ= Ġrun Service Updates () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinish er Ġ= Ġselect < Job > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Session Update . on Join Ġ{ Ġapi Session Update Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice Update . on Join Ġ{ Ġservice Update Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish er . invoke On Completion Ġ{ Ġex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġw Ġ{" $ finish er Ġis Ġcompleted Ġdue Ġto Ġ$ ex "} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( api Session Update , Ġservice Update ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . cancel And Join () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Sessions . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcopy Ġ= Ġchannels . values . toList () ĊĠĠĠĠĠĠĠ Ġchannels . clear () ĊĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcopy . forEach Ġ{ Ġch Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd {" closing Ġ${ ch . name } "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġch . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdestroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġd {" stopping Ġnetworking "} ĊĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġd {" stopping Ġcontroller "} ĊĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ Ġcontroller . shutdown () Ġ} ĊĠĠĠĠĠĠĠ Ġd {" sh ut ting Ġdown "} ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ Ġsupervisor . cancel And Join () Ġ} ĊĠĠĠĠĠĠĠ Ġd {" z iti Ġcontext Ġis Ġfinished "} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġlogin (): ĠApi Session Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġattempt Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġstatus Ch . value Ġ= ĠZ iti Context . Status . Loading ĊĠĠĠĠĠĠĠ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( attempt Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbackoff Ġ= ĠRandom . nextInt ( 0 , Ġattempt ) Ġ% Ġ 6 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdelay Seconds Ġ= Ġ( 1 Ġshl Ġbackoff ) Ġ* Ġ 5 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd { Ġ" retry ing Ġlogin () Ġafter Ġ${ delay Seconds } s Ġ( attempt =$ attempt ) "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( delay Seconds Ġ* Ġ 1 0 0 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcontroller . login () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex Ġis ĠZ iti Exception Ġ&& Ġex . code Ġ== ĠErrors . Not Authorized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Status ( Z iti Context . Status . Unavailable ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġw Ġ{ Ġ" failed Ġto Ġlogin : Ġ${ ex . localized Message }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġattempt ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmaintain Api Session () Ġ= Ġasync Ġ{ ĊĠĠĠĠĠĠĠ Ġapi Session . collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrefresh Delay Ġ= Ġit . expires At . time Ġ- Ġit . updatedAt . time Ġ- Ġ 1 0 _ 0 0 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( refresh Delay Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd Ġ{ Ġ" waiting Ġfor Ġrefresh Ġ${ refresh Delay Ġ/ Ġ 1 0 0 0 } Ġseconds " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( refresh Delay ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller . run Catch ing Ġ{ Ġcurrent Api Session () Ġ}. on Failure Ġ{ Ġex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġw Ġ{ Ġ" failed Ġto Ġget Ġcurrent Ġsession : Ġ$ ex " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Session . value Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex Ġis ĠZ iti Exception Ġ&& Ġex . code Ġ== ĠErrors . Not Authorized ) Ġthrow Ġex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Success Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Session . value Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrun Service Updates () Ġ= Ġasync Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġlast Update Ġ= ĠDate ( 0 ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġone Update Ġ= Ġasync Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd ("[ ${ id . name ()} ] Ġsle pt Ġand Ġrestart ing Ġon Ġt [ ${ Thread . currentThread (). name }] ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġup dt Ġ= Ġcontroller . getService Updates () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( up dt . last Change At . after ( last Update )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Update Ġ= Ġup dt . last Change At ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġservices Ġ= Ġcontroller . get Services (). toList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Service Updates ( services ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd ("[ ${ id . name ()} ] Ġgot Ġ${ services . size } Ġservices Ġon Ġt [ ${ Thread . currentThread (). name }] ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller . run Catch ing Ġ{ Ġget Edge Rout ers () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Success Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi {" current Ġedge Ġrout ers Ġ= Ġ$ it "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Edge Rout ers . value Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Failure Ġ{ Ġw (" failed Ġto Ġget Ġcurrent Ġedge Ġrout ers : Ġ$ it ") Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġone Update . join () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġone Update . invoke On Completion Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC ancellation Exception Ġ-> Ġ{ Ġcancel ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠZ iti Exception Ġ-> Ġif Ġ( it . code Ġ== ĠErrors . Not Authorized ) Ġthrow Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġd {" delay ing Ġservice Ġrefresh Ġfor Ġ${ refresh Delay } ms "} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( refresh Delay ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġlogout () Ġ= Ġrun Blocking Ġ{ Ġcontroller . logout () Ġ} ĊĊĠĠĠ Ġfun Ġcheck Services Loaded () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Timeout ( 3 0 _ 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices Loaded . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( tex : ĠTimeout Cancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe (" failed Ġto Ġload Ġservices : Ġ$ tex ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġget Network Session ( service : ĠService , Ġst : ĠSession Type ): ĠSession Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Enabled () ĊĊĠĠĠĠĠĠĠ Ġd (" get Network Session (${ service . name }) ") ĊĠĠĠĠĠĠĠ Ġcheck Services Loaded () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnetwork Sessions . get Or Put ( Session Key ( service . id , Ġst )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnet Session Ġ= Ġcontroller . create Net Session ( service , Ġst ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt (" received Ġ$ net Session Ġfor Ġservice [ ${ service . name }] ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnet Session ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġget Network Session ( name : ĠString , Ġst : ĠSession Type ): ĠSession Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Services Loaded () ĊĊĠĠĠĠĠĠĠ Ġval Ġservice Ġ= Ġservices ByName . get ( name ) Ġ?: Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! service . permissions . contains ( st )) Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġget Network Session ( service , Ġst ) ĊĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġget Dns Target ( addr : ĠInet SocketAddress ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( addr . address Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠZ iti DNS Manager . lookup ( addr . address ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( IP Util . isValid IPv 4 ( addr . host String )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġaddr . host String ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget IP target ( addr : ĠInet SocketAddress ): ĠInet Address ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( addr . address Ġ!= Ġnull ) Ġreturn Ġaddr . address ĊĊĠĠĠĠĠĠĠ Ġif Ġ( IP Util . isValid IPv 4 ( addr . host String )) Ġreturn ĠInet 4 Address . get ByName ( addr . host String ) ĊĠĠĠĠĠĠĠ Ġif Ġ( IP Util . isValid IPv 6 ( addr . host String )) Ġreturn ĠInet 6 Address . get ByName ( addr . host String ) ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Dial Address ( addr : ĠInet SocketAddress , Ġproto : ĠProtocol Ġ= ĠProtocol . TCP ): ĠZ iti Address . Dial ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtarget Addr Ġ= Ġget Dns Target ( addr ) Ġ?: Ġget IP target ( addr ) Ġ?: Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġservice Ġ= Ġservices ById . values . first OrNull Ġ{ Ġs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs . permissions . contains ( Session Type . Dial ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs . intercept Config ?. let Ġ{ Ġcfg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcfg . protocols . contains ( proto ) Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcfg . port Ranges . any Ġ{ Ġit . contains ( addr . port ) Ġ} Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcfg . addresses . any Ġ{ Ġit . matches ( target Addr ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġreturn ĠZ iti Address . Dial ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Ġ= Ġservice . name , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcaller Id Ġ= Ġname (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Data Ġ= ĠD ial Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdst Protocol Ġ= Ġproto , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdst Hostname Ġ= Ġif Ġ( target Addr Ġis ĠString ) Ġtarget Addr Ġelse Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdst Ip Ġ= Ġif Ġ( target Addr Ġis ĠInet Address ) Ġtarget Addr . host Address Ġelse Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdst Port Ġ= Ġaddr . port . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Service ( addr : ĠInet SocketAddress ): ĠService ? Ġ= Ġget Service ( addr . host String , Ġaddr . port ) ĊĊĠĠĠ Ġoverride Ġfun Ġget Service ( name : ĠString ): ĠService ? Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Services Loaded () ĊĠĠĠĠĠĠĠ Ġreturn Ġservices ByName . get ( name ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Service ( host : ĠInet Address , Ġport : ĠInt ): ĠService Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Services Loaded () ĊĊĠĠĠĠĠĠĠ Ġservices By Addr . get ( host )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( range , Ġservice ) Ġin Ġit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( range . contains ( port )) Ġreturn Ġservice ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthrow ĠZ iti Exception ( Errors . Service Not Available ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Service ( host : ĠString , Ġport : ĠInt ): ĠService ? Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Services Loaded () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġservices ByName . values . find Ġ{ Ġsvc Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsvc . intercept Config ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . addresses . any Ġ{ Ġit . matches ( host ) Ġ} Ġ&& Ġit . port Ranges . any Ġ{ Ġr Ġ-> Ġport Ġin Ġr . low .. r . high Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġnext Conn Id () Ġ= Ġconn Counter . increment AndGet () ĊĊĠĠĠ Ġinternal Ġval Ġchannels Ġ= ĠConcurrent HashMap < String , ĠChannel >() ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġget Channel ( ns : ĠSession ): ĠChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ ers Ġ= Ġns . edge Rout ers Ġ?: Ġthrow ĠZ iti Exception ( Errors . Edge Router Unavailable ) ĊĊĠĠĠĠĠĠĠ Ġval Ġaddr List Ġ= Ġ ers . map Ġ{ Ġit . supported Protocols [" tls "] Ġ}. filter NotNull () ĊĊĠĠĠĠĠĠĠ Ġval Ġch Map Ġ= Ġsorted Map Of < Long , Channel >() ĊĠĠĠĠĠĠĠ Ġval Ġun connected Ġ= Ġmutable ListOf < Channel >() ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( addr Ġin Ġaddr List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġget Channel ( addr ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( val Ġs Ġ= Ġc . state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠChannel . State . Connected Ġ-> Ġch Map [ s . latency ] Ġ= Ġc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġun connected . add ( c ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( ch Map . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselected Ġ= Ġconnect All ( un connected ) Ġ?: Ġthrow ĠZ iti Exception ( Errors . Edge Router Unavailable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġd {" selected Ġ$ selected "} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġselected ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Scope Ġ{ Ġlaunch Ġ{ Ġconnect All ( un connected ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġch Map . entries . first (). value ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Channel ( addr : ĠString ): ĠChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġchannels . compute If Absent ( addr ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChannel ( it , Ġid ) Ġ{ Ġapi Session . value Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġconnect All ( rout ers : ĠCollection < Edge Router >) Ġ= Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠ Ġrout ers . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . supported Protocols [" tls "] ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Channel ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġconnect All ( ch List : ĠList < Channel >): ĠChannel ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ch List . isEmpty ()) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġreturn Ġselect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( ch Ġin Ġch List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġch . connect Now (). on Await Ġ{ Ġch Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġcan 't Ġjust Ġreplace Ġold Ġwith Ġnew Ġas Ġupdates Ġdo Ġnot Ġcontain Ġsession Ġtoken ĊĠĠĠ Ġ// Ġdo Ġupdate Ġlist Ġof Ġedge Ġrout ers Ġfor Ġthis Ġsession ĊĠĠĠ Ġprivate Ġfun Ġupdate Session ( s : ĠSession ): ĠSession ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsession Key Ġ= ĠSession Key ( s . service . id , Ġs . type ) ĊĠĠĠĠĠĠĠ Ġnetwork Sessions . containsKey ( session Key ) Ġ|| Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn Ġnetwork Sessions . merge ( session Key , Ġs ) Ġ{ Ġold , Ġnew Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġold . apply Ġ{ Ġedge Rout ers Ġ= Ġnew . edge Rout ers Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġprocess Service Updates ( services : ĠCollection < Service >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevents Ġ= Ġmutable ListOf < Z iti Context . Service Event >() ĊĊĠĠĠĠĠĠĠ Ġval Ġcurrent Ids Ġ= Ġservices . map Ġ{ Ġit . id Ġ}. to Collection ( mutable Set Of ()) ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġremoved Ġaccess ĊĠĠĠĠĠĠĠ Ġval Ġrt Mgr Ġ= ĠRoute Manager () ĊĊĠĠĠĠĠĠĠ Ġval Ġremove Ids Ġ= Ġservices ById . keys . filter Ġ{ Ġ! current Ids . contains ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( rid Ġin Ġremove Ids ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices ById . remove ( rid )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservices ByName . remove ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . intercept Config ?. addresses ?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC IDR Block Ġ-> Ġrt Mgr . remove Route ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDNS Name Ġ-> ĠZ iti DNS Manager . unregister Hostname ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDomain Name Ġ-> ĠZ iti DNS Manager . unregister Domain ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevents . add ( Z iti Context . Service Event ( it , ĠZ iti Context . Service Update . Unavailable )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Sessions . remove ( Session Key ( rid , ĠSession Type . Dial )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnetwork Sessions . remove ( Session Key ( rid , ĠSession Type . Bind )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġupdate ĊĠĠĠĠĠĠĠ Ġfor Ġ( s Ġin Ġservices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold V Ġ= Ġservices ByName . put ( s . name , Ġs ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old V Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevents . add ( Z iti Context . Service Event ( s , ĠZ iti Context . Service Update . Available )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old V . permissions Ġ!= Ġs . permissions Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġold V . config Ġ!= Ġs . config ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevents . add ( Z iti Context . Service Event ( s , ĠZ iti Context . Service Update . Configuration Change )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservices ById . put ( s . id , Ġs ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddresses Ġ= Ġs . intercept Config ?. addresses Ġ?: Ġempty Set () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Addresses Ġ= Ġold V ?. intercept Config ?. addresses Ġ?: Ġempty Set () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremoved Addresses Ġ= Ġold Addresses Ġ- Ġaddresses ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremoved Addresses . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC IDR Block Ġ-> Ġrt Mgr . remove Route ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDNS Name Ġ-> ĠZ iti DNS Manager . unregister Hostname ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDomain Name Ġ-> ĠZ iti DNS Manager . unregister Domain ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadded Addresses Ġ= Ġaddresses Ġ- Ġold Addresses ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadded Addresses . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġroute Ġ= Ġwhen ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDNS Name Ġ-> ĠC IDR Block ( Z iti DNS Manager . register Hostname ( it . name ), Ġ 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC IDR Block Ġ-> Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDomain Name Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠZ iti DNS Manager . register Domain ( it . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroute ?. let Ġ{ Ġrt Mgr . add Route ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġs . post ure Sets ?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . post ure Queries . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost ure Service . register Service Check ( s . id , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost ure Service . getPost ure (). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller . send Posture Resp ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Ch . emit All ( events . as Flow ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġservices Loaded . complete ( Unit ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġopen (): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Active () ĊĠĠĠĠĠĠĠ Ġreturn ĠZ iti SocketChannel ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġopen Server (): ĠAs ynchronous Server SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Active () ĊĠĠĠĠĠĠĠ Ġreturn ĠZ iti Server SocketChannel ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= ĠgetId () ĊĠĠĠĠĠĠĠ Ġreturn Ġ"${ id ?. name Ġ?: Ġname ()} [ ${ id ?. id }] @ ${ controller () }" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Active () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( getStatus () Ġ== ĠZ iti Context . Status . Active ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĊĠĠĠĠĠĠĠ Ġ// Ġwait Ġfor Ġactive ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ch . take While Ġ{ Ġit Ġ!= ĠZ iti Context . Status . Active Ġ}. collect () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis M FA En rolled (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġapi Session . value ?. auth Queries ?. isNotEmpty () Ġ?: Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġauthenticate M FA ( code : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġauth Code . try Send ( code ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġen roll M FA (): ĠM FA Enrollment Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġm fa Enrollment Ġ= Ġrun Catch ing Ġ{ Ġcontroller . getM FA Enrollment () Ġ}. get OrThrow () ĊĠĠĠĠĠĠĠ Ġif Ġ( m fa Enrollment Ġ!= Ġnull ) Ġreturn Ġm fa Enrollment ĊĊĠĠĠĠĠĠĠ Ġcontroller . post M FA () ĊĠĠĠĠĠĠĠ Ġreturn Ġcontroller . getM FA Enrollment () !! ĊĠĠĠ Ġ} ĊĠĠĠ Ġoverride Ġfun Ġen roll M FA Async () Ġ= Ġasync Ġ{ Ġen roll M FA () Ġ}. as Comp letableFuture () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġverify M FA ( code : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcontroller . verify M FA ( code ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġoverride Ġfun Ġverify M FA Async ( code : ĠString ) Ġ= Ġasync Ġ{ Ġverify M FA ( code ) Ġ}. as Comp letableFuture () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġremove M FA ( code : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontroller . remove M FA ( code ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġoverride Ġfun Ġremove M FA Async ( code : ĠString ) Ġ= Ġasync Ġ{ Ġremove M FA ( code ) Ġ}. as Comp letableFuture () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġget M FA Recovery Codes ( code : ĠString , Ġnew Codes : ĠBoolean ): ĠArray < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcontroller . getM FA Recovery Codes ( code , Ġnew Codes ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget M FA Recovery Codes Async ( code : ĠString , Ġnew Codes : ĠBoolean ) Ġ= ĊĠĠĠĠĠĠĠ Ġasync Ġ{ Ġget M FA Recovery Codes ( code , Ġnew Codes ) Ġ}. as Comp letableFuture () ĊĊĠĠĠ Ġoverride Ġfun Ġdump ( writer : ĠWriter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwriter . append Line (""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid : ĠĠĠĠĠĠĠĠ Ġ${ id . name ()} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller : Ġ${ id . controller ()} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus : ĠĠĠĠ Ġ${ getStatus ()} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" . trim Indent ()) ĊĊĠĠĠĠĠĠĠ Ġwriter . append Line () ĊĠĠĠĠĠĠĠ Ġwriter . append Line (" === ĠServices Ġ== =") ĊĠĠĠĠĠĠĠ Ġservices ByName . forEach Ġ{ Ġ( name , Ġs ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter . append Line (" name : Ġ$ name Ġid : Ġ${ s . id } Ġpermissions : Ġ${ s . permissions . join ToString ()} Ġintercept : Ġ${ s . intercept Config }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwriter . flush () ĊĊĠĠĠĠĠĠĠ Ġwriter . append Line () ĊĠĠĠĠĠĠĠ Ġwriter . append Line (" === ĠAvailable ĠEdge ĠRout ers [ ${ current Edge Rout ers . value . size }] Ġ== =") ĊĠĠĠĠĠĠĠ Ġcurrent Edge Rout ers . value . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter . append Line ( it . toString ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwriter . append Line (" === ĠChannels [ ${ channels . size }] Ġ== =") ĊĠĠĠĠĠĠĠ Ġchannels . forEach Ġ{ Ġ( name , Ġch ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter . append Line (" ER : Ġ$ name Ġstatus : Ġ${ ch . state }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }