@@ -11,6 +11,9 @@ const c = @cImport({
11
11
@cInclude ("quiche.h" );
12
12
});
13
13
14
+ const alloc = std .heap .c_allocator ;
15
+ const mpool = std .heap .MemoryPool ();
16
+
14
17
const MAX_DATAGRAM_SIZE = 1350 ;
15
18
const LOCAL_CONN_ID_LEN = 16 ;
16
19
@@ -20,14 +23,27 @@ const event_type = enum {
20
23
TIMER ,
21
24
};
22
25
23
- const request_data = struct {
24
- buf : [2048 ]u8 ,
25
- buf_slice : []u8 ,
26
+ const request_t = struct {
26
27
from : net.Address ,
27
- stream_id : u64 ,
28
+ data : []u8 ,
29
+ data_n : u32 ,
28
30
};
29
31
30
- var requests : [32 ]request_data = undefined ;
32
+ // var requests: [32]request_data = undefined;
33
+ var rmap : request_map_t = undefined ;
34
+ const request_map_t = std .HashMap (
35
+ u64 ,
36
+ request_t ,
37
+ struct {
38
+ pub fn hash (_ : @This (), a : u64 ) u64 {
39
+ return a >> 2 ;
40
+ }
41
+ pub fn eql (_ : @This (), a : u64 , b : u64 ) bool {
42
+ return a == b ;
43
+ }
44
+ },
45
+ 90 ,
46
+ );
31
47
32
48
const quic_upstream = struct {
33
49
sock : posix.socket_t ,
@@ -36,8 +52,7 @@ const quic_upstream = struct {
36
52
conf : ? * c.quiche_config ,
37
53
conn : ? * c.quiche_conn ,
38
54
urandom : fs.File ,
39
- sess : [* c ]u8 ,
40
- sess_len : usize ,
55
+ sess : ? []u8 ,
41
56
};
42
57
43
58
fn quic_upstream_init (u : * quic_upstream ) ! void {
@@ -95,7 +110,10 @@ fn quic_upstream_connect(u: *quic_upstream) !void {
95
110
u .conf ,
96
111
) orelse return error .quiche_connect_error ;
97
112
if (u .sess ) | sess | {
98
- _ = c .quiche_conn_set_session (u .conn , sess , u .sess_len );
113
+ std .debug .print ("trying to resume session ticket" , .{});
114
+ const e = c .quiche_conn_set_session (u .conn , sess .ptr , sess .len );
115
+ alloc .free (sess );
116
+ std .debug .print ("return value: {}\n " , .{e });
99
117
}
100
118
_ = c .quiche_conn_set_keylog_path (u .conn , "/tmp/keys" );
101
119
flush_egress (u );
@@ -173,6 +191,8 @@ pub fn flush_egress(u: *quic_upstream) void {
173
191
}
174
192
175
193
pub fn main () ! void {
194
+ rmap = request_map_t .init (alloc );
195
+
176
196
const server_fd = try posix .socket (posix .AF .INET , posix .SOCK .DGRAM , 0 );
177
197
_ = try posix .fcntl (server_fd , posix .F .SETFL , posix .SOCK .NONBLOCK );
178
198
const server_addr = try net .Address .parseIp ("127.0.0.1" , 5503 );
@@ -272,8 +292,21 @@ pub fn main() !void {
272
292
if (c .quiche_conn_is_closed (q_upstream .conn ) or restart ) {
273
293
restart = false ;
274
294
275
- c .quiche_conn_session (q_upstream .conn , & q_upstream .sess , & q_upstream .sess_len );
276
- std .debug .print ("{}\n " , .{q_upstream .sess_len });
295
+ var it = rmap .valueIterator ();
296
+ while (it .next ()) | req | {
297
+ alloc .free (req .data );
298
+ }
299
+ rmap .deinit ();
300
+ rmap = request_map_t .init (alloc );
301
+
302
+ var sess : [* c ]u8 = undefined ;
303
+ var sess_len : usize = undefined ;
304
+ c .quiche_conn_session (q_upstream .conn , & sess , & sess_len );
305
+ q_upstream .sess = try alloc .alloc (u8 , sess_len );
306
+ if (q_upstream .sess ) | s | {
307
+ @memcpy (s , sess [0.. sess_len ]);
308
+ }
309
+ std .debug .print ("{}\n " , .{sess_len });
277
310
278
311
std .debug .print ("connection is closed!\n " , .{});
279
312
c .quiche_conn_free (q_upstream .conn );
@@ -288,14 +321,18 @@ pub fn main() !void {
288
321
}
289
322
}
290
323
291
- var request : * request_data = & requests [ request_id_received % requests . len ] ;
292
- request . stream_id = request_id_received * 4 ;
293
- request_id_received = request_id_received + 1 ;
324
+ var req : request_t = undefined ;
325
+ req . data = try alloc . alloc ( u8 , 1024 ) ;
326
+
294
327
var from : net.Address = undefined ;
295
328
var from_len : posix.socklen_t = @sizeOf (net .Address );
296
- const n_read = try posix .recvfrom (server_fd , & request .buf , 0 , @ptrCast (& from ), & from_len );
297
- request .buf_slice = request .buf [0.. n_read ];
298
- request .from = from ;
329
+ req .data_n = @intCast (try posix .recvfrom (server_fd , req .data , 0 , @ptrCast (& from ), & from_len ));
330
+ req .from = from ;
331
+
332
+ const stream_id : u64 = request_id_received * 4 ;
333
+ request_id_received = request_id_received + 1 ;
334
+
335
+ try rmap .put (stream_id , req );
299
336
300
337
if (q_upstream .conn == null ) {
301
338
try quic_upstream_connect (& q_upstream );
@@ -328,32 +365,39 @@ pub fn main() !void {
328
365
}
329
366
defer c .quiche_h3_event_free (h3_event );
330
367
331
- var request = & requests [(@as (usize , @intCast (s )) >> 2 ) % requests .len ];
332
-
333
368
switch (c .quiche_h3_event_type (h3_event )) {
334
369
c .QUICHE_H3_EVENT_HEADERS = > {},
335
370
c .QUICHE_H3_EVENT_DATA = > {
336
371
if (@rem (s , 4 ) == 0 ) {
372
+ const stream_id : u64 = @bitCast (s );
373
+ const req = rmap .getPtr (stream_id ) orelse break ;
374
+
375
+ req .data = try alloc .realloc (req .data , 2048 );
337
376
// TODO: call recv_body in loop and handle multiple data events on same stream
338
- const n_read_h3 = c .quiche_h3_recv_body (
377
+ req . data_n = @intCast ( c .quiche_h3_recv_body (
339
378
h3_conn ,
340
379
q_upstream .conn ,
341
380
@bitCast (s ),
342
- & request .buf ,
343
- request .buf .len ,
344
- );
345
- request .buf_slice = request .buf [0.. @bitCast (n_read_h3 )];
381
+ req .data .ptr ,
382
+ req .data .len ,
383
+ ));
346
384
}
347
385
},
348
386
c .QUICHE_H3_EVENT_FINISHED = > {
349
387
if (@rem (s , 4 ) == 0 ) {
388
+ const stream_id : u64 = @bitCast (s );
389
+ const req = rmap .getPtr (stream_id ) orelse break ;
390
+
350
391
_ = try posix .sendto (
351
392
server_fd ,
352
- request . buf_slice ,
393
+ req . data [0 .. req . data_n ] ,
353
394
0 ,
354
- @ptrCast (& request .from ),
355
- request .from .getOsSockLen (),
395
+ @ptrCast (& req .from ),
396
+ req .from .getOsSockLen (),
356
397
);
398
+
399
+ alloc .free (req .data );
400
+ _ = rmap .remove (stream_id );
357
401
}
358
402
},
359
403
c .QUICHE_H3_EVENT_GOAWAY = > {
@@ -378,9 +422,13 @@ pub fn main() !void {
378
422
if (h3_conn != null ) {
379
423
for (request_id_sent .. request_id_received ) | i | {
380
424
std .debug .print ("request id: {}\n " , .{i });
381
- const request : * request_data = & requests [i % requests .len ];
382
- const stream_id = c .quiche_h3_send_request (h3_conn , q_upstream .conn , & doh3_headers , doh3_headers .len , false );
383
- _ = c .quiche_h3_send_body (h3_conn , q_upstream .conn , @bitCast (stream_id ), request .buf_slice .ptr , request .buf_slice .len , true );
425
+
426
+ const stream_id : u64 = i << 2 ;
427
+ const req = rmap .getPtr (stream_id ) orelse break ;
428
+
429
+ _ = c .quiche_h3_send_request (h3_conn , q_upstream .conn , & doh3_headers , doh3_headers .len , false );
430
+ _ = c .quiche_h3_send_body (h3_conn , q_upstream .conn , @bitCast (stream_id ), req .data .ptr , req .data_n , true );
431
+ req .data_n = 0 ;
384
432
}
385
433
request_id_sent = request_id_received ;
386
434
}
0 commit comments