Skip to content

Commit dba97fe

Browse files
committed
Trace shared-socket QUIC routing
1 parent 38f86bb commit dba97fe

9 files changed

Lines changed: 98 additions & 76 deletions

File tree

generate_lsquic_ffi.nim

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,29 @@ from os import parentDir, `/`
77

88
import boringssl
99

10-
proc dropGeneratedCEnumsImpl(opirOutput: JsonNode): JsonNode =
10+
const preludeTypes = ["struct_lsquic_cid", "lsquic_cid_t"]
11+
12+
proc dropPreludeTypesAndGeneratedCEnumsImpl(opirOutput: JsonNode): JsonNode =
1113
var resp = newJArray()
1214
for node in opirOutput:
1315
# enums are generated manually to avoid issue described in
1416
# https://github.com/PMunch/futhark/issues/152
1517
if node{"kind"}.getStr("") == "enum":
1618
continue
19+
20+
# Futhark incorrectly maps the struct alignment on lsquic_cid_t to field alignment,
21+
# so the prelude supplies the correct native layout instead.
22+
if node{"name"}.getStr("") in preludeTypes:
23+
continue
24+
1725
resp.add node
1826
resp
1927

2028
importc:
2129
outputPath currentSourcePath.parentDir / "tmp_lsquic_ffi.nim"
2230
path currentSourcePath.parentDir / "libs/lsquic/include"
2331
addopircallback proc(opirOutput: JsonNode): JsonNode {.closure.} =
24-
dropGeneratedCEnumsImpl(opirOutput)
32+
dropPreludeTypesAndGeneratedCEnumsImpl(opirOutput)
2533
rename FILE, CFile # Rename `FILE` that STB uses to `CFile` which is the Nim equivalent
2634
rename struct_sockaddr, SockAddr # Rename `struct_sockaddr` for chronos SockAddr
2735
"lsquic.h"

lsquic/context/client.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ method dial*(
107107
if conn.isNil:
108108
GC_unref(quicClientConn)
109109
return err("could not dial: " & $remote)
110-
ctx.trackConnectionCid(conn)
111110

112111
quicClientConn.lsquicConn = conn
112+
ctx.trackConnectionCid(conn)
113113
ctx.processWhenReady()
114114

115115
ok(quicClientConn)
@@ -120,9 +120,9 @@ const Adaptive = 3
120120
proc new*(T: typedesc[ClientContext], tlsConfig: TLSConfig): Result[T, string] =
121121
var ctx = ClientContext()
122122
ctx.tlsConfig = tlsConfig
123-
ctx.initCidTracking()
124123
ctx.running = true
125124
ctx.setupSSLContext()
125+
ctx.initCidTracking()
126126

127127
lsquic_engine_init_settings(addr ctx.settings, 0)
128128
ctx.settings.es_versions = 1.cuint shl LSQVER_I001.cuint #IETF QUIC v1

lsquic/context/context.nim

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: Apache-2.0 OR MIT
22
# Copyright (c) Status Research & Development GmbH
33

4-
import std/[deques, hashes, sets]
4+
import std/[deques, hashes, sets, strutils]
55
import boringssl
66
import chronos
77
import chronos/osdefs
@@ -17,14 +17,7 @@ type
1717
len*: uint8
1818
bytes*: array[MAX_CID_LEN, uint8]
1919

20-
# The generated FFI type currently aligns fields, not just the C struct.
21-
# Read CIDs through the native wire layout until the binding is regenerated.
22-
RawLsquicCid = object
23-
buf: array[MAX_CID_LEN, uint8]
24-
len: uint8
25-
padding: array[3, uint8]
26-
27-
RawLsquicCidArray = UncheckedArray[RawLsquicCid]
20+
LsquicCidArray = UncheckedArray[lsquic_cid_t]
2821

2922
QuicContext* = ref object of RootObj
3023
settings*: struct_lsquic_engine_settings
@@ -40,16 +33,25 @@ type
4033
ownedCids*: HashSet[CidKey]
4134

4235
static:
43-
doAssert sizeof(RawLsquicCid) == 24
44-
doAssert offsetOf(RawLsquicCid, len) == 20
36+
doAssert sizeof(lsquic_cid_t) == 24
37+
doAssert offsetOf(lsquic_cid_t, len) == 20
4538

4639
func hash*(cid: CidKey): Hash =
4740
var h = hash(cid.len)
4841
for i in 0 ..< cid.len.int:
4942
h = h !& hash(cid.bytes[i])
5043
!$h
5144

52-
func toCidKey(cid: RawLsquicCid, key: var CidKey): bool =
45+
func shortLog*(cid: CidKey): string =
46+
var ret = $cid.len & ":"
47+
for i in 0 ..< min(cid.len.int, 8):
48+
ret.add(toHex(cid.bytes[i], 2))
49+
ret
50+
51+
chronicles.formatIt(CidKey):
52+
shortLog(it)
53+
54+
func toCidKey(cid: lsquic_cid_t, key: var CidKey): bool =
5355
if cid.len == 0 or cid.len.int > MAX_CID_LEN:
5456
return false
5557

@@ -68,11 +70,13 @@ proc addCids*(
6870
if quicCtx.isNil or cids.isNil:
6971
return
7072

71-
let cidsArr = cast[ptr RawLsquicCidArray](cids)
73+
let cidsArr = cast[ptr LsquicCidArray](cids)
7274
for i in 0 ..< nCids.int:
7375
var key: CidKey
7476
if toCidKey(cidsArr[i], key):
7577
quicCtx.ownedCids.incl(key)
78+
trace "Registered CID", cid = key,
79+
cidCount = quicCtx.ownedCids.len
7680

7781
proc removeCids*(
7882
ctx: pointer, peerCtxs: ptr pointer, cids: ptr lsquic_cid_t, nCids: cuint
@@ -81,11 +85,13 @@ proc removeCids*(
8185
if quicCtx.isNil or cids.isNil:
8286
return
8387

84-
let cidsArr = cast[ptr RawLsquicCidArray](cids)
88+
let cidsArr = cast[ptr LsquicCidArray](cids)
8589
for i in 0 ..< nCids.int:
8690
var key: CidKey
8791
if toCidKey(cidsArr[i], key):
8892
quicCtx.ownedCids.excl(key)
93+
trace "Removed CID", cid = key,
94+
cidCount = quicCtx.ownedCids.len
8995

9096
proc trackConnectionCid*(
9197
ctx: QuicContext, conn: ptr lsquic_conn_t
@@ -98,8 +104,10 @@ proc trackConnectionCid*(
98104
return
99105

100106
var key: CidKey
101-
if toCidKey(cast[ptr RawLsquicCid](cid)[], key):
107+
if toCidKey(cid[], key):
102108
ctx.ownedCids.incl(key)
109+
trace "Tracked connection CID", cid = key,
110+
cidCount = ctx.ownedCids.len
103111

104112
proc ownsCid*(ctx: QuicContext, cid: CidKey): bool {.raises: [].} =
105113
not ctx.isNil and cid in ctx.ownedCids

lsquic/context/io.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import chronos
55
import chronos/osdefs
6+
import chronicles
67
import ./context
78
import ../[lsquic_ffi, datagram]
89
import ../helpers/[openarray, sequninit, transportaddr]
@@ -144,6 +145,7 @@ proc sendPacketsOut*(
144145

145146
let res = sendmsg(SocketHandle(quicCtx.fd), msg.addr, 0)
146147
if res < 0:
148+
trace "sendmsg failed", sent, nspecs
147149
break
148150

149151
sent.inc

lsquic/context/server.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ proc new*(T: typedesc[ServerContext], tlsConfig: TLSConfig): Result[T, string] =
5757
var ctx = ServerContext()
5858
ctx.tlsConfig = tlsConfig
5959
ctx.running = true
60-
ctx.initCidTracking()
6160
ctx.incoming = newAsyncQueue[QuicConnection]()
6261
ctx.setupSSLContext()
62+
ctx.initCidTracking()
6363

6464
lsquic_engine_init_settings(addr ctx.settings, LSENG_SERVER)
6565
ctx.settings.es_versions = 1.cuint shl LSQVER_I001.cuint #IETF QUIC v1

lsquic/endpoint.nim

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ proc createClientContext(
3939
context.fd = fd
4040
context
4141

42-
proc serverCidLen(endpoint: QuicEndpoint): cuint {.raises: [].} =
43-
if not endpoint.serverContext.isNil and endpoint.serverContext.settings.es_scid_len != 0:
42+
proc scidLen(endpoint: QuicEndpoint): cuint {.raises: [].} =
43+
if not endpoint.serverContext.isNil and
44+
endpoint.serverContext.settings.es_scid_len != 0:
4445
return endpoint.serverContext.settings.es_scid_len
45-
if not endpoint.clientContext.isNil and endpoint.clientContext.settings.es_scid_len != 0:
46+
if not endpoint.clientContext.isNil and
47+
endpoint.clientContext.settings.es_scid_len != 0:
4648
return endpoint.clientContext.settings.es_scid_len
4749
LSQUIC_DF_SCID_LEN.cuint
4850

@@ -54,10 +56,7 @@ proc packetDcid(
5456

5557
var cidLen: uint8
5658
let offset = lsquic_dcid_from_packet(
57-
unsafeAddr packet[0],
58-
packet.len.csize_t,
59-
endpoint.serverCidLen(),
60-
addr cidLen,
59+
unsafeAddr packet[0], packet.len.csize_t, endpoint.scidLen(), addr cidLen
6160
)
6261
if offset < 0:
6362
return false
@@ -80,15 +79,23 @@ proc receiveDatagram(
8079
var cid: CidKey
8180
if endpoint.packetDcid(data, cid):
8281
if not endpoint.clientContext.isNil and endpoint.clientContext.ownsCid(cid):
82+
trace "Routing datagram to client context", cid
8383
endpoint.clientContext.receive(Datagram(data: data), local, remote)
8484
return
8585

8686
if not endpoint.serverContext.isNil and endpoint.serverContext.ownsCid(cid):
87+
trace "Routing datagram to server context", cid
8788
endpoint.serverContext.receive(Datagram(data: data), local, remote)
8889
return
8990

9091
# Unknown CIDs can be new handshakes; each engine gets a chance to claim them.
9192
# Endpoints can have both contexts; each engine needs to see the packet.
93+
trace "Routing datagram with unknown CID",
94+
bytes = data.len,
95+
hasClientContext = not endpoint.clientContext.isNil,
96+
hasServerContext = not endpoint.serverContext.isNil,
97+
local,
98+
remote
9299
if not endpoint.clientContext.isNil:
93100
endpoint.clientContext.receive(Datagram(data: data), local, remote)
94101
if not endpoint.serverContext.isNil:

lsquic/lsquic_ffi.nim

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import chronos/osdefs
1111
import zlib
1212
import boringssl
1313

14-
type ptrdiff_t* {.importc: "ptrdiff_t", header: "<stddef.h>".} = int
14+
type
15+
ptrdiff_t* {.importc: "ptrdiff_t", header: "<stddef.h>".} = int
16+
uint_fast8_t* {.importc: "uint_fast8_t", header: "<stdint.h>".} = uint8
1517

1618
# enums are generated manually to avoid issue described in
1719
# https://github.com/PMunch/futhark/issues/152
@@ -43,6 +45,9 @@ borrowCEnumOps(enum_lsquic_conn_param)
4345
borrowCEnumOps(enum_LSQUIC_CONN_STATUS)
4446

4547
const
48+
MAX_CID_LEN* = 20
49+
GQUIC_CID_LEN* = 8
50+
4651
LSQVER_043* = enum_lsquic_version(0)
4752
LSQVER_046* = enum_lsquic_version(1)
4853
LSQVER_050* = enum_lsquic_version(2)
@@ -107,6 +112,19 @@ when defined(windows):
107112
{.passc: "-I" & lshpack.}
108113
{.passc: "-I" & xxhash.}
109114

115+
type
116+
struct_lsquic_cid* {.
117+
importc: "struct lsquic_cid",
118+
header: "lsquic_types.h",
119+
bycopy,
120+
completeStruct
121+
.} = object
122+
buf* {.importc: "buf".}: array[MAX_CID_LEN, uint8]
123+
len* {.importc: "len".}: uint_fast8_t
124+
padding: array[3, uint8]
125+
126+
lsquic_cid_t* = struct_lsquic_cid
127+
110128
const HAVE_BORINGSSL = "-DHAVE_BORINGSSL"
111129
const XXH_HEADER_NAME = "-DXXH_HEADER_NAME=\"<lsquic_xxhash.h>\""
112130

@@ -357,14 +375,7 @@ else:
357375
"Declaration of " & "LSQUIC_DF_CFCW_CLIENT" & " already exists, not redeclaring"
358376
)
359377
type
360-
struct_lsquic_cid_570425834 {.pure, inheritable, bycopy.} = object
361-
buf* {.align(8'i64).}: array[20'i64, uint8]
362-
## Generated based on /home/r/vacp2p/nim-lsquic/libs/lsquic/include/lsquic_types.h:27:28
363-
len* {.align(8'i64).}: uint_fast8_t_570425837
364-
365378
uint_fast8_t_570425836 = uint8 ## Generated based on /usr/include/stdint.h:60:24
366-
lsquic_cid_t_570425838 = struct_lsquic_cid_570425835
367-
## Generated based on /home/r/vacp2p/nim-lsquic/libs/lsquic/include/lsquic_types.h:32:3
368379
lsquic_stream_id_t_570425840 = uint64
369380
## Generated based on /home/r/vacp2p/nim-lsquic/libs/lsquic/include/lsquic_types.h:40:18
370381
lsquic_engine_t_570425842 = struct_lsquic_engine
@@ -554,7 +565,7 @@ type
554565
pmi_return*: proc(a0: pointer, a1: pointer, a2: pointer, a3: cschar): void {.cdecl.}
555566

556567
lsquic_cids_update_f_570425876 = proc(
557-
a0: pointer, a1: ptr pointer, a2: ptr lsquic_cid_t_570425839, a3: cuint
568+
a0: pointer, a1: ptr pointer, a2: ptr lsquic_cid_t, a3: cuint
558569
): void {.cdecl.}
559570
## Generated based on /home/r/vacp2p/nim-lsquic/libs/lsquic/include/lsquic.h:1307:16
560571
struct_lsquic_hset_if_570425878 {.pure, inheritable, bycopy.} = object
@@ -733,17 +744,6 @@ type
733744
else:
734745
struct_lsquic_conn_info_570425895
735746
)
736-
struct_lsquic_cid_570425835 = (
737-
when declared(struct_lsquic_cid):
738-
when ownSizeof(struct_lsquic_cid) != ownSizeof(struct_lsquic_cid_570425834):
739-
static:
740-
warning(
741-
"Declaration of " & "struct_lsquic_cid" & " exists but with different size"
742-
)
743-
struct_lsquic_cid
744-
else:
745-
struct_lsquic_cid_570425834
746-
)
747747
lsquic_stream_id_t_570425841 = (
748748
when declared(lsquic_stream_id_t):
749749
when ownSizeof(lsquic_stream_id_t) != ownSizeof(lsquic_stream_id_t_570425840):
@@ -910,17 +910,6 @@ type
910910
else:
911911
lsquic_stream_ctx_t_570425850
912912
)
913-
lsquic_cid_t_570425839 = (
914-
when declared(lsquic_cid_t):
915-
when ownSizeof(lsquic_cid_t) != ownSizeof(lsquic_cid_t_570425838):
916-
static:
917-
warning(
918-
"Declaration of " & "lsquic_cid_t" & " exists but with different size"
919-
)
920-
lsquic_cid_t
921-
else:
922-
lsquic_cid_t_570425838
923-
)
924913
uint_fast8_t_570425837 = (
925914
when declared(uint_fast8_t):
926915
when ownSizeof(uint_fast8_t) != ownSizeof(uint_fast8_t_570425836):
@@ -1046,11 +1035,6 @@ else:
10461035
hint(
10471036
"Declaration of " & "struct_lsquic_conn_info" & " already exists, not redeclaring"
10481037
)
1049-
when not declared(struct_lsquic_cid):
1050-
type struct_lsquic_cid* = struct_lsquic_cid_570425834
1051-
else:
1052-
static:
1053-
hint("Declaration of " & "struct_lsquic_cid" & " already exists, not redeclaring")
10541038
when not declared(lsquic_stream_id_t):
10551039
type lsquic_stream_id_t* = lsquic_stream_id_t_570425840
10561040
else:
@@ -1138,11 +1122,6 @@ when not declared(lsquic_stream_ctx_t):
11381122
else:
11391123
static:
11401124
hint("Declaration of " & "lsquic_stream_ctx_t" & " already exists, not redeclaring")
1141-
when not declared(lsquic_cid_t):
1142-
type lsquic_cid_t* = lsquic_cid_t_570425838
1143-
else:
1144-
static:
1145-
hint("Declaration of " & "lsquic_cid_t" & " already exists, not redeclaring")
11461125
when not declared(uint_fast8_t):
11471126
type uint_fast8_t* = uint_fast8_t_570425836
11481127
else:
@@ -2670,7 +2649,7 @@ else:
26702649
when not declared(lsquic_conn_id):
26712650
proc lsquic_conn_id*(
26722651
c: ptr lsquic_conn_t_570425845
2673-
): ptr lsquic_cid_t_570425839 {.cdecl, importc: "lsquic_conn_id".}
2652+
): ptr lsquic_cid_t {.cdecl, importc: "lsquic_conn_id".}
26742653

26752654
else:
26762655
static:
@@ -2968,7 +2947,7 @@ else:
29682947
)
29692948
when not declared(lsquic_cid_from_packet):
29702949
proc lsquic_cid_from_packet*(
2971-
a0: ptr uint8, bufsz: csize_t, cid: ptr lsquic_cid_t_570425839
2950+
a0: ptr uint8, bufsz: csize_t, cid: ptr lsquic_cid_t
29722951
): cint {.cdecl, importc: "lsquic_cid_from_packet".}
29732952

29742953
else:

0 commit comments

Comments
 (0)