/* Ċ Ġ* Ġ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 . net . nio Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . Cancellation Exception Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . flow .* Ċ import Ġkotlinx . coroutines . future . as Comp letableFuture Ċ import Ġkotlinx . coroutines . future . await Ċ import Ġkotlinx . coroutines . select s . select Ċ import Ġorg . open z iti . util .* Ċ import Ġjava . io . EOF Exception Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Inet SocketAddress Ċ import Ġjava . net . SocketAddress Ċ import Ġjava . net . Socket Option Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . channels .* Ċ import Ġjava . nio . channels . Completion Handler Ċ import Ġjava . nio . channels . spi . As ynchronous Channel Provider Ċ import Ġjava . util . concurrent .* Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ import Ġjavax . net . ssl .* Ċ import Ġjavax . net . ssl . SSL Engine Result . Handshake Status .* Ċ import Ġjavax . net . ssl . SSL Engine Result . Status .* Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . properties . Deleg ates Ċ Ċ /** Ċ Ġ* ĠImplementation ĠTLS Ġstream Ġconform ing Ġto Ġ[ As ynchronous SocketChannel ]. Ċ Ġ* Ċ Ġ*/ Ċ @ Suppress (" Blocking Method In Non Blocking Context ") Ċ class ĠAsync TLS Channel ( ĊĠĠĠ Ġch : ĠAs ynchronous SocketChannel , ĊĠĠĠ Ġval Ġssl : ĠSSL Context , ĊĠĠĠ Ġval Ġgroup : ĠAs ynchronous Channel Group , ĊĠĠĠ Ġprivate Ġval Ġid : ĠInt Ġ= Ġcounter . increment AndGet () Ċ ) Ġ: ĠAs ynchronous SocketChannel ( group . provider ()), ĠLog ged Ġby ĠZ iti Log (" async - tls /${ id } "), ĠCor outine Scope Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠSSL _ BUFFER _ SIZE Ġ= Ġ 3 2 Ġ* Ġ 1 0 2 4 ĊĠĠĠĠĠĠĠ Ġfun Ġopen ( group : ĠAs ynchronous Channel Group ? Ġ= Ġnull ) Ġ= ĠProvider . open As ynchronous SocketChannel ( group ) ĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġcounter Ġ= ĠAtomicInteger () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġclass ĠGroup ( val Ġprovider : ĠAs ynchronous Channel Provider , Ġval Ġdispatcher : ĠCor outine Dispatcher ) Ġ: ĊĠĠĠĠĠĠĠ ĠAs ynchronous Channel Group ( provider ), ĠCor outine Scope Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context Ġ= ĠSuper visor Job () Ġ+ Ġdispatcher Ġ+ ĠCor outine Name (" tls - group ") ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġchannels Ġ= ĠConcurrent HashMap < Int , Async TLS Channel >() ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġshut Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġshutdown () Ġ{ Ġshut Ġ= Ġtrue Ġ} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġis Shutdown (): ĠBoolean Ġ= Ġshut ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġshutdown Now () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Context . cancel Children () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Context . cancel () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġawait Termination ( timeout : ĠLong , Ġunit : ĠTimeUnit ): ĠBoolean Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġselect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Context . job . on Join Ġ{ Ġtrue Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Timeout ( unit . to Millis ( timeout )) Ġ{ Ġfalse Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġis Terminated (): ĠBoolean Ġ= Ġdispatcher . isActive ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġregister Channel ( ch : ĠAsync TLS Channel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannels [ ch . id ()] Ġ= Ġch ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġunregister Channel ( ch : ĠAsync TLS Channel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannels . remove ( ch . id ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġobject ĠDefault Group : ĠGroup ( Provider , ĠDispatch ers . IO ) ĊĊĠĠĠ Ġobject ĠProvider Ġ: ĠAs ynchronous Channel Provider () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġopen As ynchronous SocketChannel ( group : ĠAs ynchronous Channel Group ?): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAsync TLS Channel ( As ynchronous SocketChannel . open (), ĠSSL Context . getDefault (), Ġgroup Ġ?: ĠDefault Group ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġopen As ynchronous Server SocketChannel ( group : ĠAs ynchronous Channel Group ?): ĠAs ynchronous Server SocketChannel Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" server Ġchannels Ġare Ġnot Ġsupported ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġopen As ynchronous Channel Group ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġn Threads : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthread Factory : ĠThread Factory ĊĠĠĠĠĠĠĠ Ġ): ĠAs ynchronous Channel Group Ġ= ĠGroup ( this , ĠExec utors . new Fixed ThreadPool ( n Threads , Ġthread Factory ). as Coroutine Dispatcher ()) ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġopen As ynchronous Channel Group ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor Service , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Size : ĠInt ĊĠĠĠĠĠĠĠ Ġ): ĠAs ynchronous Channel Group Ġ= ĠGroup ( this , Ġexecutor . as Coroutine Dispatcher ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( ch : ĠAs ynchronous SocketChannel , Ġssl : ĠSSL Context ) Ġ: Ġthis ( ch , Ġssl , ĠDefault Group ) ĊĠĠĠ Ġconstructor ( ssl : ĠSSL Context ) Ġ: Ġthis ( As ynchronous SocketChannel . open (), Ġssl ) ĊĊĠĠĠ Ġenum Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠ Ġinitial , ĊĠĠĠĠĠĠĠ Ġconnecting , ĊĠĠĠĠĠĠĠ Ġhand sh aking , ĊĠĠĠĠĠĠĠ Ġconnected , ĊĠĠĠĠĠĠĠ Ġclosed ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġid () Ġ= Ġid ĊĊĠĠĠ Ġinternal Ġval Ġhandshake Ġ= ĠComp letable Deferred < SSL Session >() ĊĠĠĠ Ġprivate Ġvar Ġstate : ĠState Ġby ĠDeleg ates . observable ( State . initial ) Ġ{ Ġ_, Ġov , Ġnv Ġ-> ĊĠĠĠĠĠĠĠ Ġd Ġ{ Ġ" transition ing Ġ[$ ov Ġ-> Ġ$ nv ] Ġ" Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġval Ġtransport : ĠAs ynchronous SocketChannel Ġ= Ġch ĊĠĠĠ Ġinternal Ġval Ġssl Params Ġ= Ġssl . default SSL Parameters ĊĠĠĠ Ġinternal Ġval Ġengine : ĠSSL Engine Ġ= Ġssl . create SSL Engine () ĊĊĠĠĠ Ġprivate Ġval Ġplain In Ġ= ĠChannel < ByteBuffer >( 1 ) ĊĠĠĠ Ġprivate Ġval Ġplain Read Buf Ġ= ĠByteBuffer . allocate Direct ( 2 Ġ* ĠSSL _ BUFFER _ SIZE ). apply Ġ{ Ġflip () Ġ} ĊĠĠĠ Ġprivate Ġval Ġread Op Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠ Ġprivate Ġval Ġwrite Op Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠ Ġprivate Ġval Ġclose Write Ġ= ĠAtomic Boolean ( false ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( group Ġis ĠGroup ){ " group Ġis Ġnot ĠAsync TLS Channel . Group "} ĊĠĠĠĠĠĠĠ Ġcoroutine Context Ġ= ĠSuper visor Job ( group . coroutine Context . job ) Ġ+ Ġgroup . dispatcher Ġ+ ĠCor outine Name (" tls -$ id ") ĊĊĠĠĠĠĠĠĠ Ġcoroutine Context . job . invoke On Completion Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgroup . unregister Channel ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġgroup . register Channel ( this ) ĊĠĠĠĠĠĠĠ Ġtransport . remote Address ?. let Ġ{ Ġstate Ġ= ĠState . connecting Ġ} ĊĠĠĠĠĠĠĠ Ġhandshake . invoke On Completion Ġ{ Ġex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd Ġ{" handshake Ġcompleted "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . connected ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġw Ġ{" handshake Ġfailed Ġ${ ex } "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ Ġtransport . close () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . closed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġpost Connect () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ== ĠState . connecting ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . hand sh aking ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddr Ġ= Ġtransport . remote Address Ġas ĠInet SocketAddress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġssl Params . server Names Ġ= ĠlistOf ( S NI HostName ( addr . host String )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġengine . ssl Parameters Ġ= Ġssl Params ĊĠĠĠĠĠĠĠĠĠĠĠ Ġengine . use Client Mode Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġengine . begin Handshake () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Internal () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġd Ġ{ Ġ" engine Ġstatus Ġ= Ġ${ engine . handshake Status }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue HS ( EMPTY ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< A Ġ: ĠAny ?> Ġconnect ( remote : ĠSocket Address , Ġattachment : ĠA , Ġhandler : ĠCompletion Handler < Void ?, Ġin ĠA > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire NotNull ( handler ) ĊĊĠĠĠĠĠĠĠ Ġconnect ( remote ). handle Ġ{ Ġv , Ġex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . failed ( ex , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . completed ( v , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġconnect ( remote : ĠSocket Address ): ĠCompletableFuture < Void ?> Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck State ( State . initial ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( remote Ġ! is ĠInet SocketAddress ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCompletableFuture < Void ?> (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomplete Exception ally ( IllegalArgumentException ( remote . toString ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġasync Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransport . connect Suspend ( remote ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . connecting ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ}. as Comp letableFuture () ĊĠĠĠĠĠĠĠ Ġ// Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Local Address (): ĠSocket Address Ġ= Ġtransport . local Address ĊĊĠĠĠ Ġoverride Ġfun Ġget Remote Address (): ĠSocket Address Ġ= Ġtransport . remote Address ĊĊĠĠĠ Ġoverride Ġfun Ġ< T Ġ: ĠAny ?> Ġget Option ( name : ĠSocket Option < T >? ): ĠT Ġ= Ġtransport . getOption ( name ) ĊĊĠĠĠ Ġoverride Ġfun Ġ< T Ġ: ĠAny ?> Ġset Option ( name : ĠSocket Option < T > ?, Ġvalue : ĠT ): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġtransport . set Option ( name , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< A Ġ: ĠAny ?> Ġwrite ( ĊĠĠĠĠĠĠĠ Ġsrc : ĠByteBuffer , ĊĠĠĠĠĠĠĠ Ġtimeout : ĠLong , ĊĠĠĠĠĠĠĠ Ġunit : ĠTimeUnit ?, ĊĠĠĠĠĠĠĠ Ġattachment : ĠA , ĊĠĠĠĠĠĠĠ Ġhandler : ĠCompletion Handler < Int , Ġin ĠA > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwrite ( array Of ( src ), Ġ 0 , Ġ 1 , Ġtimeout , Ġunit , Ġattachment , Ġobject Ġ: ĠCompletion Handler < Long , ĠA > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcompleted ( result : ĠLong , Ġa : ĠA ) Ġ= Ġhandler . completed ( result . toInt (), Ġa ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfailed ( exc : ĠThrowable , Ġa : ĠA ) Ġ= Ġhandler . failed ( exc , Ġa ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwrite ( src : ĠByteBuffer ): ĠFuture < Int > Ġ= ĠCompletableFuture < Int >(). also Ġ{ ĊĠĠĠĠĠĠĠ Ġwrite ( src , Ġ 0 , ĠTimeUnit . SECONDS , Ġit , ĠFuture Handler ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< A Ġ: ĠAny ?> Ġwrite ( ĊĠĠĠĠĠĠĠ Ġsrc s : ĠArray < out ĠByteBuffer >, ĊĠĠĠĠĠĠĠ Ġoffset : ĠInt , ĊĠĠĠĠĠĠĠ Ġlength : ĠInt , ĊĠĠĠĠĠĠĠ Ġtimeout : ĠLong , ĊĠĠĠĠĠĠĠ Ġunit : ĠTimeUnit ?, ĊĠĠĠĠĠĠĠ Ġattachment : ĠA , ĊĠĠĠĠĠĠĠ Ġhandler : ĠCompletion Handler < Long , Ġin ĠA >? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire NotNull ( handler ) Ġ{ Ġ" handler Ġis Ġrequired " Ġ} ĊĠĠĠĠĠĠĠ Ġcheck State ( State . connecting , ĠState . hand sh aking , ĠState . connected ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( close Write . get ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv Ġ{ Ġ" cannot Ġwrite Ġafter Ġshutdown Output () Ġwas Ġcalled " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠClosed Channel Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! write Op . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠWrite Pending Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Connect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandshake . await () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġssl buf Ġ= ĠByteBuffer . allocate Direct ( SSL _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġengine . wrap ( src s , Ġoffset , Ġlength , Ġssl buf ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconsumed Ġ= Ġres . bytes Cons umed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproduced Ġ= Ġres . bytes Pro duced () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pro duced Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġssl buf . flip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( transport . write Comp let ely ( ssl buf ) Ġ< Ġproduced ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" failed Ġto Ġwrite Ġcomplete ĠSSL Ġmessage ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġv Ġ{ Ġ" ssl Ġstate Ġ$ res " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconsumed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Success Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . completed ( it . to Long (), Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Failure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġex Ġ= Ġwhen ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC ancellation Exception Ġ-> ĠAs ynchronous Close Exception () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . failed ( ex , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠisOpen (): ĠBoolean Ġ= Ġ( state Ġ!= ĠState . closed ) ĊĊĠĠĠ Ġoverride Ġfun Ġbind ( local : ĠSocket Address ?): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck State ( State . initial ) ĊĠĠĠĠĠĠĠ Ġtransport . bind ( local ) ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġsupported Options (): ĠMutable Set < Socket Option <* >> Ġ= Ġtransport . supported Options () ĊĊĠĠĠ Ġoverride Ġfun Ġshutdown Input (): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġtransport . shutdown Input () ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ!= ĠState . closed Ġ&& Ġstate Ġ!= ĠState . initial ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown Output () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown Input () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . closed ĊĠĠĠĠĠĠĠ Ġcancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġshutdown Output (): ĠAs ynchronous SocketChannel Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . initial Ġ-> Ġthrow ĠNot Y et Connected Exception () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . connecting , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . hand sh aking , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . connected Ġ-> Ġ{} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . closed Ġ-> Ġthrow ĠClosed Channel Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! close Write . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠClosed Channel Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġv Ġ{ Ġ" closing Ġoutbound " Ġ} ĊĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state Ġ== ĠState . hand sh aking Ġ|| Ġstate Ġ== ĠState . connected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġengine . close Outbound () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġb Ġ= ĠByteBuffer . allocate ( 1 2 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġengine . wrap ( EMPTY , Ġb ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransport . write Comp let ely ( b ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransport . shutdown Output () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Failure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġv Ġ{ Ġ" failed Ġto Ġwrite ĠSSL Close Notify : Ġ$ it " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< A > Ġread ( ĊĠĠĠĠĠĠĠ Ġdst : ĠByteBuffer , Ġtimeout : ĠLong , Ġunit : ĠTimeUnit , ĊĠĠĠĠĠĠĠ Ġattachment : ĠA , Ġhandler : ĠCompletion Handler < Int , Ġin ĠA > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġread ( array Of ( dst ), Ġ 0 , Ġ 1 , Ġtimeout , Ġunit , Ġattachment , Ġobject Ġ: ĠCompletion Handler < Long , ĠA > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcompleted ( result : ĠLong , Ġattachment : ĠA ) Ġ= Ġhandler . completed ( result . toInt (), Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfailed ( exc : ĠThrowable , Ġattachment : ĠA ) Ġ= Ġhandler . failed ( exc , Ġattachment ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġread ( dst : ĠByteBuffer ): ĠFuture < Int > Ġ= ĠCompletableFuture < Int >(). also Ġ{ ĊĠĠĠĠĠĠĠ Ġread ( dst , Ġ 0 , ĠTimeUnit . MILLISECONDS , Ġit , ĠFuture Handler ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġ< A Ġ: ĠAny ?> Ġread ( ĊĠĠĠĠĠĠĠ Ġ_ dst s : ĠArray < out ĠByteBuffer >, ĊĠĠĠĠĠĠĠ Ġoffset : ĠInt , ĊĠĠĠĠĠĠĠ Ġlength : ĠInt , ĊĠĠĠĠĠĠĠ Ġtimeout : ĠLong , ĊĠĠĠĠĠĠĠ Ġunit : ĠTimeUnit , ĊĠĠĠĠĠĠĠ Ġattachment : ĠA , ĊĠĠĠĠĠĠĠ Ġhandler : ĠCompletion Handler < Long , Ġin ĠA >? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire NotNull ( handler ) ĊĠĠĠĠĠĠĠ Ġcheck State ( State . connecting , ĠState . hand sh aking , ĠState . connected ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(( offset Ġ< Ġ 0 ) Ġ|| Ġ( length Ġ< Ġ 0 ) Ġ|| Ġ( offset Ġ> Ġ_ dst s . size Ġ- Ġlength )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIndex OutOfBoundsException () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! readOp . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRead Pending Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdst s Ġ= Ġ_ dst s . slice Array ( offset Ġuntil Ġoffset Ġ+ Ġlength ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( plain Read Buf . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġplain Read Buf . transfer ( dst s ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . completed ( count , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Connect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandshake . await () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġin Flow Ġ= Ġplain In . receive As Flow () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġin Buf Ġ= Ġif Ġ( timeout Ġ> Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Timeout ( timeout ) Ġ{ Ġin Flow . first OrNull () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Flow . first OrNull () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( in Buf Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlen Ġ= Ġin Buf . transfer ( dst s ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( in Buf . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Read Buf . compact () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Read Buf . put ( in Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Read Buf . flip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . completed ( len , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . completed (- 1 , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( ex ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠTimeout Cancellation Exception Ġ-> Ġhandler . failed ( Inter rupted By TimeoutException (), Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠC ancellation Exception Ġ-> Ġhandler . failed ( As ynchronous Close Exception (), Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġhandler . failed ( ex , Ġattachment ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġread Op . set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġget Session (): ĠSSL Session Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġhandshake . await () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġstart Handshake () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ== ĠState . connecting ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( Coroutine Name (" post Connect ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Connect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset SSL Parameters ( params : ĠSSL Parameters ) Ġ{ ĊĠĠĠĠĠĠĠ Ġssl Params . application Protocols Ġ= Ġparams . application Protocols ĊĠĠĠĠĠĠĠ Ġssl Params . protocols Ġ= Ġparams . protocols ĊĠĠĠĠĠĠĠ Ġssl Params . cipher Su ites Ġ= Ġparams . cipher Su ites ĊĠĠĠĠĠĠĠ Ġssl Params . server Names Ġ= Ġparams . server Names ĊĠĠĠĠĠĠĠ Ġssl Params . algorithm Constraints Ġ= Ġparams . algorithm Constraints ĊĠĠĠĠĠĠĠ Ġssl Params . need Client Auth Ġ= Ġparams . need Client Auth ĊĠĠĠĠĠĠĠ Ġssl Params . use Cipher Su ites Order Ġ= Ġparams . use Cipher Su ites Order ĊĠĠĠĠĠĠĠ Ġssl Params . sn i Matchers Ġ= Ġparams . sn i Matchers ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset Enabled Protocols ( protocols : ĠArray < out ĠString > ?) Ġ{ Ġssl Params . protocols Ġ= Ġprotocols Ġ} ĊĠĠĠ Ġfun Ġget Enabled Protocols (): ĠArray < String >? Ġ= Ġssl Params . protocols ĊĊĠĠĠ Ġfun Ġset Enabled Cipher Su ites ( su ites : ĠArray < String >) Ġ{ Ġssl Params . cipher Su ites Ġ= Ġsu ites Ġ} ĊĠĠĠ Ġfun Ġget Enabled Cipher Su ites (): ĠArray < String >? Ġ= Ġssl Params . cipher Su ites ĊĊĠĠĠ Ġfun Ġget Supported Cipher Su ites (): ĠArray < String >? Ġ= Ġengine . supported Cipher Su ites ĊĠĠĠ Ġfun Ġget Supported Protocols (): ĠArray < String >? Ġ= Ġengine . supported Protocols ĊĠĠĠ Ġfun Ġget Application Protocol (): ĠString ? Ġ= Ġengine . application Protocol ĊĊĠĠĠ Ġprivate Ġfun Ġcheck State ( var arg Ġexpected : ĠState ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġin Ġexpected ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġe Ġ{ Ġ" invalid Ġst ata [$ state ], Ġexpected Ġon Ġof Ġ$ expected " Ġ} ĊĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . closed Ġ-> Ġthrow ĠClosed Channel Exception () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . connecting , ĠState . hand sh aking Ġ-> Ġthrow ĠConnection Pending Exception () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . connected Ġ-> Ġthrow ĠAlready Connected Exception () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . initial Ġ-> Ġthrow ĠNot Y et Connected Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġread Internal () Ġ= Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠ Ġv (" start Ġreading Ġloop () ") ĊĠĠĠĠĠĠĠ Ġval Ġssl In Buf Ġ= ĠByteBuffer . allocate Direct ( SSL _ BUFFER _ SIZE Ġ* Ġ 2 ). apply Ġ{ Ġflip () Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġplain Buf Ġ= ĠByteBuffer . allocate ( SSL _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠ Ġvar Ġres : ĠSSL Engine Result ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġssl In Buf . compact () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġread Ġ= Ġtransport . read Suspend ( ssl In Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( read Ġ< Ġ 0 ) Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġssl In Buf . flip () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres Ġ= Ġengine . unwrap ( ssl In Buf , Ġplain Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res . status Ġ== ĠOK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( res . handshake Status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNOT _ HAND SH AK ING , ĠFIN ISHED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! handshake . is Completed ) Ġhandshake . complete ( engine . session ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcontinue HS ( ssl In Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( res . status Ġ== ĠBUFFER _ OVER FLOW ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( plain Buf . position () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Buf . flip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain In . send ( plain Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Buf Ġ= ĠByteBuffer . allocate ( SSL _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( ssl In Buf . has Remaining () Ġ&& Ġres . status Ġin ĠarrayOf ( OK , ĠBUFFER _ OVER FLOW )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( plain Buf . position () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Buf . flip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain In . send ( plain Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain Buf Ġ= ĠByteBuffer . allocate ( SSL _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( res . status Ġ!= ĠCLO SED ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġv (" reader Ġclosed ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplain In . close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandshake . complete Exception ally ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= ĠState . closed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex Ġis ĠSSL Exception Ġ&& Ġex . cause Ġis ĠEOF Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġv (" closed Ġdue Ġto Ġclose _ notify ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain In . close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplain In . close ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransport . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġcontinue HS ( in Buf : ĠByteBuffer ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhs Buf Ġ= ĠByteBuffer . allocate Direct ( SSL _ BUFFER _ SIZE ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv { Ġ" engine . handshake Status Ġ= Ġ${ engine . handshake Status }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( engine . handshake Status !! ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNE ED _ TASK Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ ĠCompletableFuture . supply Async Ġ{ Ġengine . deleg ated Task ?. run () Ġ}. await () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Failure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandshake . complete Exception ally ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ continue HS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNE ED _ WRAP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( engine . handshake Status Ġ== ĠNE ED _ WRAP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġengine . wrap ( EMPTY , Ġhs Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt {" wrap : Ġ$ res Ġbuf [$ hs Buf ] "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhs Buf . flip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkotlin . run Catch ing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransport . write Comp let ely ( hs Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhs Buf . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Failure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandshake . complete Exception ally ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ continue HS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNE ED _ UN WRAP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( engine . handshake Status Ġ== ĠNE ED _ UN WRAP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġengine . unwrap ( in Buf , Ġhs Buf ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt {" unwrap : Ġ$ res "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res . status Ġ== ĠBUFFER _ UNDER FLOW ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFIN ISHED , ĠNOT _ HAND SH AK ING Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! handshake . is Completed ) Ġhandshake . complete ( engine . session ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }