1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
U
Z±d©Èã@sDddlZddlZddlZddlZddlmZddlZddlZddlZddl    Z    ddl
Z
ddl m Z m Z dZdd„Zdd„Zd    d
„ZGd d „d ejƒZGd d„dejƒZGdd„dƒZdZGdd„deƒZdd„Zdd„Ze d¡Zeedœdd„Ze    j Gdd„dƒƒZ!dd„Z"d d!„Z#e d"¡Z$e    j Gd#d$„d$ƒƒZ%d%d&„Z&d'd(„Z'd)d*„Z(e    j Gd+d,„d,ƒƒZ)e    j Gd-d.„d.ƒƒZ*e    j Gd/d0„d0ƒƒZ+d1d2„Z,Gd3d4„d4ƒZ-d5Z.d6Z/d7Z0d8Z1d6Z2d9d:„Z3d;d<„Z4d=d>„Z5d?d@„Z6dAdB„Z7GdCdD„dDƒZ8dEdF„Z9dGdH„Z:dIdJ„Z;e    j GdKdL„dLƒƒZ<GdMdN„dNe
j=j>ee dOZ?GdPdQ„dQe dOZ@dS)RéN)Úcount)ÚNoPublicConstructorÚFinali÷ÿcCs|jtjjkrdSdSdS)Néé0)ÚfamilyÚtrioÚsocketÚAF_INET©Úsock©r úAd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\trio/_dtls.pyÚpacket_header_overheadsrcCs*|jtjjkrdt|ƒSdt|ƒSdS)Ni@i)rrr    r
rr r r rÚworst_case_mtu!s rcCs dt|ƒS)NiÜ)rr r r rÚbest_guess_mtu(src@s eZdZdZdZdZdZdZdS)Ú ContentTypeéééééN)Ú__name__Ú
__module__Ú __qualname__Úchange_cipher_specÚalertÚ    handshakeZapplication_dataZ    heartbeatr r r rr/s
rc@s`eZdZdZdZdZdZdZdZdZ    dZ
dZ d    Z d
Z d Zd Zd ZdZdZdZdZdZdZdZdS)Ú HandshakeTyperéééééé é é ééérrrrréééþN)rrrZ hello_requestÚ client_helloZ server_helloÚhello_verify_requestZnew_session_ticketZend_of_early_dataZencrypted_extensionsZ certificateZserver_key_exchangeZcertificate_requestZserver_hello_doneZcertificate_verifyZclient_key_exchangeÚfinishedZcertificate_urlZcertificate_statusZsupplemental_dataZ
key_updateZcompressed_certificateZekt_keyZ message_hashr r r rr7s*rc@s$eZdZeddgƒZeddgƒZdS)ÚProtocolVersionr,éÿéýN)rrrÚbytesÚDTLS10ZDTLS12r r r rr0Os r0løc@s eZdZdS)Ú    BadPacketN)rrrr r r rr5\sr5cCs|dd…dkS)Nr!ésr ©Úpacketr r rÚpart_of_handshake_untrustedfsr9cCs:z|dtjko|dtjkWStk
r4YdSXdS)Nrr&F)rrrr-Ú
IndexErrorr7r r rÚis_client_hello_untrustedms  þr;z!B2sQH)ÚdataÚreturncCs| ¡S©N)Úhex)r<r r rÚto_hex„sr@c@sFeZdZUeed<ejedZe    ed<eed<ejedZ
e    ed<dS)ÚRecordÚ content_type©ÚreprÚversionÚ epoch_seqnoÚpayloadN) rrrÚintÚ__annotations__ÚattrÚibr@rEr3rGr r r rrAˆs
rAc
cs¤d}|t|ƒkr zt ||¡\}}}}Wn.tjk
rV}ztdƒ|‚W5d}~XYnX|tj7}||||…}t|ƒ|kr†tdƒ‚||7}t||||ƒVqdS)Nrzinvalid record headerz short record)ÚlenÚ RECORD_HEADERÚ unpack_fromÚstructÚerrorr5ÚsizerA)r8ÚiÚctrErFZ payload_lenÚexcrGr r rÚrecords_untrusteds 
 rUcCs&t |j|j|jt|jƒ¡}||jSr>)rMÚpackrBrErFrLrG)ÚrecordÚheaderr r rÚ encode_record¢sürYz    !B3sH3s3sc@sJeZdZUeed<eed<eed<eed<eed<ejedZe    ed<dS)    ÚHandshakeFragmentÚmsg_typeÚmsg_lenÚmsg_seqÚ frag_offsetÚfrag_lenrCÚfragN)
rrrrHrIrJrKr@r`r3r r r rrZµs
rZc
Cs zt |¡\}}}}}Wn.tjk
rF}ztdƒ|‚W5d}~XYnXt |d¡}t |d¡}t |d¡}    |tjd…}
t|
ƒ|    krŽtdƒ‚t    |||||    |
ƒS)Nzbad handshake message headerÚbigz5handshake fragment length doesn't match record length)
ÚHANDSHAKE_MESSAGE_HEADERrNrOrPr5rHÚ
from_bytesrQrLrZ) rGr[Ú msg_len_bytesr]Úfrag_offset_bytesÚfrag_len_bytesrTr\r^r_r`r r rÚ#decode_handshake_fragment_untrusted¿s2úû    úrgc
Cs>t |j|j dd¡|j|j dd¡|j dd¡¡}||jS)Nr!ra)    rbrVr[r\Úto_bytesr]r^r_r`)ZhsfZ    hs_headerr r rÚencode_handshake_fragmentÝs   ûric
CszÜtt|ƒƒ}|jtjkr"tdƒ‚t|jƒ}|jt    j
kr@tdƒ‚|j dkrRtdƒ‚|j |j krftdƒ‚|j}|d}d|}||}|d}||}|d|…}    |||…}
||d…} t|
ƒ|krÌtdƒ‚|j|
|    | fWStjtfk
r} ztd    ƒ| ‚W5d} ~ XYnXdS)
Nznot a handshake recordznot a ClientHellorzfragmented ClientHelloé"é#rz short cookiezbad ClientHello)ÚnextrUrBrrr5rgrGr[rr-r^r_r\r`rLrFrOrPr:) r8rWÚfragmentÚbodyZsession_id_lenZcookie_len_offsetZ
cookie_lenZ cookie_startZ
cookie_endZ before_cookieÚcookieZ after_cookierTr r rÚdecode_client_hello_untrustedès2  
 
      rpc@sFeZdZUejedZeed<e    ed<e
ed<ejedZ e ed<dS)ÚHandshakeMessagerCÚrecord_versionr[r]rnN) rrrrJrKr@rrr3rIrrHrnÚ    bytearrayr r r rrq-s
rqc@s>eZdZUejedZeed<e    ed<ejedZ
eed<dS)ÚPseudoHandshakeMessagerCrrrBrGN) rrrrJrKr@rrr3rIrHrGr r r rrt7s
rtc@seZdZUeed<dS)ÚOpaqueHandshakeMessagerWN)rrrrArIr r r rruCs
rucCsg}i}t|ƒD]þ}|jt@r.| t|ƒ¡q|jtjtjfkrZ| t    |j
|j|j ƒ¡q|jtj ksjt ‚t|j ƒ}t|jƒ}|j|kr¶t|j
||jt|jƒƒ}| |¡|||j<n
||j}|j|jksÐt ‚|j|jksàt ‚t|jƒ|jksôt ‚|j|j|j|j|j…<q|Sr>)rUrFÚ
EPOCH_MASKÚappendrurBrrrrtrErGrÚAssertionErrorrgrr[r]rqrsr\rLrnr`r^r_)ZvolleyÚmessagesZmessages_by_seqrWrmr[Úmsgr r rÚdecode_volley_trustedLsF 
ÿÿ
 
 
ü
 
þ
ÿr{c@s$eZdZdd„Zdd„Zdd„ZdS)Ú RecordEncodercCs tƒ|_dSr>©rÚ _record_seq©Úselfr r rÚ__init__yszRecordEncoder.__init__cCst|ƒ|_dSr>r})r€Únr r rÚset_first_record_number|sz%RecordEncoder.set_first_record_numberc
Csg}tƒ}|D]Þ}t|tƒrjt|jƒ}|t|ƒt|ƒdkrP| |¡tƒ}||7}t|ƒ|ksht‚qt|tƒrè|t|ƒt    j
t|j ƒ}|dkr¨| |¡tƒ}|t      |j |jt|jƒt|j ƒ¡7}||j 7}t|ƒ|ksæt‚qt|jƒ dd¡}d}    d}
|    t|jƒks|
s|t|ƒt    j
tj
}|dkrL| |¡tƒ}q|j|    |    |…} |     dd¡} t| ƒ dd¡} |    t| ƒ7}    |t      tj|jt|jƒtj
t| ƒ¡7}|t  |j||j| | ¡7}|| 7}|
d7}
t|ƒ|kst‚qq|r| |¡|S)Nrr!rar)rsÚ
isinstancerurYrWrLrwrxrtrMrQrGrVrBrrrlr~rnrhrbrrr[r])r€ryZmtuÚpacketsr8ÚmessageÚencodedÚspacerdr^Z frags_encodedr`rerfr r rÚ encode_volleys|
 
 
 
 
 
ü
ÿþýÿ
 
   üû
zRecordEncoder.encode_volleyN)rrrrrƒr‰r r r rr|xsr|éé Úsha256r#cCstt ¡tƒSr>)rHrÚ current_timeÚCOOKIE_REFRESH_INTERVALr r r rÚ_current_cookie_ticksrcGs8g}|D]$}| t dt|ƒ¡¡| |¡qd |¡S)Nú!Qó)rwrOrVrLÚjoin)ÚfieldsÚoutÚfieldr r rÚ    _signable    s
 r–cCs^t|ƒtkst‚t|ƒtks t‚t|t d|¡tdd„|DƒŽ|ƒ}|t ||t    ¡dt
…S)Nrcss|]}t|ƒ ¡VqdSr>)ÚstrÚencode)Ú.0Úpartr r rÚ    <genexpr>sz_make_cookie.<locals>.<genexpr>) rLÚ
SALT_BYTESrxÚ    KEY_BYTESr–rOrVÚhmacÚdigestÚ COOKIE_HASHÚ COOKIE_LENGTH)ÚkeyÚsaltÚtickÚaddressÚclient_hello_bitsZ signable_datar r rÚ _make_cookies
ú    r§cCsht|ƒtkr`|dt…}tƒ}t|||||ƒ}t||t|ddƒ||ƒ}t ||¡t ||¡BSdSdS)NrrF)rLrœrr§ÚmaxržÚcompare_digest)r¢ror¥r¦r£r¤Z
cur_cookieZ
old_cookier r rÚ valid_cookie!s    ÿÿrªc Csxt t¡}tƒ}t|||||ƒ}tjtt|ƒgƒ|}t    t
j t|ƒddt|ƒ|d}t |ƒ}    t ttjtj||    ƒƒ}
|
S)Nr)r[r\r]r^r_r`)ÚosÚurandomrœrr§r0r4r3rLrZrr.rirYrArr) r¢r¥rFr¦r£r¤rornZhsrGr8r r rÚ challenge_for5s"
úÿr­c@seZdZdd„ZdS)Ú_QueuecCst |¡\|_|_dSr>)rZopen_memory_channelÚsÚr)r€Úincoming_packets_bufferr r rr^sz_Queue.__init__N)rrrrr r r rr®]sr®cCsBg}z |dƒ}Wntjk
r*Yq8YnX| |¡qd |¡S)Ni@r‘)ÚSSLÚ WantReadErrorrwr’)Zread_fnÚchunksÚchunkr r rÚ
_read_loopbs 
 r¶c    
Ãsz|jdkrdSzt|ƒ\}}}Wntk
r6YdSX|jdkrNt t¡|_t|j|||ƒsÄt|j|||ƒ}z8|j    4IdHš|j
  ||¡IdHW5QIdHRXWnt t jfk
rÀYnXn²t |||j¡}|j |¡z|j |¡|j ¡Wntjk
rYdSX|j |¡|j |¡}|dk    rT|j||fkrLdS| ¡||f|_||j|<|jj |¡dSr>)Ú_listening_contextrpr5Ú_listening_keyr«r¬rrªr­Ú
_send_lockr    ÚsendtoÚOSErrorrÚClosedResourceErrorÚ DTLSChannelÚ_createÚ_record_encoderrƒÚ_sslÚ    bio_writeZ DTLSv1_listenr²ÚErrorÚ_streamsÚgetÚ _client_helloÚ _set_replacedÚ_incoming_connections_qr¯Ú send_nowait)    Úendpointr¥r8rFroÚbitsZchallenge_packetÚstreamZ
old_streamr r rÚhandle_client_hello_untrustedmsH
 
 ÿ(        
 
 
rÌc
Ãshzz| t¡IdH\}}Wn:tk
rV}z|jtjkrDWY¢
qn‚W5d}~XYnX|ƒ}zž|dkrrW¢’WdSt|ƒrŽt|||ƒIdHnl||jkrú|j|}|jrÀt    |ƒrÀ| 
¡IdHqúz|j j   |¡Wqútjk
rö|jd7_YqúXnW5~XqWn\tjk
r YdStk
rb}z$|jtjtjfkrPWY¢
dS‚W5d}~XYnXdS)Nr)ÚrecvfromÚMAX_UDP_PACKET_SIZEr»ÚerrnoÚ
ECONNRESETr;rÌrÃÚ_did_handshaker9Ú_resend_final_volleyÚ_qr¯rÈrZ
WouldBlockÚ_packets_dropped_in_trior¼ÚEBADFÚENOTSOCK)Z endpoint_refr r8r¥rTrÉrËr r rÚdtls_receive_loop¶s: 
 
 
 
 
 
r×c@seZdZUeed<dS)ÚDTLSChannelStatisticsZ incoming_packets_dropped_in_trioN)rrrrHrIr r r rrØís
rØc@sŽeZdZdZdd„Zdd„Zdd„Zdd    „Zd
d „Zd d „Z    dd„Z
dd„Z dd„Z ddœdd„Z dd„Zdd„Zdd„Zdd„Zd d!„Zd"S)#r½u`A DTLS connection.
 
    This class has no public constructor â€“ you get instances by calling
    `DTLSEndpoint.serve` or `~DTLSEndpoint.connect`.
 
    .. attribute:: endpoint
 
       The `DTLSEndpoint` that this connection is using.
 
    .. attribute:: peer_address
 
       The IP/port of the remote peer that this connection is associated with.
 
    cCs‚||_||_d|_d|_d|_| tjtjB¡t     |¡|_
d|_ |  t |jjƒ¡d|_d|_t|jƒ|_t ¡|_tƒ|_dS)NrF)rÉÚ peer_addressrÔrÅrÑZ set_optionsr²ZOP_NO_QUERY_MTUÚOP_NO_RENEGOTIATIONÚ
ConnectionrÀÚ_handshake_mtuÚset_ciphertext_mturr    Ú    _replacedÚ_closedr®r±rÓrÚLockÚ_handshake_lockr|r¿)r€rÉrÙÚctxr r rrs  
zDTLSChannel.__init__cCsd|_|jj ¡dS©NT)rÞrÓr¯Úcloserr r rrÆszDTLSChannel._set_replacedcCs|jrt d¡‚dS)Nz1peer tore down this connection to start a new one)rÞrZBrokenResourceErrorrr r rÚ_check_replacedsÿzDTLSChannel._check_replacedcCs@|jr
dSd|_|jj |j¡|kr0|jj|j=|jj ¡dS)uãClose this connection.
 
        `DTLSChannel`\s don't actually own any OS-level resources â€“ the
        socket is owned by the `DTLSEndpoint`, not the individual connections. So
        you don't really *have* to call this. But it will interrupt any other tasks
        calling `receive` with a `ClosedResourceError`, and cause future attempts to use
        this connection to fail.
 
        You can also use this object as a synchronous or asynchronous context manager.
 
        NT)rßrÉrÃrÄrÙrÓr°rärr r rrä,s  zDTLSChannel.closecCs|Sr>r rr r rÚ    __enter__AszDTLSChannel.__enter__cGs | ¡dSr>©rä©r€Úargsr r rÚ__exit__DszDTLSChannel.__exit__cÃs| ¡tj ¡IdHdS)z¨Close this connection, but asynchronously.
 
        This is included to satisfy the `trio.abc.Channel` contract. It's
        identical to `close`, but async.
 
        N)rärÚlowlevelÚ
checkpointrr r rÚacloseGszDTLSChannel.aclosec ÃsX|j ||j¡}|D]>}|jj4IdHš|jj ||j¡IdHW5QIdHRXqdSr>)r¿r‰rÜrÉr¹r    rºrÙ)r€Úvolley_messagesr…r8r r rÚ _send_volleyQsÿzDTLSChannel._send_volleycÃs| |j¡IdHdSr>)rïÚ _final_volleyrr r rrÒYsz DTLSChannel._resend_final_volleygð?)Úinitial_retransmit_timeoutc ƒsˆj4IdHšòˆjr,W5QIdHR£dS|}g‰d}‡‡fdd„}zˆj ¡Wntjk
rjYnX|ƒ‰ˆs€t d¡‚ˆsˆt‚ˆ ¡ˆ     ˆ¡IdHˆj
  ¡t   |¡}ˆjj2zà3dHW}ˆj |¡zˆj ¡Wntjtjfk
