11# SPDX-License-Identifier: Apache-2.0 OR MIT
22# Copyright (c) Status Research & Development GmbH
33
4- import std/ deques
4+ import std/ [ deques, hashes, sets, strutils]
55import boringssl
66import chronos
77import chronos/ osdefs
@@ -12,17 +12,96 @@ import
1212let SSL_CTX_ID = SSL_CTX_get_ex_new_index (0 , nil , nil , nil , nil ) # Yes, this is global
1313doAssert SSL_CTX_ID >= 0 , " could not generate global ssl_ctx id"
1414
15- type QuicContext * = ref object of RootObj
16- settings* : struct_lsquic_engine_settings
17- api* : struct_lsquic_engine_api
18- engine* : ptr struct_lsquic_engine
19- stream_if* : struct_lsquic_stream_if
20- tlsConfig* : TLSConfig
21- tickTimeout* : Timeout
22- sslCtx* : ptr SSL_CTX
23- fd* : cint
24- processing: bool
25- running* : bool
15+ type
16+ CidKey * = object
17+ len* : uint8
18+ bytes* : array [MAX_CID_LEN , uint8 ]
19+
20+ LsquicCidArray = UncheckedArray [lsquic_cid_t]
21+
22+ QuicContext * = ref object of RootObj
23+ settings* : struct_lsquic_engine_settings
24+ api* : struct_lsquic_engine_api
25+ engine* : ptr struct_lsquic_engine
26+ stream_if* : struct_lsquic_stream_if
27+ tlsConfig* : TLSConfig
28+ tickTimeout* : Timeout
29+ sslCtx* : ptr SSL_CTX
30+ fd* : cint
31+ processing: bool
32+ running* : bool
33+ ownedCids: HashSet [CidKey ]
34+
35+ func hash * (cid: CidKey ): Hash =
36+ var h = hash (cid.len)
37+ for i in 0 ..< cid.len.int :
38+ h = h !& hash (cid.bytes[i])
39+ !$ h
40+
41+ func shortLog * (cid: CidKey ): string =
42+ var ret = $ cid.len & " :"
43+ for i in 0 ..< min (cid.len.int , 8 ):
44+ ret.add (toHex (cid.bytes[i], 2 ))
45+ ret
46+
47+ chronicles.formatIt (CidKey ):
48+ shortLog (it)
49+
50+ func toCidKey (cid: lsquic_cid_t, key: var CidKey ): bool =
51+ if cid.len == 0 or cid.len.int > MAX_CID_LEN :
52+ return false
53+
54+ key = CidKey (len: cid.len)
55+ for i in 0 ..< cid.len.int :
56+ key.bytes[i] = cid.buf[i]
57+ true
58+
59+ proc initCidTracking * (ctx: QuicContext ) {.raises : [].} =
60+ ctx.ownedCids = initHashSet [CidKey ]()
61+
62+ proc addCids * (
63+ ctx: pointer , _: ptr pointer , cids: ptr lsquic_cid_t, nCids: cuint
64+ ) {.cdecl , raises : [].} =
65+ let quicCtx = cast [QuicContext ](ctx)
66+ if quicCtx.isNil or cids.isNil:
67+ return
68+
69+ let cidsArr = cast [ptr LsquicCidArray ](cids)
70+ for i in 0 ..< nCids.int :
71+ var key: CidKey
72+ if toCidKey (cidsArr[i], key):
73+ quicCtx.ownedCids.incl (key)
74+ trace " Registered CID" , cid = key, cidCount = quicCtx.ownedCids.len
75+
76+ proc removeCids * (
77+ ctx: pointer , _: ptr pointer , cids: ptr lsquic_cid_t, nCids: cuint
78+ ) {.cdecl , raises : [].} =
79+ let quicCtx = cast [QuicContext ](ctx)
80+ if quicCtx.isNil or cids.isNil:
81+ return
82+
83+ let cidsArr = cast [ptr LsquicCidArray ](cids)
84+ for i in 0 ..< nCids.int :
85+ var key: CidKey
86+ if toCidKey (cidsArr[i], key):
87+ quicCtx.ownedCids.excl (key)
88+ trace " Removed CID" , cid = key, cidCount = quicCtx.ownedCids.len
89+
90+ proc trackConnectionCid * (ctx: QuicContext , conn: ptr lsquic_conn_t) {.raises : [].} =
91+ if ctx.isNil or conn.isNil:
92+ return
93+
94+ let cid = lsquic_conn_id (conn)
95+ if cid.isNil:
96+ return
97+
98+ var key: CidKey
99+ if toCidKey (cid[], key):
100+ ctx.ownedCids.incl (key)
101+ trace " Tracked connection CID" , cid = key, cidCount = ctx.ownedCids.len
102+
103+ proc ownsCid * (ctx: QuicContext , cid: CidKey ): bool {.raises : [].} =
104+ not ctx.isNil and cid in ctx.ownedCids
26105
27106proc isRunning * (ctx: QuicContext ): bool {.raises : [].} =
28107 not ctx.isNil and ctx.running and not ctx.engine.isNil
0 commit comments