rYnBXdˆ_|ƒˆ_ˆ     ˆj¡IdHW5QR£W5QIdHR£dS|ƒ}|rÀt|dtƒr„|djtjkr„ˆ     |¡IdHqÀ|‰|dkr–|}d}q¸qÀ6ˆjs°t‚ˆ ¡W5QRX|jr€td|dƒ}|d    7}|dkr€tˆjtˆj
jƒƒˆ_q€W5QIdHRXdS)
u Perform the handshake.
 
        Calling this is optional â€“ if you don't, then it will be automatically called
        the first time you call `send` or `receive`. But calling it explicitly can be
        useful in case you want to control the retransmit timeout, use a cancel scope to
        place an overall timeout on the handshake, or catch errors from the handshake
        specifically.
 
        It's safe to call this multiple times, or call it simultaneously from multiple
        tasks â€“ the first call will perform the handshake, and the rest will be no-ops.
 
        Args:
 
          initial_retransmit_timeout (float): Since UDP is an unreliable protocol, it's
            possible that some of the packets we send during the handshake will get
            lost. To handle this, DTLS uses a timer to automatically retransmit
            handshake packets that don't receive a response. This lets you set the
            timeout we use to detect packet loss. Ideally, it should be set to ~1.5
            times the round-trip time to your peer, but 1 second is a reasonable
            default. There's `some useful guidance here
            <https://tlswg.org/dtls13-spec/draft-ietf-tls-dtls13.html#name-timer-values>`__.
 
            This is the *initial* timeout, because if packets keep being lost then Trio
            will automatically back off to longer values, to avoid overloading the
            network.
 
        NrcsJtˆjjƒ}t|ƒ}|rBˆrBt|dtƒrB|djˆdjkrBgS|SdS)Nr)r¶rÀÚbio_readr{r„rqr])Z volley_bytesZnew_volley_messages©r€rîr rÚ read_volley€s ÿþ ýüz-DTLSChannel.do_handshake.<locals>.read_volleyz'something wrong with peer's ClientHelloTr gN@r)rárÑrÀÚ do_handshaker²r³rÂrxrårïrÉÚ_ensure_receive_looprZ move_on_afterrÓr°rÁrðr„rtrBrrrÞZcancelled_caughtÚminrÜrr    )r€rñÚtimeoutZvolley_failed_sendsrôZcscoper8Z maybe_volleyr rórrõ\sf
 
   ÿþ
 
 
ÿzDTLSChannel.do_handshakec
Ãs†|jr tj‚|stdƒ‚|js,| ¡IdH| ¡|j |¡|j    j
4IdHš&|j    j   t |jjƒ|j¡IdHW5QIdHRXdS)z Send a packet of data, securely.z2openssl doesn't support sending empty DTLS packetsN)rßrr¼Ú
ValueErrorrÑrõrårÀÚwriterÉr¹r    rºr¶ròrÙ)r€r<r r rÚsendÞs 
ÿzDTLSChannel.sendcÃsz|js| ¡IdHz|jj ¡IdH}Wn(tjk
rR|jsFt‚|     ¡YnX|j
  |¡t |j
j ƒ}|r|SqdS)aŠFetch the next packet of data from this connection's peer, waiting if
        necessary.
 
        This is safe to call from multiple tasks simultaneously, in case you have some
        reason to do that. And more importantly, it's cancellation-safe, meaning that
        cancelling a call to `receive` will never cause a packet to be lost or corrupt
        the underlying connection.
 
        N)rÑrõrÓr°ÚreceiverZ EndOfChannelrÞrxrårÀrÁr¶Úread)r€r8Z    cleartextr r rrüîs
 
  zDTLSChannel.receivecCs||_|j |¡dS)ujTells Trio the `largest amount of data that can be sent in a single packet to
        this peer <https://en.wikipedia.org/wiki/Maximum_transmission_unit>`__.
 
        Trio doesn't actually enforce this limit â€“ if you pass a huge packet to `send`,
        then we'll dutifully encrypt it and attempt to send it. But calling this method
        does have two useful effects:
 
        - If called before the handshake is performed, then Trio will automatically
          fragment handshake messages to fit within the given MTU. It also might
          fragment them even smaller, if it detects signs of packet loss, so setting
          this should never be necessary to make a successful connection. But, the
          packet loss detection only happens after multiple timeouts have expired, so if
          you have reason to believe that a smaller MTU is required, then you can set
          this to skip those timeouts and establish the connection more quickly.
 
        - It changes the value returned from `get_cleartext_mtu`. So if you have some
          kind of estimate of the network-level MTU, then you can use this to figure out
          how much overhead DTLS will need for hashes/padding/etc., and how much space
          you have left for your application data.
 
        The MTU here is measuring the largest UDP *payload* you think can be sent, the
        amount of encrypted data that can be handed to the operating system in a single
        call to `send`. It should *not* include IP/UDP headers. Note that OS estimates
        of the MTU often are link-layer MTUs, so you have to subtract off 28 bytes on
        IPv4 and 48 bytes on IPv6 to get the ciphertext MTU.
 
        By default, Trio assumes an MTU of 1472 bytes on IPv4, and 1452 bytes on IPv6,
        which correspond to the common Ethernet MTU of 1500 bytes after accounting for
        IP/UDP overhead.
 
        N)rÜrÀrÝ)r€Znew_mtur r rrÝs zDTLSChannel.set_ciphertext_mtucCs|js tj‚|j ¡S)zÈReturns the largest number of bytes that you can pass in a single call to
        `send` while still fitting within the network-level MTU.
 
        See `set_ciphertext_mtu` for more details.
 
        )rÑrZNeedHandshakeErrorrÀÚget_cleartext_mturr r rrþ+szDTLSChannel.get_cleartext_mtucCs
t|jƒS)a€Returns an object with statistics about this connection.
 
        Currently this has only one attribute:
 
        - ``incoming_packets_dropped_in_trio`` (``int``): Gives a count of the number of
          incoming packets from this peer that Trio successfully received from the
          network, but then got dropped because the internal channel buffer was full. If
          this is non-zero, then you might want to call ``receive`` more often, or use a
          larger ``incoming_packets_buffer``, or just not worry about it because your
          UDP-based protocol should be able to handle the occasional lost packet, right?
 
        )rØrÔrr r rÚ
statistics6s zDTLSChannel.statisticsN)rrrÚ__doc__rrÆrårärærêrírïrÒrõrûrürÝrþrÿr r r rr½òs" 
# r½)Ú    metaclassc@sfeZdZdZddœdd„Zdd„Zdd    „Zd
d „Zd d „Zdd„Z    dd„Z
e j dœdd„Z dd„ZdS)Ú DTLSEndpointaÛA DTLS endpoint.
 
    A single UDP socket can handle arbitrarily many DTLS connections simultaneously,
    acting as a client or server as needed. A `DTLSEndpoint` object holds a UDP socket
    and manages these connections, which are represented as `DTLSChannel` objects.
 
    Args:
      socket: (trio.socket.SocketType): A ``SOCK_DGRAM`` socket. If you want to accept
        incoming connections in server mode, then you should probably bind the socket to
        some known port.
      incoming_packets_buffer (int): Each `DTLSChannel` using this socket has its own
        buffer that holds incoming packets until you call `~DTLSChannel.receive` to read
        them. This lets you adjust the size of this buffer. `~DTLSChannel.statistics`
        lets you check if the buffer has overflowed.
 
    .. attribute:: socket
                   incoming_packets_buffer
 
       Both constructor arguments are also exposed as attributes, in case you need to
       access them later.
 
    é
)r±cCs~ddlmad|_|jtjjkr(tdƒ‚||_||_tj     ¡|_
t   ¡|_ d|_d|_ttdƒƒ|_t ¡|_d|_d|_dS)Nr)r²z!DTLS requires a SOCK_DGRAM socketÚinfF)ZOpenSSLr²r    ÚtyperÚ
SOCK_DGRAMrùr±rëZcurrent_trio_tokenÚ_tokenÚweakrefÚWeakValueDictionaryrÃr·r¸r®ÚfloatrÇràr¹rßÚ_receive_loop_spawned)r€r    r±r r rr^s  
 
zDTLSEndpoint.__init__cCs(|js$tj tt |¡|j¡d|_dSrã)r rrëZspawn_system_taskr×rÚrefr    rr r rröxsÿz!DTLSEndpoint._ensure_receive_loopcCsV|jdkrdS|jsRz|j |j¡Wntk
r:YnXtjd|›t|ddS)Nzunclosed DTLS endpoint )Úsource)    r    rßrZ run_sync_soonräÚ RuntimeErrorÚwarningsÚwarnÚResourceWarningrr r rÚ__del__‚s
ÿzDTLSEndpoint.__del__cCs<d|_|j ¡t|j ¡ƒD] }| ¡q|jj ¡dS)z}Close this socket, and all associated DTLS connections.
 
        This object can also be used as a context manager.
 
        TN)rßr    räÚlistrÃÚvaluesrÇr¯)r€rËr r rrä’s
 
 
zDTLSEndpoint.closecCs|Sr>r rr r rræžszDTLSEndpoint.__enter__cGs | ¡dSr>rçrèr r rrê¡szDTLSEndpoint.__exit__cCs|jr tj‚dSr>)rßrr¼rr r rÚ _check_closed¤szDTLSEndpoint._check_closed)Ú task_statusc
‡sÒ| ¡|jdk    rt d¡‚z|j ¡Wntk
rFtdƒ‚YnX| ¡|     dd„¡zf||_| 
¡‡‡fdd„}t  ¡4IdHš*}|j j 2z3dHW}| ||¡q–6W5QIdHRXW5d|_XdS)a–Listen for incoming connections, and spawn a handler for each using an
        internal nursery.
 
        Similar to `~trio.serve_tcp`, this function never returns until cancelled, or
        the `DTLSEndpoint` is closed and all handlers have exited.
 
        Usage commonly looks like::
 
            async def handler(dtls_channel):
                ...
 
            async with trio.open_nursery() as nursery:
                await nursery.start(dtls_endpoint.serve, ssl_context, handler)
                # ... do other things here ...
 
        The ``dtls_channel`` passed into the handler function has already performed the
        "cookie exchange" part of the DTLS handshake, so the peer address is
        trustworthy. But the actual cryptographic handshake doesn't happen until you
        start using it, giving you a chance for any last minute configuration, and the
        option to catch and handle handshake errors.
 
        Args:
          ssl_context (OpenSSL.SSL.Context): The PyOpenSSL context object to use for
            incoming connections.
          async_fn: The handler function that will be invoked for each incoming
            connection.
 
        Nz!another task is already listeningz-DTLS socket must be bound before it can servecWsdSrãr )Ú_r r rÚ<lambda>Ñr‘z$DTLSEndpoint.serve.<locals>.<lambda>c    “s(|ˆ|fˆžŽIdHW5QRXdSr>r )rË©réÚasync_fnr rÚhandler_wrapperÖsz+DTLSEndpoint.serve.<locals>.handler_wrapper)rr·rZBusyResourceErrorr    Ú getsocknamer»rröZset_cookie_verify_callbackÚstartedZ open_nurseryrÇr°Z
start_soon)r€Ú ssl_contextrrrérZnurseryrËr rrÚserve¨s"
 
$zDTLSEndpoint.servecCsJ| ¡t |||¡}|j ¡|j |¡}|dk    r<| ¡||j|<|S)u—Initiate an outgoing DTLS connection.
 
        Notice that this is a synchronous method. That's because it doesn't actually
        initiate any I/O â€“ it just sets up a `DTLSChannel` object. The actual handshake
        doesn't occur until you start using the `DTLSChannel`. This gives you a chance
        to do further configuration first, like setting MTU etc.
 
        Args:
          address: The address to connect to. Usually a (host, port) tuple, like
            ``("127.0.0.1", 12345)``.
          ssl_context (OpenSSL.SSL.Context): The PyOpenSSL context object to use for
            this connection.
 
        Returns:
          DTLSChannel
 
        N)rr½r¾rÀZset_connect_staterÃrÄrÆ)r€r¥rZchannelZ old_channelr r rÚconnectàs
 
zDTLSEndpoint.connectN)rrrrrrörrärærêrrZTASK_STATUS_IGNOREDrr r r r rrFs
 ÿ 8r)ArOržr«ÚenumÚ    itertoolsrrrÏrrJrZ
trio._utilrrrÎrrrÚIntEnumrrr0rvÚ    Exceptionr5r9r;ÚStructrMr3r—r@ÚfrozenrArUrYrbrZrgrirprqrtrur{r|rŽrr rœr¡rr–r§rªr­r®r¶rÌr×rØÚabcZChannelr½rr r r rÚ<module>    sz 
 
 
     E     ,|    ( I7V