From 12b037ced0be4ba44f8a9bc8a2e00b311af5daca Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 00:47:48 +0100 Subject: [PATCH 01/49] streams: design note for the reader/writer/stream layer Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- STREAMS.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 STREAMS.md diff --git a/STREAMS.md b/STREAMS.md new file mode 100644 index 0000000..f8478a1 --- /dev/null +++ b/STREAMS.md @@ -0,0 +1,82 @@ +# Streams and pipes over the I/O plane (design, branch `streams`) + +## Why + +Today the I/O plane offers two primitives, `await_recv` and `await_send`, and the HTTP engine +builds everything else on them: a 16 KB request buffer it fills and parses, a reply slab it +appends to and flushes. Both are streams in all but name. Naming them, and moving them below the +HTTP engine, gives three things: + +1. a transport-independent surface, so a raw TCP server, a WebSocket upgrade or a TLS layer + later do not need to know the engine; +2. the reply side formalised as a writer: reserve space in the slab, write into it, advance, + flush - what the arena handler already does by hand; +3. the request side as a reader over the kernel-filled provided buffers, which is where the one + copy left on the hot path lives (provided buffer -> request buffer) and where a zero-copy + parse of the common single-segment head becomes possible. + +The shape is System.IO.Pipelines: Kestrel is transport -> PipeReader/PipeWriter -> parser, and +this runtime has the same layering, with coroutines instead of tasks. "Async" here means "may +suspend the coroutine"; the caller does not see it. + +## The pieces + +**`ioma_writer`** - the slab with a head reserve, a tail, and a connection to flush to. + + void *ioma_writer_reserve(w, size_t n); /* n bytes at the tail, flushing first if they do not fit */ + void ioma_writer_advance(w, size_t n); /* the caller wrote n of them */ + int ioma_writer_write (w, data, n); /* copy in (reserve + memcpy + advance) */ + int ioma_writer_flush (w); /* send what is in the slab; suspends */ + int ioma_writer_send (w, data, n); /* write + flush */ + +The HTTP response keeps its head-building on top (first flush builds the head into the lead). +`ioma_write`, `ioma_printf`, `ioma_flush` become thin calls; `ioma_reserve`/`ioma_advance` are new +on the context, for handlers that format straight into the reply. + +**`ioma_reader`** - the connection's received bytes as segments, consumed in place. + + struct ioma_segment { const char *p; size_t len; }; + int ioma_reader_read (r, const struct ioma_segment **segs, size_t *n); /* what is buffered; waits for more when nothing is; 0 at EOF, -1 on error */ + void ioma_reader_advance(r, size_t consumed, size_t examined); /* consumed: returned to the ring; examined: do not wake me until more than this arrives */ + int ioma_reader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ + +The segments are the provided buffers as the kernel filled them (2 KB each, in order). A parser +that needs contiguity coalesces: parse in place when the data sits in one segment, copy into a +scratch buffer when it spans. `consumed`/`examined` are Pipelines' contract and what makes +"read until a full head is here" cheap: the reader does not wake the coroutine for a partial +head it already examined. + +**`ioma_stream`** - one connection's reader and writer together, what a handler of a non-HTTP +protocol would receive. + +## The HTTP engine on top + +- `read_head`: `reader_read`; if the head ends inside the first segment, `phr_parse_request` + runs on the segment itself - no copy - and the request's slices point into the provided + buffer, which stays owned by the connection until the reply is finished (then `advance` + returns it). If the head spans segments, coalesce into the request buffer as today. +- Body reads (`ioma_body_all`, `read_until`, `read_next_chunk`) walk segments through the same + chunk parser; the whole read still needs contiguous output, so it copies when the body spans. +- Pipelining falls out: the bytes after a request are simply not consumed. +- The reply: unchanged behaviour, on the writer. + +## Costs and gates + +- Holding a provided buffer for the life of a request (instead of copying and returning it at + once) means a slow handler pins one 2 KB buffer per in-flight request. 4096 per worker; the + -ENOBUFS parking already handles exhaustion. Measure under the 500k profile. +- An extra indirection per read/write is nothing next to a syscall, but the reader's segment + bookkeeping must not add branches to the single-segment fast path. Gate: keep-alive and churn + on 4 reactors within noise of main, then the arena profiles. +- No vtable in the first cut: one transport. TLS or a test transport can come as a compile-time + layer or a later vtable once there is a second implementation to justify it. + +## Order of work + +1. Writer: reserve/advance/write/flush/send in the io plane; the response on it; + `ioma_reserve`/`ioma_advance` public. Small, no behaviour change, measurable. +2. Reader with `copy` only (Stream semantics) and the engine's `read_head` and body stage on it, + still copying. Same behaviour, same numbers expected. Removes `await_recv` from the engine. +3. Segments + `advance(consumed, examined)`, then the zero-copy head parse. This is the step with + a payoff and the risk; it gets the fragmentation validator and the raw-socket smoke tests. +4. `ioma_stream` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. From 657b9b3a8fd05897c45b5495fc44254af20be49a Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 01:01:04 +0100 Subject: [PATCH 02/49] streams: the reader returns one contiguous span, coalescing lazily; why not segments Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- STREAMS.md | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/STREAMS.md b/STREAMS.md index f8478a1..f96677b 100644 --- a/STREAMS.md +++ b/STREAMS.md @@ -33,30 +33,43 @@ The HTTP response keeps its head-building on top (first flush builds the head in `ioma_write`, `ioma_printf`, `ioma_flush` become thin calls; `ioma_reserve`/`ioma_advance` are new on the context, for handlers that format straight into the reply. -**`ioma_reader`** - the connection's received bytes as segments, consumed in place. - - struct ioma_segment { const char *p; size_t len; }; - int ioma_reader_read (r, const struct ioma_segment **segs, size_t *n); /* what is buffered; waits for more when nothing is; 0 at EOF, -1 on error */ - void ioma_reader_advance(r, size_t consumed, size_t examined); /* consumed: returned to the ring; examined: do not wake me until more than this arrives */ - int ioma_reader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ - -The segments are the provided buffers as the kernel filled them (2 KB each, in order). A parser -that needs contiguity coalesces: parse in place when the data sits in one segment, copy into a -scratch buffer when it spans. `consumed`/`examined` are Pipelines' contract and what makes -"read until a full head is here" cheap: the reader does not wake the coroutine for a partial -head it already examined. +**`ioma_reader`** - the connection's received bytes, one contiguous span at a time. + + int ioma_reader_read (r, ioma_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ + void ioma_reader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ + int ioma_reader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ + +Why one span and not a list of segments. io_uring hands data over as provided buffers, each a +pointer and a length, and the reader keeps them as such internally (the rx queue does already). +But every consumer needs contiguous bytes: picohttpparser takes one buffer, the chunk parser +takes one buffer, and the request model hands handlers `ioma_slice`s, which are contiguous by +definition - a header value split across two provided buffers cannot be a slice without a +copy. A segment-aware parser would not remove that copy, only move it, and the parser would be +ours to write and to keep fast. So the reader coalesces, and it does so lazily: + +- when everything buffered lies in one provided buffer - a whole request head in one receive, + the common case - `read` returns that buffer's bytes in place: zero copy, the buffer stays + owned by the connection until `advance` consumes past it; +- when the data spans buffers, `read` copies the pieces into the connection's request buffer + (16 KB, on the coroutine's stack: no allocation) and returns that. Spanning requests pay the + copy they pay today; nothing else does. + +That is Kestrel's `IsSingleSegment` fast path, kept inside the reader rather than in every +parser, and `advance(consumed, examined)` is Pipelines' contract: `consumed` releases buffers, +`examined` keeps `read` from returning the same incomplete head twice - it suspends until more +arrives instead. **`ioma_stream`** - one connection's reader and writer together, what a handler of a non-HTTP protocol would receive. ## The HTTP engine on top -- `read_head`: `reader_read`; if the head ends inside the first segment, `phr_parse_request` - runs on the segment itself - no copy - and the request's slices point into the provided - buffer, which stays owned by the connection until the reply is finished (then `advance` - returns it). If the head spans segments, coalesce into the request buffer as today. -- Body reads (`ioma_body_all`, `read_until`, `read_next_chunk`) walk segments through the same - chunk parser; the whole read still needs contiguous output, so it copies when the body spans. +- `read_head`: `reader_read` gives a span; `phr_parse_request` runs on it. In the common case + that is the provided buffer itself - no copy - and the request's slices point into it; the + buffer stays owned by the connection until the reply is finished, when `advance` returns it. + A head that spans receives arrives coalesced in the request buffer, as today. +- Body reads (`ioma_body_all`, `read_until`, `read_next_chunk`) run the chunk parser on spans + the same way; the whole read wants contiguous output and gets it from the same coalescing. - Pipelining falls out: the bytes after a request are simply not consumed. - The reply: unchanged behaviour, on the writer. @@ -77,6 +90,7 @@ protocol would receive. `ioma_reserve`/`ioma_advance` public. Small, no behaviour change, measurable. 2. Reader with `copy` only (Stream semantics) and the engine's `read_head` and body stage on it, still copying. Same behaviour, same numbers expected. Removes `await_recv` from the engine. -3. Segments + `advance(consumed, examined)`, then the zero-copy head parse. This is the step with - a payoff and the risk; it gets the fragmentation validator and the raw-socket smoke tests. +3. Spans + `advance(consumed, examined)`, then the zero-copy single-buffer path. This is the + step with a payoff and the risk; it gets the fragmentation validator and the raw-socket + smoke tests. 4. `ioma_stream` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. From d38940e3ec028c516b947cff2ece474a2772f641 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 01:29:25 +0100 Subject: [PATCH 03/49] Pipes: a reader and a writer over the connection; the HTTP engine reads through the reader io/pipe.h: the reader hands out received bytes as one contiguous span at a time - in place in the kernel's buffer when they lie within one, gathered into the consumer's buffer when they span or when kept bytes must stay contiguous - with read/examine/ drop/keep/run_begin/release/copy; it holds at most two kernel buffers, one with kept bytes of earlier runs, one with the live bytes. The writer is a slab with reserve/ advance/write/flush/send. Both suspend the coroutine when they must wait. The engine now reads through the reader: read_head parses the live span in place and keeps the head (zero copy when it arrived in one receive), the chunk parser walks spans, ioma_body_all keeps its bytes, streamed reads copy straight from the kernel's buffer, and release at the end of a request replaces the pipelining carry-over. The 16 KB request buffer is the reader's gathering buffer. Public: ioma_pipe with ioma_run_pipes for raw TCP handlers, on the same runner as ioma_run. tests/pipe-server.c is a line echo on it, tests/pipes.py drives it (split lines, two lines in a packet, a line spanning kernel buffers, one too long); smoke gains a head split across three sends and a body arriving after its head. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .gitignore | 1 + CMakeLists.txt | 3 + Makefile | 16 +- include/ioma.h | 35 ++++ src/http/engine.c | 397 ++++++++++++++++++++------------------------ src/http/run.c | 43 ++++- src/io/conn.c | 17 ++ src/io/internal.h | 1 + src/io/pipe.c | 362 ++++++++++++++++++++++++++++++++++++++++ src/io/pipe.h | 70 ++++++++ tests/pipe-server.c | 42 +++++ tests/pipes.py | 78 +++++++++ tests/smoke.py | 4 + 13 files changed, 844 insertions(+), 225 deletions(-) create mode 100644 src/io/pipe.c create mode 100644 src/io/pipe.h create mode 100644 tests/pipe-server.c create mode 100644 tests/pipes.py diff --git a/.gitignore b/.gitignore index 7a5013e..8d273a5 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ compile_commands.json .idea/ tests/ioma-test-server tests/ioma-unit +tests/ioma-pipe-server diff --git a/CMakeLists.txt b/CMakeLists.txt index 1899ce0..d5a9e2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ add_library(ioma src/io/bufring.c src/io/conn.c src/io/proactor.c + src/io/pipe.c src/http/engine.c src/http/api.c src/http/router.c @@ -97,6 +98,8 @@ if(IOMA_EXAMPLES) target_link_libraries(ioma-hello PRIVATE ioma::ioma) add_executable(ioma-test-server tests/server.c) target_link_libraries(ioma-test-server PRIVATE ioma::ioma) + add_executable(ioma-pipe-server tests/pipe-server.c) + target_link_libraries(ioma-pipe-server PRIVATE ioma::ioma) add_executable(ioma-unit tests/unit.c) target_link_libraries(ioma-unit PRIVATE ioma::ioma) enable_testing() diff --git a/Makefile b/Makefile index 769db64..ca5488e 100644 --- a/Makefile +++ b/Makefile @@ -36,12 +36,13 @@ LIBDIR := $(PREFIX)/lib INCDIR := $(PREFIX)/include/ioma PCDIR := $(LIBDIR)/pkgconfig -UNITS := io/uring io/coro io/bufring io/conn io/proactor http/engine http/api http/router http/run +UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run OBJ := $(addprefix obj/,$(addsuffix .o,$(UNITS))) obj/io/switch_x86_64.o obj/picohttpparser.o PICOBJ := $(addprefix obj/pic/,$(addsuffix .o,$(UNITS))) obj/pic/io/switch_x86_64.o obj/pic/picohttpparser.o EXAMPLES := ioma-hello TESTSRV := tests/ioma-test-server +PIPESRV := tests/ioma-pipe-server UNIT := tests/ioma-unit .PHONY: all lib examples check clean install uninstall @@ -88,14 +89,21 @@ $(TESTSRV): tests/server.c libioma.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) $(UNIT): tests/unit.c libioma.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) +$(PIPESRV): tests/pipe-server.c libioma.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) CHECK_PORT ?= 8099 -check: $(TESTSRV) $(UNIT) +PIPE_PORT ?= 8100 +check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ IOMA_WORKERS=2 IOMA_PORT=$(CHECK_PORT) ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ python3 tests/smoke.py $(CHECK_PORT); s=$$?; python3 tests/stress.py $(CHECK_PORT); t=$$?; \ - kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t)) + kill -INT $$pid; wait $$pid 2>/dev/null; \ + ./$(PIPESRV) $(PIPE_PORT) >/dev/null 2>&1 & pid=$$!; \ + for i in $$(seq 1 50); do ss -ltn | grep -q ":$(PIPE_PORT) " && break; sleep 0.1; done; \ + python3 tests/pipes.py $(PIPE_PORT); u=$$?; \ + kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t | u)) # --- pkg-config --- ioma.pc: ioma.pc.in @@ -118,4 +126,4 @@ uninstall: rm -f $(DESTDIR)$(PCDIR)/ioma.pc clean: - rm -rf obj libioma.a libioma.so $(EXAMPLES) $(TESTSRV) $(UNIT) ioma.pc + rm -rf obj libioma.a libioma.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioma.pc diff --git a/include/ioma.h b/include/ioma.h index fbf4c52..22d2e25 100644 --- a/include/ioma.h +++ b/include/ioma.h @@ -269,6 +269,41 @@ ioma_endpoint *ioma__endpoint(const char *method, struct ioma_endpoint_args args #define IOMA_DELETE(...) IOMA_ROUTE("DELETE", __VA_ARGS__) #define IOMA_DEFAULT(fn) ioma_default(fn) +/* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ + +/* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. + * Every call that must wait suspends the connection's coroutine, and the worker's loop resumes + * it on the completion, so a handler reads and writes in straight-line code. The HTTP engine is + * one such handler; ioma_run_pipes runs one of yours on raw TCP connections instead. */ +typedef struct ioma_pipe ioma_pipe; +typedef void (*ioma_pipe_handler)(ioma_pipe *pipe); +int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn); /* like ioma_run, without HTTP */ + +/* Reading. The live bytes are the ones received and not yet consumed, always handed out as one + * contiguous span - in place in the kernel's buffer when they lie within one. read returns them + * once some are unexamined, otherwise it waits for more; examine says how many were looked at + * without being consumed, so the next read waits for more rather than returning the same bytes; + * drop consumes; keep consumes but leaves the bytes where they are, contiguous with earlier kept + * bytes and valid until release; copy is the plain read into your own buffer. read and copy + * return 0 at the end of input, IOMA_PIPE_GONE on a dead peer, IOMA_PIPE_FULL when kept plus + * live bytes would exceed the pipe's buffer. */ +#define IOMA_PIPE_GONE (-1) +#define IOMA_PIPE_FULL (-2) +int ioma_pipe_read (ioma_pipe *pipe, ioma_slice *live); +void ioma_pipe_examine(ioma_pipe *pipe, size_t n); +void ioma_pipe_drop (ioma_pipe *pipe, size_t n); +const char *ioma_pipe_keep (ioma_pipe *pipe, size_t n); +void ioma_pipe_release(ioma_pipe *pipe); +int ioma_pipe_copy (ioma_pipe *pipe, void *dst, size_t n); + +/* Writing: a slab, sent on flush. reserve n bytes to write into directly and advance by what was + * written, or write to copy in; send is write then flush. -1 once the peer is gone. */ +void *ioma_pipe_reserve(ioma_pipe *pipe, size_t n); +void ioma_pipe_advance(ioma_pipe *pipe, size_t n); +int ioma_pipe_write (ioma_pipe *pipe, const void *data, size_t n); +int ioma_pipe_flush (ioma_pipe *pipe); +int ioma_pipe_send (ioma_pipe *pipe, const void *data, size_t n); + /* ── run ───────────────────────────────────────────────────────────────────────────────── */ /* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port`, and block until diff --git a/src/http/engine.c b/src/http/engine.c index d9daa82..ecb3895 100644 --- a/src/http/engine.c +++ b/src/http/engine.c @@ -1,10 +1,12 @@ /* * engine.c - the HTTP/1.1 engine: parse a request head with picohttpparser, run the middleware - * chain and the endpoint against a context, read the body on demand (whole or streamed) and + * chain and the endpoint against a context, read the body on demand (whole or streamed) through + * the connection's reader (io/pipe.h) and * drain what was left, then send what was written. All of it runs on the connection's coroutine, * so await_recv and await_send simply suspend it and the loop resumes it. */ #include "http/internal.h" +#include "io/pipe.h" #include "picohttpparser.h" #include @@ -39,21 +41,12 @@ static_assert(offsetof(ioma_kv, key) == offsetof(struct phr_header, name) && /* The engine's per-request state, behind ctx->priv. */ struct serve_state { - conn_t *conn; - char *read_buf; /* the read buffer (IOMA_REQ_CAP): head, then body */ - size_t filled; /* bytes received into it: the head and, for a */ - /* Content-Length body, its bytes as they arrive */ - size_t head_len; /* where the body starts */ - size_t body_read; /* body bytes handed out so far */ - bool body_done; /* the whole body has been taken off the wire */ - bool body_whole; /* ioma_body_all read it into read_buf */ - int body_err; /* 0, a status to answer (400, 413), or -1: peer gone */ - size_t next_req_off, next_req_len; /* the next pipelined request's bytes, in read_buf */ - /* a chunked body: its raw bytes are staged in read_buf and decoded from there */ - size_t raw_pos, raw_end; /* raw bytes not yet consumed: read_buf[raw_pos, raw_end) */ - size_t stage_floor; /* the stage stays above this: the head, plus a whole */ - /* read's decoded body so far */ - size_t chunk_left; /* data bytes of the current chunk still to deliver */ + ioma_reader *reader; /* the connection's bytes; the head is kept in it */ + size_t body_read; /* body bytes handed out so far */ + bool body_done; /* the whole body has been taken off the wire */ + bool body_whole; /* ioma_body_all kept it */ + int body_err; /* 0, a status to answer (400, 413), or -1: peer gone */ + size_t chunk_left; /* data bytes of the current chunk still to deliver */ }; #define STATE(ctx) ((struct serve_state *)(ctx)->priv) @@ -325,7 +318,7 @@ static int fail(ioma_response *res) static int flush(ioma_ctx *ctx, bool final) { ioma_response *res = &ctx->res; - conn_t *conn = STATE(ctx)->conn; + conn_t *conn = STATE(ctx)->reader->conn; if (res->failed) return -1; @@ -381,7 +374,7 @@ static int finish(ioma_ctx *ctx) bool pending = !res->head_sent || res->len; /* nothing sent yet, or bytes still in the slab */ if (pending && flush(ctx, true) < 0) return -1; - if (res->chunked && await_send(STATE(ctx)->conn, "0\r\n\r\n", 5) < 0) + if (res->chunked && await_send(STATE(ctx)->reader->conn, "0\r\n\r\n", 5) < 0) return -1; return 0; } @@ -467,107 +460,62 @@ static void body_fail(ioma_ctx *ctx, int status) ctx->res.status = status; } -/* --- a Content-Length body --- */ - -/* Up to n body bytes into dst: first the ones that arrived with the head, then straight from the - * wire, never past the declared length (a pipelined request is never consumed). One receive's - * worth; the count, or -1 when the peer is gone. */ -static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) -{ - size_t remaining = ctx->req.content_length - state->body_read; - if (n > remaining) - n = remaining; - size_t buffered = state->filled - state->head_len; /* body bytes that came with the head */ - if (state->body_read < buffered) { - if (n > buffered - state->body_read) - n = buffered - state->body_read; - memcpy(dst, state->read_buf + state->head_len + state->body_read, n); - } else { - int got = await_recv(state->conn, dst, n); - if (got <= 0) { - state->body_err = -1; - return -1; - } - n = (size_t)got; - } - state->body_read += n; - if (state->body_read == ctx->req.content_length) - state->body_done = true; - return (int)n; -} - -/* --- a chunked body: the raw bytes are staged in read_buf, after the head --- */ - -/* More raw bytes into the stage, read_buf[raw_pos, raw_end). Below stage_floor the buffer is - * spoken for, so an empty stage restarts there and a full one is compacted down to it. false with - * the failure recorded: no room at all (413), or the peer gone. */ -static bool raw_fill(ioma_ctx *ctx, struct serve_state *state) +/* The live bytes with something unexamined, or more of them; a failure recorded: no room is a + * 413, the peer gone or the input ending inside the body is -1. */ +static bool body_bytes(ioma_ctx *ctx, ioma_slice *live) { - char *buf = state->read_buf; - if (state->raw_pos == state->raw_end) { - state->raw_pos = state->raw_end = state->stage_floor; - } else if (state->raw_end == IOMA_REQ_CAP && state->raw_pos > state->stage_floor) { - size_t held = state->raw_end - state->raw_pos; - memmove(buf + state->stage_floor, buf + state->raw_pos, held); - state->raw_pos = state->stage_floor; - state->raw_end = state->stage_floor + held; - } - if (state->raw_end == IOMA_REQ_CAP) { /* a size line, or a whole body, too big */ + int rc = ioma_reader_read(STATE(ctx)->reader, live); + if (rc > 0) + return true; + if (rc == IOMA_PIPE_FULL) body_fail(ctx, 413); - return false; - } - int n = await_recv(state->conn, buf + state->raw_end, IOMA_REQ_CAP - state->raw_end); - if (n <= 0) { - state->body_err = -1; - return false; - } - state->raw_end += (size_t)n; - return true; + else + STATE(ctx)->body_err = -1; + return false; } -/* The line at the front of the stage, filling until its CRLF is there. Its length without the - * CRLF, or -1 with the failure recorded. */ -static long raw_line(ioma_ctx *ctx, struct serve_state *state) +/* --- a chunked body --- */ + +/* The line at the front of the live bytes, whole: its length without the CRLF, or -1 recorded. */ +static long body_line(ioma_ctx *ctx, ioma_slice *live) { for (;;) { - char *line = state->read_buf + state->raw_pos; - char *eol = memmem(line, state->raw_end - state->raw_pos, "\r\n", 2); - if (eol) - return eol - line; - if (!raw_fill(ctx, state)) + if (!body_bytes(ctx, live)) return -1; + const char *eol = memmem(live->p, live->len, "\r\n", 2); + if (eol) + return eol - live->p; + ioma_reader_examine(STATE(ctx)->reader, live->len); } } -/* After the last chunk: trailer lines up to an empty one, then the body is done and whatever - * follows is the next request. */ -static bool chunk_trailers(ioma_ctx *ctx, struct serve_state *state) +/* After the last chunk: trailer lines up to an empty one, then the body is done. */ +static bool chunk_trailers(ioma_ctx *ctx) { + ioma_slice live = { nullptr, 0 }; for (;;) { - long len = raw_line(ctx, state); + long len = body_line(ctx, &live); if (len < 0) return false; - state->raw_pos += (size_t)len + 2; + ioma_reader_drop(STATE(ctx)->reader, (size_t)len + 2); if (len == 0) break; } - state->body_done = true; - state->next_req_off = state->raw_pos; - state->next_req_len = state->raw_end - state->raw_pos; + STATE(ctx)->body_done = true; return true; } /* The next chunk's size line - hex digits, an optional extension, CRLF - into chunk_left. The * last chunk (size 0) also takes its trailers and ends the body. */ -static bool chunk_header(ioma_ctx *ctx, struct serve_state *state) +static bool chunk_header(ioma_ctx *ctx) { - long len = raw_line(ctx, state); + ioma_slice live = { nullptr, 0 }; + long len = body_line(ctx, &live); if (len < 0) return false; - const char *line = state->read_buf + state->raw_pos; - size_t size = 0, i = 0; + size_t size = 0, i = 0; for (; i < (size_t)len; i++) { - int digit = ioma__hexval((unsigned char)line[i]); + int digit = ioma__hexval((unsigned char)live.p[i]); if (digit < 0) break; if (size > (SIZE_MAX >> 4)) { @@ -576,104 +524,134 @@ static bool chunk_header(ioma_ctx *ctx, struct serve_state *state) } size = (size << 4) | (size_t)digit; } - bool ended = i == (size_t)len || line[i] == ';' || line[i] == ' ' || line[i] == '\t'; + bool ended = i == (size_t)len || live.p[i] == ';' || live.p[i] == ' ' || live.p[i] == '\t'; if (i == 0 || !ended) { body_fail(ctx, 400); return false; } - state->raw_pos += (size_t)len + 2; + ioma_reader_drop(STATE(ctx)->reader, (size_t)len + 2); if (size == 0) - return chunk_trailers(ctx, state); - state->chunk_left = size; + return chunk_trailers(ctx); + STATE(ctx)->chunk_left = size; return true; } -/* Up to n data bytes of the current chunk: into dst, or when dst is null in place at the stage - * floor (a whole read), which then moves past them. What the stage holds, after one fill when it - * is empty; the CRLF that ends the chunk is consumed with its last byte. The count, or -1. */ -static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) +/* The CRLF that ends a chunk's data. */ +static bool chunk_end(ioma_ctx *ctx) { - char *buf = state->read_buf; - if (state->raw_pos == state->raw_end && !raw_fill(ctx, state)) - return -1; - size_t avail = state->raw_end - state->raw_pos; - if (n > avail) - n = avail; - if (n > state->chunk_left) - n = state->chunk_left; - if (dst) { - memcpy(dst, buf + state->raw_pos, n); - } else { - memmove(buf + state->stage_floor, buf + state->raw_pos, n); /* leftwards: the floor never passes raw_pos */ - state->stage_floor += n; + ioma_slice live = { nullptr, 0 }; + for (;;) { + if (!body_bytes(ctx, &live)) + return false; + if (live.len >= 2) + break; + ioma_reader_examine(STATE(ctx)->reader, live.len); } - state->raw_pos += n; - state->chunk_left -= n; - state->body_read += n; - if (state->chunk_left == 0) { - while (state->raw_end - state->raw_pos < 2) - if (!raw_fill(ctx, state)) - return -1; - if (buf[state->raw_pos] != '\r' || buf[state->raw_pos + 1] != '\n') { - body_fail(ctx, 400); - return -1; - } - state->raw_pos += 2; + if (live.p[0] != '\r' || live.p[1] != '\n') { + body_fail(ctx, 400); + return false; } - return (int)n; + ioma_reader_drop(STATE(ctx)->reader, 2); + return true; } /* --- the three reads --- */ -/* The whole body, in place right after the head: a Content-Length body is received until it is - * complete, a chunked one is decoded down over its own raw bytes. Once; then the slice, which is - * also req.body. */ +/* The whole body, kept in the reader: a Content-Length body once it is all here, a chunked one + * chunk by chunk with the data slid together. In place after the head when it all arrived in + * one kernel buffer, gathered otherwise. Once; then the slice, which is also req.body. */ ioma_slice ioma_body_all(ioma_ctx *ctx) { struct serve_state *state = STATE(ctx); + ioma_reader *r = state->reader; ioma_request *req = &ctx->req; - const ioma_slice none = { req->body.p, 0 }; + const ioma_slice none = { nullptr, 0 }; if (state->body_whole) return req->body; if (state->body_read || state->body_err) /* already streaming, or failed */ return none; - char *body = state->read_buf + state->head_len; if (req->chunked) { while (!state->body_done) { if (state->chunk_left == 0) { - if (!chunk_header(ctx, state)) + if (!chunk_header(ctx)) return none; - } else if (chunk_data(ctx, state, nullptr, state->chunk_left) < 0) { + continue; + } + ioma_slice live = { nullptr, 0 }; + if (!body_bytes(ctx, &live)) + return none; + size_t n = live.len < state->chunk_left ? live.len : state->chunk_left; + if (!ioma_reader_keep(r, n)) { + body_fail(ctx, 413); return none; } + state->chunk_left -= n; + state->body_read += n; + if (state->chunk_left == 0 && !chunk_end(ctx)) + return none; } - req->body = (ioma_slice){ body, state->stage_floor - state->head_len }; + req->body = ioma_reader_run(r); } else { - size_t total = state->head_len + req->content_length; - if (total > IOMA_REQ_CAP) { + if (req->content_length > IOMA_REQ_CAP) { body_fail(ctx, 413); return none; } - while (state->filled < total) { - int n = await_recv(state->conn, state->read_buf + state->filled, IOMA_REQ_CAP - state->filled); - if (n <= 0) { - state->body_err = -1; + ioma_slice live = none; + while (req->content_length && live.len < req->content_length) { + if (live.len) + ioma_reader_examine(r, live.len); + if (!body_bytes(ctx, &live)) return none; - } - state->filled += (size_t)n; } - req->body = (ioma_slice){ body, req->content_length }; - state->next_req_off = total; - state->next_req_len = state->filled - total; - state->body_read = req->content_length; - state->body_done = true; + const char *kept = req->content_length ? ioma_reader_keep(r, req->content_length) : live.p; + if (req->content_length && !kept) { + body_fail(ctx, 413); + return none; + } + req->body = (ioma_slice){ kept, req->content_length }; + state->body_read = req->content_length; + state->body_done = true; } state->body_whole = true; return req->body; } +/* Up to n bytes of a Content-Length body into dst, straight from the reader. */ +static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) +{ + size_t remaining = ctx->req.content_length - state->body_read; + if (n > remaining) + n = remaining; + int got = ioma_reader_copy(state->reader, dst, n); + if (got <= 0) { + state->body_err = -1; /* gone, or the input ended inside the body */ + return -1; + } + state->body_read += (size_t)got; + if (state->body_read == ctx->req.content_length) + state->body_done = true; + return got; +} + +/* Up to n data bytes of the current chunk into dst; the CRLF after its last byte is taken too. */ +static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) +{ + if (n > state->chunk_left) + n = state->chunk_left; + int got = ioma_reader_copy(state->reader, dst, n); + if (got <= 0) { + state->body_err = -1; + return -1; + } + state->chunk_left -= (size_t)got; + state->body_read += (size_t)got; + if (state->chunk_left == 0 && !chunk_end(ctx)) + return -1; + return got; +} + /* The next bytes of the body into dst, reading until n are there or the body ends. */ int ioma_body_read_until(ioma_ctx *ctx, void *dst, size_t n) { @@ -687,7 +665,7 @@ int ioma_body_read_until(ioma_ctx *ctx, void *dst, size_t n) if (!ctx->req.chunked) k = fixed_data(ctx, state, out + got, n - got); else if (state->chunk_left == 0) - k = chunk_header(ctx, state) ? 0 : -1; + k = chunk_header(ctx) ? 0 : -1; else k = chunk_data(ctx, state, out + got, n - got); if (k < 0) @@ -707,7 +685,7 @@ int ioma_body_read_next_chunk(ioma_ctx *ctx, void *dst, size_t cap) if (state->body_done) return 0; if (state->chunk_left == 0) { - if (!chunk_header(ctx, state)) + if (!chunk_header(ctx)) return -1; if (state->body_done) return 0; @@ -752,41 +730,47 @@ static void drain_body(ioma_ctx *ctx) * version, headers). What is buffered is parsed first: after a reply, a pipelined next request * may already be there. More is read only when the head is incomplete. Returns the head's * length, or -1 once the connection is finished (431 or 400 answered, or the peer went away). */ -static long read_head(conn_t *conn, char *read_buf, size_t *filled, ioma_request *req) +static long read_head(ioma_ctx *ctx, conn_t *conn) { - size_t already_parsed = 0; /* what the previous attempt scanned */ + ioma_reader *r = STATE(ctx)->reader; + ioma_request *req = &ctx->req; + size_t already = 0; /* what the previous attempt scanned */ + ioma_slice live = { nullptr, 0 }; for (;;) { - if (*filled) { - req->n_headers = IOMA_MAX_HEADERS; /* in: room; out: count */ - int parsed = phr_parse_request(read_buf, *filled, - &req->method.p, &req->method.len, - &req->target.p, &req->target.len, - &req->minor_version, - (struct phr_header *)req->headers, &req->n_headers, - already_parsed); - if (parsed >= 0) - return parsed; - if (parsed == -1) { /* malformed */ - send_status(conn, 400); - return -1; - } - already_parsed = *filled; /* incomplete: read more */ - } - if (*filled == IOMA_REQ_CAP) { + int rc = ioma_reader_read(r, &live); + if (rc == 0) + return -1; /* the peer is done: a clean end between requests */ + if (rc == IOMA_PIPE_FULL) { send_status(conn, 431); return -1; } - int n = await_recv(conn, read_buf + *filled, IOMA_REQ_CAP - *filled); - if (n <= 0) - return -1; /* peer closed or error */ - *filled += (size_t)n; + if (rc < 0) + return -1; + req->n_headers = IOMA_MAX_HEADERS; /* in: room; out: count */ + int parsed = phr_parse_request(live.p, live.len, + &req->method.p, &req->method.len, + &req->target.p, &req->target.len, + &req->minor_version, + (struct phr_header *)req->headers, &req->n_headers, + already); + if (parsed >= 0) { + ioma_reader_keep(r, (size_t)parsed); /* the head stays put, where it was parsed */ + ioma_reader_run_begin(r); /* the body's kept bytes are a run of their own */ + return parsed; + } + if (parsed == -1) { /* malformed */ + send_status(conn, 400); + return -1; + } + ioma_reader_examine(r, live.len); /* incomplete: the next read waits for more */ + already = live.len; } } /* The rest of the request from its head: path and query, the query split into params, the * headers lower-cased and the three the engine needs picked out. The body stays on the wire; * body_start is where it begins. */ -static void fill_request(ioma_request *req, const char *body_start, char *params_arena, size_t arena_cap) +static void fill_request(ioma_request *req, char *params_arena, size_t arena_cap) { const char *qmark = memchr(req->target.p, '?', req->target.len); if (qmark) { @@ -805,31 +789,16 @@ static void fill_request(ioma_request *req, const char *body_start, char *params req->chunked = picked.transfer_enc.p && token_present_ci(picked.transfer_enc.p, picked.transfer_enc.len, "chunked"); req->content_length = picked.content_length.p ? parse_size(picked.content_length.p, picked.content_length.len) : 0; req->keep_alive = keep_alive_from(req->minor_version, picked.connection); - req->body = (ioma_slice){ body_start, 0 }; + req->body = (ioma_slice){ nullptr, 0 }; /* on demand: ioma_body_all fills it */ } /* The engine's bookkeeping for reading the body on demand: where it starts, what already * arrived with the head, and - for a Content-Length body that is entirely here - where the next * request starts. */ -static void init_body_state(struct serve_state *state, conn_t *conn, char *read_buf, size_t filled, - size_t head_len, const ioma_request *req) -{ - memset(state, 0, sizeof *state); - state->conn = conn; - state->read_buf = read_buf; - state->filled = filled; - state->head_len = head_len; - state->raw_pos = head_len; /* chunked: what came with the head is raw body */ - state->raw_end = filled; - state->stage_floor = head_len; - if (!req->chunked) { - size_t total = head_len + req->content_length; - state->body_done = req->content_length == 0; - if (filled >= total) { - state->next_req_off = total; - state->next_req_len = filled - total; - } - } +static void init_body_state(struct serve_state *state, ioma_reader *reader, const ioma_request *req) +{ + *state = (struct serve_state){ .reader = reader }; + state->body_done = !req->chunked && req->content_length == 0; } /* A response with its defaults and an empty slab. */ @@ -849,52 +818,46 @@ static void init_response(ioma_response *res, char *slab) res->failed = false; } -/* After a kept-alive reply: move the bytes that belong to the next request to the front of the - * buffer and return how many there are. */ -static size_t carry_next_request(struct serve_state *state, char *read_buf) -{ - if (state->next_req_len) - memmove(read_buf, read_buf + state->next_req_off, state->next_req_len); - return state->next_req_len; -} /* The proactor handler for every connection: one request per iteration - get the head, run * the chain against a context, drain what it left of the body, send what it wrote - while kept * alive. Returning closes the connection. */ void ioma__serve(conn_t *conn) { - char read_buf[IOMA_REQ_CAP]; /* the request: head, then body bytes */ - char params[IOMA_PARAM_CAP]; /* decoded query parameters */ - char slab[IOMA_LEAD + IOMA_OUT_CAP + 2]; /* lead, the write slab, CRLF slack */ - size_t filled = 0; /* bytes in read_buf */ + char gather[IOMA_REQ_CAP]; /* where a request's bytes go when they must be contiguous */ + char params[IOMA_PARAM_CAP]; /* decoded query parameters */ + char slab[IOMA_LEAD + IOMA_OUT_CAP + 2]; /* lead, the write slab, CRLF slack */ + ioma_reader reader; /* the connection's bytes, across requests */ + ioma_reader_init(&reader, conn, gather, sizeof gather); for (;;) { ioma_ctx ctx; /* this request's context */ - struct serve_state state; /* and the engine's side of it */ + struct serve_state state = { .reader = &reader }; + ctx.priv = &state; - long head_len = read_head(conn, read_buf, &filled, &ctx.req); + long head_len = read_head(&ctx, conn); if (head_len < 0) - return; - fill_request(&ctx.req, read_buf + (size_t)head_len, params, sizeof params); - init_body_state(&state, conn, read_buf, filled, (size_t)head_len, &ctx.req); + break; + fill_request(&ctx.req, params, sizeof params); + init_body_state(&state, &reader, &ctx.req); init_response(&ctx.res, slab); ctx.user = nullptr; - ctx.priv = &state; ioma__dispatch(&ctx); /* middleware chain + endpoint */ if (state.body_err) { /* too large, malformed, or gone */ if (state.body_err > 0 && !ctx.res.head_sent) send_status(conn, state.body_err); - return; + break; } drain_body(&ctx); /* what the handler left unread */ if (state.body_err) - return; + break; if (finish(&ctx) < 0) /* sends; suspends meanwhile */ - return; + break; if (!ctx.req.keep_alive || ctx.res.close) - return; - filled = carry_next_request(&state, read_buf); + break; + ioma_reader_release(&reader); /* this request's bytes go; a pipelined next one stays */ } + ioma_reader_close(&reader); } diff --git a/src/http/run.c b/src/http/run.c index 206bc75..869f2ed 100644 --- a/src/http/run.c +++ b/src/http/run.c @@ -2,6 +2,7 @@ * run.c - ioma_run: one proactor thread per core serving HTTP, until SIGINT/SIGTERM. */ #include "http/internal.h" +#include "io/pipe.h" #include #include @@ -53,7 +54,9 @@ static void raise_nofile(void) } /* Start the workers (workers <= 0: one per available core) and block until a stop signal. */ -int ioma_run(int workers, int port) +/* Worker threads, one proactor each, serving `port` with `handler` on every connection until + * SIGINT/SIGTERM. What ioma_run and ioma_run_pipes share. */ +static int run_workers(int workers, int port, handler_fn handler) { if (workers <= 0) workers = cpu_count(); @@ -71,8 +74,6 @@ int ioma_run(int workers, int port) sigaction(SIGINT, &sa, nullptr); sigaction(SIGTERM, &sa, nullptr); - ioma__router_build(); /* the routes, resolved once, shared read-only */ - proactor_t *ws = calloc((size_t)workers, sizeof *ws); pthread_t *th = calloc((size_t)workers, sizeof *th); if (!ws || !th) { @@ -86,7 +87,7 @@ int ioma_run(int workers, int port) ws[i].id = i; ws[i].cpu = i; ws[i].port = (uint16_t)port; - ws[i].handler = ioma__serve; + ws[i].handler = handler; ws[i].stop = &g_stop; if (pthread_create(&th[i], nullptr, worker_thread, &ws[i]) != 0) { perror("pthread_create"); @@ -101,3 +102,37 @@ int ioma_run(int workers, int port) free(ws); return 0; } + +int ioma_run(int workers, int port) +{ + ioma__router_build(); /* the routes, resolved once, shared read-only */ + return run_workers(workers, port, ioma__serve); +} + +/* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ + +#ifndef IOMA_PIPE_BUF +#define IOMA_PIPE_BUF 16384 /* a pipe's gathering buffer (kept + live bytes) */ +#endif +#ifndef IOMA_PIPE_SLAB +#define IOMA_PIPE_SLAB 8192 /* a pipe's write slab */ +#endif + +static ioma_pipe_handler g_pipe_handler; + +/* The connection handler behind ioma_run_pipes: a pipe over the connection, the handler on it. */ +static void serve_pipe(conn_t *conn) +{ + char gather[IOMA_PIPE_BUF]; + char slab[IOMA_PIPE_SLAB]; + struct ioma_pipe pipe; + ioma__pipe_init(&pipe, conn, gather, sizeof gather, slab, sizeof slab); + g_pipe_handler(&pipe); + ioma__pipe_close(&pipe); +} + +int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn) +{ + g_pipe_handler = fn; + return run_workers(workers, port, serve_pipe); +} diff --git a/src/io/conn.c b/src/io/conn.c index b6e57c0..344d663 100644 --- a/src/io/conn.c +++ b/src/io/conn.c @@ -278,6 +278,23 @@ void ioma__conn_main(void *arg) /* Copy the next delivered slice into buf, parking while the queue is empty. Returns the byte * count, 0 when the peer closed, or -errno. A fully consumed buffer goes back to the ring. */ +/* The next received buffer, whole: the caller owns it until ioma__return_buf. Suspends until one + * arrives; 1 with the item, 0 at the end of input, <0 an error. */ +int ioma__await_item(conn_t *c, struct rx_item *out) +{ + for (;;) { + if (c->rx_head != c->rx_tail) { + *out = c->rx[c->rx_head & RX_MASK]; + c->rx_head++; + return 1; + } + if (c->eof) + return c->err; + c->waiter = coro_current(); + coro_yield(); /* ioma__on_recv wakes us */ + } +} + int await_recv(conn_t *c, void *buf, size_t len) { if (len == 0) diff --git a/src/io/internal.h b/src/io/internal.h index 5337313..afbf5c2 100644 --- a/src/io/internal.h +++ b/src/io/internal.h @@ -56,6 +56,7 @@ typedef struct op { struct io_uring_sqe *ioma__sqe(proactor_t *p); /* claim an SQE; flushes without waiting if the SQ is full */ /* bufring.c */ +int ioma__await_item(conn_t *c, struct rx_item *out); /* conn.c: the next received buffer, whole */ void ioma__return_buf(proactor_t *p, uint16_t buf_id); /* stage a buffer's return; published per batch */ void ioma__bufring_publish(proactor_t *p); /* publish staged returns: one atomic release */ void ioma__bufring_init(proactor_t *p); /* bufring.c: map, register, fill */ diff --git a/src/io/pipe.c b/src/io/pipe.c new file mode 100644 index 0000000..0e72507 --- /dev/null +++ b/src/io/pipe.c @@ -0,0 +1,362 @@ +/* + * io/pipe.c - the reader and the writer of io/pipe.h, and the public pipe on top of them. + */ +#include "io/pipe.h" +#include "io/internal.h" + +#include + +/* ── the reader ────────────────────────────────────────────────────────────────────────── */ + +void ioma_reader_init(ioma_reader *r, conn_t *conn, char *buf, size_t cap) +{ + *r = (ioma_reader){}; + r->conn = conn; + r->buf = buf; + r->cap = cap; +} + +/* The live bytes: in buf, or in the current kernel buffer. */ +static ioma_slice live_span(const ioma_reader *r) +{ + if (r->live_in_buf) + return (ioma_slice){ r->buf + r->buf_pos, r->buf_end - r->buf_pos }; + if (r->has_cur) + return (ioma_slice){ (const char *)r->cur.ptr + r->cur_pos, r->cur.len - r->cur_pos }; + return (ioma_slice){ nullptr, 0 }; +} + +/* Let the current kernel buffer go once nothing is left in it, neither live bytes nor the run. + * One that also holds frozen kept bytes lives on as `pinned`. */ +static void cur_done(ioma_reader *r) +{ + if (!r->has_cur || r->cur_pos < r->cur.len || (r->run_in_cur && r->run_len)) + return; + if (!r->cur_is_pinned) + ioma__return_buf(r->conn->p, r->cur.buf_id); + r->has_cur = false; + r->cur_is_pinned = false; + r->cur_pos = 0; +} + +/* Reclaim the bytes dropped from the front of buf's live region. */ +static void compact(ioma_reader *r) +{ + if (r->buf_pos > r->floor) { + memmove(r->buf + r->floor, r->buf + r->buf_pos, r->buf_end - r->buf_pos); + r->buf_end -= r->buf_pos - r->floor; + r->buf_pos = r->floor; + } +} + +/* Move the current buffer's run and live bytes into buf, so what follows can join them. */ +static bool gather(ioma_reader *r) +{ + size_t live = r->has_cur ? r->cur.len - r->cur_pos : 0; + size_t run = r->run_in_cur ? r->run_len : 0; + if (r->floor + run + live > r->cap) + return false; + if (run) { + memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->run_start, run); + r->run_start = r->floor; + r->floor += run; + } + r->run_in_cur = false; + if (live) + memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->cur_pos, live); + r->buf_pos = r->floor; + r->buf_end = r->floor + live; + r->live_in_buf = true; + if (r->has_cur) { + r->cur_pos = r->cur.len; + cur_done(r); + } + return true; +} + +/* A buffer that cannot be used: back to the ring, and the reader is done. */ +static int refuse(ioma_reader *r, const struct rx_item *item) +{ + ioma__return_buf(r->conn->p, item->buf_id); + r->error = IOMA_PIPE_FULL; + return IOMA_PIPE_FULL; +} + +/* More bytes: the next kernel buffer, in place when nothing is live, else appended in buf. */ +static int more(ioma_reader *r) +{ + if (r->eof) + return 0; + struct rx_item item; + int rc = ioma__await_item(r->conn, &item); + if (rc <= 0) { + r->eof = true; + if (rc < 0) + r->error = IOMA_PIPE_GONE; + return rc < 0 ? IOMA_PIPE_GONE : 0; + } + if (!r->live_in_buf && !r->has_cur) { /* nothing live: this buffer is the live span */ + r->cur = item; + r->has_cur = true; + r->cur_pos = 0; + r->cur_is_pinned = false; + return 1; + } + if (!r->live_in_buf && !gather(r)) /* the live bytes leave the current buffer first */ + return refuse(r, &item); + if (r->buf_end + item.len > r->cap) { + compact(r); + if (r->buf_end + item.len > r->cap) + return refuse(r, &item); + } + memcpy(r->buf + r->buf_end, item.ptr, item.len); + r->buf_end += item.len; + ioma__return_buf(r->conn->p, item.buf_id); + return 1; +} + +int ioma_reader_read(ioma_reader *r, ioma_slice *live) +{ + if (r->error) + return r->error; + for (;;) { + ioma_slice l = live_span(r); + if (l.len > r->examined) { + *live = l; + return 1; + } + int rc = more(r); + if (rc <= 0) + return rc; + } +} + +void ioma_reader_examine(ioma_reader *r, size_t n) +{ + r->examined = n; +} + +/* Forget n live bytes of the current place. */ +static void consume(ioma_reader *r, size_t n) +{ + if (r->live_in_buf) { + r->buf_pos += n; + if (r->buf_pos == r->buf_end) { + r->buf_pos = r->buf_end = r->floor; + r->live_in_buf = false; + } + } else if (r->has_cur) { + r->cur_pos += n; + cur_done(r); + } + r->examined = r->examined > n ? r->examined - n : 0; +} + +void ioma_reader_drop(ioma_reader *r, size_t n) +{ + consume(r, n); +} + +const char *ioma_reader_keep(ioma_reader *r, size_t n) +{ + const char *kept; + if (r->live_in_buf) { + if (r->run_len == 0) { /* a run starts where the live bytes are */ + r->run_in_cur = false; + r->run_start = r->buf_pos; + r->floor = r->buf_pos; + } else if (r->buf_pos != r->floor) { /* dropped bytes in between: slide these down */ + memmove(r->buf + r->floor, r->buf + r->buf_pos, n); + } + kept = r->buf + r->floor; + r->floor += n; + } else if (r->has_cur && (r->run_len == 0 || r->run_in_cur)) { /* in place */ + if (r->run_len == 0) { + r->run_in_cur = true; + r->run_start = r->cur_pos; + } + size_t run_end = r->run_start + r->run_len; + if (run_end != r->cur_pos) + memmove((char *)r->cur.ptr + run_end, (const char *)r->cur.ptr + r->cur_pos, n); + kept = (const char *)r->cur.ptr + run_end; + } else if (r->has_cur) { /* the run is in buf, the live bytes are not: copy across */ + if (r->floor + n > r->cap) { + r->error = IOMA_PIPE_FULL; + return nullptr; + } + memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->cur_pos, n); + kept = r->buf + r->floor; + r->floor += n; + } else { + return nullptr; /* nothing live: the caller's mistake */ + } + r->run_len += n; + consume(r, n); + return kept; +} + +void ioma_reader_run_begin(ioma_reader *r) +{ + if (r->run_in_cur && r->run_len) { + if (r->has_pinned && !r->cur_is_pinned) { /* another buffer is pinned already: this run moves to buf */ + if (r->floor + r->run_len > r->cap) { + r->error = IOMA_PIPE_FULL; + } else { + memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->run_start, r->run_len); + r->floor += r->run_len; + } + } else { + r->pinned = r->cur; + r->has_pinned = true; + r->cur_is_pinned = true; + } + } + r->run_len = 0; + r->run_in_cur = false; + cur_done(r); +} + +ioma_slice ioma_reader_run(const ioma_reader *r) +{ + const char *base = r->run_in_cur ? (const char *)r->cur.ptr : r->buf; + return (ioma_slice){ base + r->run_start, r->run_len }; +} + +void ioma_reader_release(ioma_reader *r) +{ + r->run_len = 0; + r->run_in_cur = false; + if (r->live_in_buf) { + memmove(r->buf, r->buf + r->buf_pos, r->buf_end - r->buf_pos); + r->buf_end -= r->buf_pos; + r->buf_pos = 0; + } else { + r->buf_pos = r->buf_end = 0; + } + r->floor = 0; + if (r->has_pinned) { + if (r->cur_is_pinned) + r->cur_is_pinned = false; /* it lives on as the current buffer */ + else + ioma__return_buf(r->conn->p, r->pinned.buf_id); + r->has_pinned = false; + } + cur_done(r); +} + +void ioma_reader_close(ioma_reader *r) +{ + if (r->has_cur && !r->cur_is_pinned) + ioma__return_buf(r->conn->p, r->cur.buf_id); + if (r->has_pinned) + ioma__return_buf(r->conn->p, r->pinned.buf_id); + r->has_cur = r->has_pinned = r->cur_is_pinned = false; +} + +int ioma_reader_copy(ioma_reader *r, void *dst, size_t n) +{ + if (r->error) + return r->error; + for (;;) { + ioma_slice l = live_span(r); + if (l.len) { + size_t k = l.len < n ? l.len : n; + memcpy(dst, l.p, k); + consume(r, k); + return (int)k; + } + int rc = more(r); + if (rc <= 0) + return rc; + } +} + +/* ── the writer ────────────────────────────────────────────────────────────────────────── */ + +void ioma_writer_init(ioma_writer *w, conn_t *conn, char *buf, size_t cap) +{ + *w = (ioma_writer){}; + w->conn = conn; + w->buf = buf; + w->cap = cap; +} + +int ioma_writer_flush(ioma_writer *w) +{ + if (w->failed) + return -1; + if (w->len == 0) + return 0; + int rc = await_send(w->conn, w->buf, w->len); + w->len = 0; + if (rc < 0) { + w->failed = true; + return -1; + } + return 0; +} + +void *ioma_writer_reserve(ioma_writer *w, size_t n) +{ + if (w->failed || n > w->cap) + return nullptr; + if (w->len + n > w->cap && ioma_writer_flush(w) < 0) + return nullptr; + return w->buf + w->len; +} + +void ioma_writer_advance(ioma_writer *w, size_t n) +{ + w->len += n; +} + +int ioma_writer_write(ioma_writer *w, const void *data, size_t n) +{ + if (w->failed) + return -1; + if (n > w->cap) { /* larger than the slab: straight from the caller's memory */ + if (ioma_writer_flush(w) < 0) + return -1; + if (await_send(w->conn, data, n) < 0) { + w->failed = true; + return -1; + } + return 0; + } + void *at = ioma_writer_reserve(w, n); + if (!at) + return -1; + memcpy(at, data, n); + w->len += n; + return 0; +} + +int ioma_writer_send(ioma_writer *w, const void *data, size_t n) +{ + return ioma_writer_write(w, data, n) < 0 ? -1 : ioma_writer_flush(w); +} + +/* ── the pipe ──────────────────────────────────────────────────────────────────────────── */ + +void ioma__pipe_init(struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap) +{ + ioma_reader_init(&p->in, conn, gather, gather_cap); + ioma_writer_init(&p->out, conn, slab, slab_cap); +} + +void ioma__pipe_close(struct ioma_pipe *p) +{ + ioma_reader_close(&p->in); +} + +int ioma_pipe_read (ioma_pipe *p, ioma_slice *live) { return ioma_reader_read(&p->in, live); } +void ioma_pipe_examine(ioma_pipe *p, size_t n) { ioma_reader_examine(&p->in, n); } +void ioma_pipe_drop (ioma_pipe *p, size_t n) { ioma_reader_drop(&p->in, n); } +const char *ioma_pipe_keep (ioma_pipe *p, size_t n) { return ioma_reader_keep(&p->in, n); } +void ioma_pipe_release(ioma_pipe *p) { ioma_reader_release(&p->in); } +int ioma_pipe_copy (ioma_pipe *p, void *dst, size_t n) { return ioma_reader_copy(&p->in, dst, n); } +void *ioma_pipe_reserve(ioma_pipe *p, size_t n) { return ioma_writer_reserve(&p->out, n); } +void ioma_pipe_advance(ioma_pipe *p, size_t n) { ioma_writer_advance(&p->out, n); } +int ioma_pipe_write (ioma_pipe *p, const void *data, size_t n) { return ioma_writer_write(&p->out, data, n); } +int ioma_pipe_flush (ioma_pipe *p) { return ioma_writer_flush(&p->out); } +int ioma_pipe_send (ioma_pipe *p, const void *data, size_t n) { return ioma_writer_send(&p->out, data, n); } diff --git a/src/io/pipe.h b/src/io/pipe.h new file mode 100644 index 0000000..4448356 --- /dev/null +++ b/src/io/pipe.h @@ -0,0 +1,70 @@ +/* + * io/pipe.h - a connection as a pipe: a reader over the buffers the kernel filled and a writer + * over a slab. Every call that must wait suspends the calling coroutine and the worker's loop + * resumes it on the completion, so the same code drives any connection the I/O plane runs. The + * HTTP engine reads through the reader; ioma_run_pipes hands a pipe to a handler of your own. + */ +#pragma once + +#include "ioma.h" +#include "io/proactor.h" + +/* The reader hands out received bytes as one contiguous span at a time: in place in the kernel's + * buffer when they lie within one, gathered into the consumer's buffer when they span, or when + * the consumer keeps bytes it wants contiguous. Live bytes are the ones not yet consumed; kept + * bytes stay where they are - the consumer's, to point into and even overwrite - until release. + * At most two kernel buffers are held: one with kept bytes of earlier runs, one with the live + * bytes and the run in progress. */ +typedef struct ioma_reader { + conn_t *conn; + char *buf; /* the gathering buffer, the consumer's */ + size_t cap; + size_t floor; /* buf[0, floor): kept bytes */ + bool live_in_buf; /* the live bytes are buf[buf_pos, buf_end), else in cur */ + size_t buf_pos, buf_end; + struct rx_item cur; /* the kernel buffer the live bytes sit in */ + bool has_cur; + size_t cur_pos; /* its bytes consumed so far */ + struct rx_item pinned; /* a kernel buffer that holds frozen kept bytes */ + bool has_pinned; + bool cur_is_pinned; /* cur and pinned are the same buffer */ + bool run_in_cur; /* the run in progress sits in cur (in place), else in buf */ + size_t run_start, run_len; + size_t examined; /* live bytes the consumer looked at without consuming */ + bool eof; + int error; /* 0, or IOMA_PIPE_GONE / IOMA_PIPE_FULL, sticky */ +} ioma_reader; + +void ioma_reader_init (ioma_reader *r, conn_t *conn, char *buf, size_t cap); +void ioma_reader_close (ioma_reader *r); /* returns the buffers it holds */ +int ioma_reader_read (ioma_reader *r, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ +void ioma_reader_examine (ioma_reader *r, size_t n); /* looked at n live bytes: the next read waits for more */ +void ioma_reader_drop (ioma_reader *r, size_t n); /* consume n live bytes */ +const char *ioma_reader_keep (ioma_reader *r, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ +void ioma_reader_run_begin(ioma_reader *r); /* freeze the run; the next keep starts another */ +ioma_slice ioma_reader_run (const ioma_reader *r); /* the run in progress */ +void ioma_reader_release (ioma_reader *r); /* forget every kept byte; live bytes stay */ +int ioma_reader_copy (ioma_reader *r, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ + +/* The writer: a slab, sent on flush. */ +typedef struct ioma_writer { + conn_t *conn; + char *buf; + size_t cap, len; + bool failed; /* the peer is gone: every call fails from here on */ +} ioma_writer; + +void ioma_writer_init (ioma_writer *w, conn_t *conn, char *buf, size_t cap); +void *ioma_writer_reserve(ioma_writer *w, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ +void ioma_writer_advance(ioma_writer *w, size_t n); +int ioma_writer_write (ioma_writer *w, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ +int ioma_writer_flush (ioma_writer *w); /* send the slab; suspends */ +int ioma_writer_send (ioma_writer *w, const void *data, size_t n); /* write, then flush */ + +/* The pair, as the public API sees it. */ +struct ioma_pipe { + ioma_reader in; + ioma_writer out; +}; +void ioma__pipe_init (struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap); +void ioma__pipe_close(struct ioma_pipe *p); diff --git a/tests/pipe-server.c b/tests/pipe-server.c new file mode 100644 index 0000000..53ecc08 --- /dev/null +++ b/tests/pipe-server.c @@ -0,0 +1,42 @@ +/* + * pipe-server.c - a line echo server on ioma_run_pipes: the pipe API without HTTP. Each line + * comes back as "echo: "; "quit" ends the connection; a line longer than the pipe's + * buffer ends it too (the reader reports no room). `make check` runs tests/pipes.py against it. + */ +#include + +#include +#include + +/* One connection: lines in, echoes out, until the peer leaves. */ +static void echo(ioma_pipe *pipe) +{ + for (;;) { + ioma_slice live = { NULL, 0 }; + if (ioma_pipe_read(pipe, &live) <= 0) /* the end, or no room for a longer line */ + return; + const char *nl = memchr(live.p, '\n', live.len); + if (!nl) { /* half a line: wait for the rest */ + ioma_pipe_examine(pipe, live.len); + continue; + } + size_t n = (size_t)(nl - live.p) + 1; + if (n == 5 && memcmp(live.p, "quit\n", 5) == 0) + return; + char *out = ioma_pipe_reserve(pipe, 6 + n); /* format straight into the slab */ + if (!out) + return; + memcpy(out, "echo: ", 6); /* NOLINT(bugprone-not-null-terminated-result): bytes, not a C string */ + memcpy(out + 6, live.p, n); + ioma_pipe_advance(pipe, 6 + n); + ioma_pipe_drop(pipe, n); + if (ioma_pipe_flush(pipe) < 0) + return; + } +} + +int main(int argc, char **argv) +{ + int port = argc > 1 ? (int)strtol(argv[1], NULL, 10) : 8100; + return ioma_run_pipes(2, port, echo); +} diff --git a/tests/pipes.py b/tests/pipes.py new file mode 100644 index 0000000..3735b44 --- /dev/null +++ b/tests/pipes.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +"""The pipe API through tests/pipe-server.c, a line echo: whole lines, a line split across +sends, two lines in one packet, a quit, and a line too long for the pipe's buffer.""" +import socket, sys, time + +PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8100 + + +def connect(): + for attempt in range(20): + try: + s = socket.create_connection(("127.0.0.1", PORT), timeout=5) + return s + except OSError: + if attempt == 19: + raise + time.sleep(0.05) + + +def read_until(s, want): + data = b"" + while len(data) < want: + chunk = s.recv(65536) + if not chunk: + break + data += chunk + return data + + +def read_to_close(s): + data = b"" + while True: + try: + chunk = s.recv(65536) + except socket.timeout: + break + if not chunk: + break + data += chunk + return data + + +results = [] + + +def check(name, cond): + print(f"{'ok ' if cond else 'FAIL'} {name}") + results.append(cond) + + +s = connect() +s.sendall(b"hello\n") +results and None +check("a line comes back echoed", read_until(s, 12) == b"echo: hello\n") +s.sendall(b"ab") +time.sleep(0.05) +s.sendall(b"c\n") +check("a line split across sends is echoed whole", read_until(s, 10) == b"echo: abc\n") +s.sendall(b"x\ny\n") +check("two lines in one packet -> two echoes", read_until(s, 16) == b"echo: x\necho: y\n") +s.sendall(b"quit\n") +check("quit closes the connection", read_to_close(s) == b"") +s.close() + +s = connect() +s.sendall(b"z" * 20000) +check("a line longer than the pipe's buffer closes the connection", read_to_close(s) == b"") +s.close() + +s = connect() +big = b"w" * 6000 + b"\n" +s.sendall(big) +check("a 6 KB line, spanning kernel buffers, is echoed whole", read_until(s, 6 + len(big)) == b"echo: " + big) +s.close() + +failed = results.count(False) +print("all passed" if not failed else f"{failed} FAILED") +sys.exit(1 if failed else 0) diff --git a/tests/smoke.py b/tests/smoke.py index f663552..ec4a800 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -274,6 +274,10 @@ def raw_exchange(pieces, pause=0.03): results.append(check("POST /chunks with a 2000-byte chunk into a 1 KB buffer -> 413", len(rs) == 1 and rs[0][0] == 413)) rs = raw_exchange([b"POST /chunks HTTP/1.1\r\nHost: x\r\nConnection: close\r\nContent-Length: 5\r\n\r\nhello"]) results.append(check("POST /chunks with a Content-Length body -> 400 not chunked", rs == [(400, b"not chunked\n")])) +rs = raw_exchange([b"GET /heal", b"th HTTP/1.1\r\nHost: x\r\nConn", b"ection: close\r\n\r\n"]) +results.append(check("a head split across three sends -> gathered and served", rs == [(200, b"ok")])) +rs = raw_exchange([b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\n\r\n", b"hel", b"lo" + pipelined]) +results.append(check("a body arriving after the head, in pieces, then a pipelined request", len(rs) == 2 and rs[0] == (200, b"hello") and rs[1][0] == 200)) rs = raw_exchange([b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhel", b"lo\r\n0\r\n\r\n" + pipelined]) results.append(check("POST /echo chunked read whole (split), then a pipelined request", len(rs) == 2 and rs[0] == (200, b"hello") and rs[1][0] == 200)) From d7d10feca54facfc03627f8a7f51479f96117b08 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 01:30:20 +0100 Subject: [PATCH 04/49] streams: docs for the pipe layer; status in the design note Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 38 +++++++++++++++++++++++++++++++++----- README.md | 3 ++- STREAMS.md | 10 ++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 819596c..e3bf2f0 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -164,7 +164,34 @@ kernel balances connections over the listeners (`SO_REUSEPORT`), and worker *i* --- -## 4. HTTP +## 4. Pipes: the reader and the writer + +The connection's bytes reach the HTTP engine, or a handler of your own under `ioma_run_pipes`, +through a pipe (`io/pipe.h`; `ioma_pipe` in the public header): a reader over the buffers the +kernel filled and a writer over a slab. Every call that has to wait suspends the coroutine and +the loop resumes it on the completion, so one piece of code drives any connection the I/O plane +runs - the shape of .NET's PipeReader and PipeWriter, with coroutines in place of tasks. + +**The reader** hands out received bytes as one contiguous span at a time. The kernel delivers +them as provided buffers, 2 KB each, and the reader keeps them as such: when everything live +lies in one buffer - a whole request head in one receive, the common case - `read` returns that +buffer's bytes in place, no copy. Only when the bytes span buffers, or when the consumer keeps +bytes it wants contiguous, are they gathered into the consumer's buffer (the 16 KB request +buffer, for HTTP). Four verbs drive it: `examine` (looked at n bytes without consuming them, so +the next `read` waits for more instead of returning the same incomplete head), `drop` +(consume), `keep` (consume, but the bytes stay where they are, contiguous with the run and valid +until `release`) and `copy` (the plain read into a buffer of your own). A run is a stretch of +kept bytes: the head is one and a whole-read body another; `run_begin` freezes the head's so +the body's can move without it. At most two kernel buffers are held at a time, one with frozen +kept bytes and one with the live bytes, so a slow handler pins one 2 KB buffer per request in +flight; the starvation log says when `BUF_COUNT` should grow. + +**The writer** is the slab: `reserve` n bytes to format into directly and `advance` by what was +written, `write` to copy in, `flush` to send (a suspension), `send` for both. The HTTP reply +keeps its own head-building and chunk framing on its slab and sends through the same await; a +raw pipe writes straight. + +## 5. HTTP `serve()` in `http.c` is the coroutine every connection runs. Per request: @@ -172,8 +199,9 @@ kernel balances connections over the listeners (`SO_REUSEPORT`), and worker *i* copy). `-2` means "incomplete": read more and parse again, so a request split at any byte works. 2. **Body, on demand**: one pass over the headers picks out `Content-Length`, `Transfer-Encoding` and `Connection` (a length test rejects almost every header before a byte - is compared), but the body stays on the wire. `ioma_body_all` reads it whole into the request - buffer, a chunked one decoded down over its own raw bytes; `ioma_body_read_until` streams it, any + is compared), but the body stays on the wire. `ioma_body_all` keeps it whole in the reader - in place + after the head when it all arrived in one receive, gathered otherwise, a chunked one slid + together chunk by chunk; `ioma_body_read_until` streams it, any size, filling the caller's buffer; `ioma_body_read_next_chunk` hands over one chunk exactly as the sender framed it. All three chunked paths share one small parser (a raw stage after the head, a size-line reader, a data mover) that survives a split at any byte. Whatever a handler leaves @@ -206,7 +234,7 @@ a body (`ioma_textf`). --- -## 5. Router and middleware +## 6. Router and middleware Endpoints are registered in groups before the workers start: a group is a path prefix plus middleware, groups nest, and the root (`NULL`) is the group with no prefix whose middleware @@ -238,7 +266,7 @@ opens a group for the block that follows (a run-once `for`, the group popped whe `IOMA_USE` adds middleware to it. The middleware lists travel in small structs ended by a null, so every argument is type-checked and a wrong signature is a compile error. -## 6. One keep-alive request, end to end +## 7. One keep-alive request, end to end 1. Bytes arrive. The kernel copies them into a provided buffer and posts a `RECV` CQE. 2. `enter` returns; dispatch queues the slice on the connection and resumes its coroutine. diff --git a/README.md b/README.md index fad479f..170d5c0 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ in front of it, in one send when it fits and streamed when it does not. Endpoint under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware of every group above it; the root is `NULL`, with `ioma_use` for middleware on everything. `ioma_run` resolves it all once into a segment tree and flat chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port. -The same registrations read as a script with the `IOMA_GET`, `IOMA_GROUP` and `IOMA_USE` macros, a group's block +Underneath, a connection is a pipe: `ioma_run_pipes` hands a handler of your own the reader and writer the +HTTP engine uses, for raw TCP, with the same suspend-and-resume. The same registrations read as a script with the `IOMA_GET`, `IOMA_GROUP` and `IOMA_USE` macros, a group's block nesting the routes below it; the hello example and `tests/server.c` are written that way. `playground/hello/main.c` is a complete example. diff --git a/STREAMS.md b/STREAMS.md index f96677b..12e236e 100644 --- a/STREAMS.md +++ b/STREAMS.md @@ -1,5 +1,15 @@ # Streams and pipes over the I/O plane (design, branch `streams`) +**Status.** Steps 1 to 4 below are on the branch: `io/pipe.h` (reader, writer), the HTTP engine +reading through the reader with the in-place fast path, and the public `ioma_pipe` with +`ioma_run_pipes`, a line-echo fixture and its tests. The reader's verbs ended up as examine / +drop / keep / copy rather than one `advance(consumed, examined)`, because kept bytes - the +request model's slices - need to stay put, which Pipelines has no notion of. Open, to talk +about: the public surface (run_begin/run stay private for now); outbound connections +(`ioma_connect` on IORING_OP_CONNECT, the same pipe over a socket to a database or a peer); +a second transport (QUIC, TLS) and whether that wants a vtable; letting the live bytes sit in a +second kernel buffer while a run continues in the first, so streamed bodies never copy twice. + ## Why Today the I/O plane offers two primitives, `await_recv` and `await_send`, and the HTTP engine From eaa646bb0c63f9824fb7206a4e4090415de481a9 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 01:32:40 +0100 Subject: [PATCH 05/49] streams: the end-to-end walkthrough on the reader Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index e3bf2f0..77d9c3d 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -270,11 +270,12 @@ so every argument is type-checked and a wrong signature is a compile error. 1. Bytes arrive. The kernel copies them into a provided buffer and posts a `RECV` CQE. 2. `enter` returns; dispatch queues the slice on the connection and resumes its coroutine. -3. `await_recv` copies the slice into `serve`'s buffer and returns the buffer to the ring. +3. The reader hands `serve` the slice in place - no copy; the buffer stays the request's until it is done. 4. picohttpparser parses; the route runs; the response is serialized into the head buffer. 5. `await_send` stages a SEND SQE and yields back to the loop. 6. The loop finishes the batch and calls `enter` once: the SEND is submitted and the loop waits. -7. The SEND CQE (`OP` tag) resumes the coroutine; `serve` loops to `await_recv` and parks. +7. The SEND CQE (`OP` tag) resumes the coroutine; `serve` releases the request's bytes, the buffer + goes back to the ring, and the next `read` parks. Two switches in, two out — tens of nanoseconds. The cost of a request is the kernel's, not ours. From 6f43c4d70f7938d92c3b638fc4f38c1d1589ff89 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 19:22:28 +0100 Subject: [PATCH 06/49] streams: ioma_pipereader and ioma_pipewriter Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- STREAMS.md | 20 +++++------ src/http/engine.c | 48 +++++++++++++------------- src/io/pipe.c | 86 +++++++++++++++++++++++------------------------ src/io/pipe.h | 44 ++++++++++++------------ 4 files changed, 99 insertions(+), 99 deletions(-) diff --git a/STREAMS.md b/STREAMS.md index 12e236e..7c0352b 100644 --- a/STREAMS.md +++ b/STREAMS.md @@ -31,23 +31,23 @@ suspend the coroutine"; the caller does not see it. ## The pieces -**`ioma_writer`** - the slab with a head reserve, a tail, and a connection to flush to. +**`ioma_pipewriter`** - the slab with a head reserve, a tail, and a connection to flush to. - void *ioma_writer_reserve(w, size_t n); /* n bytes at the tail, flushing first if they do not fit */ - void ioma_writer_advance(w, size_t n); /* the caller wrote n of them */ - int ioma_writer_write (w, data, n); /* copy in (reserve + memcpy + advance) */ - int ioma_writer_flush (w); /* send what is in the slab; suspends */ - int ioma_writer_send (w, data, n); /* write + flush */ + void *ioma_pipewriter_reserve(w, size_t n); /* n bytes at the tail, flushing first if they do not fit */ + void ioma_pipewriter_advance(w, size_t n); /* the caller wrote n of them */ + int ioma_pipewriter_write (w, data, n); /* copy in (reserve + memcpy + advance) */ + int ioma_pipewriter_flush (w); /* send what is in the slab; suspends */ + int ioma_pipewriter_send (w, data, n); /* write + flush */ The HTTP response keeps its head-building on top (first flush builds the head into the lead). `ioma_write`, `ioma_printf`, `ioma_flush` become thin calls; `ioma_reserve`/`ioma_advance` are new on the context, for handlers that format straight into the reply. -**`ioma_reader`** - the connection's received bytes, one contiguous span at a time. +**`ioma_pipereader`** - the connection's received bytes, one contiguous span at a time. - int ioma_reader_read (r, ioma_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ - void ioma_reader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ - int ioma_reader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ + int ioma_pipereader_read (r, ioma_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ + void ioma_pipereader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ + int ioma_pipereader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ Why one span and not a list of segments. io_uring hands data over as provided buffers, each a pointer and a length, and the reader keeps them as such internally (the rx queue does already). diff --git a/src/http/engine.c b/src/http/engine.c index ecb3895..4ab4ab3 100644 --- a/src/http/engine.c +++ b/src/http/engine.c @@ -41,7 +41,7 @@ static_assert(offsetof(ioma_kv, key) == offsetof(struct phr_header, name) && /* The engine's per-request state, behind ctx->priv. */ struct serve_state { - ioma_reader *reader; /* the connection's bytes; the head is kept in it */ + ioma_pipereader *reader; /* the connection's bytes; the head is kept in it */ size_t body_read; /* body bytes handed out so far */ bool body_done; /* the whole body has been taken off the wire */ bool body_whole; /* ioma_body_all kept it */ @@ -464,7 +464,7 @@ static void body_fail(ioma_ctx *ctx, int status) * 413, the peer gone or the input ending inside the body is -1. */ static bool body_bytes(ioma_ctx *ctx, ioma_slice *live) { - int rc = ioma_reader_read(STATE(ctx)->reader, live); + int rc = ioma_pipereader_read(STATE(ctx)->reader, live); if (rc > 0) return true; if (rc == IOMA_PIPE_FULL) @@ -485,7 +485,7 @@ static long body_line(ioma_ctx *ctx, ioma_slice *live) const char *eol = memmem(live->p, live->len, "\r\n", 2); if (eol) return eol - live->p; - ioma_reader_examine(STATE(ctx)->reader, live->len); + ioma_pipereader_examine(STATE(ctx)->reader, live->len); } } @@ -497,7 +497,7 @@ static bool chunk_trailers(ioma_ctx *ctx) long len = body_line(ctx, &live); if (len < 0) return false; - ioma_reader_drop(STATE(ctx)->reader, (size_t)len + 2); + ioma_pipereader_drop(STATE(ctx)->reader, (size_t)len + 2); if (len == 0) break; } @@ -529,7 +529,7 @@ static bool chunk_header(ioma_ctx *ctx) body_fail(ctx, 400); return false; } - ioma_reader_drop(STATE(ctx)->reader, (size_t)len + 2); + ioma_pipereader_drop(STATE(ctx)->reader, (size_t)len + 2); if (size == 0) return chunk_trailers(ctx); STATE(ctx)->chunk_left = size; @@ -545,13 +545,13 @@ static bool chunk_end(ioma_ctx *ctx) return false; if (live.len >= 2) break; - ioma_reader_examine(STATE(ctx)->reader, live.len); + ioma_pipereader_examine(STATE(ctx)->reader, live.len); } if (live.p[0] != '\r' || live.p[1] != '\n') { body_fail(ctx, 400); return false; } - ioma_reader_drop(STATE(ctx)->reader, 2); + ioma_pipereader_drop(STATE(ctx)->reader, 2); return true; } @@ -563,7 +563,7 @@ static bool chunk_end(ioma_ctx *ctx) ioma_slice ioma_body_all(ioma_ctx *ctx) { struct serve_state *state = STATE(ctx); - ioma_reader *r = state->reader; + ioma_pipereader *r = state->reader; ioma_request *req = &ctx->req; const ioma_slice none = { nullptr, 0 }; @@ -583,7 +583,7 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) if (!body_bytes(ctx, &live)) return none; size_t n = live.len < state->chunk_left ? live.len : state->chunk_left; - if (!ioma_reader_keep(r, n)) { + if (!ioma_pipereader_keep(r, n)) { body_fail(ctx, 413); return none; } @@ -592,7 +592,7 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) if (state->chunk_left == 0 && !chunk_end(ctx)) return none; } - req->body = ioma_reader_run(r); + req->body = ioma_pipereader_run(r); } else { if (req->content_length > IOMA_REQ_CAP) { body_fail(ctx, 413); @@ -601,11 +601,11 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) ioma_slice live = none; while (req->content_length && live.len < req->content_length) { if (live.len) - ioma_reader_examine(r, live.len); + ioma_pipereader_examine(r, live.len); if (!body_bytes(ctx, &live)) return none; } - const char *kept = req->content_length ? ioma_reader_keep(r, req->content_length) : live.p; + const char *kept = req->content_length ? ioma_pipereader_keep(r, req->content_length) : live.p; if (req->content_length && !kept) { body_fail(ctx, 413); return none; @@ -624,7 +624,7 @@ static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ size_t remaining = ctx->req.content_length - state->body_read; if (n > remaining) n = remaining; - int got = ioma_reader_copy(state->reader, dst, n); + int got = ioma_pipereader_copy(state->reader, dst, n); if (got <= 0) { state->body_err = -1; /* gone, or the input ended inside the body */ return -1; @@ -640,7 +640,7 @@ static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ { if (n > state->chunk_left) n = state->chunk_left; - int got = ioma_reader_copy(state->reader, dst, n); + int got = ioma_pipereader_copy(state->reader, dst, n); if (got <= 0) { state->body_err = -1; return -1; @@ -732,12 +732,12 @@ static void drain_body(ioma_ctx *ctx) * length, or -1 once the connection is finished (431 or 400 answered, or the peer went away). */ static long read_head(ioma_ctx *ctx, conn_t *conn) { - ioma_reader *r = STATE(ctx)->reader; + ioma_pipereader *r = STATE(ctx)->reader; ioma_request *req = &ctx->req; size_t already = 0; /* what the previous attempt scanned */ ioma_slice live = { nullptr, 0 }; for (;;) { - int rc = ioma_reader_read(r, &live); + int rc = ioma_pipereader_read(r, &live); if (rc == 0) return -1; /* the peer is done: a clean end between requests */ if (rc == IOMA_PIPE_FULL) { @@ -754,15 +754,15 @@ static long read_head(ioma_ctx *ctx, conn_t *conn) (struct phr_header *)req->headers, &req->n_headers, already); if (parsed >= 0) { - ioma_reader_keep(r, (size_t)parsed); /* the head stays put, where it was parsed */ - ioma_reader_run_begin(r); /* the body's kept bytes are a run of their own */ + ioma_pipereader_keep(r, (size_t)parsed); /* the head stays put, where it was parsed */ + ioma_pipereader_run_begin(r); /* the body's kept bytes are a run of their own */ return parsed; } if (parsed == -1) { /* malformed */ send_status(conn, 400); return -1; } - ioma_reader_examine(r, live.len); /* incomplete: the next read waits for more */ + ioma_pipereader_examine(r, live.len); /* incomplete: the next read waits for more */ already = live.len; } } @@ -795,7 +795,7 @@ static void fill_request(ioma_request *req, char *params_arena, size_t arena_cap /* The engine's bookkeeping for reading the body on demand: where it starts, what already * arrived with the head, and - for a Content-Length body that is entirely here - where the next * request starts. */ -static void init_body_state(struct serve_state *state, ioma_reader *reader, const ioma_request *req) +static void init_body_state(struct serve_state *state, ioma_pipereader *reader, const ioma_request *req) { *state = (struct serve_state){ .reader = reader }; state->body_done = !req->chunked && req->content_length == 0; @@ -827,8 +827,8 @@ void ioma__serve(conn_t *conn) char gather[IOMA_REQ_CAP]; /* where a request's bytes go when they must be contiguous */ char params[IOMA_PARAM_CAP]; /* decoded query parameters */ char slab[IOMA_LEAD + IOMA_OUT_CAP + 2]; /* lead, the write slab, CRLF slack */ - ioma_reader reader; /* the connection's bytes, across requests */ - ioma_reader_init(&reader, conn, gather, sizeof gather); + ioma_pipereader reader; /* the connection's bytes, across requests */ + ioma_pipereader_init(&reader, conn, gather, sizeof gather); for (;;) { ioma_ctx ctx; /* this request's context */ @@ -857,7 +857,7 @@ void ioma__serve(conn_t *conn) break; if (!ctx.req.keep_alive || ctx.res.close) break; - ioma_reader_release(&reader); /* this request's bytes go; a pipelined next one stays */ + ioma_pipereader_release(&reader); /* this request's bytes go; a pipelined next one stays */ } - ioma_reader_close(&reader); + ioma_pipereader_close(&reader); } diff --git a/src/io/pipe.c b/src/io/pipe.c index 0e72507..d996ec7 100644 --- a/src/io/pipe.c +++ b/src/io/pipe.c @@ -8,16 +8,16 @@ /* ── the reader ────────────────────────────────────────────────────────────────────────── */ -void ioma_reader_init(ioma_reader *r, conn_t *conn, char *buf, size_t cap) +void ioma_pipereader_init(ioma_pipereader *r, conn_t *conn, char *buf, size_t cap) { - *r = (ioma_reader){}; + *r = (ioma_pipereader){}; r->conn = conn; r->buf = buf; r->cap = cap; } /* The live bytes: in buf, or in the current kernel buffer. */ -static ioma_slice live_span(const ioma_reader *r) +static ioma_slice live_span(const ioma_pipereader *r) { if (r->live_in_buf) return (ioma_slice){ r->buf + r->buf_pos, r->buf_end - r->buf_pos }; @@ -28,7 +28,7 @@ static ioma_slice live_span(const ioma_reader *r) /* Let the current kernel buffer go once nothing is left in it, neither live bytes nor the run. * One that also holds frozen kept bytes lives on as `pinned`. */ -static void cur_done(ioma_reader *r) +static void cur_done(ioma_pipereader *r) { if (!r->has_cur || r->cur_pos < r->cur.len || (r->run_in_cur && r->run_len)) return; @@ -40,7 +40,7 @@ static void cur_done(ioma_reader *r) } /* Reclaim the bytes dropped from the front of buf's live region. */ -static void compact(ioma_reader *r) +static void compact(ioma_pipereader *r) { if (r->buf_pos > r->floor) { memmove(r->buf + r->floor, r->buf + r->buf_pos, r->buf_end - r->buf_pos); @@ -50,7 +50,7 @@ static void compact(ioma_reader *r) } /* Move the current buffer's run and live bytes into buf, so what follows can join them. */ -static bool gather(ioma_reader *r) +static bool gather(ioma_pipereader *r) { size_t live = r->has_cur ? r->cur.len - r->cur_pos : 0; size_t run = r->run_in_cur ? r->run_len : 0; @@ -75,7 +75,7 @@ static bool gather(ioma_reader *r) } /* A buffer that cannot be used: back to the ring, and the reader is done. */ -static int refuse(ioma_reader *r, const struct rx_item *item) +static int refuse(ioma_pipereader *r, const struct rx_item *item) { ioma__return_buf(r->conn->p, item->buf_id); r->error = IOMA_PIPE_FULL; @@ -83,7 +83,7 @@ static int refuse(ioma_reader *r, const struct rx_item *item) } /* More bytes: the next kernel buffer, in place when nothing is live, else appended in buf. */ -static int more(ioma_reader *r) +static int more(ioma_pipereader *r) { if (r->eof) return 0; @@ -115,7 +115,7 @@ static int more(ioma_reader *r) return 1; } -int ioma_reader_read(ioma_reader *r, ioma_slice *live) +int ioma_pipereader_read(ioma_pipereader *r, ioma_slice *live) { if (r->error) return r->error; @@ -131,13 +131,13 @@ int ioma_reader_read(ioma_reader *r, ioma_slice *live) } } -void ioma_reader_examine(ioma_reader *r, size_t n) +void ioma_pipereader_examine(ioma_pipereader *r, size_t n) { r->examined = n; } /* Forget n live bytes of the current place. */ -static void consume(ioma_reader *r, size_t n) +static void consume(ioma_pipereader *r, size_t n) { if (r->live_in_buf) { r->buf_pos += n; @@ -152,12 +152,12 @@ static void consume(ioma_reader *r, size_t n) r->examined = r->examined > n ? r->examined - n : 0; } -void ioma_reader_drop(ioma_reader *r, size_t n) +void ioma_pipereader_drop(ioma_pipereader *r, size_t n) { consume(r, n); } -const char *ioma_reader_keep(ioma_reader *r, size_t n) +const char *ioma_pipereader_keep(ioma_pipereader *r, size_t n) { const char *kept; if (r->live_in_buf) { @@ -195,7 +195,7 @@ const char *ioma_reader_keep(ioma_reader *r, size_t n) return kept; } -void ioma_reader_run_begin(ioma_reader *r) +void ioma_pipereader_run_begin(ioma_pipereader *r) { if (r->run_in_cur && r->run_len) { if (r->has_pinned && !r->cur_is_pinned) { /* another buffer is pinned already: this run moves to buf */ @@ -216,13 +216,13 @@ void ioma_reader_run_begin(ioma_reader *r) cur_done(r); } -ioma_slice ioma_reader_run(const ioma_reader *r) +ioma_slice ioma_pipereader_run(const ioma_pipereader *r) { const char *base = r->run_in_cur ? (const char *)r->cur.ptr : r->buf; return (ioma_slice){ base + r->run_start, r->run_len }; } -void ioma_reader_release(ioma_reader *r) +void ioma_pipereader_release(ioma_pipereader *r) { r->run_len = 0; r->run_in_cur = false; @@ -244,7 +244,7 @@ void ioma_reader_release(ioma_reader *r) cur_done(r); } -void ioma_reader_close(ioma_reader *r) +void ioma_pipereader_close(ioma_pipereader *r) { if (r->has_cur && !r->cur_is_pinned) ioma__return_buf(r->conn->p, r->cur.buf_id); @@ -253,7 +253,7 @@ void ioma_reader_close(ioma_reader *r) r->has_cur = r->has_pinned = r->cur_is_pinned = false; } -int ioma_reader_copy(ioma_reader *r, void *dst, size_t n) +int ioma_pipereader_copy(ioma_pipereader *r, void *dst, size_t n) { if (r->error) return r->error; @@ -273,15 +273,15 @@ int ioma_reader_copy(ioma_reader *r, void *dst, size_t n) /* ── the writer ────────────────────────────────────────────────────────────────────────── */ -void ioma_writer_init(ioma_writer *w, conn_t *conn, char *buf, size_t cap) +void ioma_pipewriter_init(ioma_pipewriter *w, conn_t *conn, char *buf, size_t cap) { - *w = (ioma_writer){}; + *w = (ioma_pipewriter){}; w->conn = conn; w->buf = buf; w->cap = cap; } -int ioma_writer_flush(ioma_writer *w) +int ioma_pipewriter_flush(ioma_pipewriter *w) { if (w->failed) return -1; @@ -296,26 +296,26 @@ int ioma_writer_flush(ioma_writer *w) return 0; } -void *ioma_writer_reserve(ioma_writer *w, size_t n) +void *ioma_pipewriter_reserve(ioma_pipewriter *w, size_t n) { if (w->failed || n > w->cap) return nullptr; - if (w->len + n > w->cap && ioma_writer_flush(w) < 0) + if (w->len + n > w->cap && ioma_pipewriter_flush(w) < 0) return nullptr; return w->buf + w->len; } -void ioma_writer_advance(ioma_writer *w, size_t n) +void ioma_pipewriter_advance(ioma_pipewriter *w, size_t n) { w->len += n; } -int ioma_writer_write(ioma_writer *w, const void *data, size_t n) +int ioma_pipewriter_write(ioma_pipewriter *w, const void *data, size_t n) { if (w->failed) return -1; if (n > w->cap) { /* larger than the slab: straight from the caller's memory */ - if (ioma_writer_flush(w) < 0) + if (ioma_pipewriter_flush(w) < 0) return -1; if (await_send(w->conn, data, n) < 0) { w->failed = true; @@ -323,7 +323,7 @@ int ioma_writer_write(ioma_writer *w, const void *data, size_t n) } return 0; } - void *at = ioma_writer_reserve(w, n); + void *at = ioma_pipewriter_reserve(w, n); if (!at) return -1; memcpy(at, data, n); @@ -331,32 +331,32 @@ int ioma_writer_write(ioma_writer *w, const void *data, size_t n) return 0; } -int ioma_writer_send(ioma_writer *w, const void *data, size_t n) +int ioma_pipewriter_send(ioma_pipewriter *w, const void *data, size_t n) { - return ioma_writer_write(w, data, n) < 0 ? -1 : ioma_writer_flush(w); + return ioma_pipewriter_write(w, data, n) < 0 ? -1 : ioma_pipewriter_flush(w); } /* ── the pipe ──────────────────────────────────────────────────────────────────────────── */ void ioma__pipe_init(struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap) { - ioma_reader_init(&p->in, conn, gather, gather_cap); - ioma_writer_init(&p->out, conn, slab, slab_cap); + ioma_pipereader_init(&p->in, conn, gather, gather_cap); + ioma_pipewriter_init(&p->out, conn, slab, slab_cap); } void ioma__pipe_close(struct ioma_pipe *p) { - ioma_reader_close(&p->in); + ioma_pipereader_close(&p->in); } -int ioma_pipe_read (ioma_pipe *p, ioma_slice *live) { return ioma_reader_read(&p->in, live); } -void ioma_pipe_examine(ioma_pipe *p, size_t n) { ioma_reader_examine(&p->in, n); } -void ioma_pipe_drop (ioma_pipe *p, size_t n) { ioma_reader_drop(&p->in, n); } -const char *ioma_pipe_keep (ioma_pipe *p, size_t n) { return ioma_reader_keep(&p->in, n); } -void ioma_pipe_release(ioma_pipe *p) { ioma_reader_release(&p->in); } -int ioma_pipe_copy (ioma_pipe *p, void *dst, size_t n) { return ioma_reader_copy(&p->in, dst, n); } -void *ioma_pipe_reserve(ioma_pipe *p, size_t n) { return ioma_writer_reserve(&p->out, n); } -void ioma_pipe_advance(ioma_pipe *p, size_t n) { ioma_writer_advance(&p->out, n); } -int ioma_pipe_write (ioma_pipe *p, const void *data, size_t n) { return ioma_writer_write(&p->out, data, n); } -int ioma_pipe_flush (ioma_pipe *p) { return ioma_writer_flush(&p->out); } -int ioma_pipe_send (ioma_pipe *p, const void *data, size_t n) { return ioma_writer_send(&p->out, data, n); } +int ioma_pipe_read (ioma_pipe *p, ioma_slice *live) { return ioma_pipereader_read(&p->in, live); } +void ioma_pipe_examine(ioma_pipe *p, size_t n) { ioma_pipereader_examine(&p->in, n); } +void ioma_pipe_drop (ioma_pipe *p, size_t n) { ioma_pipereader_drop(&p->in, n); } +const char *ioma_pipe_keep (ioma_pipe *p, size_t n) { return ioma_pipereader_keep(&p->in, n); } +void ioma_pipe_release(ioma_pipe *p) { ioma_pipereader_release(&p->in); } +int ioma_pipe_copy (ioma_pipe *p, void *dst, size_t n) { return ioma_pipereader_copy(&p->in, dst, n); } +void *ioma_pipe_reserve(ioma_pipe *p, size_t n) { return ioma_pipewriter_reserve(&p->out, n); } +void ioma_pipe_advance(ioma_pipe *p, size_t n) { ioma_pipewriter_advance(&p->out, n); } +int ioma_pipe_write (ioma_pipe *p, const void *data, size_t n) { return ioma_pipewriter_write(&p->out, data, n); } +int ioma_pipe_flush (ioma_pipe *p) { return ioma_pipewriter_flush(&p->out); } +int ioma_pipe_send (ioma_pipe *p, const void *data, size_t n) { return ioma_pipewriter_send(&p->out, data, n); } diff --git a/src/io/pipe.h b/src/io/pipe.h index 4448356..4cda98d 100644 --- a/src/io/pipe.h +++ b/src/io/pipe.h @@ -15,7 +15,7 @@ * bytes stay where they are - the consumer's, to point into and even overwrite - until release. * At most two kernel buffers are held: one with kept bytes of earlier runs, one with the live * bytes and the run in progress. */ -typedef struct ioma_reader { +typedef struct ioma_pipereader { conn_t *conn; char *buf; /* the gathering buffer, the consumer's */ size_t cap; @@ -33,38 +33,38 @@ typedef struct ioma_reader { size_t examined; /* live bytes the consumer looked at without consuming */ bool eof; int error; /* 0, or IOMA_PIPE_GONE / IOMA_PIPE_FULL, sticky */ -} ioma_reader; +} ioma_pipereader; -void ioma_reader_init (ioma_reader *r, conn_t *conn, char *buf, size_t cap); -void ioma_reader_close (ioma_reader *r); /* returns the buffers it holds */ -int ioma_reader_read (ioma_reader *r, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ -void ioma_reader_examine (ioma_reader *r, size_t n); /* looked at n live bytes: the next read waits for more */ -void ioma_reader_drop (ioma_reader *r, size_t n); /* consume n live bytes */ -const char *ioma_reader_keep (ioma_reader *r, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ -void ioma_reader_run_begin(ioma_reader *r); /* freeze the run; the next keep starts another */ -ioma_slice ioma_reader_run (const ioma_reader *r); /* the run in progress */ -void ioma_reader_release (ioma_reader *r); /* forget every kept byte; live bytes stay */ -int ioma_reader_copy (ioma_reader *r, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ +void ioma_pipereader_init (ioma_pipereader *r, conn_t *conn, char *buf, size_t cap); +void ioma_pipereader_close (ioma_pipereader *r); /* returns the buffers it holds */ +int ioma_pipereader_read (ioma_pipereader *r, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ +void ioma_pipereader_examine (ioma_pipereader *r, size_t n); /* looked at n live bytes: the next read waits for more */ +void ioma_pipereader_drop (ioma_pipereader *r, size_t n); /* consume n live bytes */ +const char *ioma_pipereader_keep (ioma_pipereader *r, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ +void ioma_pipereader_run_begin(ioma_pipereader *r); /* freeze the run; the next keep starts another */ +ioma_slice ioma_pipereader_run (const ioma_pipereader *r); /* the run in progress */ +void ioma_pipereader_release (ioma_pipereader *r); /* forget every kept byte; live bytes stay */ +int ioma_pipereader_copy (ioma_pipereader *r, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ /* The writer: a slab, sent on flush. */ -typedef struct ioma_writer { +typedef struct ioma_pipewriter { conn_t *conn; char *buf; size_t cap, len; bool failed; /* the peer is gone: every call fails from here on */ -} ioma_writer; +} ioma_pipewriter; -void ioma_writer_init (ioma_writer *w, conn_t *conn, char *buf, size_t cap); -void *ioma_writer_reserve(ioma_writer *w, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ -void ioma_writer_advance(ioma_writer *w, size_t n); -int ioma_writer_write (ioma_writer *w, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ -int ioma_writer_flush (ioma_writer *w); /* send the slab; suspends */ -int ioma_writer_send (ioma_writer *w, const void *data, size_t n); /* write, then flush */ +void ioma_pipewriter_init (ioma_pipewriter *w, conn_t *conn, char *buf, size_t cap); +void *ioma_pipewriter_reserve(ioma_pipewriter *w, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ +void ioma_pipewriter_advance(ioma_pipewriter *w, size_t n); +int ioma_pipewriter_write (ioma_pipewriter *w, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ +int ioma_pipewriter_flush (ioma_pipewriter *w); /* send the slab; suspends */ +int ioma_pipewriter_send (ioma_pipewriter *w, const void *data, size_t n); /* write, then flush */ /* The pair, as the public API sees it. */ struct ioma_pipe { - ioma_reader in; - ioma_writer out; + ioma_pipereader in; + ioma_pipewriter out; }; void ioma__pipe_init (struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap); void ioma__pipe_close(struct ioma_pipe *p); From fb5616928a9f765e9808083049d2d3a5c7f36cbf Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 19:23:58 +0100 Subject: [PATCH 07/49] streams: pr and pw for the reader and writer parameters Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/pipe.c | 350 +++++++++++++++++++++++++------------------------- src/io/pipe.h | 32 ++--- 2 files changed, 191 insertions(+), 191 deletions(-) diff --git a/src/io/pipe.c b/src/io/pipe.c index d996ec7..bd1d7ba 100644 --- a/src/io/pipe.c +++ b/src/io/pipe.c @@ -8,264 +8,264 @@ /* ── the reader ────────────────────────────────────────────────────────────────────────── */ -void ioma_pipereader_init(ioma_pipereader *r, conn_t *conn, char *buf, size_t cap) +void ioma_pipereader_init(ioma_pipereader *pr, conn_t *conn, char *buf, size_t cap) { - *r = (ioma_pipereader){}; - r->conn = conn; - r->buf = buf; - r->cap = cap; + *pr = (ioma_pipereader){}; + pr->conn = conn; + pr->buf = buf; + pr->cap = cap; } /* The live bytes: in buf, or in the current kernel buffer. */ -static ioma_slice live_span(const ioma_pipereader *r) +static ioma_slice live_span(const ioma_pipereader *pr) { - if (r->live_in_buf) - return (ioma_slice){ r->buf + r->buf_pos, r->buf_end - r->buf_pos }; - if (r->has_cur) - return (ioma_slice){ (const char *)r->cur.ptr + r->cur_pos, r->cur.len - r->cur_pos }; + if (pr->live_in_buf) + return (ioma_slice){ pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos }; + if (pr->has_cur) + return (ioma_slice){ (const char *)pr->cur.ptr + pr->cur_pos, pr->cur.len - pr->cur_pos }; return (ioma_slice){ nullptr, 0 }; } /* Let the current kernel buffer go once nothing is left in it, neither live bytes nor the run. * One that also holds frozen kept bytes lives on as `pinned`. */ -static void cur_done(ioma_pipereader *r) +static void cur_done(ioma_pipereader *pr) { - if (!r->has_cur || r->cur_pos < r->cur.len || (r->run_in_cur && r->run_len)) + if (!pr->has_cur || pr->cur_pos < pr->cur.len || (pr->run_in_cur && pr->run_len)) return; - if (!r->cur_is_pinned) - ioma__return_buf(r->conn->p, r->cur.buf_id); - r->has_cur = false; - r->cur_is_pinned = false; - r->cur_pos = 0; + if (!pr->cur_is_pinned) + ioma__return_buf(pr->conn->p, pr->cur.buf_id); + pr->has_cur = false; + pr->cur_is_pinned = false; + pr->cur_pos = 0; } /* Reclaim the bytes dropped from the front of buf's live region. */ -static void compact(ioma_pipereader *r) +static void compact(ioma_pipereader *pr) { - if (r->buf_pos > r->floor) { - memmove(r->buf + r->floor, r->buf + r->buf_pos, r->buf_end - r->buf_pos); - r->buf_end -= r->buf_pos - r->floor; - r->buf_pos = r->floor; + if (pr->buf_pos > pr->floor) { + memmove(pr->buf + pr->floor, pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos); + pr->buf_end -= pr->buf_pos - pr->floor; + pr->buf_pos = pr->floor; } } /* Move the current buffer's run and live bytes into buf, so what follows can join them. */ -static bool gather(ioma_pipereader *r) +static bool gather(ioma_pipereader *pr) { - size_t live = r->has_cur ? r->cur.len - r->cur_pos : 0; - size_t run = r->run_in_cur ? r->run_len : 0; - if (r->floor + run + live > r->cap) + size_t live = pr->has_cur ? pr->cur.len - pr->cur_pos : 0; + size_t run = pr->run_in_cur ? pr->run_len : 0; + if (pr->floor + run + live > pr->cap) return false; if (run) { - memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->run_start, run); - r->run_start = r->floor; - r->floor += run; + memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->run_start, run); + pr->run_start = pr->floor; + pr->floor += run; } - r->run_in_cur = false; + pr->run_in_cur = false; if (live) - memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->cur_pos, live); - r->buf_pos = r->floor; - r->buf_end = r->floor + live; - r->live_in_buf = true; - if (r->has_cur) { - r->cur_pos = r->cur.len; - cur_done(r); + memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->cur_pos, live); + pr->buf_pos = pr->floor; + pr->buf_end = pr->floor + live; + pr->live_in_buf = true; + if (pr->has_cur) { + pr->cur_pos = pr->cur.len; + cur_done(pr); } return true; } /* A buffer that cannot be used: back to the ring, and the reader is done. */ -static int refuse(ioma_pipereader *r, const struct rx_item *item) +static int refuse(ioma_pipereader *pr, const struct rx_item *item) { - ioma__return_buf(r->conn->p, item->buf_id); - r->error = IOMA_PIPE_FULL; + ioma__return_buf(pr->conn->p, item->buf_id); + pr->error = IOMA_PIPE_FULL; return IOMA_PIPE_FULL; } /* More bytes: the next kernel buffer, in place when nothing is live, else appended in buf. */ -static int more(ioma_pipereader *r) +static int more(ioma_pipereader *pr) { - if (r->eof) + if (pr->eof) return 0; struct rx_item item; - int rc = ioma__await_item(r->conn, &item); + int rc = ioma__await_item(pr->conn, &item); if (rc <= 0) { - r->eof = true; + pr->eof = true; if (rc < 0) - r->error = IOMA_PIPE_GONE; + pr->error = IOMA_PIPE_GONE; return rc < 0 ? IOMA_PIPE_GONE : 0; } - if (!r->live_in_buf && !r->has_cur) { /* nothing live: this buffer is the live span */ - r->cur = item; - r->has_cur = true; - r->cur_pos = 0; - r->cur_is_pinned = false; + if (!pr->live_in_buf && !pr->has_cur) { /* nothing live: this buffer is the live span */ + pr->cur = item; + pr->has_cur = true; + pr->cur_pos = 0; + pr->cur_is_pinned = false; return 1; } - if (!r->live_in_buf && !gather(r)) /* the live bytes leave the current buffer first */ - return refuse(r, &item); - if (r->buf_end + item.len > r->cap) { - compact(r); - if (r->buf_end + item.len > r->cap) - return refuse(r, &item); + if (!pr->live_in_buf && !gather(pr)) /* the live bytes leave the current buffer first */ + return refuse(pr, &item); + if (pr->buf_end + item.len > pr->cap) { + compact(pr); + if (pr->buf_end + item.len > pr->cap) + return refuse(pr, &item); } - memcpy(r->buf + r->buf_end, item.ptr, item.len); - r->buf_end += item.len; - ioma__return_buf(r->conn->p, item.buf_id); + memcpy(pr->buf + pr->buf_end, item.ptr, item.len); + pr->buf_end += item.len; + ioma__return_buf(pr->conn->p, item.buf_id); return 1; } -int ioma_pipereader_read(ioma_pipereader *r, ioma_slice *live) +int ioma_pipereader_read(ioma_pipereader *pr, ioma_slice *live) { - if (r->error) - return r->error; + if (pr->error) + return pr->error; for (;;) { - ioma_slice l = live_span(r); - if (l.len > r->examined) { + ioma_slice l = live_span(pr); + if (l.len > pr->examined) { *live = l; return 1; } - int rc = more(r); + int rc = more(pr); if (rc <= 0) return rc; } } -void ioma_pipereader_examine(ioma_pipereader *r, size_t n) +void ioma_pipereader_examine(ioma_pipereader *pr, size_t n) { - r->examined = n; + pr->examined = n; } /* Forget n live bytes of the current place. */ -static void consume(ioma_pipereader *r, size_t n) +static void consume(ioma_pipereader *pr, size_t n) { - if (r->live_in_buf) { - r->buf_pos += n; - if (r->buf_pos == r->buf_end) { - r->buf_pos = r->buf_end = r->floor; - r->live_in_buf = false; + if (pr->live_in_buf) { + pr->buf_pos += n; + if (pr->buf_pos == pr->buf_end) { + pr->buf_pos = pr->buf_end = pr->floor; + pr->live_in_buf = false; } - } else if (r->has_cur) { - r->cur_pos += n; - cur_done(r); + } else if (pr->has_cur) { + pr->cur_pos += n; + cur_done(pr); } - r->examined = r->examined > n ? r->examined - n : 0; + pr->examined = pr->examined > n ? pr->examined - n : 0; } -void ioma_pipereader_drop(ioma_pipereader *r, size_t n) +void ioma_pipereader_drop(ioma_pipereader *pr, size_t n) { - consume(r, n); + consume(pr, n); } -const char *ioma_pipereader_keep(ioma_pipereader *r, size_t n) +const char *ioma_pipereader_keep(ioma_pipereader *pr, size_t n) { const char *kept; - if (r->live_in_buf) { - if (r->run_len == 0) { /* a run starts where the live bytes are */ - r->run_in_cur = false; - r->run_start = r->buf_pos; - r->floor = r->buf_pos; - } else if (r->buf_pos != r->floor) { /* dropped bytes in between: slide these down */ - memmove(r->buf + r->floor, r->buf + r->buf_pos, n); + if (pr->live_in_buf) { + if (pr->run_len == 0) { /* a run starts where the live bytes are */ + pr->run_in_cur = false; + pr->run_start = pr->buf_pos; + pr->floor = pr->buf_pos; + } else if (pr->buf_pos != pr->floor) { /* dropped bytes in between: slide these down */ + memmove(pr->buf + pr->floor, pr->buf + pr->buf_pos, n); } - kept = r->buf + r->floor; - r->floor += n; - } else if (r->has_cur && (r->run_len == 0 || r->run_in_cur)) { /* in place */ - if (r->run_len == 0) { - r->run_in_cur = true; - r->run_start = r->cur_pos; + kept = pr->buf + pr->floor; + pr->floor += n; + } else if (pr->has_cur && (pr->run_len == 0 || pr->run_in_cur)) { /* in place */ + if (pr->run_len == 0) { + pr->run_in_cur = true; + pr->run_start = pr->cur_pos; } - size_t run_end = r->run_start + r->run_len; - if (run_end != r->cur_pos) - memmove((char *)r->cur.ptr + run_end, (const char *)r->cur.ptr + r->cur_pos, n); - kept = (const char *)r->cur.ptr + run_end; - } else if (r->has_cur) { /* the run is in buf, the live bytes are not: copy across */ - if (r->floor + n > r->cap) { - r->error = IOMA_PIPE_FULL; + size_t run_end = pr->run_start + pr->run_len; + if (run_end != pr->cur_pos) + memmove((char *)pr->cur.ptr + run_end, (const char *)pr->cur.ptr + pr->cur_pos, n); + kept = (const char *)pr->cur.ptr + run_end; + } else if (pr->has_cur) { /* the run is in buf, the live bytes are not: copy across */ + if (pr->floor + n > pr->cap) { + pr->error = IOMA_PIPE_FULL; return nullptr; } - memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->cur_pos, n); - kept = r->buf + r->floor; - r->floor += n; + memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->cur_pos, n); + kept = pr->buf + pr->floor; + pr->floor += n; } else { return nullptr; /* nothing live: the caller's mistake */ } - r->run_len += n; - consume(r, n); + pr->run_len += n; + consume(pr, n); return kept; } -void ioma_pipereader_run_begin(ioma_pipereader *r) +void ioma_pipereader_run_begin(ioma_pipereader *pr) { - if (r->run_in_cur && r->run_len) { - if (r->has_pinned && !r->cur_is_pinned) { /* another buffer is pinned already: this run moves to buf */ - if (r->floor + r->run_len > r->cap) { - r->error = IOMA_PIPE_FULL; + if (pr->run_in_cur && pr->run_len) { + if (pr->has_pinned && !pr->cur_is_pinned) { /* another buffer is pinned already: this run moves to buf */ + if (pr->floor + pr->run_len > pr->cap) { + pr->error = IOMA_PIPE_FULL; } else { - memcpy(r->buf + r->floor, (const char *)r->cur.ptr + r->run_start, r->run_len); - r->floor += r->run_len; + memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->run_start, pr->run_len); + pr->floor += pr->run_len; } } else { - r->pinned = r->cur; - r->has_pinned = true; - r->cur_is_pinned = true; + pr->pinned = pr->cur; + pr->has_pinned = true; + pr->cur_is_pinned = true; } } - r->run_len = 0; - r->run_in_cur = false; - cur_done(r); + pr->run_len = 0; + pr->run_in_cur = false; + cur_done(pr); } -ioma_slice ioma_pipereader_run(const ioma_pipereader *r) +ioma_slice ioma_pipereader_run(const ioma_pipereader *pr) { - const char *base = r->run_in_cur ? (const char *)r->cur.ptr : r->buf; - return (ioma_slice){ base + r->run_start, r->run_len }; + const char *base = pr->run_in_cur ? (const char *)pr->cur.ptr : pr->buf; + return (ioma_slice){ base + pr->run_start, pr->run_len }; } -void ioma_pipereader_release(ioma_pipereader *r) +void ioma_pipereader_release(ioma_pipereader *pr) { - r->run_len = 0; - r->run_in_cur = false; - if (r->live_in_buf) { - memmove(r->buf, r->buf + r->buf_pos, r->buf_end - r->buf_pos); - r->buf_end -= r->buf_pos; - r->buf_pos = 0; + pr->run_len = 0; + pr->run_in_cur = false; + if (pr->live_in_buf) { + memmove(pr->buf, pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos); + pr->buf_end -= pr->buf_pos; + pr->buf_pos = 0; } else { - r->buf_pos = r->buf_end = 0; + pr->buf_pos = pr->buf_end = 0; } - r->floor = 0; - if (r->has_pinned) { - if (r->cur_is_pinned) - r->cur_is_pinned = false; /* it lives on as the current buffer */ + pr->floor = 0; + if (pr->has_pinned) { + if (pr->cur_is_pinned) + pr->cur_is_pinned = false; /* it lives on as the current buffer */ else - ioma__return_buf(r->conn->p, r->pinned.buf_id); - r->has_pinned = false; + ioma__return_buf(pr->conn->p, pr->pinned.buf_id); + pr->has_pinned = false; } - cur_done(r); + cur_done(pr); } -void ioma_pipereader_close(ioma_pipereader *r) +void ioma_pipereader_close(ioma_pipereader *pr) { - if (r->has_cur && !r->cur_is_pinned) - ioma__return_buf(r->conn->p, r->cur.buf_id); - if (r->has_pinned) - ioma__return_buf(r->conn->p, r->pinned.buf_id); - r->has_cur = r->has_pinned = r->cur_is_pinned = false; + if (pr->has_cur && !pr->cur_is_pinned) + ioma__return_buf(pr->conn->p, pr->cur.buf_id); + if (pr->has_pinned) + ioma__return_buf(pr->conn->p, pr->pinned.buf_id); + pr->has_cur = pr->has_pinned = pr->cur_is_pinned = false; } -int ioma_pipereader_copy(ioma_pipereader *r, void *dst, size_t n) +int ioma_pipereader_copy(ioma_pipereader *pr, void *dst, size_t n) { - if (r->error) - return r->error; + if (pr->error) + return pr->error; for (;;) { - ioma_slice l = live_span(r); + ioma_slice l = live_span(pr); if (l.len) { size_t k = l.len < n ? l.len : n; memcpy(dst, l.p, k); - consume(r, k); + consume(pr, k); return (int)k; } - int rc = more(r); + int rc = more(pr); if (rc <= 0) return rc; } @@ -273,67 +273,67 @@ int ioma_pipereader_copy(ioma_pipereader *r, void *dst, size_t n) /* ── the writer ────────────────────────────────────────────────────────────────────────── */ -void ioma_pipewriter_init(ioma_pipewriter *w, conn_t *conn, char *buf, size_t cap) +void ioma_pipewriter_init(ioma_pipewriter *pw, conn_t *conn, char *buf, size_t cap) { - *w = (ioma_pipewriter){}; - w->conn = conn; - w->buf = buf; - w->cap = cap; + *pw = (ioma_pipewriter){}; + pw->conn = conn; + pw->buf = buf; + pw->cap = cap; } -int ioma_pipewriter_flush(ioma_pipewriter *w) +int ioma_pipewriter_flush(ioma_pipewriter *pw) { - if (w->failed) + if (pw->failed) return -1; - if (w->len == 0) + if (pw->len == 0) return 0; - int rc = await_send(w->conn, w->buf, w->len); - w->len = 0; + int rc = await_send(pw->conn, pw->buf, pw->len); + pw->len = 0; if (rc < 0) { - w->failed = true; + pw->failed = true; return -1; } return 0; } -void *ioma_pipewriter_reserve(ioma_pipewriter *w, size_t n) +void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n) { - if (w->failed || n > w->cap) + if (pw->failed || n > pw->cap) return nullptr; - if (w->len + n > w->cap && ioma_pipewriter_flush(w) < 0) + if (pw->len + n > pw->cap && ioma_pipewriter_flush(pw) < 0) return nullptr; - return w->buf + w->len; + return pw->buf + pw->len; } -void ioma_pipewriter_advance(ioma_pipewriter *w, size_t n) +void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n) { - w->len += n; + pw->len += n; } -int ioma_pipewriter_write(ioma_pipewriter *w, const void *data, size_t n) +int ioma_pipewriter_write(ioma_pipewriter *pw, const void *data, size_t n) { - if (w->failed) + if (pw->failed) return -1; - if (n > w->cap) { /* larger than the slab: straight from the caller's memory */ - if (ioma_pipewriter_flush(w) < 0) + if (n > pw->cap) { /* larger than the slab: straight from the caller's memory */ + if (ioma_pipewriter_flush(pw) < 0) return -1; - if (await_send(w->conn, data, n) < 0) { - w->failed = true; + if (await_send(pw->conn, data, n) < 0) { + pw->failed = true; return -1; } return 0; } - void *at = ioma_pipewriter_reserve(w, n); + void *at = ioma_pipewriter_reserve(pw, n); if (!at) return -1; memcpy(at, data, n); - w->len += n; + pw->len += n; return 0; } -int ioma_pipewriter_send(ioma_pipewriter *w, const void *data, size_t n) +int ioma_pipewriter_send(ioma_pipewriter *pw, const void *data, size_t n) { - return ioma_pipewriter_write(w, data, n) < 0 ? -1 : ioma_pipewriter_flush(w); + return ioma_pipewriter_write(pw, data, n) < 0 ? -1 : ioma_pipewriter_flush(pw); } /* ── the pipe ──────────────────────────────────────────────────────────────────────────── */ diff --git a/src/io/pipe.h b/src/io/pipe.h index 4cda98d..924c574 100644 --- a/src/io/pipe.h +++ b/src/io/pipe.h @@ -35,16 +35,16 @@ typedef struct ioma_pipereader { int error; /* 0, or IOMA_PIPE_GONE / IOMA_PIPE_FULL, sticky */ } ioma_pipereader; -void ioma_pipereader_init (ioma_pipereader *r, conn_t *conn, char *buf, size_t cap); -void ioma_pipereader_close (ioma_pipereader *r); /* returns the buffers it holds */ -int ioma_pipereader_read (ioma_pipereader *r, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ -void ioma_pipereader_examine (ioma_pipereader *r, size_t n); /* looked at n live bytes: the next read waits for more */ -void ioma_pipereader_drop (ioma_pipereader *r, size_t n); /* consume n live bytes */ -const char *ioma_pipereader_keep (ioma_pipereader *r, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ -void ioma_pipereader_run_begin(ioma_pipereader *r); /* freeze the run; the next keep starts another */ -ioma_slice ioma_pipereader_run (const ioma_pipereader *r); /* the run in progress */ -void ioma_pipereader_release (ioma_pipereader *r); /* forget every kept byte; live bytes stay */ -int ioma_pipereader_copy (ioma_pipereader *r, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ +void ioma_pipereader_init (ioma_pipereader *pr, conn_t *conn, char *buf, size_t cap); +void ioma_pipereader_close (ioma_pipereader *pr); /* returns the buffers it holds */ +int ioma_pipereader_read (ioma_pipereader *pr, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ +void ioma_pipereader_examine (ioma_pipereader *pr, size_t n); /* looked at n live bytes: the next read waits for more */ +void ioma_pipereader_drop (ioma_pipereader *pr, size_t n); /* consume n live bytes */ +const char *ioma_pipereader_keep (ioma_pipereader *pr, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ +void ioma_pipereader_run_begin(ioma_pipereader *pr); /* freeze the run; the next keep starts another */ +ioma_slice ioma_pipereader_run (const ioma_pipereader *pr); /* the run in progress */ +void ioma_pipereader_release (ioma_pipereader *pr); /* forget every kept byte; live bytes stay */ +int ioma_pipereader_copy (ioma_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ /* The writer: a slab, sent on flush. */ typedef struct ioma_pipewriter { @@ -54,12 +54,12 @@ typedef struct ioma_pipewriter { bool failed; /* the peer is gone: every call fails from here on */ } ioma_pipewriter; -void ioma_pipewriter_init (ioma_pipewriter *w, conn_t *conn, char *buf, size_t cap); -void *ioma_pipewriter_reserve(ioma_pipewriter *w, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ -void ioma_pipewriter_advance(ioma_pipewriter *w, size_t n); -int ioma_pipewriter_write (ioma_pipewriter *w, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ -int ioma_pipewriter_flush (ioma_pipewriter *w); /* send the slab; suspends */ -int ioma_pipewriter_send (ioma_pipewriter *w, const void *data, size_t n); /* write, then flush */ +void ioma_pipewriter_init (ioma_pipewriter *pw, conn_t *conn, char *buf, size_t cap); +void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ +void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n); +int ioma_pipewriter_write (ioma_pipewriter *pw, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ +int ioma_pipewriter_flush (ioma_pipewriter *pw); /* send the slab; suspends */ +int ioma_pipewriter_send (ioma_pipewriter *pw, const void *data, size_t n); /* write, then flush */ /* The pair, as the public API sees it. */ struct ioma_pipe { From a20d95559fb1a776ba9bc37c1cb6419f62fac036 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:18:12 +0100 Subject: [PATCH 08/49] io/conn.h: the connection out of proactor.h conn.h is what a user of a connection needs: RX_QUEUE, rx_item, the recv state, struct conn, and the awaits (await_recv, await_send, ioma__await_item). proactor.h keeps the worker: the ring tunables, struct proactor, run and spawn. The pipe and the HTTP plane include conn.h; run.c takes proactor.h as well. The loop-side plumbing conn.c and proactor.c share stays in io/internal.h. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/http/internal.h | 5 +++-- src/http/run.c | 1 + src/io/conn.h | 53 +++++++++++++++++++++++++++++++++++++++++++++ src/io/internal.h | 1 - src/io/pipe.h | 2 +- src/io/proactor.h | 39 ++------------------------------- 6 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 src/io/conn.h diff --git a/src/http/internal.h b/src/http/internal.h index 725153b..79fd19e 100644 --- a/src/http/internal.h +++ b/src/http/internal.h @@ -1,11 +1,12 @@ /* * http/internal.h - what the HTTP plane's files share with each other. Private; not installed. - * The plane sits on the I/O plane's interface (io/proactor.h): connections and the awaits. + * The plane sits on the I/O plane's interface: io/conn.h, connections and the awaits (run.c also + * takes io/proactor.h, the worker itself). */ #pragma once #include "ioma.h" -#include "io/proactor.h" +#include "io/conn.h" #include #include diff --git a/src/http/run.c b/src/http/run.c index 869f2ed..39cf8d9 100644 --- a/src/http/run.c +++ b/src/http/run.c @@ -3,6 +3,7 @@ */ #include "http/internal.h" #include "io/pipe.h" +#include "io/proactor.h" #include #include diff --git a/src/io/conn.h b/src/io/conn.h new file mode 100644 index 0000000..c2c2d38 --- /dev/null +++ b/src/io/conn.h @@ -0,0 +1,53 @@ +/* + * conn.h - one connection on its worker: the socket, the queue of buffers the kernel filled for + * it, the state of its multishot recv, and the awaits a coroutine calls on it. Thread-per-core: + * a connection is only ever touched by the worker that accepted it. + */ +#pragma once + +#include +#include +#include + +#include "io/coro.h" + +#ifndef RX_QUEUE +#define RX_QUEUE 64 /* undelivered slices one connection may hold, pow 2 */ +#endif + +typedef struct proactor proactor_t; +typedef struct conn conn_t; + +/* A slice the kernel delivered into a provided buffer, waiting for the handler to read it. */ +struct rx_item { + uint8_t *ptr; + uint32_t len; + uint16_t buf_id; +}; + +enum recv_state { + RECV_ARMED, /* multishot recv in flight; the kernel may post CQEs */ + RECV_STARVED, /* it ended on -ENOBUFS; re-armed once buffers return */ + RECV_DONE, /* it posted its terminal CQE */ +}; + +struct conn { + int fd; /* the socket, or its file slot under fixed files */ + proactor_t *p; + coro_t *waiter; /* coroutine parked in await_recv, or nullptr */ + struct rx_item rx[RX_QUEUE]; /* delivered while nobody was reading */ + unsigned rx_head, rx_tail; + enum recv_state recv; + int refs; /* the handler coroutine + the armed/starved recv */ + bool closed; /* the handler returned; fd closed */ + bool eof; /* recv ended: peer FIN, error, or queue overflow */ + int err; /* 0 on FIN, else the negative errno */ + struct conn *pool_next; /* free-list link while recycled (not in use): a LIFO - a */ + /* returned conn becomes the head and points at the old one */ +}; + +/* Awaits: call from a coroutine on the owning worker. The coroutine parks; the loop resumes it + * when the completion arrives. */ +int await_recv(conn_t *c, void *buf, size_t len); /* >0 bytes, 0 peer closed, <0 -errno */ +int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ +int ioma__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno */ diff --git a/src/io/internal.h b/src/io/internal.h index afbf5c2..5337313 100644 --- a/src/io/internal.h +++ b/src/io/internal.h @@ -56,7 +56,6 @@ typedef struct op { struct io_uring_sqe *ioma__sqe(proactor_t *p); /* claim an SQE; flushes without waiting if the SQ is full */ /* bufring.c */ -int ioma__await_item(conn_t *c, struct rx_item *out); /* conn.c: the next received buffer, whole */ void ioma__return_buf(proactor_t *p, uint16_t buf_id); /* stage a buffer's return; published per batch */ void ioma__bufring_publish(proactor_t *p); /* publish staged returns: one atomic release */ void ioma__bufring_init(proactor_t *p); /* bufring.c: map, register, fill */ diff --git a/src/io/pipe.h b/src/io/pipe.h index 924c574..bce7583 100644 --- a/src/io/pipe.h +++ b/src/io/pipe.h @@ -7,7 +7,7 @@ #pragma once #include "ioma.h" -#include "io/proactor.h" +#include "io/conn.h" /* The reader hands out received bytes as one contiguous span at a time: in place in the kernel's * buffer when they lie within one, gathered into the consumer's buffer when they span, or when diff --git a/src/io/proactor.h b/src/io/proactor.h index e2e05c2..c2dce1c 100644 --- a/src/io/proactor.h +++ b/src/io/proactor.h @@ -1,6 +1,6 @@ /* * proactor.h - one worker: one thread, one io_uring, one SO_REUSEPORT listener, one provided - * buffer ring, and the coroutines that run on it. Thread-per-core, shared-nothing: nothing in + * buffer ring, and the coroutines that run on it. The connections it serves are io/conn.h. Thread-per-core, shared-nothing: nothing in * here is touched by any other thread except the stop flag. * * The loop: run freshly spawned coroutines, re-arm recvs parked on -ENOBUFS, publish and enter @@ -14,6 +14,7 @@ #include #include +#include "io/conn.h" #include "io/coro.h" #include "io/uring.h" @@ -28,9 +29,6 @@ static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COU #ifndef BUF_SIZE #define BUF_SIZE 2048 /* bytes per recv buffer (a request rarely needs more) */ #endif -#ifndef RX_QUEUE -#define RX_QUEUE 64 /* undelivered slices one connection may hold, pow 2 */ -#endif #ifndef STACK_SIZE #define STACK_SIZE (64UL * 1024) /* per coroutine, plus a guard page */ #endif @@ -39,36 +37,8 @@ static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COU #endif typedef struct proactor proactor_t; -typedef struct conn conn_t; typedef void (*handler_fn)(conn_t *c); -/* A slice the kernel delivered into a provided buffer, waiting for the handler to read it. */ -struct rx_item { - uint8_t *ptr; - uint32_t len; - uint16_t buf_id; -}; - -enum recv_state { - RECV_ARMED, /* multishot recv in flight; the kernel may post CQEs */ - RECV_STARVED, /* it ended on -ENOBUFS; re-armed once buffers return */ - RECV_DONE, /* it posted its terminal CQE */ -}; - -struct conn { - int fd; /* the socket, or its file slot under fixed files */ - proactor_t *p; - coro_t *waiter; /* coroutine parked in await_recv, or nullptr */ - struct rx_item rx[RX_QUEUE]; /* delivered while nobody was reading */ - unsigned rx_head, rx_tail; - enum recv_state recv; - int refs; /* the handler coroutine + the armed/starved recv */ - bool closed; /* the handler returned; fd closed */ - bool eof; /* recv ended: peer FIN, error, or queue overflow */ - int err; /* 0 on FIN, else the negative errno */ - struct conn *pool_next; /* free-list link while recycled (not in use) */ -}; - struct proactor { /* set by the creator */ int id; @@ -102,8 +72,3 @@ void proactor_run(proactor_t *p); /* Start a coroutine on this worker. Safe from the loop or from any coroutine on it. */ void proactor_spawn(proactor_t *p, void (*fn)(void *), void *arg); - -/* Awaits: call from a coroutine on the owning worker. The coroutine parks; the loop resumes it - * when the completion arrives. */ -int await_recv(conn_t *c, void *buf, size_t len); /* >0 bytes, 0 peer closed, <0 -errno */ -int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ From a58ba4a5c197d5ccdd8109926adcaf7f1c718145 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:18:32 +0100 Subject: [PATCH 09/49] io/conn.h: no stdbool.h, bool is a keyword here Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/conn.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/io/conn.h b/src/io/conn.h index c2c2d38..af0c11d 100644 --- a/src/io/conn.h +++ b/src/io/conn.h @@ -5,7 +5,6 @@ */ #pragma once -#include #include #include From 9f410d1e7f84cb1d2e0dedfb7c32752bda37c3d2 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:20:45 +0100 Subject: [PATCH 10/49] io/bufring.h: the provided buffer ring as a module Its tunables, BUF_COUNT and BUF_SIZE with the power-of-two assert, its struct - ring, slab, local tail, the dirty and returned flags that used to be loose fields of the proactor - and its operations with the module prefix: init, return, publish, unregister, unmap, and ioma__bufring_at for a buffer's bytes. The proactor embeds one; conn.c, pipe.c and proactor.c address it through it. internal.h keeps only what the plane's files share. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/bufring.c | 66 ++++++++++++++++++++++++----------------------- src/io/bufring.h | 42 ++++++++++++++++++++++++++++++ src/io/conn.c | 12 ++++----- src/io/internal.h | 9 ------- src/io/pipe.c | 12 ++++----- src/io/proactor.c | 12 ++++----- src/io/proactor.h | 14 ++-------- 7 files changed, 96 insertions(+), 71 deletions(-) create mode 100644 src/io/bufring.h diff --git a/src/io/bufring.c b/src/io/bufring.c index 5d6c9f5..57eceda 100644 --- a/src/io/bufring.c +++ b/src/io/bufring.c @@ -1,9 +1,10 @@ /* - * bufring.c - the provided buffer ring: a slab of BUF_COUNT x BUF_SIZE bytes that the kernel - * picks from when a multishot recv delivers data, and how buffers go back to it. + * bufring.c - the provided buffer ring of io/bufring.h. */ -#include "io/internal.h" +#include "io/bufring.h" +#include +#include #include #include @@ -19,68 +20,69 @@ static void *map_pages(size_t bytes) } /* Map the slab and the ring, register the ring as buffer group BGID, and offer every buffer. */ -void ioma__bufring_init(proactor_t *p) +void ioma__bufring_init(struct bufring *b, struct uring *ring, int worker) { - p->buf_ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); - p->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); + b->ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); + b->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); struct io_uring_buf_reg reg; memset(®, 0, sizeof reg); - reg.ring_addr = (uint64_t)(uintptr_t)p->buf_ring; + reg.ring_addr = (uint64_t)(uintptr_t)b->ring; reg.ring_entries = BUF_COUNT; reg.bgid = BGID; - int rc = uring_register(&p->ring, IORING_REGISTER_PBUF_RING, ®, 1); + int rc = uring_register(ring, IORING_REGISTER_PBUF_RING, ®, 1); if (rc < 0) { - fprintf(stderr, "[w%d] register pbuf ring: %s\n", p->id, strerror(-rc)); + fprintf(stderr, "[w%d] register pbuf ring: %s\n", worker, strerror(-rc)); abort(); } /* Fill every slot, then publish the tail once. bufs[0] overlaps the ring header and the tail * sits in bufs[0].resv, so writing only addr/len/bid leaves it untouched. */ for (unsigned i = 0; i < BUF_COUNT; i++) { - struct io_uring_buf *b = &p->buf_ring->bufs[i]; - b->addr = (uint64_t)(uintptr_t)(p->slab + (size_t)i * BUF_SIZE); - b->len = BUF_SIZE; - b->bid = (uint16_t)i; + struct io_uring_buf *slot = &b->ring->bufs[i]; + slot->addr = (uint64_t)(uintptr_t)ioma__bufring_at(b, (uint16_t)i); + slot->len = BUF_SIZE; + slot->bid = (uint16_t)i; } - p->buf_tail = BUF_COUNT; - __atomic_store_n(&p->buf_ring->tail, (uint16_t)p->buf_tail, __ATOMIC_RELEASE); + b->tail = BUF_COUNT; + __atomic_store_n(&b->ring->tail, (uint16_t)b->tail, __ATOMIC_RELEASE); } /* Stage a buffer's return to the ring. The loop publishes the tail once per batch: one atomic * release for many returns, and the kernel is not re-reading a hot tail per request. */ -void ioma__return_buf(proactor_t *p, uint16_t buf_id) +void ioma__bufring_return(struct bufring *b, uint16_t buf_id) { - struct io_uring_buf *b = &p->buf_ring->bufs[p->buf_tail & BUF_MASK]; - b->addr = (uint64_t)(uintptr_t)(p->slab + (size_t)buf_id * BUF_SIZE); - b->len = BUF_SIZE; - b->bid = buf_id; - p->buf_tail++; - p->buffers_returned = true; /* lets the loop re-arm starved recvs */ - p->buf_dirty = true; /* tail needs publishing before the enter */ + struct io_uring_buf *slot = &b->ring->bufs[b->tail & BUF_MASK]; + slot->addr = (uint64_t)(uintptr_t)ioma__bufring_at(b, buf_id); + slot->len = BUF_SIZE; + slot->bid = buf_id; + b->tail++; + b->returned = true; /* lets the loop re-arm starved recvs */ + b->dirty = true; /* tail needs publishing before the enter */ } /* Publish staged returns to the kernel. */ -void ioma__bufring_publish(proactor_t *p) +void ioma__bufring_publish(struct bufring *b) { - if (!p->buf_dirty) + if (!b->dirty) return; - __atomic_store_n(&p->buf_ring->tail, (uint16_t)p->buf_tail, __ATOMIC_RELEASE); - p->buf_dirty = false; + __atomic_store_n(&b->ring->tail, (uint16_t)b->tail, __ATOMIC_RELEASE); + b->dirty = false; } /* Unregister the group. Call before uring_exit. */ -void ioma__bufring_unregister(proactor_t *p) +void ioma__bufring_unregister(struct bufring *b, struct uring *ring) { + (void)b; struct io_uring_buf_reg reg; memset(®, 0, sizeof reg); reg.bgid = BGID; - uring_register(&p->ring, IORING_UNREGISTER_PBUF_RING, ®, 1); + uring_register(ring, IORING_UNREGISTER_PBUF_RING, ®, 1); } /* Unmap the ring and the slab. Call after uring_exit, once no in-flight op can reference them. */ -void ioma__bufring_unmap(proactor_t *p) +void ioma__bufring_unmap(struct bufring *b) { - munmap(p->buf_ring, (size_t)BUF_COUNT * sizeof(struct io_uring_buf)); - munmap(p->slab, (size_t)BUF_COUNT * BUF_SIZE); + munmap(b->ring, (size_t)BUF_COUNT * sizeof(struct io_uring_buf)); + munmap(b->slab, (size_t)BUF_COUNT * BUF_SIZE); } diff --git a/src/io/bufring.h b/src/io/bufring.h new file mode 100644 index 0000000..88031c1 --- /dev/null +++ b/src/io/bufring.h @@ -0,0 +1,42 @@ +/* + * bufring.h - the provided buffer ring: a slab of BUF_COUNT x BUF_SIZE bytes that the kernel + * picks from when a multishot recv delivers data, registered as one buffer group, and how + * buffers go back to it. One per worker, touched only by that worker's thread; returns are + * staged and published to the kernel once per loop iteration. + */ +#pragma once + +#include + +#include "io/uring.h" + +/* tunables (override with -D) */ +#ifndef BUF_COUNT +#define BUF_COUNT 4096 /* provided recv buffers per worker, power of two */ +#endif +static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COUNT <= 65536, "BUF_COUNT: a power of two, at most 65536 (16-bit buffer ids)"); +#ifndef BUF_SIZE +#define BUF_SIZE 2048 /* bytes per recv buffer (a request rarely needs more) */ +#endif +#define BUF_MASK (BUF_COUNT - 1U) +#define BGID 1 /* the one buffer group a worker registers */ + +struct bufring { + struct io_uring_buf_ring *ring; /* kernel-shared ring of buffer descriptors */ + uint8_t *slab; /* BUF_COUNT x BUF_SIZE */ + unsigned tail; /* local tail, published to ring->tail */ + bool dirty; /* staged returns awaiting one publish */ + bool returned; /* any return since the loop's last starved sweep */ +}; + +void ioma__bufring_init (struct bufring *b, struct uring *ring, int worker); /* map, register, offer every buffer */ +void ioma__bufring_return (struct bufring *b, uint16_t buf_id); /* stage a buffer's return */ +void ioma__bufring_publish (struct bufring *b); /* the staged returns, one release */ +void ioma__bufring_unregister(struct bufring *b, struct uring *ring); /* before uring_exit */ +void ioma__bufring_unmap (struct bufring *b); /* after uring_exit */ + +/* Where a buffer's bytes are. */ +static inline uint8_t *ioma__bufring_at(const struct bufring *b, uint16_t buf_id) +{ + return b->slab + (size_t)buf_id * BUF_SIZE; +} diff --git a/src/io/conn.c b/src/io/conn.c index 344d663..e9f668e 100644 --- a/src/io/conn.c +++ b/src/io/conn.c @@ -185,7 +185,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) if (result <= 0) { /* peer FIN (0), an error, or our own cancel */ if (has_buf) - ioma__return_buf(p, buf_id); + ioma__bufring_return(&p->bufs, buf_id); if (!c->eof) { c->eof = true; c->err = result; @@ -197,11 +197,11 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) } if (c->closed) { - ioma__return_buf(p, buf_id); /* the handler is gone; nobody will read it */ + ioma__bufring_return(&p->bufs, buf_id); /* the handler is gone; nobody will read it */ } else if (c->rx_tail - c->rx_head == RX_QUEUE) { /* The handler is not draining. Rather than let one peer hoard the buffer group, end its * input: the next read sees -ENOBUFS. */ - ioma__return_buf(p, buf_id); + ioma__bufring_return(&p->bufs, buf_id); if (!c->eof) { c->eof = true; c->err = -ENOBUFS; @@ -211,7 +211,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) wake_reader(c); } else { struct rx_item *item = &c->rx[c->rx_tail++ & RX_MASK]; - item->ptr = p->slab + (size_t)buf_id * BUF_SIZE; + item->ptr = ioma__bufring_at(&p->bufs, buf_id); item->len = (uint32_t)result; item->buf_id = buf_id; wake_reader(c); @@ -260,7 +260,7 @@ static void conn_close(conn_t *c) c->refs--; /* the recv side's reference; ours, dropped last, keeps c alive */ } while (c->rx_head != c->rx_tail) - ioma__return_buf(p, c->rx[c->rx_head++ & RX_MASK].buf_id); + ioma__bufring_return(&p->bufs, c->rx[c->rx_head++ & RX_MASK].buf_id); close_socket(p, c->fd); conn_unref(c); @@ -307,7 +307,7 @@ int await_recv(conn_t *c, void *buf, size_t len) item->ptr += n; item->len -= (uint32_t)n; if (item->len == 0) { - ioma__return_buf(c->p, item->buf_id); + ioma__bufring_return(&c->p->bufs, item->buf_id); c->rx_head++; } return (int)n; diff --git a/src/io/internal.h b/src/io/internal.h index 5337313..db61575 100644 --- a/src/io/internal.h +++ b/src/io/internal.h @@ -14,9 +14,7 @@ /* ── constants ─────────────────────────────────────────────────────────────────────────── */ -#define BGID 1 /* the one provided-buffer group per worker */ #define RX_MASK (RX_QUEUE - 1U) -#define BUF_MASK (BUF_COUNT - 1U) #ifndef CONN_POOL_MAX #define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker */ @@ -55,13 +53,6 @@ typedef struct op { /* proactor.c */ struct io_uring_sqe *ioma__sqe(proactor_t *p); /* claim an SQE; flushes without waiting if the SQ is full */ -/* bufring.c */ -void ioma__return_buf(proactor_t *p, uint16_t buf_id); /* stage a buffer's return; published per batch */ -void ioma__bufring_publish(proactor_t *p); /* publish staged returns: one atomic release */ -void ioma__bufring_init(proactor_t *p); /* bufring.c: map, register, fill */ -void ioma__bufring_unregister(proactor_t *p); /* bufring.c: before uring_exit */ -void ioma__bufring_unmap(proactor_t *p); /* bufring.c: after uring_exit */ - /* ── connections (conn.c) ──────────────────────────────────────────────────────────────── */ conn_t *ioma__conn_new(proactor_t *p, int fd); diff --git a/src/io/pipe.c b/src/io/pipe.c index bd1d7ba..e14b67e 100644 --- a/src/io/pipe.c +++ b/src/io/pipe.c @@ -33,7 +33,7 @@ static void cur_done(ioma_pipereader *pr) if (!pr->has_cur || pr->cur_pos < pr->cur.len || (pr->run_in_cur && pr->run_len)) return; if (!pr->cur_is_pinned) - ioma__return_buf(pr->conn->p, pr->cur.buf_id); + ioma__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); pr->has_cur = false; pr->cur_is_pinned = false; pr->cur_pos = 0; @@ -77,7 +77,7 @@ static bool gather(ioma_pipereader *pr) /* A buffer that cannot be used: back to the ring, and the reader is done. */ static int refuse(ioma_pipereader *pr, const struct rx_item *item) { - ioma__return_buf(pr->conn->p, item->buf_id); + ioma__bufring_return(&pr->conn->p->bufs, item->buf_id); pr->error = IOMA_PIPE_FULL; return IOMA_PIPE_FULL; } @@ -111,7 +111,7 @@ static int more(ioma_pipereader *pr) } memcpy(pr->buf + pr->buf_end, item.ptr, item.len); pr->buf_end += item.len; - ioma__return_buf(pr->conn->p, item.buf_id); + ioma__bufring_return(&pr->conn->p->bufs, item.buf_id); return 1; } @@ -238,7 +238,7 @@ void ioma_pipereader_release(ioma_pipereader *pr) if (pr->cur_is_pinned) pr->cur_is_pinned = false; /* it lives on as the current buffer */ else - ioma__return_buf(pr->conn->p, pr->pinned.buf_id); + ioma__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); pr->has_pinned = false; } cur_done(pr); @@ -247,9 +247,9 @@ void ioma_pipereader_release(ioma_pipereader *pr) void ioma_pipereader_close(ioma_pipereader *pr) { if (pr->has_cur && !pr->cur_is_pinned) - ioma__return_buf(pr->conn->p, pr->cur.buf_id); + ioma__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); if (pr->has_pinned) - ioma__return_buf(pr->conn->p, pr->pinned.buf_id); + ioma__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); pr->has_cur = pr->has_pinned = pr->cur_is_pinned = false; } diff --git a/src/io/proactor.c b/src/io/proactor.c index 471ed22..04319cc 100644 --- a/src/io/proactor.c +++ b/src/io/proactor.c @@ -118,9 +118,9 @@ static void run_ready(proactor_t *p) * connection never spins the loop. */ static void rearm_starved(proactor_t *p) { - if (p->nstarved == 0 || !p->buffers_returned) + if (p->nstarved == 0 || !p->bufs.returned) return; - p->buffers_returned = false; + p->bufs.returned = false; for (unsigned i = 0; i < p->nstarved; i++) ioma__arm_recv(p, p->starved[i]); /* keeps the ref it already holds */ p->nstarved = 0; @@ -218,7 +218,7 @@ void proactor_run(proactor_t *p) unsigned slots = fixed_slots(); /* optional: sockets live in a file table */ if (slots) uring_register_files_sparse(&p->ring, slots); - ioma__bufring_init(p); + ioma__bufring_init(&p->bufs, &p->ring, p->id); p->listen_fd = listener_open(p->port); arm_accept(p); fprintf(stderr, "[w%d] listening on 0.0.0.0:%u (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", @@ -231,7 +231,7 @@ void proactor_run(proactor_t *p) while (!*p->stop) { run_ready(p); rearm_starved(p); - ioma__bufring_publish(p); + ioma__bufring_publish(&p->bufs); rc = uring_submit_wait(&p->ring, 1, &wait_at_most); /* one syscall per batch */ if (rc < 0 && rc != -ETIME && rc != -EINTR && rc != -EAGAIN && rc != -EBUSY) { @@ -251,9 +251,9 @@ void proactor_run(proactor_t *p) /* Sockets, then the ring (which cancels every in-flight op and drops its buffer references), * then the memory the kernel could still have referenced. */ close(p->listen_fd); - ioma__bufring_unregister(p); + ioma__bufring_unregister(&p->bufs, &p->ring); uring_exit(&p->ring); - ioma__bufring_unmap(p); + ioma__bufring_unmap(&p->bufs); free(p->starved); ioma__conn_pool_drain(p); coro_pool_drain(); diff --git a/src/io/proactor.h b/src/io/proactor.h index c2dce1c..a4c00e5 100644 --- a/src/io/proactor.h +++ b/src/io/proactor.h @@ -14,6 +14,7 @@ #include #include +#include "io/bufring.h" #include "io/conn.h" #include "io/coro.h" #include "io/uring.h" @@ -22,13 +23,6 @@ #ifndef RING_ENTRIES #define RING_ENTRIES 4096 /* SQ depth; the CQ is twice that */ #endif -#ifndef BUF_COUNT -#define BUF_COUNT 4096 /* provided recv buffers per worker, power of two */ -#endif -static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COUNT <= 65536, "BUF_COUNT: a power of two, at most 65536 (16-bit buffer ids)"); -#ifndef BUF_SIZE -#define BUF_SIZE 2048 /* bytes per recv buffer (a request rarely needs more) */ -#endif #ifndef STACK_SIZE #define STACK_SIZE (64UL * 1024) /* per coroutine, plus a guard page */ #endif @@ -50,11 +44,7 @@ struct proactor { /* owned by the worker thread */ struct uring ring; int listen_fd; - struct io_uring_buf_ring *buf_ring; /* kernel-shared ring of buffer descriptors */ - uint8_t *slab; /* BUF_COUNT x BUF_SIZE */ - unsigned buf_tail; /* local tail, published to buf_ring->tail */ - bool buffers_returned; /* since the last starved sweep */ - bool buf_dirty; /* staged buffer returns awaiting one publish */ + struct bufring bufs; /* the provided buffers recvs deliver into */ conn_t **starved; /* connections parked on -ENOBUFS */ unsigned nstarved, cap_starved; uint64_t starved_total; /* recvs that found the ring empty, ever */ From d038d243725b1665ffecdd54c24264b328e0ff71 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:20:55 +0100 Subject: [PATCH 11/49] conn.c: comment names the ring's return Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/conn.c b/src/io/conn.c index e9f668e..bf755db 100644 --- a/src/io/conn.c +++ b/src/io/conn.c @@ -278,7 +278,7 @@ void ioma__conn_main(void *arg) /* Copy the next delivered slice into buf, parking while the queue is empty. Returns the byte * count, 0 when the peer closed, or -errno. A fully consumed buffer goes back to the ring. */ -/* The next received buffer, whole: the caller owns it until ioma__return_buf. Suspends until one +/* The next received buffer, whole: the caller owns it until ioma__bufring_return. Suspends until one * arrives; 1 with the item, 0 at the end of input, <0 an error. */ int ioma__await_item(conn_t *c, struct rx_item *out) { From b9d29b3a302ba82bbd4f184bf32f9e1e580b1cc6 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:22:39 +0100 Subject: [PATCH 12/49] io/internal.h down to the completion protocol; the rest to its module's header RX_MASK and CONN_POOL_MAX join RX_QUEUE in conn.h, with conn.c's loop-facing exports (conn_new, conn_main, arm_recv, on_recv, pool_drain) in a section of their own, the way bufring.h declares its loop-facing init and publish. ioma__sqe, the worker's SQE claim, is in proactor.h. What is left in internal.h is what the loop and the operations share and neither owns: the user_data tags, UD, op_t, and the trace switch. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/conn.h | 14 +++++++++++++- src/io/internal.h | 38 ++++++++------------------------------ src/io/pipe.c | 2 +- src/io/proactor.h | 4 ++++ 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/io/conn.h b/src/io/conn.h index af0c11d..bcb872c 100644 --- a/src/io/conn.h +++ b/src/io/conn.h @@ -10,8 +10,13 @@ #include "io/coro.h" +/* tunables (override with -D) */ #ifndef RX_QUEUE -#define RX_QUEUE 64 /* undelivered slices one connection may hold, pow 2 */ +#define RX_QUEUE 64 /* undelivered slices one connection may hold, pow 2 */ +#endif +#define RX_MASK (RX_QUEUE - 1U) +#ifndef CONN_POOL_MAX +#define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker */ #endif typedef struct proactor proactor_t; @@ -50,3 +55,10 @@ struct conn { int await_recv(conn_t *c, void *buf, size_t len); /* >0 bytes, 0 peer closed, <0 -errno */ int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ int ioma__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno */ + +/* For the loop (proactor.c): a connection's life from accept to the pool. */ +conn_t *ioma__conn_new(proactor_t *p, int fd); /* from the pool, or fresh */ +void ioma__conn_main(void *arg); /* the connection's coroutine body */ +void ioma__arm_recv(proactor_t *p, conn_t *c); /* one multishot recv */ +void ioma__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); /* a recv CQE */ +void ioma__conn_pool_drain(proactor_t *p); /* free the pool at teardown */ diff --git a/src/io/internal.h b/src/io/internal.h index db61575..d94475b 100644 --- a/src/io/internal.h +++ b/src/io/internal.h @@ -1,8 +1,7 @@ /* - * io/internal.h - what the I/O plane's files share with each other. Private; not installed. - * - * Exported internals carry an ioma__ prefix so they cannot collide with a user's symbols. Only - * declarations, types and macros live here; LTO inlines the small hot ones across files. + * io/internal.h - the contract between the loop (proactor.c) and the operations (conn.c): how + * a completion finds what it belongs to, and the trace switch. Private; not installed. Each + * module's own declarations are in its header (uring.h, coro.h, bufring.h, conn.h, proactor.h). */ #pragma once @@ -10,15 +9,6 @@ #include #include -#include - -/* ── constants ─────────────────────────────────────────────────────────────────────────── */ - -#define RX_MASK (RX_QUEUE - 1U) - -#ifndef CONN_POOL_MAX -#define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker */ -#endif /* -DTRACE: one line per completion and lifetime event, for chasing a misbehaving path. */ #ifdef TRACE @@ -31,10 +21,11 @@ /* user_data is a pointer with a tag in its low three bits; everything pointed at is 8-aligned. */ enum { - TAG_OP = 0, - TAG_RECV = 1, - TAG_ACCEPT = 2, - TAG_IGNORE = 3, }; + TAG_OP = 0, /* an op_t: a one-shot await */ + TAG_RECV = 1, /* a conn_t: its multishot recv */ + TAG_ACCEPT = 2, /* the listener's multishot accept */ + TAG_IGNORE = 3, /* a completion nobody waits for */ +}; #define UD(ptr, tag) ((uint64_t)(uintptr_t)(ptr) | (uint64_t)(tag)) #define UD_PTR(ud) ((void *)(uintptr_t)((ud) & ~(uint64_t)7)) @@ -47,16 +38,3 @@ typedef struct op { int res; unsigned flags; } op_t; - -/* ── shared between the plane's files ──────────────────────────────────────────────────── */ - -/* proactor.c */ -struct io_uring_sqe *ioma__sqe(proactor_t *p); /* claim an SQE; flushes without waiting if the SQ is full */ - -/* ── connections (conn.c) ──────────────────────────────────────────────────────────────── */ - -conn_t *ioma__conn_new(proactor_t *p, int fd); -void ioma__conn_main(void *arg); /* the connection's coroutine body */ -void ioma__arm_recv(proactor_t *p, conn_t *c); -void ioma__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); -void ioma__conn_pool_drain(proactor_t *p); diff --git a/src/io/pipe.c b/src/io/pipe.c index e14b67e..8a8e74d 100644 --- a/src/io/pipe.c +++ b/src/io/pipe.c @@ -2,7 +2,7 @@ * io/pipe.c - the reader and the writer of io/pipe.h, and the public pipe on top of them. */ #include "io/pipe.h" -#include "io/internal.h" +#include "io/proactor.h" #include diff --git a/src/io/proactor.h b/src/io/proactor.h index a4c00e5..64d2e6d 100644 --- a/src/io/proactor.h +++ b/src/io/proactor.h @@ -62,3 +62,7 @@ void proactor_run(proactor_t *p); /* Start a coroutine on this worker. Safe from the loop or from any coroutine on it. */ void proactor_spawn(proactor_t *p, void (*fn)(void *), void *arg); + +/* Claim an SQE to stage an operation; flushes without waiting when the SQ is full. For the + * plane's own files: every op goes through here so it rides the loop's next enter. */ +struct io_uring_sqe *ioma__sqe(proactor_t *p); From 70042ffd0cfed7cdef95e16eb986b2d7ec34f5b8 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:23:08 +0100 Subject: [PATCH 13/49] io: stdlib.h where it is used, not through internal.h Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/io/conn.c | 1 + src/io/proactor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/io/conn.c b/src/io/conn.c index bf755db..79b66cc 100644 --- a/src/io/conn.c +++ b/src/io/conn.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff --git a/src/io/proactor.c b/src/io/proactor.c index 04319cc..be14a57 100644 --- a/src/io/proactor.c +++ b/src/io/proactor.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include From aba7f63bd4912ff8726a33d7b57ecb6d354b9de5 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 20:30:14 +0100 Subject: [PATCH 14/49] http: engine.h and router.h; internal.h keeps the one shared helper A header per module that exports something, as in the I/O plane: engine.h declares ioma__serve for the runner, router.h declares ioma__router_build and ioma__dispatch for the runner and the engine. internal.h is down to ioma__hexval, shared by the percent decoder and the chunk-size parser. api.c and run.c export nothing private and get no header. Each file includes the standard headers it uses. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- src/http/api.c | 1 + src/http/engine.c | 4 ++++ src/http/engine.h | 8 ++++++++ src/http/internal.h | 18 +++--------------- src/http/router.c | 4 +++- src/http/router.h | 10 ++++++++++ src/http/run.c | 5 ++++- 7 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 src/http/engine.h create mode 100644 src/http/router.h diff --git a/src/http/api.c b/src/http/api.c index e89fd41..b006585 100644 --- a/src/http/api.c +++ b/src/http/api.c @@ -4,6 +4,7 @@ * Nothing here touches the runtime. */ #include "http/internal.h" +#include "ioma.h" #include #include diff --git a/src/http/engine.c b/src/http/engine.c index 4ab4ab3..b704135 100644 --- a/src/http/engine.c +++ b/src/http/engine.c @@ -5,13 +5,17 @@ * drain what was left, then send what was written. All of it runs on the connection's coroutine, * so await_recv and await_send simply suspend it and the loop resumes it. */ +#include "http/engine.h" #include "http/internal.h" +#include "http/router.h" #include "io/pipe.h" #include "picohttpparser.h" #include #include #include +#include +#include #include #ifndef IOMA_REQ_CAP diff --git a/src/http/engine.h b/src/http/engine.h new file mode 100644 index 0000000..63b1d7b --- /dev/null +++ b/src/http/engine.h @@ -0,0 +1,8 @@ +/* + * http/engine.h - the HTTP/1.1 engine's one entry for the runner: the per-connection loop. + */ +#pragma once + +#include "io/conn.h" + +void ioma__serve(conn_t *conn); /* requests on the connection until it ends */ diff --git a/src/http/internal.h b/src/http/internal.h index 79fd19e..60210be 100644 --- a/src/http/internal.h +++ b/src/http/internal.h @@ -1,22 +1,10 @@ /* - * http/internal.h - what the HTTP plane's files share with each other. Private; not installed. - * The plane sits on the I/O plane's interface: io/conn.h, connections and the awaits (run.c also - * takes io/proactor.h, the worker itself). + * http/internal.h - the helpers the HTTP plane's files share and no module owns. Private; not + * installed. Each module's own entries are in its header (engine.h, router.h). */ #pragma once -#include "ioma.h" -#include "io/conn.h" - -#include -#include -#include - -void ioma__serve(conn_t *conn); /* engine.c: the per-connection HTTP loop */ -void ioma__dispatch(ioma_ctx *ctx); /* router.c: middleware chain + endpoint */ -void ioma__router_build(void); /* router.c: resolve the routes, once */ - -/* The value of a hex digit, or -1. */ +/* The value of a hex digit, or -1. Percent-decoding (api.c) and chunk sizes (engine.c). */ static inline int ioma__hexval(unsigned char c) { if (c >= '0' && c <= '9') diff --git a/src/http/router.c b/src/http/router.c index f6739b1..2ff6813 100644 --- a/src/http/router.c +++ b/src/http/router.c @@ -4,8 +4,10 @@ * and every worker shares it without a lock. A request costs one walk down the tree and one call * through its endpoint's flat middleware chain. */ -#include "http/internal.h" +#include "http/router.h" +#include +#include #include diff --git a/src/http/router.h b/src/http/router.h new file mode 100644 index 0000000..72adc26 --- /dev/null +++ b/src/http/router.h @@ -0,0 +1,10 @@ +/* + * http/router.h - the router's entries for the runner and the engine: resolve everything + * registered once, before the workers start; then dispatch each request through the result. + */ +#pragma once + +#include "ioma.h" + +void ioma__router_build(void); /* the segment tree and the flat chains, once */ +void ioma__dispatch(ioma_ctx *ctx); /* the request's endpoint, behind its chain */ diff --git a/src/http/run.c b/src/http/run.c index 39cf8d9..11fe0aa 100644 --- a/src/http/run.c +++ b/src/http/run.c @@ -1,13 +1,16 @@ /* * run.c - ioma_run: one proactor thread per core serving HTTP, until SIGINT/SIGTERM. */ -#include "http/internal.h" +#include "http/engine.h" +#include "http/router.h" #include "io/pipe.h" #include "io/proactor.h" #include #include #include +#include +#include #include #include #include From 67382d7dfeac71b377e644ca89b3c6a00cb06f7b Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 21:42:20 +0100 Subject: [PATCH 15/49] Pipes only: the reply on the pipewriter, the pipe built by the connection, await_recv gone The pipewriter has a head and a tail now: front(n) reserves bytes just before the pending data, back(n) just after it, and one flush sends the span. The HTTP reply's lead and slack are the writer's - the head and a chunk's size line go in front, a chunk's CRLF behind - and the chunked terminator rides the final send instead of a send of its own. The engine no longer owns a slab or calls await_send; ioma_response loses buf/cap/len, and ioma_reserve / ioma_advance on the context are the way to format straight into the reply. The connection's coroutine builds the pipe, so every handler receives one: ioma__serve takes a pipe, ioma_run_pipes passes the user's function through, and run.c's wrapper is gone. await_recv had no callers left and is deleted; the reader's primitive, ioma__await_item, is the one way bytes leave the queue. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 19 ++-- PERF.md | 2 +- include/ioma.h | 7 +- src/http/engine.c | 236 +++++++++++++++++++++++++--------------------- src/http/engine.h | 4 +- src/http/run.c | 25 +---- src/io/conn.c | 41 +++----- src/io/conn.h | 5 +- src/io/pipe.c | 69 ++++++++++---- src/io/pipe.h | 59 +++++++++--- src/io/proactor.h | 3 +- 11 files changed, 256 insertions(+), 214 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 77d9c3d..f9f726a 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -76,8 +76,8 @@ A **stackful coroutine** is a function running on its own stack that can pause i variables intact. That is what lets a handler be written as plain sequential code: ```c -n = await_recv(c, buf, sizeof buf); /* pauses here until data arrives */ -await_send(c, reply, len); /* pauses here until the send completes */ +ioma_pipe_read(pipe, &live); /* pauses here until data arrives */ +ioma_pipe_send(pipe, reply, len); /* pauses here until the send completes */ ``` ### The switch @@ -144,17 +144,18 @@ address stays valid for exactly as long as the operation is in flight. Accept → take a `conn_t` from the pool → arm its multishot recv → spawn its handler coroutine. The connection has **two owners**, the handler coroutine and the armed recv, so `refs` starts at 2. -Data CQEs are queued on the connection (`rx`, a small ring of slices) and wake the handler if it is -parked in `await_recv`. When the handler returns, `conn_close` cancels the recv, returns any unread +Data CQEs are queued on the connection (`rx`, a small ring of filled buffers) and wake the handler +if it is parked in the pipe's reader. When the handler returns, `conn_close` cancels the recv, returns any unread buffers, closes the fd and drops its ref. The recv's ref drops when its terminal CQE arrives (`-ECANCELED`, or the peer's FIN). At zero refs the `conn_t` goes back to the pool. A connection is therefore never recycled while a completion for it is still coming. ### The two awaits -`await_recv` copies the next queued slice into the caller's buffer, returns the provided buffer to -the ring when the slice is fully consumed, and parks if the queue is empty. `await_send` stages a -SEND SQE (`MSG_WAITALL`, so the kernel finishes short sends itself) and parks until its CQE. +`ioma__await_item` hands the next queued buffer over whole - the pipe's reader owns it from then +until it returns it to the ring - and parks if the queue is empty. `await_send` stages a SEND SQE +(`MSG_WAITALL`, so the kernel finishes short sends itself) and parks until its CQE; the pipe's +writer is the only caller. Nothing above the pipe touches either. ### Shared nothing @@ -209,8 +210,8 @@ raw pipe writes straight. 3. **Keep-alive**: HTTP/1.1 unless `Connection: close`; HTTP/1.0 only with `Connection: keep-alive`. 4. **Dispatch** a context to the middleware chain and the route (section 5). The context holds the request and the response; the response holds the reply being shaped (status, content - type, headers) and the write slab: an 8 KB buffer with room reserved in front of it for the - head. + type, headers); the bytes go into the pipe's writer, an 8 KB slab with a lead in front of it + for the head and a chunk's size line, and slack behind it for a chunk's CRLF. 5. **Write**: the handler calls `ioma_write` / `ioma_printf`; bytes land in the buffer. If it fills, the framework sends what it has — head first, framed chunked on HTTP/1.1 or until close on HTTP/1.0 (or with a length the handler declared) — and the handler suspends on that send. diff --git a/PERF.md b/PERF.md index e930506..0e2e189 100644 --- a/PERF.md +++ b/PERF.md @@ -29,6 +29,7 @@ profiles score. | Registered file table: direct accept into slots, recv/send/close by index | keep-alive not measurable; churn +3%; connections no longer consume process fds | | PGO (`-fprofile-generate`, train, `-fprofile-use`) on top of LTO | +1.5–2% | | Request model: the query split into `params` eagerly, header names lower-cased at parse (8 bytes a step) so handlers compare with plain `ioma_slice_eq` | about −1% each; the price of direct data access | +| Parse straight from the provided buffer when a whole request sits in one (the pipe's reader keeps it in place; the copy happens only for a request that spans receives) | neutral, as predicted: the copy it removes was under 1% | | gcc 14 and C23 (was gcc 13 and gnu11) | neutral: 1.23M vs 1.22M req/s keep-alive and equal churn, wrk and oha, three interleaved rounds on 4 reactors. The standard changes what the compiler accepts, not the code it emits | The `-D` switches: `FIXED_FILES=0` disables the file table, `NO_REG_RING` the registered ring fd, @@ -78,6 +79,5 @@ utilisation, so a 2% cut in CPU per request buys far more than 2% in latency. ## Still open -- **Parse straight from the provided buffer** when a whole request sits in one, skipping the copy in `await_recv`. Small. - **Connection steering** (`SO_INCOMING_CPU`, reuseport BPF) so a connection is served by the worker on its NIC queue's CPU. Real on a NIC, irrelevant on the loopback the benchmark uses. - **Profiling on the benchmark host itself** with `perf`, to see the split of that 15 µs. This is the one thing that could reveal something not visible from the i9. diff --git a/include/ioma.h b/include/ioma.h index 22d2e25..e4ce914 100644 --- a/include/ioma.h +++ b/include/ioma.h @@ -86,9 +86,6 @@ typedef struct ioma_response { size_t content_length; /* declared with ioma_content_length */ bool has_length; - char *buf; /* the write slab */ - size_t cap, len; - bool chunked, failed; /* private: how a stream is framed; peer gone */ } ioma_response; @@ -135,6 +132,10 @@ int ioma_body_read_next_chunk(ioma_ctx *ctx, void *dst, size_t cap); * then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. * Return 0, or -1 once the peer is gone (further writes are ignored). */ int ioma_write (ioma_ctx *ctx, const void *data, size_t len); +/* Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr + * once the peer is gone or n exceeds the slab) and advance by what was written. */ +void *ioma_reserve(ioma_ctx *ctx, size_t n); +void ioma_advance(ioma_ctx *ctx, size_t n); int ioma_text (ioma_ctx *ctx, const char *s); /* a C string */ int ioma_printf(ioma_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ diff --git a/src/http/engine.c b/src/http/engine.c index b704135..3abb2d6 100644 --- a/src/http/engine.c +++ b/src/http/engine.c @@ -1,9 +1,9 @@ /* * engine.c - the HTTP/1.1 engine: parse a request head with picohttpparser, run the middleware * chain and the endpoint against a context, read the body on demand (whole or streamed) through - * the connection's reader (io/pipe.h) and - * drain what was left, then send what was written. All of it runs on the connection's coroutine, - * so await_recv and await_send simply suspend it and the loop resumes it. + * the connection's pipe (io/pipe.h) and drain + * what was left, then send what was written through the same pipe. All of it runs on the + * connection's coroutine, so a read or a flush simply suspends it and the loop resumes it. */ #include "http/engine.h" #include "http/internal.h" @@ -18,22 +18,15 @@ #include #include -#ifndef IOMA_REQ_CAP -#define IOMA_REQ_CAP 16384 /* the head, and a body read whole, must fit here */ -#endif #ifndef IOMA_PARAM_CAP #define IOMA_PARAM_CAP 2048 /* per-request arena for percent-decoded query parameters */ #endif #ifndef IOMA_HEAD_CAP #define IOMA_HEAD_CAP 4096 /* a serialized reply head must fit here */ #endif -#ifndef IOMA_OUT_CAP -#define IOMA_OUT_CAP 8192 /* the write slab: body bytes buffered before a reply streams */ -#endif #ifndef IOMA_DRAIN_MAX #define IOMA_DRAIN_MAX (1024UL * 1024) /* unread body discarded after a handler before we close instead */ #endif -#define IOMA_LEAD 512 /* room in front of the slab for the reply head or a chunk size */ /* serve() hands req.headers to picohttpparser as its header array: a kv (two slices) must lay * out exactly like a phr_header (name, name_len, value, value_len). */ @@ -45,14 +38,16 @@ static_assert(offsetof(ioma_kv, key) == offsetof(struct phr_header, name) && /* The engine's per-request state, behind ctx->priv. */ struct serve_state { - ioma_pipereader *reader; /* the connection's bytes; the head is kept in it */ + struct ioma_pipe *pipe; /* the connection: the head is kept in its reader */ size_t body_read; /* body bytes handed out so far */ bool body_done; /* the whole body has been taken off the wire */ bool body_whole; /* ioma_body_all kept it */ int body_err; /* 0, a status to answer (400, 413), or -1: peer gone */ size_t chunk_left; /* data bytes of the current chunk still to deliver */ }; -#define STATE(ctx) ((struct serve_state *)(ctx)->priv) +#define STATE(ctx) ((struct serve_state *)(ctx)->priv) +#define READER(ctx) (&STATE(ctx)->pipe->in) +#define WRITER(ctx) (&STATE(ctx)->pipe->out) /* ── request headers ───────────────────────────────────────────────────────────────────── */ @@ -213,12 +208,13 @@ static struct cslice status_line(int code) /* A bodyless framework reply (parse errors, limits): an error path, so plain snprintf. Best * effort; the caller then closes. */ -static void send_status(conn_t *conn, int code) +static void send_status(ioma_pipewriter *pw, int code) { char head[128]; int len = snprintf(head, sizeof head, "HTTP/1.1 %d %s\r\ncontent-length: 0\r\nconnection: close\r\n\r\n", code, ioma_reason(code)); - await_send(conn, head, (size_t)len); + ioma_pipewriter_reset(pw); /* whatever the handler had buffered is moot */ + ioma_pipewriter_send(pw, head, (size_t)len); } /* How the body is delimited on the wire. */ @@ -292,20 +288,14 @@ static int build_head(const ioma_ctx *ctx, char *dst, size_t cap, enum framing f return (int)(p - dst); } -/* Wrap the slab's bytes as one chunk: the size line goes just before them (into the lead), the - * CRLF just after (into the slack). start/total describe the framed span. */ -static void frame_chunk(char *body, size_t len, char **start, size_t *total) +/* The chunked terminator: the empty last chunk and the end of the trailers. */ +static void put_terminator(char *at) { - char size_line[16]; - int digits = put_hex(size_line, len); - char *at = body - (digits + 2); - memcpy(at, size_line, (size_t)digits); - at[digits] = '\r'; - at[digits + 1] = '\n'; - body[len] = '\r'; - body[len + 1] = '\n'; - *start = at; - *total = len + (size_t)digits + 4; + at[0] = '0'; + at[1] = '\r'; + at[2] = '\n'; + at[3] = '\r'; + at[4] = '\n'; } /* Mark the reply dead (the peer is gone, or a head that cannot be built) and fail the call. */ @@ -321,16 +311,15 @@ static int fail(ioma_response *res) * if the handler gave one, else chunked on HTTP/1.1, else until close on HTTP/1.0. */ static int flush(ioma_ctx *ctx, bool final) { - ioma_response *res = &ctx->res; - conn_t *conn = STATE(ctx)->reader->conn; + ioma_response *res = &ctx->res; + ioma_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; - char head[IOMA_HEAD_CAP]; int head_len = 0; if (!res->head_sent) { /* the first send: decide the framing */ enum framing framing = FRAME_LENGTH; - size_t body_len = res->has_length ? res->content_length : res->len; + size_t body_len = res->has_length ? res->content_length : pw->len; if (!res->has_length && !final) { if (ctx->req.minor_version >= 1) { framing = FRAME_CHUNKED; @@ -345,25 +334,33 @@ static int flush(ioma_ctx *ctx, bool final) return fail(res); res->head_sent = true; } - - char *start = res->buf; /* the span to send */ - size_t total = res->len; - if (res->chunked && res->len) - frame_chunk(res->buf, res->len, &start, &total); - + if (res->chunked && pw->len) { /* the slab's bytes as one chunk: size in front, CRLF behind */ + char size_line[16]; + int digits = put_hex(size_line, pw->len); + char *front = ioma_pipewriter_front(pw, (size_t)digits + 2); + char *back = ioma_pipewriter_back(pw, 2); + if (!front || !back) + return fail(res); + memcpy(front, size_line, (size_t)digits); + front[digits] = '\r'; + front[digits + 1] = '\n'; + back[0] = '\r'; + back[1] = '\n'; + } + if (final && res->chunked) { /* the terminator rides the same send */ + char *back = ioma_pipewriter_back(pw, 5); + if (!back) + return fail(res); + put_terminator(back); + } if (head_len) { - size_t lead_room = (size_t)(start - (res->buf - IOMA_LEAD)); /* free bytes in front of the span */ - if ((size_t)head_len <= lead_room) { /* prepend: one contiguous send */ - start -= head_len; - memcpy(start, head, (size_t)head_len); - total += (size_t)head_len; - } else if (await_send(conn, head, (size_t)head_len) < 0) { + char *front = ioma_pipewriter_front(pw, (size_t)head_len); + if (front) + memcpy(front, head, (size_t)head_len); /* one contiguous send */ + else if (ioma_pipewriter_through(pw, head, (size_t)head_len) < 0) /* bigger than the lead: on its own, first */ return fail(res); - } } - - res->len = 0; - if (total && await_send(conn, start, total) < 0) + if (ioma_pipewriter_flush(pw) < 0) return fail(res); return 0; } @@ -372,34 +369,41 @@ static int flush(ioma_ctx *ctx, bool final) * chunked stream. */ static int finish(ioma_ctx *ctx) { - ioma_response *res = &ctx->res; + ioma_response *res = &ctx->res; + ioma_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; - bool pending = !res->head_sent || res->len; /* nothing sent yet, or bytes still in the slab */ - if (pending && flush(ctx, true) < 0) - return -1; - if (res->chunked && await_send(STATE(ctx)->reader->conn, "0\r\n\r\n", 5) < 0) - return -1; + if (!res->head_sent || pw->len) /* nothing sent yet, or bytes still in the slab */ + return flush(ctx, true); + if (res->chunked) { /* streamed and drained: just the terminator */ + char *back = ioma_pipewriter_back(pw, 5); + if (!back) + return fail(res); + put_terminator(back); + if (ioma_pipewriter_flush(pw) < 0) + return fail(res); + } return 0; } /* Append body bytes to the slab; send it, head first, whenever it fills. */ int ioma_write(ioma_ctx *ctx, const void *data, size_t len) { - ioma_response *res = &ctx->res; + ioma_response *res = &ctx->res; + ioma_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; const char *src = data; while (len) { - size_t room = res->cap - res->len; + size_t room = ioma_pipewriter_room(pw); if (room == 0) { if (flush(ctx, false) < 0) return -1; continue; } size_t n = len < room ? len : room; - memcpy(res->buf + res->len, src, n); - res->len += n; + memcpy(ioma_pipewriter_at(pw), src, n); + ioma_pipewriter_advance(pw, n); src += n; len -= n; } @@ -422,26 +426,27 @@ static int write_formatted_heap(ioma_ctx *ctx, const char *fmt, va_list ap, size * the empty slab; if it would not fit even that, it goes through the heap. */ int ioma_printf(ioma_ctx *ctx, const char *fmt, ...) { - ioma_response *res = &ctx->res; + ioma_response *res = &ctx->res; + ioma_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; va_list ap, again; va_start(ap, fmt); va_copy(again, ap); - size_t room = res->cap - res->len; - int n = vsnprintf(res->buf + res->len, room, fmt, ap); + size_t room = ioma_pipewriter_room(pw); + int n = vsnprintf(ioma_pipewriter_at(pw), room, fmt, ap); va_end(ap); int rc = -1; if (n < 0) { /* a formatting error: nothing written */ } else if ((size_t)n < room) { /* it fit */ - res->len += (size_t)n; + ioma_pipewriter_advance(pw, (size_t)n); rc = 0; - } else if ((size_t)n >= res->cap) { /* bigger than the slab itself */ + } else if ((size_t)n >= pw->cap) { /* bigger than the slab itself */ rc = write_formatted_heap(ctx, fmt, again, (size_t)n); - } else if (flush(ctx, false) == 0) { /* make room, then it fits */ - res->len += (size_t)vsnprintf(res->buf, res->cap, fmt, again); + } else if (flush(ctx, false) == 0) { /* make room, then it fits */ + ioma_pipewriter_advance(pw, (size_t)vsnprintf(ioma_pipewriter_at(pw), pw->cap, fmt, again)); rc = 0; } va_end(again); @@ -454,6 +459,24 @@ int ioma_flush(ioma_ctx *ctx) return flush(ctx, false); } +/* n bytes of the reply to write into directly, flushing first when they do not fit. */ +void *ioma_reserve(ioma_ctx *ctx, size_t n) +{ + ioma_response *res = &ctx->res; + ioma_pipewriter *pw = WRITER(ctx); + if (res->failed || n > pw->cap) + return nullptr; + if (n > ioma_pipewriter_room(pw) && flush(ctx, false) < 0) + return nullptr; + return ioma_pipewriter_at(pw); +} + +/* The caller wrote n of the reserved bytes. */ +void ioma_advance(ioma_ctx *ctx, size_t n) +{ + ioma_pipewriter_advance(WRITER(ctx), n); +} + /* ── the body: read on demand ──────────────────────────────────────────────────────────── */ /* A body failure with a status: the engine answers with it after the handler unless a reply is @@ -468,7 +491,7 @@ static void body_fail(ioma_ctx *ctx, int status) * 413, the peer gone or the input ending inside the body is -1. */ static bool body_bytes(ioma_ctx *ctx, ioma_slice *live) { - int rc = ioma_pipereader_read(STATE(ctx)->reader, live); + int rc = ioma_pipereader_read(READER(ctx), live); if (rc > 0) return true; if (rc == IOMA_PIPE_FULL) @@ -489,7 +512,7 @@ static long body_line(ioma_ctx *ctx, ioma_slice *live) const char *eol = memmem(live->p, live->len, "\r\n", 2); if (eol) return eol - live->p; - ioma_pipereader_examine(STATE(ctx)->reader, live->len); + ioma_pipereader_examine(READER(ctx), live->len); } } @@ -501,7 +524,7 @@ static bool chunk_trailers(ioma_ctx *ctx) long len = body_line(ctx, &live); if (len < 0) return false; - ioma_pipereader_drop(STATE(ctx)->reader, (size_t)len + 2); + ioma_pipereader_drop(READER(ctx), (size_t)len + 2); if (len == 0) break; } @@ -533,7 +556,7 @@ static bool chunk_header(ioma_ctx *ctx) body_fail(ctx, 400); return false; } - ioma_pipereader_drop(STATE(ctx)->reader, (size_t)len + 2); + ioma_pipereader_drop(READER(ctx), (size_t)len + 2); if (size == 0) return chunk_trailers(ctx); STATE(ctx)->chunk_left = size; @@ -549,13 +572,13 @@ static bool chunk_end(ioma_ctx *ctx) return false; if (live.len >= 2) break; - ioma_pipereader_examine(STATE(ctx)->reader, live.len); + ioma_pipereader_examine(READER(ctx), live.len); } if (live.p[0] != '\r' || live.p[1] != '\n') { body_fail(ctx, 400); return false; } - ioma_pipereader_drop(STATE(ctx)->reader, 2); + ioma_pipereader_drop(READER(ctx), 2); return true; } @@ -567,7 +590,7 @@ static bool chunk_end(ioma_ctx *ctx) ioma_slice ioma_body_all(ioma_ctx *ctx) { struct serve_state *state = STATE(ctx); - ioma_pipereader *r = state->reader; + ioma_pipereader *pr = &state->pipe->in; ioma_request *req = &ctx->req; const ioma_slice none = { nullptr, 0 }; @@ -587,7 +610,7 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) if (!body_bytes(ctx, &live)) return none; size_t n = live.len < state->chunk_left ? live.len : state->chunk_left; - if (!ioma_pipereader_keep(r, n)) { + if (!ioma_pipereader_keep(pr, n)) { body_fail(ctx, 413); return none; } @@ -596,20 +619,20 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) if (state->chunk_left == 0 && !chunk_end(ctx)) return none; } - req->body = ioma_pipereader_run(r); + req->body = ioma_pipereader_run(pr); } else { - if (req->content_length > IOMA_REQ_CAP) { + if (req->content_length > pr->cap) { body_fail(ctx, 413); return none; } ioma_slice live = none; while (req->content_length && live.len < req->content_length) { if (live.len) - ioma_pipereader_examine(r, live.len); + ioma_pipereader_examine(pr, live.len); if (!body_bytes(ctx, &live)) return none; } - const char *kept = req->content_length ? ioma_pipereader_keep(r, req->content_length) : live.p; + const char *kept = req->content_length ? ioma_pipereader_keep(pr, req->content_length) : live.p; if (req->content_length && !kept) { body_fail(ctx, 413); return none; @@ -628,7 +651,7 @@ static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ size_t remaining = ctx->req.content_length - state->body_read; if (n > remaining) n = remaining; - int got = ioma_pipereader_copy(state->reader, dst, n); + int got = ioma_pipereader_copy(&state->pipe->in, dst, n); if (got <= 0) { state->body_err = -1; /* gone, or the input ended inside the body */ return -1; @@ -644,7 +667,7 @@ static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ { if (n > state->chunk_left) n = state->chunk_left; - int got = ioma_pipereader_copy(state->reader, dst, n); + int got = ioma_pipereader_copy(&state->pipe->in, dst, n); if (got <= 0) { state->body_err = -1; return -1; @@ -734,18 +757,18 @@ static void drain_body(ioma_ctx *ctx) * version, headers). What is buffered is parsed first: after a reply, a pipelined next request * may already be there. More is read only when the head is incomplete. Returns the head's * length, or -1 once the connection is finished (431 or 400 answered, or the peer went away). */ -static long read_head(ioma_ctx *ctx, conn_t *conn) +static long read_head(ioma_ctx *ctx) { - ioma_pipereader *r = STATE(ctx)->reader; + ioma_pipereader *pr = READER(ctx); ioma_request *req = &ctx->req; size_t already = 0; /* what the previous attempt scanned */ ioma_slice live = { nullptr, 0 }; for (;;) { - int rc = ioma_pipereader_read(r, &live); + int rc = ioma_pipereader_read(pr, &live); if (rc == 0) return -1; /* the peer is done: a clean end between requests */ if (rc == IOMA_PIPE_FULL) { - send_status(conn, 431); + send_status(WRITER(ctx), 431); return -1; } if (rc < 0) @@ -758,15 +781,15 @@ static long read_head(ioma_ctx *ctx, conn_t *conn) (struct phr_header *)req->headers, &req->n_headers, already); if (parsed >= 0) { - ioma_pipereader_keep(r, (size_t)parsed); /* the head stays put, where it was parsed */ - ioma_pipereader_run_begin(r); /* the body's kept bytes are a run of their own */ + ioma_pipereader_keep(pr, (size_t)parsed); /* the head stays put, where it was parsed */ + ioma_pipereader_run_begin(pr); /* the body's kept bytes are a run of their own */ return parsed; } if (parsed == -1) { /* malformed */ - send_status(conn, 400); + send_status(WRITER(ctx), 400); return -1; } - ioma_pipereader_examine(r, live.len); /* incomplete: the next read waits for more */ + ioma_pipereader_examine(pr, live.len); /* incomplete: the next read waits for more */ already = live.len; } } @@ -799,14 +822,14 @@ static void fill_request(ioma_request *req, char *params_arena, size_t arena_cap /* The engine's bookkeeping for reading the body on demand: where it starts, what already * arrived with the head, and - for a Content-Length body that is entirely here - where the next * request starts. */ -static void init_body_state(struct serve_state *state, ioma_pipereader *reader, const ioma_request *req) +static void init_body_state(struct serve_state *state, struct ioma_pipe *pipe, const ioma_request *req) { - *state = (struct serve_state){ .reader = reader }; + *state = (struct serve_state){ .pipe = pipe }; state->body_done = !req->chunked && req->content_length == 0; } /* A response with its defaults and an empty slab. */ -static void init_response(ioma_response *res, char *slab) +static void init_response(ioma_response *res, ioma_pipewriter *pw) { res->status = 200; res->content_type = (ioma_slice){ "text/plain", 10 }; @@ -815,53 +838,46 @@ static void init_response(ioma_response *res, char *slab) res->head_sent = false; res->content_length = 0; res->has_length = false; - res->buf = slab + IOMA_LEAD; - res->cap = IOMA_OUT_CAP; - res->len = 0; res->chunked = false; res->failed = false; + ioma_pipewriter_reset(pw); } /* The proactor handler for every connection: one request per iteration - get the head, run * the chain against a context, drain what it left of the body, send what it wrote - while kept * alive. Returning closes the connection. */ -void ioma__serve(conn_t *conn) +void ioma__serve(struct ioma_pipe *pipe) { - char gather[IOMA_REQ_CAP]; /* where a request's bytes go when they must be contiguous */ - char params[IOMA_PARAM_CAP]; /* decoded query parameters */ - char slab[IOMA_LEAD + IOMA_OUT_CAP + 2]; /* lead, the write slab, CRLF slack */ - ioma_pipereader reader; /* the connection's bytes, across requests */ - ioma_pipereader_init(&reader, conn, gather, sizeof gather); + char params[IOMA_PARAM_CAP]; /* decoded query parameters */ for (;;) { ioma_ctx ctx; /* this request's context */ - struct serve_state state = { .reader = &reader }; + struct serve_state state = { .pipe = pipe }; ctx.priv = &state; - long head_len = read_head(&ctx, conn); + long head_len = read_head(&ctx); if (head_len < 0) - break; + return; fill_request(&ctx.req, params, sizeof params); - init_body_state(&state, &reader, &ctx.req); - init_response(&ctx.res, slab); + init_body_state(&state, pipe, &ctx.req); + init_response(&ctx.res, &pipe->out); ctx.user = nullptr; ioma__dispatch(&ctx); /* middleware chain + endpoint */ if (state.body_err) { /* too large, malformed, or gone */ if (state.body_err > 0 && !ctx.res.head_sent) - send_status(conn, state.body_err); - break; + send_status(&pipe->out, state.body_err); + return; } drain_body(&ctx); /* what the handler left unread */ if (state.body_err) - break; + return; if (finish(&ctx) < 0) /* sends; suspends meanwhile */ - break; + return; if (!ctx.req.keep_alive || ctx.res.close) - break; - ioma_pipereader_release(&reader); /* this request's bytes go; a pipelined next one stays */ + return; + ioma_pipereader_release(&pipe->in); /* this request's bytes go; a pipelined next one stays */ } - ioma_pipereader_close(&reader); } diff --git a/src/http/engine.h b/src/http/engine.h index 63b1d7b..926edb9 100644 --- a/src/http/engine.h +++ b/src/http/engine.h @@ -3,6 +3,6 @@ */ #pragma once -#include "io/conn.h" +#include "io/pipe.h" -void ioma__serve(conn_t *conn); /* requests on the connection until it ends */ +void ioma__serve(struct ioma_pipe *pipe); /* requests on the connection until it ends */ diff --git a/src/http/run.c b/src/http/run.c index 11fe0aa..8b57106 100644 --- a/src/http/run.c +++ b/src/http/run.c @@ -113,30 +113,7 @@ int ioma_run(int workers, int port) return run_workers(workers, port, ioma__serve); } -/* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ - -#ifndef IOMA_PIPE_BUF -#define IOMA_PIPE_BUF 16384 /* a pipe's gathering buffer (kept + live bytes) */ -#endif -#ifndef IOMA_PIPE_SLAB -#define IOMA_PIPE_SLAB 8192 /* a pipe's write slab */ -#endif - -static ioma_pipe_handler g_pipe_handler; - -/* The connection handler behind ioma_run_pipes: a pipe over the connection, the handler on it. */ -static void serve_pipe(conn_t *conn) -{ - char gather[IOMA_PIPE_BUF]; - char slab[IOMA_PIPE_SLAB]; - struct ioma_pipe pipe; - ioma__pipe_init(&pipe, conn, gather, sizeof gather, slab, sizeof slab); - g_pipe_handler(&pipe); - ioma__pipe_close(&pipe); -} - int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn) { - g_pipe_handler = fn; - return run_workers(workers, port, serve_pipe); + return run_workers(workers, port, fn); } diff --git a/src/io/conn.c b/src/io/conn.c index 79b66cc..9815ce2 100644 --- a/src/io/conn.c +++ b/src/io/conn.c @@ -1,9 +1,10 @@ /* * conn.c - one connection's life on its worker: the pooled conn_t, its two owners' refcount, the - * multishot recv and the queue of slices it delivers, parking on -ENOBUFS, closing, and the two - * awaits a handler coroutine calls. + * multishot recv and the queue of buffers it delivers, parking on -ENOBUFS, closing, and the + * awaits the pipe is built on. */ #include "io/internal.h" +#include "io/pipe.h" #include #include @@ -107,7 +108,7 @@ void ioma__arm_recv(proactor_t *p, conn_t *c) c->recv = RECV_ARMED; } -/* Resume the coroutine parked in await_recv, if there is one. It pops the queue itself. */ +/* Resume the coroutine parked waiting for bytes, if there is one. It pops the queue itself. */ static void wake_reader(conn_t *c) { coro_t *waiter = c->waiter; @@ -192,7 +193,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) c->err = result; } c->recv = RECV_DONE; - wake_reader(c); /* a parked await_recv returns 0 / -errno */ + wake_reader(c); /* a parked reader sees 0 / -errno */ conn_unref(c); /* the recv's ref; may recycle c */ return; } @@ -270,8 +271,13 @@ static void conn_close(conn_t *c) /* The connection's coroutine: run the worker's handler to completion, then close. */ void ioma__conn_main(void *arg) { - conn_t *c = arg; - c->p->handler(c); + conn_t *c = arg; + char gather[IOMA_PIPE_GATHER]; + char slab[IOMA_PIPE_LEAD + IOMA_PIPE_CAP + IOMA_PIPE_SLACK]; + struct ioma_pipe pipe; + ioma__pipe_init(&pipe, c, gather, sizeof gather, slab, IOMA_PIPE_LEAD, IOMA_PIPE_CAP, IOMA_PIPE_SLACK); + c->p->handler(&pipe); + ioma__pipe_close(&pipe); conn_close(c); } @@ -296,29 +302,6 @@ int ioma__await_item(conn_t *c, struct rx_item *out) } } -int await_recv(conn_t *c, void *buf, size_t len) -{ - if (len == 0) - return -EINVAL; - for (;;) { - if (c->rx_head != c->rx_tail) { - struct rx_item *item = &c->rx[c->rx_head & RX_MASK]; - size_t n = item->len < len ? item->len : len; - memcpy(buf, item->ptr, n); - item->ptr += n; - item->len -= (uint32_t)n; - if (item->len == 0) { - ioma__bufring_return(&c->p->bufs, item->buf_id); - c->rx_head++; - } - return (int)n; - } - if (c->eof) - return c->err; - c->waiter = coro_current(); - coro_yield(); /* ioma__on_recv wakes us */ - } -} /* Send all of buf: a SEND SQE per round, parked until its CQE. Returns len, or -errno. */ int await_send(conn_t *c, const void *buf, size_t len) diff --git a/src/io/conn.h b/src/io/conn.h index bcb872c..d5957c8 100644 --- a/src/io/conn.h +++ b/src/io/conn.h @@ -38,7 +38,7 @@ enum recv_state { struct conn { int fd; /* the socket, or its file slot under fixed files */ proactor_t *p; - coro_t *waiter; /* coroutine parked in await_recv, or nullptr */ + coro_t *waiter; /* coroutine parked waiting for bytes, or nullptr */ struct rx_item rx[RX_QUEUE]; /* delivered while nobody was reading */ unsigned rx_head, rx_tail; enum recv_state recv; @@ -52,9 +52,8 @@ struct conn { /* Awaits: call from a coroutine on the owning worker. The coroutine parks; the loop resumes it * when the completion arrives. */ -int await_recv(conn_t *c, void *buf, size_t len); /* >0 bytes, 0 peer closed, <0 -errno */ int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ -int ioma__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno */ +int ioma__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno (the reader's primitive) */ /* For the loop (proactor.c): a connection's life from accept to the pool. */ conn_t *ioma__conn_new(proactor_t *p, int fd); /* from the pool, or fresh */ diff --git a/src/io/pipe.c b/src/io/pipe.c index 8a8e74d..dcaa928 100644 --- a/src/io/pipe.c +++ b/src/io/pipe.c @@ -273,22 +273,30 @@ int ioma_pipereader_copy(ioma_pipereader *pr, void *dst, size_t n) /* ── the writer ────────────────────────────────────────────────────────────────────────── */ -void ioma_pipewriter_init(ioma_pipewriter *pw, conn_t *conn, char *buf, size_t cap) +void ioma_pipewriter_init(ioma_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack) { - *pw = (ioma_pipewriter){}; - pw->conn = conn; - pw->buf = buf; - pw->cap = cap; + *pw = (ioma_pipewriter){}; + pw->conn = conn; + pw->buf = buf; + pw->lead = lead; + pw->cap = cap; + pw->slack = slack; +} + +void ioma_pipewriter_reset(ioma_pipewriter *pw) +{ + pw->head = pw->len = pw->tail = 0; } int ioma_pipewriter_flush(ioma_pipewriter *pw) { if (pw->failed) return -1; - if (pw->len == 0) + size_t total = pw->head + pw->len + pw->tail; + if (total == 0) return 0; - int rc = await_send(pw->conn, pw->buf, pw->len); - pw->len = 0; + int rc = await_send(pw->conn, pw->buf + pw->lead - pw->head, total); + pw->head = pw->len = pw->tail = 0; if (rc < 0) { pw->failed = true; return -1; @@ -302,7 +310,7 @@ void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n) return nullptr; if (pw->len + n > pw->cap && ioma_pipewriter_flush(pw) < 0) return nullptr; - return pw->buf + pw->len; + return ioma_pipewriter_at(pw); } void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n) @@ -310,19 +318,40 @@ void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n) pw->len += n; } -int ioma_pipewriter_write(ioma_pipewriter *pw, const void *data, size_t n) +char *ioma_pipewriter_front(ioma_pipewriter *pw, size_t n) +{ + if (n > pw->lead - pw->head) + return nullptr; + pw->head += n; + return pw->buf + pw->lead - pw->head; +} + +char *ioma_pipewriter_back(ioma_pipewriter *pw, size_t n) +{ + if (n > pw->slack - pw->tail) + return nullptr; + char *at = pw->buf + pw->lead + pw->len + pw->tail; + pw->tail += n; + return at; +} + +int ioma_pipewriter_through(ioma_pipewriter *pw, const void *data, size_t n) { if (pw->failed) return -1; - if (n > pw->cap) { /* larger than the slab: straight from the caller's memory */ - if (ioma_pipewriter_flush(pw) < 0) - return -1; - if (await_send(pw->conn, data, n) < 0) { - pw->failed = true; - return -1; - } - return 0; + if (await_send(pw->conn, data, n) < 0) { + pw->failed = true; + return -1; } + return 0; +} + +int ioma_pipewriter_write(ioma_pipewriter *pw, const void *data, size_t n) +{ + if (pw->failed) + return -1; + if (n > pw->cap) /* larger than the slab: straight from the caller's memory */ + return ioma_pipewriter_flush(pw) < 0 ? -1 : ioma_pipewriter_through(pw, data, n); void *at = ioma_pipewriter_reserve(pw, n); if (!at) return -1; @@ -338,10 +367,10 @@ int ioma_pipewriter_send(ioma_pipewriter *pw, const void *data, size_t n) /* ── the pipe ──────────────────────────────────────────────────────────────────────────── */ -void ioma__pipe_init(struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap) +void ioma__pipe_init(struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack) { ioma_pipereader_init(&p->in, conn, gather, gather_cap); - ioma_pipewriter_init(&p->out, conn, slab, slab_cap); + ioma_pipewriter_init(&p->out, conn, slab, lead, cap, slack); } void ioma__pipe_close(struct ioma_pipe *p) diff --git a/src/io/pipe.h b/src/io/pipe.h index bce7583..2e2fdb5 100644 --- a/src/io/pipe.h +++ b/src/io/pipe.h @@ -15,6 +15,8 @@ * bytes stay where they are - the consumer's, to point into and even overwrite - until release. * At most two kernel buffers are held: one with kept bytes of earlier runs, one with the live * bytes and the run in progress. */ + +// BUF_SIZE can be increased to keep entire requests in a single rx_item, avoiding buffering typedef struct ioma_pipereader { conn_t *conn; char *buf; /* the gathering buffer, the consumer's */ @@ -46,25 +48,58 @@ ioma_slice ioma_pipereader_run (const ioma_pipereader *pr); / void ioma_pipereader_release (ioma_pipereader *pr); /* forget every kept byte; live bytes stay */ int ioma_pipereader_copy (ioma_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ -/* The writer: a slab, sent on flush. */ +/* The writer: a slab with a head and a tail. Data goes in at the tail (reserve/advance, or write); + * a frame's front goes into the lead just before the pending data and its back into the slack just + * after it, and one flush sends the whole span. The HTTP reply puts its head and a chunk's size + * line in front and a chunk's CRLF behind; a raw pipe may never touch them. */ typedef struct ioma_pipewriter { conn_t *conn; - char *buf; - size_t cap, len; - bool failed; /* the peer is gone: every call fails from here on */ + char *buf; /* [lead][cap][slack] */ + size_t lead, cap, slack; + size_t head; /* bytes of the lead in use: a frame's front */ + size_t len; /* data bytes */ + size_t tail; /* bytes of the slack in use: a frame's back */ + bool failed; /* the peer is gone: every call fails from here on */ } ioma_pipewriter; -void ioma_pipewriter_init (ioma_pipewriter *pw, conn_t *conn, char *buf, size_t cap); -void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ -void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n); -int ioma_pipewriter_write (ioma_pipewriter *pw, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ -int ioma_pipewriter_flush (ioma_pipewriter *pw); /* send the slab; suspends */ -int ioma_pipewriter_send (ioma_pipewriter *pw, const void *data, size_t n); /* write, then flush */ +void ioma_pipewriter_init (ioma_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack); +void ioma_pipewriter_reset (ioma_pipewriter *pw); /* drop everything pending */ +void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ +void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n); +char *ioma_pipewriter_front (ioma_pipewriter *pw, size_t n); /* n bytes just before the pending span; nullptr when the lead has no room */ +char *ioma_pipewriter_back (ioma_pipewriter *pw, size_t n); /* n bytes just after it; nullptr when the slack has no room */ +int ioma_pipewriter_write (ioma_pipewriter *pw, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ +int ioma_pipewriter_through(ioma_pipewriter *pw, const void *data, size_t n); /* send now, ahead of the pending span, bypassing the slab */ +int ioma_pipewriter_flush (ioma_pipewriter *pw); /* send front, data and back; suspends */ +int ioma_pipewriter_send (ioma_pipewriter *pw, const void *data, size_t n); /* write, then flush */ + +/* Where the next byte goes, and how many fit before the slab is full. */ +static inline char *ioma_pipewriter_at(const ioma_pipewriter *pw) +{ + return pw->buf + pw->lead + pw->len; +} +static inline size_t ioma_pipewriter_room(const ioma_pipewriter *pw) +{ + return pw->cap - pw->len; +} -/* The pair, as the public API sees it. */ +/* The pair every handler receives, HTTP or raw (the public ioma_pipe). Its buffers live on the + * connection's coroutine stack. */ +#ifndef IOMA_PIPE_GATHER +#define IOMA_PIPE_GATHER 16384 /* the reader's gathering buffer: kept plus live bytes */ +#endif +#ifndef IOMA_PIPE_LEAD +#define IOMA_PIPE_LEAD 512 /* in front of the slab: a frame's front */ +#endif +#ifndef IOMA_PIPE_CAP +#define IOMA_PIPE_CAP 8192 /* the slab: bytes buffered before a flush */ +#endif +#ifndef IOMA_PIPE_SLACK +#define IOMA_PIPE_SLACK 8 /* behind the slab: a frame's back */ +#endif struct ioma_pipe { ioma_pipereader in; ioma_pipewriter out; }; -void ioma__pipe_init (struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t slab_cap); +void ioma__pipe_init (struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack); void ioma__pipe_close(struct ioma_pipe *p); diff --git a/src/io/proactor.h b/src/io/proactor.h index 64d2e6d..fe8c968 100644 --- a/src/io/proactor.h +++ b/src/io/proactor.h @@ -31,7 +31,8 @@ #endif typedef struct proactor proactor_t; -typedef void (*handler_fn)(conn_t *c); +struct ioma_pipe; +typedef void (*handler_fn)(struct ioma_pipe *pipe); /* a connection, as a pipe */ struct proactor { /* set by the creator */ From 2f21ed1601ffdac8de1b1e86bfedd2ab6ed48ec7 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 22:09:41 +0100 Subject: [PATCH 16/49] lib/: the library's sources (was src/) include/ for the public header, lib/ for the library, tests/ and playground/ for what links it. Build files, the tidy config and the docs follow; the sources' includes are relative to the include path and did not change. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .clang-tidy | 4 ++-- ARCHITECTURE.md | 2 +- CMakeLists.txt | 24 ++++++++++++------------ Makefile | 12 ++++++------ PERF.md | 2 +- {src => lib}/http/api.c | 0 {src => lib}/http/engine.c | 0 {src => lib}/http/engine.h | 0 {src => lib}/http/internal.h | 0 {src => lib}/http/router.c | 0 {src => lib}/http/router.h | 0 {src => lib}/http/run.c | 0 {src => lib}/io/bufring.c | 0 {src => lib}/io/bufring.h | 0 {src => lib}/io/conn.c | 0 {src => lib}/io/conn.h | 0 {src => lib}/io/coro.c | 0 {src => lib}/io/coro.h | 0 {src => lib}/io/internal.h | 0 {src => lib}/io/pipe.c | 0 {src => lib}/io/pipe.h | 0 {src => lib}/io/proactor.c | 0 {src => lib}/io/proactor.h | 0 {src => lib}/io/switch_x86_64.S | 0 {src => lib}/io/uring.c | 0 {src => lib}/io/uring.h | 0 tests/stress.py | 2 +- 27 files changed, 23 insertions(+), 23 deletions(-) rename {src => lib}/http/api.c (100%) rename {src => lib}/http/engine.c (100%) rename {src => lib}/http/engine.h (100%) rename {src => lib}/http/internal.h (100%) rename {src => lib}/http/router.c (100%) rename {src => lib}/http/router.h (100%) rename {src => lib}/http/run.c (100%) rename {src => lib}/io/bufring.c (100%) rename {src => lib}/io/bufring.h (100%) rename {src => lib}/io/conn.c (100%) rename {src => lib}/io/conn.h (100%) rename {src => lib}/io/coro.c (100%) rename {src => lib}/io/coro.h (100%) rename {src => lib}/io/internal.h (100%) rename {src => lib}/io/pipe.c (100%) rename {src => lib}/io/pipe.h (100%) rename {src => lib}/io/proactor.c (100%) rename {src => lib}/io/proactor.h (100%) rename {src => lib}/io/switch_x86_64.S (100%) rename {src => lib}/io/uring.c (100%) rename {src => lib}/io/uring.h (100%) diff --git a/.clang-tidy b/.clang-tidy index 16e220a..faa96af 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,7 +1,7 @@ # clang-tidy configuration for libioma. CLion picks this file up (it prefers a project .clang-tidy # over its own settings); from the shell, with the compile flags the Makefile uses: # -# clang-tidy src/io/*.c src/http/*.c tests/server.c -- -std=gnu23 -D_GNU_SOURCE -Iinclude -Isrc -Ithird_party/picohttpparser +# clang-tidy lib/io/*.c lib/http/*.c tests/server.c -- -std=gnu23 -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser # # (CLion's bundled clang-tidy ships without clang's builtin headers; give it gcc's with # --extra-arg=-isystem/usr/lib/gcc/x86_64-linux-gnu/13/include, or it cascades phantom warnings.) @@ -36,4 +36,4 @@ Checks: > -misc-no-recursion CheckOptions: bugprone-signed-bitwise.IgnorePositiveIntegerLiterals: true -HeaderFilterRegex: '(include|src)/.*' +HeaderFilterRegex: '(include|lib)/.*' diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index f9f726a..20e9199 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -14,7 +14,7 @@ process │ └─ pools: conn objects, coroutine stacks ``` -`include/ioma.h` is the whole public API. Under `src/` there are two planes, one concern per file: +`include/ioma.h` is the whole public API. Under `lib/` there are two planes, one concern per file: `io/` is the I/O plane - `uring.c` (the ring), `coro.c` + `switch_x86_64.S` (coroutines), `bufring.c` (the buffer ring), `conn.c` (a connection and its awaits), `proactor.c` (the worker loop), with `proactor.h` as the interface the other plane uses - and `http/` is the HTTP plane - diff --git a/CMakeLists.txt b/CMakeLists.txt index d5a9e2b..52b5315 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,17 +53,17 @@ include(GNUInstallDirs) # --- the library (static by default; -DBUILD_SHARED_LIBS=ON for a .so) --- add_library(ioma - src/io/uring.c - src/io/coro.c - src/io/switch_x86_64.S - src/io/bufring.c - src/io/conn.c - src/io/proactor.c - src/io/pipe.c - src/http/engine.c - src/http/api.c - src/http/router.c - src/http/run.c + lib/io/uring.c + lib/io/coro.c + lib/io/switch_x86_64.S + lib/io/bufring.c + lib/io/conn.c + lib/io/proactor.c + lib/io/pipe.c + lib/http/engine.c + lib/http/api.c + lib/http/router.c + lib/http/run.c third_party/picohttpparser/picohttpparser.c) add_library(ioma::ioma ALIAS ioma) @@ -72,7 +72,7 @@ target_include_directories(ioma $ $ PRIVATE - src + lib third_party/picohttpparser) target_compile_definitions(ioma PRIVATE _GNU_SOURCE) target_compile_options(ioma PRIVATE -Wall -Wextra) diff --git a/Makefile b/Makefile index ca5488e..a053fd0 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ AR ?= ar LTO := $(shell $(CC) -Werror -flto -ffat-lto-objects -x c -c /dev/null -o /dev/null 2>/dev/null && echo -flto -ffat-lto-objects) CFLAGS ?= -O3 -g $(LTO) WARN := -Wall -Wextra $(STD) -CPP := -D_GNU_SOURCE -Iinclude -Isrc -Ithird_party/picohttpparser -HDRS := $(wildcard include/*.h src/*/*.h) +CPP := -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser +HDRS := $(wildcard include/*.h lib/*/*.h) PTHREAD := -pthread VERSION := 0.1.0 @@ -57,10 +57,10 @@ libioma.so: $(PICOBJ) $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(PTHREAD) # --- static objects (used by libioma.a and the examples) --- -obj/%.o: src/%.c $(HDRS) +obj/%.o: lib/%.c $(HDRS) @mkdir -p $(@D) $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -c $< -o $@ -obj/io/switch_x86_64.o: src/io/switch_x86_64.S +obj/io/switch_x86_64.o: lib/io/switch_x86_64.S @mkdir -p $(@D) $(CC) $(CFLAGS) $(CPP) -c $< -o $@ obj/picohttpparser.o: third_party/picohttpparser/picohttpparser.c @@ -68,10 +68,10 @@ obj/picohttpparser.o: third_party/picohttpparser/picohttpparser.c $(CC) $(CFLAGS) -w -Ithird_party/picohttpparser -c $< -o $@ # --- position-independent objects (used by libioma.so) --- -obj/pic/%.o: src/%.c $(HDRS) +obj/pic/%.o: lib/%.c $(HDRS) @mkdir -p $(@D) $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -fPIC -c $< -o $@ -obj/pic/io/switch_x86_64.o: src/io/switch_x86_64.S +obj/pic/io/switch_x86_64.o: lib/io/switch_x86_64.S @mkdir -p $(@D) $(CC) $(CFLAGS) $(CPP) -fPIC -c $< -o $@ obj/pic/picohttpparser.o: third_party/picohttpparser/picohttpparser.c diff --git a/PERF.md b/PERF.md index 0e2e189..9b10c41 100644 --- a/PERF.md +++ b/PERF.md @@ -37,7 +37,7 @@ The `-D` switches: `FIXED_FILES=0` disables the file table, `NO_REG_RING` the re A recv that finds the ring empty is logged, at most once a second per worker, with counts: `ioma: [w3] recv found no provided buffer N times ...: raise BUF_COUNT`. That line is the signal to raise `-DBUF_COUNT` (a power of two, up to 65536; each buffer is `BUF_SIZE` bytes of the per-worker slab). -in `src/io/proactor.h`. Both ring features fall back at runtime on kernels that lack them. +in `lib/io/bufring.h` and `lib/io/proactor.h`. Both ring features fall back at runtime on kernels that lack them. ### How to do PGO diff --git a/src/http/api.c b/lib/http/api.c similarity index 100% rename from src/http/api.c rename to lib/http/api.c diff --git a/src/http/engine.c b/lib/http/engine.c similarity index 100% rename from src/http/engine.c rename to lib/http/engine.c diff --git a/src/http/engine.h b/lib/http/engine.h similarity index 100% rename from src/http/engine.h rename to lib/http/engine.h diff --git a/src/http/internal.h b/lib/http/internal.h similarity index 100% rename from src/http/internal.h rename to lib/http/internal.h diff --git a/src/http/router.c b/lib/http/router.c similarity index 100% rename from src/http/router.c rename to lib/http/router.c diff --git a/src/http/router.h b/lib/http/router.h similarity index 100% rename from src/http/router.h rename to lib/http/router.h diff --git a/src/http/run.c b/lib/http/run.c similarity index 100% rename from src/http/run.c rename to lib/http/run.c diff --git a/src/io/bufring.c b/lib/io/bufring.c similarity index 100% rename from src/io/bufring.c rename to lib/io/bufring.c diff --git a/src/io/bufring.h b/lib/io/bufring.h similarity index 100% rename from src/io/bufring.h rename to lib/io/bufring.h diff --git a/src/io/conn.c b/lib/io/conn.c similarity index 100% rename from src/io/conn.c rename to lib/io/conn.c diff --git a/src/io/conn.h b/lib/io/conn.h similarity index 100% rename from src/io/conn.h rename to lib/io/conn.h diff --git a/src/io/coro.c b/lib/io/coro.c similarity index 100% rename from src/io/coro.c rename to lib/io/coro.c diff --git a/src/io/coro.h b/lib/io/coro.h similarity index 100% rename from src/io/coro.h rename to lib/io/coro.h diff --git a/src/io/internal.h b/lib/io/internal.h similarity index 100% rename from src/io/internal.h rename to lib/io/internal.h diff --git a/src/io/pipe.c b/lib/io/pipe.c similarity index 100% rename from src/io/pipe.c rename to lib/io/pipe.c diff --git a/src/io/pipe.h b/lib/io/pipe.h similarity index 100% rename from src/io/pipe.h rename to lib/io/pipe.h diff --git a/src/io/proactor.c b/lib/io/proactor.c similarity index 100% rename from src/io/proactor.c rename to lib/io/proactor.c diff --git a/src/io/proactor.h b/lib/io/proactor.h similarity index 100% rename from src/io/proactor.h rename to lib/io/proactor.h diff --git a/src/io/switch_x86_64.S b/lib/io/switch_x86_64.S similarity index 100% rename from src/io/switch_x86_64.S rename to lib/io/switch_x86_64.S diff --git a/src/io/uring.c b/lib/io/uring.c similarity index 100% rename from src/io/uring.c rename to lib/io/uring.c diff --git a/src/io/uring.h b/lib/io/uring.h similarity index 100% rename from src/io/uring.h rename to lib/io/uring.h diff --git a/tests/stress.py b/tests/stress.py index 345303c..fc510a1 100644 --- a/tests/stress.py +++ b/tests/stress.py @@ -6,7 +6,7 @@ gcc -O2 -g -Wall -Iinclude -Ithird_party/picohttpparser -pthread \\ -DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4 \\ - playground/hello/main.c src/*.c src/*.S \\ + playground/hello/main.c lib/*/*.c lib/io/*.S \\ third_party/picohttpparser/picohttpparser.c -o ioma-tiny At shutdown the server must report "0 still open" on every worker. From a7c610ac78373e0970c2f8dedf61d2291d48a1c2 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 22:13:24 +0100 Subject: [PATCH 17/49] JSON, written as you go: the ioma_json writer A forward-only writer, the shape of .NET's Utf8JsonWriter: object, array, end, key, string, cstr, int, uint, double, bool, null and raw, each putting its bytes straight into a sink - the reply (content-type set for you), a raw pipe, or a memory buffer - with no tree and no allocation. Strings are escaped as they are copied, a safe run at a time; doubles take the shortest of 15, 16 or 17 significant digits that reads back the same, decimal point forced to '.'; nan and inf become null. Nesting and the commas each level owes are two bits per level; too deep, a full buffer or a gone peer fail the writer and every later call. Unit tests cover escaping, every number edge, empty containers, a top-level scalar, the depth limit and a full buffer. The fixture serves GET /json/:id and GET /json/big, whose 3000 objects stream out chunked while the writer keeps going. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 12 +++ CMakeLists.txt | 1 + Makefile | 2 +- README.md | 3 +- include/ioma.h | 51 +++++++++ lib/json/json.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/server.c | 43 ++++++++ tests/smoke.py | 34 ++++++ tests/unit.c | 68 +++++++++++- 9 files changed, 492 insertions(+), 3 deletions(-) create mode 100644 lib/json/json.c diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 20e9199..6f24fdf 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -282,6 +282,18 @@ Two switches in, two out — tens of nanoseconds. The cost of a request is the k --- +## 8. JSON, written as you go + +`lib/json/json.c` is a forward-only writer, the shape of .NET's `Utf8JsonWriter`: `ioma_json_object`, +`ioma_json_key`, `ioma_json_int`, `ioma_json_string`, `ioma_json_end` and so on, each putting its +bytes straight into a sink - the reply through `ioma_reserve`/`ioma_advance`, a raw pipe, or a +memory buffer - with no tree and no allocation. Strings are escaped as they are copied, a safe run +at a time; integers go through a digit loop; a double takes the shortest of 15, 16 or 17 +significant digits that reads back as the same value, with the decimal point forced to '.' +whatever the locale says. Nesting and the commas it owes are two bits per level, so a document +deeper than `IOMA_JSON_DEPTH` fails cleanly. A reply larger than the slab streams out chunked +while the writer keeps going, which is the whole point of writing as you go. + ## Tunables | name | default | what | diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b5315..47fa41b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ add_library(ioma lib/http/api.c lib/http/router.c lib/http/run.c + lib/json/json.c third_party/picohttpparser/picohttpparser.c) add_library(ioma::ioma ALIAS ioma) diff --git a/Makefile b/Makefile index a053fd0..525ad80 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ LIBDIR := $(PREFIX)/lib INCDIR := $(PREFIX)/include/ioma PCDIR := $(LIBDIR)/pkgconfig -UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run +UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run json/json OBJ := $(addprefix obj/,$(addsuffix .o,$(UNITS))) obj/io/switch_x86_64.o obj/picohttpparser.o PICOBJ := $(addprefix obj/pic/,$(addsuffix .o,$(UNITS))) obj/pic/io/switch_x86_64.o obj/pic/picohttpparser.o diff --git a/README.md b/README.md index 170d5c0..3072b05 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware o is `NULL`, with `ioma_use` for middleware on everything. `ioma_run` resolves it all once into a segment tree and flat chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port. Underneath, a connection is a pipe: `ioma_run_pipes` hands a handler of your own the reader and writer the -HTTP engine uses, for raw TCP, with the same suspend-and-resume. The same registrations read as a script with the `IOMA_GET`, `IOMA_GROUP` and `IOMA_USE` macros, a group's block +HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with +the `ioma_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills. The same registrations read as a script with the `IOMA_GET`, `IOMA_GROUP` and `IOMA_USE` macros, a group's block nesting the routes below it; the hello example and `tests/server.c` are written that way. `playground/hello/main.c` is a complete example. diff --git a/include/ioma.h b/include/ioma.h index e4ce914..124aa49 100644 --- a/include/ioma.h +++ b/include/ioma.h @@ -270,6 +270,57 @@ ioma_endpoint *ioma__endpoint(const char *method, struct ioma_endpoint_args args #define IOMA_DELETE(...) IOMA_ROUTE("DELETE", __VA_ARGS__) #define IOMA_DEFAULT(fn) ioma_default(fn) +/* ── JSON, written as you go ───────────────────────────────────────────────────────────── */ + +/* A forward-only JSON writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation. The + * bytes go straight into the reply - or a raw pipe, or a buffer - escaped as they are written, + * and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what + * it means: + * + * ioma_json j = ioma_json_reply(ctx); // content-type: application/json + * ioma_json_object(&j); + * ioma_json_key(&j, "id"); ioma_json_int(&j, id); + * ioma_json_key(&j, "name"); ioma_json_string(&j, name); + * ioma_json_key(&j, "tags"); ioma_json_array(&j); + * ioma_json_cstr(&j, "new"); + * ioma_json_end(&j); + * ioma_json_end(&j); + * + * Strings are taken as UTF-8 and passed through; '"', '\' and control characters are escaped. + * Every call returns false once the sink is gone (the peer left; the buffer is full) or the + * nesting passed IOMA_JSON_DEPTH, and the rest is dropped, so checking the last call is enough. */ +#define IOMA_JSON_DEPTH 64 +typedef struct ioma_json { + enum { IOMA_JSON_TO_REPLY, IOMA_JSON_TO_PIPE, IOMA_JSON_TO_MEM } kind; + union { + ioma_ctx *ctx; + struct ioma_pipe *pipe; + struct { char *p; size_t cap, *len; } mem; + } to; + uint64_t has_value; /* per level: a value is there, so a comma is due */ + uint64_t is_object; /* per level: it closes with '}' rather than ']' */ + unsigned depth; + bool after_key; /* the next value follows a key: no comma */ + bool failed; +} ioma_json; + +ioma_json ioma_json_reply(ioma_ctx *ctx); /* into the reply; sets its content type */ +ioma_json ioma_json_pipe (struct ioma_pipe *pipe); /* into a raw pipe's slab */ +ioma_json ioma_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ + +bool ioma_json_object(ioma_json *j); /* { */ +bool ioma_json_array (ioma_json *j); /* [ */ +bool ioma_json_end (ioma_json *j); /* } or ], whichever is open */ +bool ioma_json_key (ioma_json *j, const char *name); /* "name": */ +bool ioma_json_string(ioma_json *j, ioma_slice s); /* "...", escaped */ +bool ioma_json_cstr (ioma_json *j, const char *s); +bool ioma_json_int (ioma_json *j, int64_t v); +bool ioma_json_uint (ioma_json *j, uint64_t v); +bool ioma_json_double(ioma_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ +bool ioma_json_bool (ioma_json *j, bool v); +bool ioma_json_null (ioma_json *j); +bool ioma_json_raw (ioma_json *j, ioma_slice json); /* already JSON: copied as is */ + /* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ /* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. diff --git a/lib/json/json.c b/lib/json/json.c new file mode 100644 index 0000000..1634b8d --- /dev/null +++ b/lib/json/json.c @@ -0,0 +1,281 @@ +/* + * json/json.c - the forward-only JSON writer of ioma.h. Every value goes straight to the sink: + * a run of safe bytes at a time, an escape at a time, a number formatted into a small stack + * buffer. The sink is the reply, a raw pipe, or a buffer; the writer never allocates. + */ +#include "ioma.h" + +#include +#include +#include +#include +#include + +#define RUN_MAX 1024 /* bytes asked of the sink at a time */ + +/* n bytes of the sink to write into, or nullptr; the caller then advances by what it wrote. */ +static char *reserve(ioma_json *j, size_t n) +{ + switch (j->kind) { + case IOMA_JSON_TO_REPLY: return ioma_reserve(j->to.ctx, n); + case IOMA_JSON_TO_PIPE: return ioma_pipe_reserve(j->to.pipe, n); + case IOMA_JSON_TO_MEM: return *j->to.mem.len + n <= j->to.mem.cap ? j->to.mem.p + *j->to.mem.len : nullptr; + } + return nullptr; +} + +static void advance(ioma_json *j, size_t n) +{ + switch (j->kind) { + case IOMA_JSON_TO_REPLY: ioma_advance(j->to.ctx, n); break; + case IOMA_JSON_TO_PIPE: ioma_pipe_advance(j->to.pipe, n); break; + case IOMA_JSON_TO_MEM: *j->to.mem.len += n; break; + } +} + +/* Raw bytes to the sink, in runs the slab can take; false marks the writer failed. */ +static bool put(ioma_json *j, const char *p, size_t n) +{ + while (n) { + size_t run = n < RUN_MAX ? n : RUN_MAX; + char *at = reserve(j, run); + if (!at) { + j->failed = true; + return false; + } + memcpy(at, p, run); + advance(j, run); + p += run; + n -= run; + } + return true; +} + +static bool put_cstr(ioma_json *j, const char *s) +{ + return put(j, s, strlen(s)); +} + +/* The bytes that must be escaped: the quote, the backslash, and control characters. */ +static bool needs_escape(unsigned char c) +{ + return c < 0x20 || c == '"' || c == '\\'; +} + +/* A string, quoted and escaped: safe runs are copied whole, escapes one at a time. */ +static bool put_string(ioma_json *j, const char *p, size_t n) +{ + static const char hex[] = "0123456789abcdef"; + if (!put(j, "\"", 1)) + return false; + while (n) { + size_t run = 0; + while (run < n && !needs_escape((unsigned char)p[run])) + run++; + if (run && !put(j, p, run)) + return false; + p += run; + n -= run; + if (n == 0) + break; + unsigned char c = (unsigned char)*p++; + n--; + char esc[6] = { '\\', 0, 0, 0, 0, 0 }; + size_t len = 2; + switch (c) { + case '"': esc[1] = '"'; break; + case '\\': esc[1] = '\\'; break; + case '\n': esc[1] = 'n'; break; + case '\r': esc[1] = 'r'; break; + case '\t': esc[1] = 't'; break; + case '\b': esc[1] = 'b'; break; + case '\f': esc[1] = 'f'; break; + default: /* \u00XX */ + esc[1] = 'u'; + esc[2] = '0'; + esc[3] = '0'; + esc[4] = hex[c >> 4]; + esc[5] = hex[c & 15]; + len = 6; + break; + } + if (!put(j, esc, len)) + return false; + } + return put(j, "\"", 1); +} + +/* Before a value: the comma its level owes, unless it follows a key. */ +static bool separator(ioma_json *j) +{ + if (j->failed) + return false; + if (j->after_key) { + j->after_key = false; + return true; + } + uint64_t bit = (uint64_t)1 << (j->depth & 63U); + if (j->has_value & bit) + return put(j, ",", 1); + j->has_value |= bit; + return true; +} + +/* ── the sinks ─────────────────────────────────────────────────────────────────────────── */ + +ioma_json ioma_json_reply(ioma_ctx *ctx) +{ + ioma_content_type(ctx, "application/json"); + ioma_json j = { .kind = IOMA_JSON_TO_REPLY }; + j.to.ctx = ctx; + return j; +} + +ioma_json ioma_json_pipe(struct ioma_pipe *pipe) +{ + ioma_json j = { .kind = IOMA_JSON_TO_PIPE }; + j.to.pipe = pipe; + return j; +} + +ioma_json ioma_json_mem(char *buf, size_t cap, size_t *len) +{ + ioma_json j = { .kind = IOMA_JSON_TO_MEM }; + j.to.mem.p = buf; + j.to.mem.cap = cap; + j.to.mem.len = len; + *len = 0; + return j; +} + +/* ── the values ────────────────────────────────────────────────────────────────────────── */ + +/* Open a container: its own level starts empty. */ +static bool open_level(ioma_json *j, char bracket) +{ + if (!separator(j)) + return false; + if (j->depth == IOMA_JSON_DEPTH) { + j->failed = true; + return false; + } + j->depth++; + uint64_t bit = (uint64_t)1 << (j->depth & 63U); + j->has_value &= ~bit; + if (bracket == '{') + j->is_object |= bit; + else + j->is_object &= ~bit; + return put(j, &bracket, 1); +} + +bool ioma_json_object(ioma_json *j) +{ + return open_level(j, '{'); +} + +bool ioma_json_array(ioma_json *j) +{ + return open_level(j, '['); +} + +/* Close the innermost container. Which bracket is remembered by what was written: an object's + * level is one that took keys - tracked as a bit too. */ +bool ioma_json_end(ioma_json *j) +{ + if (j->failed || j->depth == 0) + return false; + bool object = j->is_object & ((uint64_t)1 << (j->depth & 63U)); + j->depth--; + j->after_key = false; + return put(j, object ? "}" : "]", 1); +} + +bool ioma_json_key(ioma_json *j, const char *name) +{ + if (!separator(j)) + return false; + if (!put_string(j, name, strlen(name)) || !put(j, ":", 1)) + return false; + j->after_key = true; + return true; +} + +bool ioma_json_string(ioma_json *j, ioma_slice s) +{ + return separator(j) && put_string(j, s.p, s.len); +} + +bool ioma_json_cstr(ioma_json *j, const char *s) +{ + return separator(j) && put_string(j, s, strlen(s)); +} + +/* Decimal digits of a magnitude, right-aligned in tmp; the start of them. */ +static char *digits(char *tmp_end, uint64_t v) +{ + char *p = tmp_end; + do { + *--p = (char)('0' + (v % 10)); + v /= 10; + } while (v); + return p; +} + +bool ioma_json_uint(ioma_json *j, uint64_t v) +{ + char tmp[24]; + char *p = digits(tmp + sizeof tmp, v); + return separator(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); +} + +bool ioma_json_int(ioma_json *j, int64_t v) +{ + char tmp[24]; + uint64_t magnitude = v < 0 ? (uint64_t)(-(v + 1)) + 1 : (uint64_t)v; /* INT64_MIN has no positive twin */ + char *p = digits(tmp + sizeof tmp, magnitude); + if (v < 0) + *--p = '-'; + return separator(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); +} + +/* The shortest decimal that reads back as the same double: 15, 16 or 17 significant digits, the + * first that round-trips. snprintf follows the locale's decimal point; JSON wants '.'. */ +bool ioma_json_double(ioma_json *j, double v) +{ + if (!isfinite(v)) + return ioma_json_null(j); + char tmp[32]; + int n = 0; + for (int precision = 15; precision <= 17; precision++) { + n = snprintf(tmp, sizeof tmp, "%.*g", precision, v); + if (n < 0 || strtod(tmp, nullptr) == v) + break; + } + if (n < 0 || (size_t)n >= sizeof tmp) { + j->failed = true; + return false; + } + const char *point = localeconv()->decimal_point; + if (point[0] != '.') { + char *at = strchr(tmp, point[0]); + if (at) + *at = '.'; + } + return separator(j) && put(j, tmp, (size_t)n); +} + +bool ioma_json_bool(ioma_json *j, bool v) +{ + return separator(j) && put_cstr(j, v ? "true" : "false"); +} + +bool ioma_json_null(ioma_json *j) +{ + return separator(j) && put_cstr(j, "null"); +} + +bool ioma_json_raw(ioma_json *j, ioma_slice json) +{ + return separator(j) && put(j, json.p, json.len); +} diff --git a/tests/server.c b/tests/server.c index 7f88258..72c8052 100644 --- a/tests/server.c +++ b/tests/server.c @@ -223,6 +223,47 @@ static void endpoint_header(ioma_ctx *ctx, ioma_next *next) ioma_next_run(ctx, next); } +/* GET /json/:id - a small document, written as you go into the reply. */ +static void json_item(ioma_ctx *ctx) +{ + int64_t id; + if (!ioma_to_i64(ctx->req.route_params[0].value, &id)) { + ctx->res.status = 400; + ioma_text(ctx, "id must be an integer\n"); + return; + } + ioma_json j = ioma_json_reply(ctx); + ioma_json_object(&j); + ioma_json_key(&j, "id"); ioma_json_int(&j, id); + ioma_json_key(&j, "name"); ioma_json_cstr(&j, "Zo\xc3\xab \"Z\" O'Neil\n"); + ioma_json_key(&j, "ratio"); ioma_json_double(&j, 0.1); + ioma_json_key(&j, "ok"); ioma_json_bool(&j, true); + ioma_json_key(&j, "none"); ioma_json_null(&j); + ioma_json_key(&j, "tags"); ioma_json_array(&j); + ioma_json_cstr(&j, "a"); + ioma_json_cstr(&j, "b"); + ioma_json_end(&j); + ioma_json_end(&j); +} + +/* GET /json/big?n=N - N objects in an array, far more than the slab holds: it streams, chunked. */ +static void json_big(ioma_ctx *ctx) +{ + int64_t n = 2000; + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioma_slice_eq(ctx->req.params[i].key, "n")) + ioma_to_i64(ctx->req.params[i].value, &n); + ioma_json j = ioma_json_reply(ctx); + ioma_json_array(&j); + for (int64_t i = 0; i < n; i++) { + ioma_json_object(&j); + ioma_json_key(&j, "i"); ioma_json_int(&j, i); + ioma_json_key(&j, "sq"); ioma_json_int(&j, i * i); + ioma_json_end(&j); + } + ioma_json_end(&j); +} + /* Middleware: stamps a Server header, then runs the rest of the chain. Setting headers before * calling ioma_next_run means they land even on a reply that streams (afterwards the head may * already be on the wire); c->status and the rest are there to inspect on the way back out. @@ -271,6 +312,8 @@ int main(void) IOMA_GET ("/stream", stream); IOMA_POST("/upload", upload); IOMA_POST("/chunks", chunks); + IOMA_GET ("/json/:id", json_item); + IOMA_GET ("/json/big", json_big); /* static beside the capture */ IOMA_DEFAULT(not_found); /* groups: /api with middleware of its own (IOMA_USE inside a block adds to that group; listing diff --git a/tests/smoke.py b/tests/smoke.py index ec4a800..6c82f21 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -303,6 +303,40 @@ def raw_exchange(pieces, pause=0.03): st, hd, body = None, {}, b"" s.close() results.append(check("ignored 2 MB body -> reply served with Connection: close", st == 404 and hd.get("connection") == "close")) +# --- the JSON writer: a document written as you go, and one that streams --- +st, hd, body = get("/json/42") +results.append(check("GET /json/:id -> escaped document, application/json", + st == 200 and hd.get("content-type") == "application/json" + and body == b'{"id":42,"name":"Zo\xc3\xab \\"Z\\" O\'Neil\\n","ratio":0.1,"ok":true,"none":null,"tags":["a","b"]}')) +st, hd, body = get("/json/x") +results.append(check("GET /json/x -> 400 from the handler", st == 400)) + + +def dechunk(raw): + out = b"" + while True: + line, _, raw = raw.partition(b"\r\n") + n = int(line.split(b";")[0], 16) + if n == 0: + return out + out += raw[:n] + raw = raw[n + 2:] + + +s = connect() +s.send(b"GET /json/big?n=3000 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +raw = b"" +while True: + piece = s.recv(65536) + if not piece: + break + raw += piece +s.close() +head, _, rest = raw.partition(b"\r\n\r\n") +doc = __import__("json").loads(dechunk(rest)) +results.append(check("GET /json/big -> 3000 objects streamed chunked, valid JSON", + b"transfer-encoding: chunked" in head.lower() and len(doc) == 3000 and doc[2999] == {"i": 2999, "sq": 2999 * 2999})) + # --- groups: prefixes chain, middleware wraps outer to inner, one endpoint's own middleware --- st, hd, body = get("/api/ping") results.append(check("GET /api/ping -> group prefix, group middleware, root middleware", diff --git a/tests/unit.c b/tests/unit.c index 117a814..a9b4b94 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -4,6 +4,7 @@ */ #include +#include #include #include @@ -186,13 +187,78 @@ static void test_kv_parse(void) CHECK(ioma_kv_parse("page=12", 7, kv, 8, arena, sizeof arena) == 1 && ioma_to_int(kv[0].value, &v) && v == 12); } +/* The JSON writer into memory: what a document looks like, byte for byte. */ +static bool json_is(const char *want, void (*write)(ioma_json *)) +{ + char buf[512]; + size_t len; + ioma_json j = ioma_json_mem(buf, sizeof buf, &len); + write(&j); + return !j.failed && len == strlen(want) && memcmp(buf, want, len) == 0; +} +static void doc_nested(ioma_json *j) +{ + ioma_json_object(j); + ioma_json_key(j, "id"); ioma_json_int(j, 42); + ioma_json_key(j, "name"); ioma_json_cstr(j, "Zo\xc3\xab \"Z\" O'Neil\n\t\x01"); + ioma_json_key(j, "tags"); ioma_json_array(j); ioma_json_cstr(j, "a"); ioma_json_cstr(j, "b"); ioma_json_end(j); + ioma_json_key(j, "empty"); ioma_json_object(j); ioma_json_end(j); + ioma_json_key(j, "none"); ioma_json_null(j); + ioma_json_key(j, "ok"); ioma_json_bool(j, true); + ioma_json_key(j, "raw"); ioma_json_raw(j, S("[1,2]")); + ioma_json_end(j); +} +static void doc_numbers(ioma_json *j) +{ + ioma_json_array(j); + ioma_json_int(j, 0); ioma_json_int(j, -7); ioma_json_int(j, INT64_MIN); ioma_json_int(j, INT64_MAX); + ioma_json_uint(j, UINT64_MAX); + ioma_json_double(j, 0.1); ioma_json_double(j, 2.5); ioma_json_double(j, -0.0); ioma_json_double(j, 1e21); + ioma_json_double(j, 9007199254740993.0); ioma_json_double(j, 1.0 / 3.0); + ioma_json_double(j, INFINITY); ioma_json_double(j, NAN); + ioma_json_end(j); +} +static void doc_top_level(ioma_json *j) { ioma_json_cstr(j, "just a string"); } +static void doc_array_of_arrays(ioma_json *j) +{ + ioma_json_array(j); + ioma_json_array(j); ioma_json_int(j, 1); ioma_json_end(j); + ioma_json_array(j); ioma_json_end(j); + ioma_json_end(j); +} + +static void test_json(void) +{ + CHECK(json_is("{\"id\":42,\"name\":\"Zo\xc3\xab \\\"Z\\\" O'Neil\\n\\t\\u0001\",\"tags\":[\"a\",\"b\"],\"empty\":{},\"none\":null,\"ok\":true,\"raw\":[1,2]}", doc_nested)); + CHECK(json_is("[0,-7,-9223372036854775808,9223372036854775807,18446744073709551615,0.1,2.5,-0,1e+21,9007199254740992,0.3333333333333333,null,null]", doc_numbers)); + CHECK(json_is("\"just a string\"", doc_top_level)); + CHECK(json_is("[[1],[]]", doc_array_of_arrays)); + + char small[8]; + size_t len; + ioma_json j = ioma_json_mem(small, sizeof small, &len); + CHECK(ioma_json_object(&j) && ioma_json_key(&j, "k")); /* {"k": is 5 bytes */ + CHECK(!ioma_json_cstr(&j, "too long for what is left") && j.failed); + CHECK(!ioma_json_int(&j, 1)); /* failed stays failed */ + + char deep[512]; + j = ioma_json_mem(deep, sizeof deep, &len); + bool ok = true; + for (int i = 0; i < IOMA_JSON_DEPTH; i++) + ok = ok && ioma_json_array(&j); + CHECK(ok && !ioma_json_array(&j)); /* one level too many */ + j = ioma_json_mem(deep, sizeof deep, &len); + CHECK(!ioma_json_end(&j)); /* nothing open */ +} + int main(void) { test_integers(); + test_json(); test_doubles(); test_bools(); test_strings(); test_kv_parse(); - printf("unit: %d checks, %d failed\n", checks, failures); + printf("unit: %d checks, %d failed\n", checks, failures); /* test_json ran first, above */ return failures ? 1 : 0; } From d236bf0a98f51ffefad0ac43830cb05898b8a676 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 22:50:43 +0100 Subject: [PATCH 18/49] ioxd: the library's name (was ioma) The C sibling of ioxide, the .NET library this design started from, gets a name that says so and stays four letters: ioxd_ and IOXD_ prefixes, , libioxd, ioxd.pc, the ioxd CMake package, IOXD_WORKERS and IOXD_PORT, the ioxd: log prefix, the server header the fixture sends. Mechanical throughout; nothing else changed. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .clang-tidy | 2 +- .gitignore | 22 +-- ARCHITECTURE.md | 54 +++--- CMakeLists.txt | 114 ++++++------ DESIGN.md | 2 +- Makefile | 74 ++++---- PERF.md | 10 +- README.md | 33 ++-- STREAMS.md | 38 ++-- cmake/iomaConfig.cmake.in | 7 - cmake/ioxdConfig.cmake.in | 7 + include/{ioma.h => ioxd.h} | 352 ++++++++++++++++++------------------- ioma | Bin 0 -> 143904 bytes ioma-hello | Bin 0 -> 264320 bytes ioma.pc.in => ioxd.pc.in | 8 +- lib/http/api.c | 62 +++---- lib/http/engine.c | 250 +++++++++++++------------- lib/http/engine.h | 2 +- lib/http/internal.h | 2 +- lib/http/router.c | 180 +++++++++---------- lib/http/router.h | 6 +- lib/http/run.c | 16 +- lib/io/bufring.c | 14 +- lib/io/bufring.h | 12 +- lib/io/conn.c | 48 ++--- lib/io/conn.h | 12 +- lib/io/pipe.c | 138 +++++++-------- lib/io/pipe.h | 86 ++++----- lib/io/proactor.c | 24 +-- lib/io/proactor.h | 6 +- lib/json/json.c | 72 ++++---- libioma.a | Bin 0 -> 1237342 bytes libioma.so | Bin 0 -> 301776 bytes playground/hello/main.c | 34 ++-- tests/ioma-pipe-server | Bin 0 -> 155304 bytes tests/ioma-test-server | Bin 0 -> 347040 bytes tests/ioma-unit | Bin 0 -> 231584 bytes tests/pipe-server.c | 22 +-- tests/server.c | 280 ++++++++++++++--------------- tests/smoke.py | 14 +- tests/stress.py | 4 +- tests/unit.c | 170 +++++++++--------- 42 files changed, 1089 insertions(+), 1088 deletions(-) delete mode 100644 cmake/iomaConfig.cmake.in create mode 100644 cmake/ioxdConfig.cmake.in rename include/{ioma.h => ioxd.h} (58%) create mode 100755 ioma create mode 100755 ioma-hello rename ioma.pc.in => ioxd.pc.in (62%) create mode 100644 libioma.a create mode 100755 libioma.so create mode 100755 tests/ioma-pipe-server create mode 100755 tests/ioma-test-server create mode 100755 tests/ioma-unit diff --git a/.clang-tidy b/.clang-tidy index faa96af..dbf6e9c 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,4 +1,4 @@ -# clang-tidy configuration for libioma. CLion picks this file up (it prefers a project .clang-tidy +# clang-tidy configuration for libioxd. CLion picks this file up (it prefers a project .clang-tidy # over its own settings); from the shell, with the compile flags the Makefile uses: # # clang-tidy lib/io/*.c lib/http/*.c tests/server.c -- -std=gnu23 -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser diff --git a/.gitignore b/.gitignore index 8d273a5..d4e787c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,16 +2,16 @@ obj/ *.o # libraries and examples -libioma.a -libioma.so -libioma.so.* -ioma-hello -ioma.pc +libioxd.a +libioxd.so +libioxd.so.* +ioxd-hello +ioxd.pc # old binaries -ioma -ioma-tiny -ioma-trace +ioxd +ioxd-tiny +ioxd-trace stackful stackful-tiny stackful-trace @@ -25,6 +25,6 @@ compile_commands.json # IDE .idea/ -tests/ioma-test-server -tests/ioma-unit -tests/ioma-pipe-server +tests/ioxd-test-server +tests/ioxd-unit +tests/ioxd-pipe-server diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 6f24fdf..d16038f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,6 +1,6 @@ -# How libioma works +# How libioxd works -libioma is an HTTP/1.1 server library in C. It runs one worker per CPU core, each worker owns +libioxd is an HTTP/1.1 server library in C. It runs one worker per CPU core, each worker owns its own io_uring, and every connection is served by a small coroutine that suspends while the kernel does the I/O. There are no locks and nothing is shared between workers. @@ -14,12 +14,12 @@ process │ └─ pools: conn objects, coroutine stacks ``` -`include/ioma.h` is the whole public API. Under `lib/` there are two planes, one concern per file: +`include/ioxd.h` is the whole public API. Under `lib/` there are two planes, one concern per file: `io/` is the I/O plane - `uring.c` (the ring), `coro.c` + `switch_x86_64.S` (coroutines), `bufring.c` (the buffer ring), `conn.c` (a connection and its awaits), `proactor.c` (the worker loop), with `proactor.h` as the interface the other plane uses - and `http/` is the HTTP plane - `engine.c` (parse, body, reply, the serve loop), `router.c` (routes and middleware), `api.c` -(handler helpers), `run.c` (`ioma_run`). Each plane has an `internal.h` for what its files share. +(handler helpers), `run.c` (`ioxd_run`). Each plane has an `internal.h` for what its files share. --- @@ -29,7 +29,7 @@ io_uring is two ring buffers shared with the kernel. You write **submission entr "do this") into one ring, the kernel writes **completion entries** (CQEs, "this finished, result N") into the other. One syscall, `io_uring_enter`, both submits and waits. -libioma talks to it directly (`uring.c`), the way ioxide does, with three setup flags: +libioxd talks to it directly (`uring.c`), the way ioxide does, with three setup flags: - **SINGLE_ISSUER** — only this thread submits, so the kernel skips its SQ locking. - **DEFER_TASKRUN** — completion work runs batched inside our `enter` call, never as an interrupt @@ -76,8 +76,8 @@ A **stackful coroutine** is a function running on its own stack that can pause i variables intact. That is what lets a handler be written as plain sequential code: ```c -ioma_pipe_read(pipe, &live); /* pauses here until data arrives */ -ioma_pipe_send(pipe, reply, len); /* pauses here until the send completes */ +ioxd_pipe_read(pipe, &live); /* pauses here until data arrives */ +ioxd_pipe_send(pipe, reply, len); /* pauses here until the send completes */ ``` ### The switch @@ -126,7 +126,7 @@ stages a SEND SQE and parks; the SQE rides the next `enter` together with the re ### Routing a completion -Every SQE carries a 64-bit `user_data`. libioma stores a pointer in it with a 3-bit **tag** in the +Every SQE carries a 64-bit `user_data`. libioxd stores a pointer in it with a 3-bit **tag** in the low bits (everything it points at is 8-byte aligned): | tag | points at | meaning | @@ -152,7 +152,7 @@ therefore never recycled while a completion for it is still coming. ### The two awaits -`ioma__await_item` hands the next queued buffer over whole - the pipe's reader owns it from then +`ioxd__await_item` hands the next queued buffer over whole - the pipe's reader owns it from then until it returns it to the ring - and parks if the queue is empty. `await_send` stages a SEND SQE (`MSG_WAITALL`, so the kernel finishes short sends itself) and parks until its CQE; the pipe's writer is the only caller. Nothing above the pipe touches either. @@ -167,8 +167,8 @@ kernel balances connections over the listeners (`SO_REUSEPORT`), and worker *i* ## 4. Pipes: the reader and the writer -The connection's bytes reach the HTTP engine, or a handler of your own under `ioma_run_pipes`, -through a pipe (`io/pipe.h`; `ioma_pipe` in the public header): a reader over the buffers the +The connection's bytes reach the HTTP engine, or a handler of your own under `ioxd_run_pipes`, +through a pipe (`io/pipe.h`; `ioxd_pipe` in the public header): a reader over the buffers the kernel filled and a writer over a slab. Every call that has to wait suspends the coroutine and the loop resumes it on the completion, so one piece of code drives any connection the I/O plane runs - the shape of .NET's PipeReader and PipeWriter, with coroutines in place of tasks. @@ -200,10 +200,10 @@ raw pipe writes straight. copy). `-2` means "incomplete": read more and parse again, so a request split at any byte works. 2. **Body, on demand**: one pass over the headers picks out `Content-Length`, `Transfer-Encoding` and `Connection` (a length test rejects almost every header before a byte - is compared), but the body stays on the wire. `ioma_body_all` keeps it whole in the reader - in place + is compared), but the body stays on the wire. `ioxd_body_all` keeps it whole in the reader - in place after the head when it all arrived in one receive, gathered otherwise, a chunked one slid - together chunk by chunk; `ioma_body_read_until` streams it, any - size, filling the caller's buffer; `ioma_body_read_next_chunk` hands over one chunk exactly as the + together chunk by chunk; `ioxd_body_read_until` streams it, any + size, filling the caller's buffer; `ioxd_body_read_next_chunk` hands over one chunk exactly as the sender framed it. All three chunked paths share one small parser (a raw stage after the head, a size-line reader, a data mover) that survives a split at any byte. Whatever a handler leaves unread is drained after it returns, up to a limit, past which the reply says close. @@ -212,7 +212,7 @@ raw pipe writes straight. the request and the response; the response holds the reply being shaped (status, content type, headers); the bytes go into the pipe's writer, an 8 KB slab with a lead in front of it for the head and a chunk's size line, and slack behind it for a chunk's CRLF. -5. **Write**: the handler calls `ioma_write` / `ioma_printf`; bytes land in the buffer. If it +5. **Write**: the handler calls `ioxd_write` / `ioxd_printf`; bytes land in the buffer. If it fills, the framework sends what it has — head first, framed chunked on HTTP/1.1 or until close on HTTP/1.0 (or with a length the handler declared) — and the handler suspends on that send. 6. **Finish**: after the chain returns, whatever is buffered goes out. The usual case is that @@ -231,7 +231,7 @@ the handler. Three key/value arrays hang off it, read directly: `headers` (names at parse time, so a plain compare works), `params` (the query, split and percent-decoded into a small per-request arena only when a value needs it, otherwise a zero-copy view), and `route_params` (the `:name` captures the router filled in, in pattern order). A `scratch` arena is there for building -a body (`ioma_textf`). +a body (`ioxd_textf`). --- @@ -239,7 +239,7 @@ a body (`ioma_textf`). Endpoints are registered in groups before the workers start: a group is a path prefix plus middleware, groups nest, and the root (`NULL`) is the group with no prefix whose middleware -`ioma_use` adds. `ioma_run` resolves the whole table once, and after that it is read-only, so +`ioxd_use` adds. `ioxd_run` resolves the whole table once, and after that it is read-only, so every worker reads it without a lock. The resolution turns each endpoint's full path (the prefixes of its groups, outermost first, then @@ -251,20 +251,20 @@ comes to nothing - including when it reaches the end without the request's metho path with only a GET lets a POST fall through to a capture route that has one. Captured segments land in `req->route_params`, named from the endpoint that matched. A path the tree knows without the method is a 405 with an `allow` header; a path it does not know goes to the fallback -(`ioma_default`, a plain 404 unless replaced). Nothing is scanned and nothing is compiled per +(`ioxd_default`, a plain 404 unless replaced). Nothing is scanned and nothing is compiled per request; the tree is the map. Middleware is an onion: each layer receives the context and a `next`; it does work, calls -`ioma_next_run` to continue, and can do more on the way back out, or it replies and returns to +`ioxd_next_run` to continue, and can do more on the way back out, or it replies and returns to short-circuit the request. Each endpoint's chain is flattened at resolution - the root's middleware, then each group's from outermost to innermost, then the endpoint's own - into one array, so dispatch is a call through it with no walking of groups. The fallbacks run behind the root's middleware only. -The `IOMA_` macros are the same registrations as a script: `IOMA_GROUP(prefix, middleware...)` +The `IOXD_` macros are the same registrations as a script: `IOXD_GROUP(prefix, middleware...)` opens a group for the block that follows (a run-once `for`, the group popped when it ends), -`IOMA_GET(path, handler, middleware...)` and its siblings register into the open group, and -`IOMA_USE` adds middleware to it. The middleware lists travel in small structs ended by a null, +`IOXD_GET(path, handler, middleware...)` and its siblings register into the open group, and +`IOXD_USE` adds middleware to it. The middleware lists travel in small structs ended by a null, so every argument is type-checked and a wrong signature is a compile error. ## 7. One keep-alive request, end to end @@ -284,14 +284,14 @@ Two switches in, two out — tens of nanoseconds. The cost of a request is the k ## 8. JSON, written as you go -`lib/json/json.c` is a forward-only writer, the shape of .NET's `Utf8JsonWriter`: `ioma_json_object`, -`ioma_json_key`, `ioma_json_int`, `ioma_json_string`, `ioma_json_end` and so on, each putting its -bytes straight into a sink - the reply through `ioma_reserve`/`ioma_advance`, a raw pipe, or a +`lib/json/json.c` is a forward-only writer, the shape of .NET's `Utf8JsonWriter`: `ioxd_json_object`, +`ioxd_json_key`, `ioxd_json_int`, `ioxd_json_string`, `ioxd_json_end` and so on, each putting its +bytes straight into a sink - the reply through `ioxd_reserve`/`ioxd_advance`, a raw pipe, or a memory buffer - with no tree and no allocation. Strings are escaped as they are copied, a safe run at a time; integers go through a digit loop; a double takes the shortest of 15, 16 or 17 significant digits that reads back as the same value, with the decimal point forced to '.' whatever the locale says. Nesting and the commas it owes are two bits per level, so a document -deeper than `IOMA_JSON_DEPTH` fails cleanly. A reply larger than the slab streams out chunked +deeper than `IOXD_JSON_DEPTH` fails cleanly. A reply larger than the slab streams out chunked while the writer keeps going, which is the whole point of writing as you go. ## Tunables @@ -303,6 +303,6 @@ while the writer keeps going, which is the whole point of writing as you go. | `RX_QUEUE` | 64 | slices a connection may hold undelivered | | `STACK_SIZE` | 64 KB | per coroutine, plus a guard page | | `CORO_POOL_MAX`, `CONN_POOL_MAX` | 512, 1024 | idle stacks / conns kept warm per worker (not connection limits) | -| `IOMA_REQ_CAP` | 16 KB | a request must fit here, else 413/431 | +| `IOXD_REQ_CAP` | 16 KB | a request must fit here, else 413/431 | Override any of them with `-D` at build time. diff --git a/CMakeLists.txt b/CMakeLists.txt index 47fa41b..57ff007 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ -# CMake build for the ioma library plus the playground examples. +# CMake build for the ioxd library plus the playground examples. # # Consume it from another CMake project either as a subdirectory: -# add_subdirectory(ioma) -# target_link_libraries(myapp PRIVATE ioma::ioma) +# add_subdirectory(ioxd) +# target_link_libraries(myapp PRIVATE ioxd::ioxd) # or, after `cmake --install`, via find_package: -# find_package(ioma REQUIRED) -# target_link_libraries(myapp PRIVATE ioma::ioma) +# find_package(ioxd REQUIRED) +# target_link_libraries(myapp PRIVATE ioxd::ioxd) cmake_minimum_required(VERSION 3.21) # PROJECT_IS_TOP_LEVEL, find_program(NO_CACHE) # The compiler: unless one is given (-DCMAKE_C_COMPILER, CC in the environment, a toolchain file), @@ -13,32 +13,32 @@ cmake_minimum_required(VERSION 3.21) # PROJECT_IS_TOP_LEVEL, find_program(NO_C # and the code is C23, which needs gcc 14. Decided before project(), where CMake fixes the # compiler; the make build does the same. if(NOT CMAKE_C_COMPILER AND NOT DEFINED ENV{CC} AND NOT CMAKE_TOOLCHAIN_FILE) - set(ioma_newest_gcc "") - set(ioma_newest_gcc_version 0) + set(ioxd_newest_gcc "") + set(ioxd_newest_gcc_version 0) foreach(candidate gcc gcc-14 gcc-15 gcc-16) unset(candidate_path) find_program(candidate_path ${candidate} NO_CACHE) if(candidate_path) execute_process(COMMAND ${candidate_path} -dumpfullversion OUTPUT_VARIABLE candidate_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) - if(candidate_version VERSION_GREATER ioma_newest_gcc_version) - set(ioma_newest_gcc ${candidate_path}) - set(ioma_newest_gcc_version ${candidate_version}) + if(candidate_version VERSION_GREATER ioxd_newest_gcc_version) + set(ioxd_newest_gcc ${candidate_path}) + set(ioxd_newest_gcc_version ${candidate_version}) endif() endif() endforeach() - if(ioma_newest_gcc) - set(CMAKE_C_COMPILER ${ioma_newest_gcc}) + if(ioxd_newest_gcc) + set(CMAKE_C_COMPILER ${ioxd_newest_gcc}) endif() endif() -project(ioma VERSION 0.1.0 LANGUAGES C ASM) +project(ioxd VERSION 0.1.0 LANGUAGES C ASM) set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) # gnu23: _GNU_SOURCE, statement exprs if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 14) - message(FATAL_ERROR "libioma is C23 and needs gcc 14 or newer; this is gcc ${CMAKE_C_COMPILER_VERSION}. " + message(FATAL_ERROR "libioxd is C23 and needs gcc 14 or newer; this is gcc ${CMAKE_C_COMPILER_VERSION}. " "Configure with -DCMAKE_C_COMPILER=gcc-14 (in CLion: Settings > Build > Toolchains).") endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -52,7 +52,7 @@ find_package(Threads REQUIRED) include(GNUInstallDirs) # --- the library (static by default; -DBUILD_SHARED_LIBS=ON for a .so) --- -add_library(ioma +add_library(ioxd lib/io/uring.c lib/io/coro.c lib/io/switch_x86_64.S @@ -66,74 +66,74 @@ add_library(ioma lib/http/run.c lib/json/json.c third_party/picohttpparser/picohttpparser.c) -add_library(ioma::ioma ALIAS ioma) +add_library(ioxd::ioxd ALIAS ioxd) -target_include_directories(ioma +target_include_directories(ioxd PUBLIC $ - $ + $ PRIVATE lib third_party/picohttpparser) -target_compile_definitions(ioma PRIVATE _GNU_SOURCE) -target_compile_options(ioma PRIVATE -Wall -Wextra) +target_compile_definitions(ioxd PRIVATE _GNU_SOURCE) +target_compile_options(ioxd PRIVATE -Wall -Wextra) # Fat LTO objects when supported: the archive stays plain-linkable, and consumers that link with # -flto get cross-file inlining (the demo below does). include(CheckCCompilerFlag) -check_c_compiler_flag("-flto -ffat-lto-objects" IOMA_HAVE_FAT_LTO) -if(IOMA_HAVE_FAT_LTO) - target_compile_options(ioma PRIVATE -flto -ffat-lto-objects) - target_link_options(ioma PRIVATE -flto) +check_c_compiler_flag("-flto -ffat-lto-objects" IOXD_HAVE_FAT_LTO) +if(IOXD_HAVE_FAT_LTO) + target_compile_options(ioxd PRIVATE -flto -ffat-lto-objects) + target_link_options(ioxd PRIVATE -flto) endif() -target_link_libraries(ioma PUBLIC Threads::Threads) -set_target_properties(ioma PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 0) +target_link_libraries(ioxd PUBLIC Threads::Threads) +set_target_properties(ioxd PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 0) # Vendored parser: silence its warnings, they are not ours to fix. set_source_files_properties(third_party/picohttpparser/picohttpparser.c PROPERTIES COMPILE_OPTIONS "-w") -# --- playground examples (off when ioma is a subproject) --- -option(IOMA_EXAMPLES "Build the playground examples" ${PROJECT_IS_TOP_LEVEL}) -if(IOMA_EXAMPLES) - add_executable(ioma-hello playground/hello/main.c) - target_link_libraries(ioma-hello PRIVATE ioma::ioma) - add_executable(ioma-test-server tests/server.c) - target_link_libraries(ioma-test-server PRIVATE ioma::ioma) - add_executable(ioma-pipe-server tests/pipe-server.c) - target_link_libraries(ioma-pipe-server PRIVATE ioma::ioma) - add_executable(ioma-unit tests/unit.c) - target_link_libraries(ioma-unit PRIVATE ioma::ioma) +# --- playground examples (off when ioxd is a subproject) --- +option(IOXD_EXAMPLES "Build the playground examples" ${PROJECT_IS_TOP_LEVEL}) +if(IOXD_EXAMPLES) + add_executable(ioxd-hello playground/hello/main.c) + target_link_libraries(ioxd-hello PRIVATE ioxd::ioxd) + add_executable(ioxd-test-server tests/server.c) + target_link_libraries(ioxd-test-server PRIVATE ioxd::ioxd) + add_executable(ioxd-pipe-server tests/pipe-server.c) + target_link_libraries(ioxd-pipe-server PRIVATE ioxd::ioxd) + add_executable(ioxd-unit tests/unit.c) + target_link_libraries(ioxd-unit PRIVATE ioxd::ioxd) enable_testing() - add_test(NAME unit COMMAND ioma-unit) - if(IOMA_HAVE_FAT_LTO) - target_compile_options(ioma-hello PRIVATE -flto) - target_link_options(ioma-hello PRIVATE -flto) - target_compile_options(ioma-test-server PRIVATE -flto) - target_link_options(ioma-test-server PRIVATE -flto) + add_test(NAME unit COMMAND ioxd-unit) + if(IOXD_HAVE_FAT_LTO) + target_compile_options(ioxd-hello PRIVATE -flto) + target_link_options(ioxd-hello PRIVATE -flto) + target_compile_options(ioxd-test-server PRIVATE -flto) + target_link_options(ioxd-test-server PRIVATE -flto) endif() endif() -# --- install + export so find_package(ioma) works --- -install(TARGETS ioma EXPORT iomaTargets +# --- install + export so find_package(ioxd) works --- +install(TARGETS ioxd EXPORT ioxdTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(FILES include/ioma.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ioma) -install(EXPORT iomaTargets - NAMESPACE ioma:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioma - FILE iomaTargets.cmake) +install(FILES include/ioxd.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ioxd) +install(EXPORT ioxdTargets + NAMESPACE ioxd:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioxd + FILE ioxdTargets.cmake) # A config file that re-finds the public Threads dependency, then loads the exported targets. include(CMakePackageConfigHelpers) configure_package_config_file( - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/iomaConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/iomaConfig.cmake - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioma) + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ioxdConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/ioxdConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioxd) write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/iomaConfigVersion.cmake + ${CMAKE_CURRENT_BINARY_DIR}/ioxdConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/iomaConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/iomaConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioma) + ${CMAKE_CURRENT_BINARY_DIR}/ioxdConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/ioxdConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioxd) diff --git a/DESIGN.md b/DESIGN.md index ee6120e..cfe6614 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,6 +1,6 @@ # ioxide's TCP core, read for a minimal stackful C runtime -> Note: this is the design record for **ioma** (github.com/MDA2AV/ioma). Paths like `ioxide/...` and `ringzero/...` refer to the author's sibling repos (github.com/MDA2AV/ioxide, github.com/MDA2AV/ringzero); ioma itself is the `stackful/`→`ioma/` runtime described in section 3 and shipped in this repository. +> Note: this is the design record for **ioxd** (github.com/MDA2AV/ioxd). Paths like `ioxide/...` and `ringzero/...` refer to the author's sibling repos (github.com/MDA2AV/ioxide, github.com/MDA2AV/ringzero); ioxd itself is the `stackful/`→`ioxd/` runtime described in section 3 and shipped in this repository. Scope: `ioxide/src/ioxide` — `io_uring/Ring.cs`, `Native/*`, `Reactor/*`, `Reactor/Transport/Tcp/*`, diff --git a/Makefile b/Makefile index 525ad80..d0ce6e8 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ -# ioma - a static and shared library plus the playground examples that link it. +# ioxd - a static and shared library plus the playground examples that link it. # -# make build libioma.a, libioma.so and the examples +# make build libioxd.a, libioxd.so and the examples # make lib just the libraries -# make install install libs, headers (under /include/ioma) and ioma.pc +# make install install libs, headers (under /include/ioxd) and ioxd.pc # sudo make install PREFIX=/usr/local # -# Downstream then builds with: cc app.c $(pkg-config --cflags --libs ioma) -o app +# Downstream then builds with: cc app.c $(pkg-config --cflags --libs ioxd) -o app # The compiler: unless CC is given, the newest gcc on the PATH (a distro's `gcc` is often older # than a `gcc-NN` installed beside it). The code is C23, which needs gcc 14 or newer. @@ -15,7 +15,7 @@ CC := $(if $(CC),$(CC),gcc) endif STD := $(shell $(CC) -std=gnu23 -x c -c /dev/null -o /dev/null 2>/dev/null && echo -std=gnu23) ifeq ($(STD),) -$(error $(CC) does not know -std=gnu23: libioma is C23 and needs gcc 14 or newer (make CC=gcc-14)) +$(error $(CC) does not know -std=gnu23: libioxd is C23 and needs gcc 14 or newer (make CC=gcc-14)) endif AR ?= ar # Fat LTO objects when the compiler supports them: the archive stays linkable by anyone (it also @@ -29,34 +29,34 @@ HDRS := $(wildcard include/*.h lib/*/*.h) PTHREAD := -pthread VERSION := 0.1.0 -SONAME := libioma.so.0 +SONAME := libioxd.so.0 PREFIX ?= /usr/local LIBDIR := $(PREFIX)/lib -INCDIR := $(PREFIX)/include/ioma +INCDIR := $(PREFIX)/include/ioxd PCDIR := $(LIBDIR)/pkgconfig UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run json/json OBJ := $(addprefix obj/,$(addsuffix .o,$(UNITS))) obj/io/switch_x86_64.o obj/picohttpparser.o PICOBJ := $(addprefix obj/pic/,$(addsuffix .o,$(UNITS))) obj/pic/io/switch_x86_64.o obj/pic/picohttpparser.o -EXAMPLES := ioma-hello -TESTSRV := tests/ioma-test-server -PIPESRV := tests/ioma-pipe-server -UNIT := tests/ioma-unit +EXAMPLES := ioxd-hello +TESTSRV := tests/ioxd-test-server +PIPESRV := tests/ioxd-pipe-server +UNIT := tests/ioxd-unit .PHONY: all lib examples check clean install uninstall all: lib examples -lib: libioma.a libioma.so +lib: libioxd.a libioxd.so -libioma.a: $(OBJ) +libioxd.a: $(OBJ) $(AR) rcs $@ $^ -libioma.so: $(PICOBJ) +libioxd.so: $(PICOBJ) $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(PTHREAD) -# --- static objects (used by libioma.a and the examples) --- +# --- static objects (used by libioxd.a and the examples) --- obj/%.o: lib/%.c $(HDRS) @mkdir -p $(@D) $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -c $< -o $@ @@ -67,7 +67,7 @@ obj/picohttpparser.o: third_party/picohttpparser/picohttpparser.c @mkdir -p $(@D) $(CC) $(CFLAGS) -w -Ithird_party/picohttpparser -c $< -o $@ -# --- position-independent objects (used by libioma.so) --- +# --- position-independent objects (used by libioxd.so) --- obj/pic/%.o: lib/%.c $(HDRS) @mkdir -p $(@D) $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -fPIC -c $< -o $@ @@ -81,22 +81,22 @@ obj/pic/picohttpparser.o: third_party/picohttpparser/picohttpparser.c # --- examples link the static library --- examples: $(EXAMPLES) # Link the static archive directly so the example runs in-tree without installing the .so. -ioma-hello: playground/hello/main.c libioma.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) +ioxd-hello: playground/hello/main.c libioxd.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) # --- tests: the unit test, then the fixture server with both suites against it --- -$(TESTSRV): tests/server.c libioma.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) -$(UNIT): tests/unit.c libioma.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) -$(PIPESRV): tests/pipe-server.c libioma.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioma.a -o $@ $(PTHREAD) +$(TESTSRV): tests/server.c libioxd.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) +$(UNIT): tests/unit.c libioxd.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) +$(PIPESRV): tests/pipe-server.c libioxd.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) CHECK_PORT ?= 8099 PIPE_PORT ?= 8100 check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ - IOMA_WORKERS=2 IOMA_PORT=$(CHECK_PORT) ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ + IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ python3 tests/smoke.py $(CHECK_PORT); s=$$?; python3 tests/stress.py $(CHECK_PORT); t=$$?; \ kill -INT $$pid; wait $$pid 2>/dev/null; \ @@ -106,24 +106,24 @@ check: $(TESTSRV) $(UNIT) $(PIPESRV) kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t | u)) # --- pkg-config --- -ioma.pc: ioma.pc.in +ioxd.pc: ioxd.pc.in sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' $< > $@ # --- install / uninstall --- -install: lib ioma.pc +install: lib ioxd.pc install -d $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR) $(DESTDIR)$(PCDIR) - install -m644 libioma.a $(DESTDIR)$(LIBDIR)/ - install -m755 libioma.so $(DESTDIR)$(LIBDIR)/libioma.so.$(VERSION) - ln -sf libioma.so.$(VERSION) $(DESTDIR)$(LIBDIR)/$(SONAME) - ln -sf $(SONAME) $(DESTDIR)$(LIBDIR)/libioma.so - install -m644 include/ioma.h $(DESTDIR)$(INCDIR)/ - install -m644 ioma.pc $(DESTDIR)$(PCDIR)/ - @echo "installed ioma $(VERSION) to $(PREFIX)" + install -m644 libioxd.a $(DESTDIR)$(LIBDIR)/ + install -m755 libioxd.so $(DESTDIR)$(LIBDIR)/libioxd.so.$(VERSION) + ln -sf libioxd.so.$(VERSION) $(DESTDIR)$(LIBDIR)/$(SONAME) + ln -sf $(SONAME) $(DESTDIR)$(LIBDIR)/libioxd.so + install -m644 include/ioxd.h $(DESTDIR)$(INCDIR)/ + install -m644 ioxd.pc $(DESTDIR)$(PCDIR)/ + @echo "installed ioxd $(VERSION) to $(PREFIX)" uninstall: - rm -f $(DESTDIR)$(LIBDIR)/libioma.a $(DESTDIR)$(LIBDIR)/libioma.so* + rm -f $(DESTDIR)$(LIBDIR)/libioxd.a $(DESTDIR)$(LIBDIR)/libioxd.so* rm -rf $(DESTDIR)$(INCDIR) - rm -f $(DESTDIR)$(PCDIR)/ioma.pc + rm -f $(DESTDIR)$(PCDIR)/ioxd.pc clean: - rm -rf obj libioma.a libioma.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioma.pc + rm -rf obj libioxd.a libioxd.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioxd.pc diff --git a/PERF.md b/PERF.md index 9b10c41..abbb212 100644 --- a/PERF.md +++ b/PERF.md @@ -1,6 +1,6 @@ # Performance notes -What has been tried on libioma, what it measured, and what is left. Numbers are saturated +What has been tried on libioxd, what it measured, and what is left. Numbers are saturated keep-alive throughput of the HttpArena baseline handler with the server pinned to 4 cores of an i9-14900K and the load on other cores, unless stated otherwise. Run-to-run noise is about ±1%, so treat anything under that as "no change". Connection churn is the same load with one request per @@ -28,14 +28,14 @@ profiles score. | Registered ring fd (`IORING_REGISTER_RING_FDS`) | not measurable | | Registered file table: direct accept into slots, recv/send/close by index | keep-alive not measurable; churn +3%; connections no longer consume process fds | | PGO (`-fprofile-generate`, train, `-fprofile-use`) on top of LTO | +1.5–2% | -| Request model: the query split into `params` eagerly, header names lower-cased at parse (8 bytes a step) so handlers compare with plain `ioma_slice_eq` | about −1% each; the price of direct data access | +| Request model: the query split into `params` eagerly, header names lower-cased at parse (8 bytes a step) so handlers compare with plain `ioxd_slice_eq` | about −1% each; the price of direct data access | | Parse straight from the provided buffer when a whole request sits in one (the pipe's reader keeps it in place; the copy happens only for a request that spans receives) | neutral, as predicted: the copy it removes was under 1% | | gcc 14 and C23 (was gcc 13 and gnu11) | neutral: 1.23M vs 1.22M req/s keep-alive and equal churn, wrk and oha, three interleaved rounds on 4 reactors. The standard changes what the compiler accepts, not the code it emits | The `-D` switches: `FIXED_FILES=0` disables the file table, `NO_REG_RING` the registered ring fd, `BUF_SIZE`/`BUF_COUNT`/`RING_ENTRIES`/`RX_QUEUE`/`STACK_SIZE`/`CORO_POOL_MAX`/`CONN_POOL_MAX` are A recv that finds the ring empty is logged, at most once a second per worker, with counts: -`ioma: [w3] recv found no provided buffer N times ...: raise BUF_COUNT`. That line is the signal to raise +`ioxd: [w3] recv found no provided buffer N times ...: raise BUF_COUNT`. That line is the signal to raise `-DBUF_COUNT` (a power of two, up to 65536; each buffer is `BUF_SIZE` bytes of the per-worker slab). in `lib/io/bufring.h` and `lib/io/proactor.h`. Both ring features fall back at runtime on kernels that lack them. @@ -61,10 +61,10 @@ At saturation the per-request cost is about 3 µs on the i9 and about 15 µs on and nearly all of it is the kernel: the multishot recv delivery, the send, the TCP stack. The userspace work (parse, route, serialize, two coroutine switches in and two out) is well under a microsecond. That is why the remaining wins are in the low single digits: the peers pay the same -kernel cost, and libioma, libreactor and libxev land within a couple of percent of each other. +kernel cost, and libioxd, libreactor and libxev land within a couple of percent of each other. The 8-CPU saturation profile is the one place where every percent still matters: at the offered -500K req/s libioma sits at ~100% CPU on those cores, and queueing latency explodes near full +500K req/s libioxd sits at ~100% CPU on those cores, and queueing latency explodes near full utilisation, so a 2% cut in CPU per request buys far more than 2% in latency. ## Not worth it here diff --git a/README.md b/README.md index 3072b05..c60cad1 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,47 @@ -# libioma +# libioxd -An HTTP/1.1 server library in C. One worker per core, io_uring underneath with no liburing, and a +An HTTP/1.1 server library in C, the sibling of [ioxide](https://github.com/MDA2AV/ioxide), the .NET +library this design started from. One worker per core, io_uring underneath with no liburing, and a stackful coroutine per connection, so an endpoint is a plain function that takes a request and returns a response. Modelled on [ioxide](https://github.com/MDA2AV/ioxide)'s TCP core. How the runtime works is in [`ARCHITECTURE.md`](ARCHITECTURE.md). ## Build -Run `make` in the repo root. It produces `libioma.a`, `libioma.so` and the demo server -`ioma-hello`. CMake works too. Requirements: Linux 6.x, x86-64, gcc 14 or newer: the code is C23. On Ubuntu 24.04 +Run `make` in the repo root. It produces `libioxd.a`, `libioxd.so` and the demo server +`ioxd-hello`. CMake works too. Requirements: Linux 6.x, x86-64, gcc 14 or newer: the code is C23. On Ubuntu 24.04 `sudo apt install gcc-14`; make and CMake pick the newest gcc they find unless told otherwise. ## Run -`./ioma-hello` is the smallest server: two routes, `GET /hello/:name` and a `POST /repeat/:times` +`./ioxd-hello` is the smallest server: two routes, `GET /hello/:name` and a `POST /repeat/:times` that reads the body and streams it back, one worker per core on port 8080. Ctrl-C stops it. A server exercising every feature of the request and response model is `tests/server.c`, the fixture the test suites run against. ## Use it in your project Install with `make install` (set `PREFIX` to choose where), then build against it with pkg-config -(`ioma`) or CMake (`find_package(ioma)`, link `ioma::ioma`). Adding the repo as a CMake -subdirectory works as well. Include `ioma.h`. Compile and link your program with `-flto` and the +(`ioxd`) or CMake (`find_package(ioxd)`, link `ioxd::ioxd`). Adding the repo as a CMake +subdirectory works as well. Include `ioxd.h`. Compile and link your program with `-flto` and the compiler inlines your handlers into the engine (the library ships fat LTO objects); it is worth about two percent. An endpoint is a function that receives a context holding the request and the response. Everything in the request is a slice (pointer and length); headers, query parameters and route parameters are key/value arrays on it that you read directly, and the body is read only when you -ask: `ioma_body_all` reads it whole, `ioma_body_read_until` streams it, `ioma_body_read_next_chunk` hands over +ask: `ioxd_body_all` reads it whole, `ioxd_body_read_until` streams it, `ioxd_body_read_next_chunk` hands over one chunk at a time, and what you leave unread is drained. -Everything arrives as slices, bytes with a length; `ioma_to_int`, `ioma_to_double`, `ioma_to_bool` and -the `ioma_slice_*` helpers compare and convert them without copying, and fail instead of guessing. -Set the status and content type on the response, add headers with `ioma_header`, and write the -body into its slab with `ioma_write`, `ioma_text` or `ioma_printf`; the framework sends the head -in front of it, in one send when it fits and streamed when it does not. Endpoints live in groups: a group is a path prefix plus middleware, groups nest, and `ioma_get(api, "/users/:id", user)` +Everything arrives as slices, bytes with a length; `ioxd_to_int`, `ioxd_to_double`, `ioxd_to_bool` and +the `ioxd_slice_*` helpers compare and convert them without copying, and fail instead of guessing. +Set the status and content type on the response, add headers with `ioxd_header`, and write the +body into its slab with `ioxd_write`, `ioxd_text` or `ioxd_printf`; the framework sends the head +in front of it, in one send when it fits and streamed when it does not. Endpoints live in groups: a group is a path prefix plus middleware, groups nest, and `ioxd_get(api, "/users/:id", user)` under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware of every group above it; the root -is `NULL`, with `ioma_use` for middleware on everything. `ioma_run` resolves it all once into a segment tree and flat +is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it all once into a segment tree and flat chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port. -Underneath, a connection is a pipe: `ioma_run_pipes` hands a handler of your own the reader and writer the +Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with -the `ioma_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills. The same registrations read as a script with the `IOMA_GET`, `IOMA_GROUP` and `IOMA_USE` macros, a group's block +the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills. The same registrations read as a script with the `IOXD_GET`, `IOXD_GROUP` and `IOXD_USE` macros, a group's block nesting the routes below it; the hello example and `tests/server.c` are written that way. `playground/hello/main.c` is a complete example. diff --git a/STREAMS.md b/STREAMS.md index 7c0352b..684677c 100644 --- a/STREAMS.md +++ b/STREAMS.md @@ -1,12 +1,12 @@ # Streams and pipes over the I/O plane (design, branch `streams`) **Status.** Steps 1 to 4 below are on the branch: `io/pipe.h` (reader, writer), the HTTP engine -reading through the reader with the in-place fast path, and the public `ioma_pipe` with -`ioma_run_pipes`, a line-echo fixture and its tests. The reader's verbs ended up as examine / +reading through the reader with the in-place fast path, and the public `ioxd_pipe` with +`ioxd_run_pipes`, a line-echo fixture and its tests. The reader's verbs ended up as examine / drop / keep / copy rather than one `advance(consumed, examined)`, because kept bytes - the request model's slices - need to stay put, which Pipelines has no notion of. Open, to talk about: the public surface (run_begin/run stay private for now); outbound connections -(`ioma_connect` on IORING_OP_CONNECT, the same pipe over a socket to a database or a peer); +(`ioxd_connect` on IORING_OP_CONNECT, the same pipe over a socket to a database or a peer); a second transport (QUIC, TLS) and whether that wants a vtable; letting the live bytes sit in a second kernel buffer while a run continues in the first, so streamed bodies never copy twice. @@ -31,28 +31,28 @@ suspend the coroutine"; the caller does not see it. ## The pieces -**`ioma_pipewriter`** - the slab with a head reserve, a tail, and a connection to flush to. +**`ioxd_pipewriter`** - the slab with a head reserve, a tail, and a connection to flush to. - void *ioma_pipewriter_reserve(w, size_t n); /* n bytes at the tail, flushing first if they do not fit */ - void ioma_pipewriter_advance(w, size_t n); /* the caller wrote n of them */ - int ioma_pipewriter_write (w, data, n); /* copy in (reserve + memcpy + advance) */ - int ioma_pipewriter_flush (w); /* send what is in the slab; suspends */ - int ioma_pipewriter_send (w, data, n); /* write + flush */ + void *ioxd_pipewriter_reserve(w, size_t n); /* n bytes at the tail, flushing first if they do not fit */ + void ioxd_pipewriter_advance(w, size_t n); /* the caller wrote n of them */ + int ioxd_pipewriter_write (w, data, n); /* copy in (reserve + memcpy + advance) */ + int ioxd_pipewriter_flush (w); /* send what is in the slab; suspends */ + int ioxd_pipewriter_send (w, data, n); /* write + flush */ The HTTP response keeps its head-building on top (first flush builds the head into the lead). -`ioma_write`, `ioma_printf`, `ioma_flush` become thin calls; `ioma_reserve`/`ioma_advance` are new +`ioxd_write`, `ioxd_printf`, `ioxd_flush` become thin calls; `ioxd_reserve`/`ioxd_advance` are new on the context, for handlers that format straight into the reply. -**`ioma_pipereader`** - the connection's received bytes, one contiguous span at a time. +**`ioxd_pipereader`** - the connection's received bytes, one contiguous span at a time. - int ioma_pipereader_read (r, ioma_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ - void ioma_pipereader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ - int ioma_pipereader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ + int ioxd_pipereader_read (r, ioxd_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ + void ioxd_pipereader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ + int ioxd_pipereader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ Why one span and not a list of segments. io_uring hands data over as provided buffers, each a pointer and a length, and the reader keeps them as such internally (the rx queue does already). But every consumer needs contiguous bytes: picohttpparser takes one buffer, the chunk parser -takes one buffer, and the request model hands handlers `ioma_slice`s, which are contiguous by +takes one buffer, and the request model hands handlers `ioxd_slice`s, which are contiguous by definition - a header value split across two provided buffers cannot be a slice without a copy. A segment-aware parser would not remove that copy, only move it, and the parser would be ours to write and to keep fast. So the reader coalesces, and it does so lazily: @@ -69,7 +69,7 @@ parser, and `advance(consumed, examined)` is Pipelines' contract: `consumed` rel `examined` keeps `read` from returning the same incomplete head twice - it suspends until more arrives instead. -**`ioma_stream`** - one connection's reader and writer together, what a handler of a non-HTTP +**`ioxd_stream`** - one connection's reader and writer together, what a handler of a non-HTTP protocol would receive. ## The HTTP engine on top @@ -78,7 +78,7 @@ protocol would receive. that is the provided buffer itself - no copy - and the request's slices point into it; the buffer stays owned by the connection until the reply is finished, when `advance` returns it. A head that spans receives arrives coalesced in the request buffer, as today. -- Body reads (`ioma_body_all`, `read_until`, `read_next_chunk`) run the chunk parser on spans +- Body reads (`ioxd_body_all`, `read_until`, `read_next_chunk`) run the chunk parser on spans the same way; the whole read wants contiguous output and gets it from the same coalescing. - Pipelining falls out: the bytes after a request are simply not consumed. - The reply: unchanged behaviour, on the writer. @@ -97,10 +97,10 @@ protocol would receive. ## Order of work 1. Writer: reserve/advance/write/flush/send in the io plane; the response on it; - `ioma_reserve`/`ioma_advance` public. Small, no behaviour change, measurable. + `ioxd_reserve`/`ioxd_advance` public. Small, no behaviour change, measurable. 2. Reader with `copy` only (Stream semantics) and the engine's `read_head` and body stage on it, still copying. Same behaviour, same numbers expected. Removes `await_recv` from the engine. 3. Spans + `advance(consumed, examined)`, then the zero-copy single-buffer path. This is the step with a payoff and the risk; it gets the fragmentation validator and the raw-socket smoke tests. -4. `ioma_stream` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. +4. `ioxd_stream` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. diff --git a/cmake/iomaConfig.cmake.in b/cmake/iomaConfig.cmake.in deleted file mode 100644 index 3dddfbe..0000000 --- a/cmake/iomaConfig.cmake.in +++ /dev/null @@ -1,7 +0,0 @@ -@PACKAGE_INIT@ - -# ioma links pthreads publicly, so a consumer must re-find it before the targets load. -include(CMakeFindDependencyMacro) -find_dependency(Threads) - -include("${CMAKE_CURRENT_LIST_DIR}/iomaTargets.cmake") diff --git a/cmake/ioxdConfig.cmake.in b/cmake/ioxdConfig.cmake.in new file mode 100644 index 0000000..063e440 --- /dev/null +++ b/cmake/ioxdConfig.cmake.in @@ -0,0 +1,7 @@ +@PACKAGE_INIT@ + +# ioxd links pthreads publicly, so a consumer must re-find it before the targets load. +include(CMakeFindDependencyMacro) +find_dependency(Threads) + +include("${CMAKE_CURRENT_LIST_DIR}/ioxdTargets.cmake") diff --git a/include/ioma.h b/include/ioxd.h similarity index 58% rename from include/ioma.h rename to include/ioxd.h index 124aa49..ed453b3 100644 --- a/include/ioma.h +++ b/include/ioxd.h @@ -1,5 +1,5 @@ /* - * ioma.h - the libioma API: what you write endpoints against. The one header that is installed. + * ioxd.h - the libioxd API: what you write endpoints against. The one header that is installed. * * Every request gets a context: the request, the response, and a slot for your own data. The * context is passed to each middleware and to the handler, and any of them may read the request @@ -10,13 +10,13 @@ * The handler runs on the connection's coroutine, so a read or a write that has to touch the * wire simply suspends it until the I/O completes. * - * static void user(ioma_ctx *ctx) { - * ioma_slice id = ctx->req.route_params[0].value; // the :id of "/users/:id" - * ioma_printf(c, "user %.*s\n", (int)id.len, id.p); + * static void user(ioxd_ctx *ctx) { + * ioxd_slice id = ctx->req.route_params[0].value; // the :id of "/users/:id" + * ioxd_printf(c, "user %.*s\n", (int)id.len, id.p); * } * int main(void) { - * ioma_route("GET", "/users/:id", user); - * return ioma_run(0, 8080); // one worker per core + * ioxd_route("GET", "/users/:id", user); + * return ioxd_run(0, 8080); // one worker per core * } */ #pragma once @@ -25,50 +25,50 @@ #include #include -#ifndef IOMA_MAX_HEADERS -#define IOMA_MAX_HEADERS 64 /* request headers kept */ +#ifndef IOXD_MAX_HEADERS +#define IOXD_MAX_HEADERS 64 /* request headers kept */ #endif -#ifndef IOMA_MAX_PARAMS -#define IOMA_MAX_PARAMS 32 /* query parameters kept */ +#ifndef IOXD_MAX_PARAMS +#define IOXD_MAX_PARAMS 32 /* query parameters kept */ #endif -#ifndef IOMA_MAX_ROUTE_PARAMS -#define IOMA_MAX_ROUTE_PARAMS 8 /* :name captures a route pattern may have */ +#ifndef IOXD_MAX_ROUTE_PARAMS +#define IOXD_MAX_ROUTE_PARAMS 8 /* :name captures a route pattern may have */ #endif -#ifndef IOMA_MAX_RESP_HEADERS -#define IOMA_MAX_RESP_HEADERS 16 /* headers a reply may add */ +#ifndef IOXD_MAX_RESP_HEADERS +#define IOXD_MAX_RESP_HEADERS 16 /* headers a reply may add */ #endif /* A slice: pointer + length, the C span. Not NUL-terminated. */ -typedef struct { const char *p; size_t len; } ioma_slice; +typedef struct { const char *p; size_t len; } ioxd_slice; /* One key/value pair of slices: a header, a query parameter, a route parameter. */ -typedef struct { ioma_slice key, value; } ioma_kv; +typedef struct { ioxd_slice key, value; } ioxd_kv; /* ── the request ───────────────────────────────────────────────────────────────────────── */ /* All the data of a request, as slices into the connection's read buffer (decoded parameters * into a per-request arena), valid only until the handler returns. Read the arrays directly; * header names are lower-cased, so compare them with lowercase literals. The body is not here - * until you ask for it: ioma_body reads it whole, ioma_body_read streams it. */ -typedef struct ioma_request { - ioma_slice method; /* "GET", "POST", ... */ - ioma_slice target; /* raw request target: path plus any query */ - ioma_slice path; /* the path, query stripped */ - ioma_slice query; /* raw text after '?', undecoded */ + * until you ask for it: ioxd_body reads it whole, ioxd_body_read streams it. */ +typedef struct ioxd_request { + ioxd_slice method; /* "GET", "POST", ... */ + ioxd_slice target; /* raw request target: path plus any query */ + ioxd_slice path; /* the path, query stripped */ + ioxd_slice query; /* raw text after '?', undecoded */ int minor_version; /* 0 or 1 for HTTP/1.0 or 1.1 */ - ioma_kv headers[IOMA_MAX_HEADERS]; /* names lower-cased, values as received */ + ioxd_kv headers[IOXD_MAX_HEADERS]; /* names lower-cased, values as received */ size_t n_headers; - ioma_kv params[IOMA_MAX_PARAMS]; /* query parameters, percent-decoded */ + ioxd_kv params[IOXD_MAX_PARAMS]; /* query parameters, percent-decoded */ size_t n_params; - ioma_kv route_params[IOMA_MAX_ROUTE_PARAMS]; /* the :name captures, in pattern order */ + ioxd_kv route_params[IOXD_MAX_ROUTE_PARAMS]; /* the :name captures, in pattern order */ size_t n_route_params; size_t content_length; /* what the head declared; 0 if nothing */ bool chunked; /* the body is chunked: length unknown */ - ioma_slice body; /* the whole body, once ioma_body read it */ + ioxd_slice body; /* the whole body, once ioxd_body read it */ bool keep_alive; /* computed from version + Connection */ -} ioma_request; +} ioxd_request; /* ── the response ──────────────────────────────────────────────────────────────────────── */ @@ -76,36 +76,36 @@ typedef struct ioma_request { * sent and emptied, and the head (status, content type, headers) goes out in front of the first * send - after the chain when everything fit, earlier when the body streams - and is frozen from * then on (head_sent). You may write into buf + len yourself and advance len, up to cap. */ -typedef struct ioma_response { +typedef struct ioxd_response { int status; /* 200 by default */ - ioma_slice content_type; /* "text/plain" by default; any slice */ - ioma_kv headers[IOMA_MAX_RESP_HEADERS]; /* added with ioma_header */ + ioxd_slice content_type; /* "text/plain" by default; any slice */ + ioxd_kv headers[IOXD_MAX_RESP_HEADERS]; /* added with ioxd_header */ size_t n_headers; bool close; /* close the connection after this reply */ bool head_sent; - size_t content_length; /* declared with ioma_content_length */ + size_t content_length; /* declared with ioxd_content_length */ bool has_length; bool chunked, failed; /* private: how a stream is framed; peer gone */ -} ioma_response; +} ioxd_response; /* ── the context ───────────────────────────────────────────────────────────────────────── */ -typedef struct ioma_ctx { - ioma_request req; - ioma_response res; +typedef struct ioxd_ctx { + ioxd_request req; + ioxd_response res; void *user; /* free slot: middleware hands data to the handler */ void *priv; /* the engine's own state */ -} ioma_ctx; +} ioxd_ctx; -typedef void (*ioma_handler)(ioma_ctx *ctx); +typedef void (*ioxd_handler)(ioxd_ctx *ctx); -/* Middleware runs around the handler (the onion model): shape the context, call ioma_next_run to +/* Middleware runs around the handler (the onion model): shape the context, call ioxd_next_run to * run the rest of the chain and then the endpoint, then act on the result - or write a reply and - * return WITHOUT calling ioma_next_run to short-circuit (auth failure, cache hit). */ -typedef struct ioma_next ioma_next; -typedef void (*ioma_mw)(ioma_ctx *ctx, ioma_next *next); -void ioma_next_run(ioma_ctx *ctx, ioma_next *next); + * return WITHOUT calling ioxd_next_run to short-circuit (auth failure, cache hit). */ +typedef struct ioxd_next ioxd_next; +typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next); +void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next); /* ── the body ──────────────────────────────────────────────────────────────────────────── */ @@ -113,51 +113,51 @@ void ioma_next_run(ioma_ctx *ctx, ioma_next *next); * must fit the buffer (16 KB by default): otherwise the slice is empty and res.status is 413, * which becomes the reply - a handler that streams its reply should check and stop. Not after * one of the reads below. */ -ioma_slice ioma_body_all(ioma_ctx *ctx); +ioxd_slice ioxd_body_all(ioxd_ctx *ctx); /* The next bytes of the body into dst, reading until n are there or the body ends. Returns the * count (less than n only at the end), 0 once it is all consumed, -1 on error (the connection * then closes after the reply). Any size of body, nothing kept in the engine. */ -int ioma_body_read_until(ioma_ctx *ctx, void *dst, size_t n); +int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n); /* The next chunk of a chunked body, exactly as the sender framed it, into dst: the rest of the * current chunk when a read stopped inside one, else the next whole one. Returns its length, 0 at * the last chunk, -1 on error - a chunk larger than cap is a 413 - or when the body is not * chunked. */ -int ioma_body_read_next_chunk(ioma_ctx *ctx, void *dst, size_t cap); +int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap); /* ── the reply ─────────────────────────────────────────────────────────────────────────── */ /* Body writes into the slab. When it fills, it is sent - head first - and the body streams from * then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. * Return 0, or -1 once the peer is gone (further writes are ignored). */ -int ioma_write (ioma_ctx *ctx, const void *data, size_t len); +int ioxd_write (ioxd_ctx *ctx, const void *data, size_t len); /* Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr * once the peer is gone or n exceeds the slab) and advance by what was written. */ -void *ioma_reserve(ioma_ctx *ctx, size_t n); -void ioma_advance(ioma_ctx *ctx, size_t n); -int ioma_text (ioma_ctx *ctx, const char *s); /* a C string */ -int ioma_printf(ioma_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ +void *ioxd_reserve(ioxd_ctx *ctx, size_t n); +void ioxd_advance(ioxd_ctx *ctx, size_t n); +int ioxd_text (ioxd_ctx *ctx, const char *s); /* a C string */ +int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ -/* Shape the head. Only before it is sent: ioma_header returns false afterwards. */ -bool ioma_header (ioma_ctx *ctx, const char *name, const char *value); /* both stay valid until sent; the name is sent lower-cased */ -void ioma_content_type (ioma_ctx *ctx, const char *type); -void ioma_content_length(ioma_ctx *ctx, size_t n); /* stream a large body with a known length */ -int ioma_flush (ioma_ctx *ctx); /* send what is in the slab now (starts streaming) */ +/* Shape the head. Only before it is sent: ioxd_header returns false afterwards. */ +bool ioxd_header (ioxd_ctx *ctx, const char *name, const char *value); /* both stay valid until sent; the name is sent lower-cased */ +void ioxd_content_type (ioxd_ctx *ctx, const char *type); +void ioxd_content_length(ioxd_ctx *ctx, size_t n); /* stream a large body with a known length */ +int ioxd_flush (ioxd_ctx *ctx); /* send what is in the slab now (starts streaming) */ /* ── slices ────────────────────────────────────────────────────────────────────────────── */ /* Everything a request carries is a slice: bytes with a length, not NUL-terminated, valid until * the handler returns. These compare and convert one without copying it. */ -bool ioma_slice_eq (ioma_slice s, const char *cstr); /* exact */ -bool ioma_slice_eq_ci (ioma_slice s, const char *cstr); /* ASCII case-insensitive */ -bool ioma_slice_starts_with(ioma_slice s, const char *prefix); -bool ioma_slice_ends_with (ioma_slice s, const char *suffix); -ioma_slice ioma_slice_trim (ioma_slice s); /* no leading/trailing space, tab, CR, LF */ +bool ioxd_slice_eq (ioxd_slice s, const char *cstr); /* exact */ +bool ioxd_slice_eq_ci (ioxd_slice s, const char *cstr); /* ASCII case-insensitive */ +bool ioxd_slice_starts_with(ioxd_slice s, const char *prefix); +bool ioxd_slice_ends_with (ioxd_slice s, const char *suffix); +ioxd_slice ioxd_slice_trim (ioxd_slice s); /* no leading/trailing space, tab, CR, LF */ /* A NUL-terminated copy in buf, for whatever wants a C string. False when it did not fit: buf * then holds what fit, still terminated (cap 0 writes nothing). */ -bool ioma_cstr(ioma_slice s, char *buf, size_t cap); +bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap); /* Conversions. The whole slice must be the value - nothing around it, nothing after it - and a * number that does not fit the type fails. On failure *out is left alone and false comes back, @@ -165,110 +165,110 @@ bool ioma_cstr(ioma_slice s, char *buf, size_t cap); * Doubles: also a fraction and an exponent ("2.5", ".5", "1e-3"); never inf, nan or hex; too * large fails, too small rounds towards zero. * Booleans: true/false, 1/0, yes/no, on/off, any case. */ -bool ioma_to_int (ioma_slice s, int *out); -bool ioma_to_i64 (ioma_slice s, int64_t *out); -bool ioma_to_u64 (ioma_slice s, uint64_t *out); -bool ioma_to_double(ioma_slice s, double *out); -bool ioma_to_bool (ioma_slice s, bool *out); +bool ioxd_to_int (ioxd_slice s, int *out); +bool ioxd_to_i64 (ioxd_slice s, int64_t *out); +bool ioxd_to_u64 (ioxd_slice s, uint64_t *out); +bool ioxd_to_double(ioxd_slice s, double *out); +bool ioxd_to_bool (ioxd_slice s, bool *out); /* Parse "k=v&k2=v2" - a query string, a form body - into out, up to cap pairs. Keys and values * that need it ('+', %XX) are decoded into arena and point there; the rest are views of s. * Returns the pair count. A pair that does not fit the arena is skipped. */ -size_t ioma_kv_parse(const char *text, size_t len, ioma_kv *out, size_t cap, char *arena, size_t arena_cap); +size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap); /* ── routing ───────────────────────────────────────────────────────────────────────────── */ /* Endpoints live in groups, and groups nest. A group is a path prefix plus middleware: an * endpoint "/users" in a group "/api" under a group "/v1" answers at "/v1/api/users", wrapped by * the middleware of every group above it, outermost first, then its own. NULL as the group is - * the root: no prefix, and the middleware given to ioma_use. + * the root: no prefix, and the middleware given to ioxd_use. * - * Register everything before ioma_run, from the main thread. ioma_run resolves it once: every + * Register everything before ioxd_run, from the main thread. ioxd_run resolves it once: every * endpoint's full path into a segment tree and its middleware into one flat chain, which the * workers then share read-only. A request costs one walk down the tree - no scan, no regex - and * one call through its chain. */ -typedef struct ioma_group ioma_group; -typedef struct ioma_endpoint ioma_endpoint; +typedef struct ioxd_group ioxd_group; +typedef struct ioxd_endpoint ioxd_endpoint; -ioma_group *ioma_group_new(ioma_group *parent, const char *prefix); /* "/api"; "" for middleware only */ -void ioma_group_use(ioma_group *group, ioma_mw mw); /* wraps everything below it */ +ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix); /* "/api"; "" for middleware only */ +void ioxd_group_use(ioxd_group *group, ioxd_mw mw); /* wraps everything below it */ /* An endpoint: method matched exactly; path matched by segment below the group's prefix, with * :name captures ("/users/:id") landing in req.route_params. A static segment beats a capture at * any depth, and a static path that lacks the method falls through to a capture route that has * it. A trailing slash is tolerated. */ -ioma_endpoint *ioma_route(ioma_group *group, const char *method, const char *path, ioma_handler fn); -void ioma_endpoint_use(ioma_endpoint *endpoint, ioma_mw mw); /* wraps this one only */ +ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn); +void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw); /* wraps this one only */ -/* The verbs, for short: ioma_get(api, "/users/:id", user). */ -static inline ioma_endpoint *ioma_get (ioma_group *g, const char *path, ioma_handler fn) { return ioma_route(g, "GET", path, fn); } -static inline ioma_endpoint *ioma_post (ioma_group *g, const char *path, ioma_handler fn) { return ioma_route(g, "POST", path, fn); } -static inline ioma_endpoint *ioma_put (ioma_group *g, const char *path, ioma_handler fn) { return ioma_route(g, "PUT", path, fn); } -static inline ioma_endpoint *ioma_patch (ioma_group *g, const char *path, ioma_handler fn) { return ioma_route(g, "PATCH", path, fn); } -static inline ioma_endpoint *ioma_delete(ioma_group *g, const char *path, ioma_handler fn) { return ioma_route(g, "DELETE", path, fn); } +/* The verbs, for short: ioxd_get(api, "/users/:id", user). */ +static inline ioxd_endpoint *ioxd_get (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "GET", path, fn); } +static inline ioxd_endpoint *ioxd_post (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "POST", path, fn); } +static inline ioxd_endpoint *ioxd_put (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PUT", path, fn); } +static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PATCH", path, fn); } +static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "DELETE", path, fn); } /* Root middleware: every request, the fallbacks included. */ -void ioma_use(ioma_mw mw); +void ioxd_use(ioxd_mw mw); /* The fallback when no path matches (a built-in 404 by default). A path that matches without the * method gets a built-in 405 with an allow header. */ -void ioma_default(ioma_handler fn); +void ioxd_default(ioxd_handler fn); /* ── the same, as a script ─────────────────────────────────────────────────────────────── */ -/* Registration as a block-structured script: a current group, which the block after IOMA_GROUP +/* Registration as a block-structured script: a current group, which the block after IOXD_GROUP * sets (the root outside any block), endpoints registered into it, with their own middleware - * listed after the handler, and IOMA_USE adding middleware to it - so a group's middleware is - * either listed after its prefix or added with IOMA_USE inside its block. Plain functions + * listed after the handler, and IOXD_USE adding middleware to it - so a group's middleware is + * either listed after its prefix or added with IOXD_USE inside its block. Plain functions * underneath, so everything is type-checked; a group's block runs exactly once (do not break out * of it). * - * IOMA_USE(log); - * IOMA_GET("/", home); - * IOMA_GROUP("/api", api_header) { - * IOMA_GET("/ping", ping); - * IOMA_GROUP("/admin", require_token) { - * IOMA_GET("/stats", stats, timing); + * IOXD_USE(log); + * IOXD_GET("/", home); + * IOXD_GROUP("/api", api_header) { + * IOXD_GET("/ping", ping); + * IOXD_GROUP("/admin", require_token) { + * IOXD_GET("/stats", stats, timing); * } * } */ -#define IOMA_MAX_MW 16 /* middleware per group and per endpoint */ -struct ioma_group_args { const char *prefix; ioma_mw mws[IOMA_MAX_MW + 1]; }; /* +1: the ending null */ -struct ioma_endpoint_args { const char *path; ioma_handler fn; ioma_mw mws[IOMA_MAX_MW + 1]; }; +#define IOXD_MAX_MW 16 /* middleware per group and per endpoint */ +struct ioxd_group_args { const char *prefix; ioxd_mw mws[IOXD_MAX_MW + 1]; }; /* +1: the ending null */ +struct ioxd_endpoint_args { const char *path; ioxd_handler fn; ioxd_mw mws[IOXD_MAX_MW + 1]; }; /* What the macros call: the current group's stack and an endpoint with a middleware list. */ -ioma_group *ioma__group_begin(struct ioma_group_args args); -ioma_group *ioma__group_end(void); -ioma_group *ioma__group_current(void); -ioma_endpoint *ioma__endpoint(const char *method, struct ioma_endpoint_args args); +ioxd_group *ioxd__group_begin(struct ioxd_group_args args); +ioxd_group *ioxd__group_end(void); +ioxd_group *ioxd__group_current(void); +ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args); /* The argument lists become the structs above. An argument count picks the expansion, so the * middleware list always has its own braces and no macro is ever invoked with an empty variadic * part: clean under -Wall -Wextra -pedantic, in C11 and later. */ -#define IOMA__CAT2(a, b) a##b -#define IOMA__CAT(a, b) IOMA__CAT2(a, b) -#define IOMA__PICK(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, name, ...) name -#define IOMA__RW(path, fn, ...) (struct ioma_endpoint_args){ (path), (fn), { __VA_ARGS__, NULL } } -#define IOMA__RB(path, fn) (struct ioma_endpoint_args){ (path), (fn), { NULL } } -#define IOMA__ROUTE_ARGS(...) IOMA__PICK(__VA_ARGS__, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, \ - IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, IOMA__RW, \ - IOMA__RW, IOMA__RW, IOMA__RB, IOMA__RB, IOMA__RB)(__VA_ARGS__) -#define IOMA__GW(prefix, ...) (struct ioma_group_args){ (prefix), { __VA_ARGS__, NULL } } -#define IOMA__GB(prefix) (struct ioma_group_args){ (prefix), { NULL } } -#define IOMA__GROUP_ARGS(...) IOMA__PICK(__VA_ARGS__, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, \ - IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GW, \ - IOMA__GW, IOMA__GW, IOMA__GW, IOMA__GB, IOMA__GB)(__VA_ARGS__) - -#define IOMA_GROUP(...) \ - for (ioma_group *IOMA__CAT(ioma__block_, __LINE__) = ioma__group_begin(IOMA__GROUP_ARGS(__VA_ARGS__)); \ - IOMA__CAT(ioma__block_, __LINE__); IOMA__CAT(ioma__block_, __LINE__) = ioma__group_end()) -#define IOMA_USE(mw) ioma_group_use(ioma__group_current(), (mw)) -#define IOMA_ROUTE(method, ...) ioma__endpoint((method), IOMA__ROUTE_ARGS(__VA_ARGS__)) -#define IOMA_GET(...) IOMA_ROUTE("GET", __VA_ARGS__) -#define IOMA_POST(...) IOMA_ROUTE("POST", __VA_ARGS__) -#define IOMA_PUT(...) IOMA_ROUTE("PUT", __VA_ARGS__) -#define IOMA_PATCH(...) IOMA_ROUTE("PATCH", __VA_ARGS__) -#define IOMA_DELETE(...) IOMA_ROUTE("DELETE", __VA_ARGS__) -#define IOMA_DEFAULT(fn) ioma_default(fn) +#define IOXD__CAT2(a, b) a##b +#define IOXD__CAT(a, b) IOXD__CAT2(a, b) +#define IOXD__PICK(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, name, ...) name +#define IOXD__RW(path, fn, ...) (struct ioxd_endpoint_args){ (path), (fn), { __VA_ARGS__, NULL } } +#define IOXD__RB(path, fn) (struct ioxd_endpoint_args){ (path), (fn), { NULL } } +#define IOXD__ROUTE_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RB, IOXD__RB, IOXD__RB)(__VA_ARGS__) +#define IOXD__GW(prefix, ...) (struct ioxd_group_args){ (prefix), { __VA_ARGS__, NULL } } +#define IOXD__GB(prefix) (struct ioxd_group_args){ (prefix), { NULL } } +#define IOXD__GROUP_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GB, IOXD__GB)(__VA_ARGS__) + +#define IOXD_GROUP(...) \ + for (ioxd_group *IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_begin(IOXD__GROUP_ARGS(__VA_ARGS__)); \ + IOXD__CAT(ioxd__block_, __LINE__); IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_end()) +#define IOXD_USE(mw) ioxd_group_use(ioxd__group_current(), (mw)) +#define IOXD_ROUTE(method, ...) ioxd__endpoint((method), IOXD__ROUTE_ARGS(__VA_ARGS__)) +#define IOXD_GET(...) IOXD_ROUTE("GET", __VA_ARGS__) +#define IOXD_POST(...) IOXD_ROUTE("POST", __VA_ARGS__) +#define IOXD_PUT(...) IOXD_ROUTE("PUT", __VA_ARGS__) +#define IOXD_PATCH(...) IOXD_ROUTE("PATCH", __VA_ARGS__) +#define IOXD_DELETE(...) IOXD_ROUTE("DELETE", __VA_ARGS__) +#define IOXD_DEFAULT(fn) ioxd_default(fn) /* ── JSON, written as you go ───────────────────────────────────────────────────────────── */ @@ -277,24 +277,24 @@ ioma_endpoint *ioma__endpoint(const char *method, struct ioma_endpoint_args args * and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what * it means: * - * ioma_json j = ioma_json_reply(ctx); // content-type: application/json - * ioma_json_object(&j); - * ioma_json_key(&j, "id"); ioma_json_int(&j, id); - * ioma_json_key(&j, "name"); ioma_json_string(&j, name); - * ioma_json_key(&j, "tags"); ioma_json_array(&j); - * ioma_json_cstr(&j, "new"); - * ioma_json_end(&j); - * ioma_json_end(&j); + * ioxd_json j = ioxd_json_reply(ctx); // content-type: application/json + * ioxd_json_object(&j); + * ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); + * ioxd_json_key(&j, "name"); ioxd_json_string(&j, name); + * ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + * ioxd_json_cstr(&j, "new"); + * ioxd_json_end(&j); + * ioxd_json_end(&j); * * Strings are taken as UTF-8 and passed through; '"', '\' and control characters are escaped. * Every call returns false once the sink is gone (the peer left; the buffer is full) or the - * nesting passed IOMA_JSON_DEPTH, and the rest is dropped, so checking the last call is enough. */ -#define IOMA_JSON_DEPTH 64 -typedef struct ioma_json { - enum { IOMA_JSON_TO_REPLY, IOMA_JSON_TO_PIPE, IOMA_JSON_TO_MEM } kind; + * nesting passed IOXD_JSON_DEPTH, and the rest is dropped, so checking the last call is enough. */ +#define IOXD_JSON_DEPTH 64 +typedef struct ioxd_json { + enum { IOXD_JSON_TO_REPLY, IOXD_JSON_TO_PIPE, IOXD_JSON_TO_MEM } kind; union { - ioma_ctx *ctx; - struct ioma_pipe *pipe; + ioxd_ctx *ctx; + struct ioxd_pipe *pipe; struct { char *p; size_t cap, *len; } mem; } to; uint64_t has_value; /* per level: a value is there, so a comma is due */ @@ -302,34 +302,34 @@ typedef struct ioma_json { unsigned depth; bool after_key; /* the next value follows a key: no comma */ bool failed; -} ioma_json; - -ioma_json ioma_json_reply(ioma_ctx *ctx); /* into the reply; sets its content type */ -ioma_json ioma_json_pipe (struct ioma_pipe *pipe); /* into a raw pipe's slab */ -ioma_json ioma_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ - -bool ioma_json_object(ioma_json *j); /* { */ -bool ioma_json_array (ioma_json *j); /* [ */ -bool ioma_json_end (ioma_json *j); /* } or ], whichever is open */ -bool ioma_json_key (ioma_json *j, const char *name); /* "name": */ -bool ioma_json_string(ioma_json *j, ioma_slice s); /* "...", escaped */ -bool ioma_json_cstr (ioma_json *j, const char *s); -bool ioma_json_int (ioma_json *j, int64_t v); -bool ioma_json_uint (ioma_json *j, uint64_t v); -bool ioma_json_double(ioma_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ -bool ioma_json_bool (ioma_json *j, bool v); -bool ioma_json_null (ioma_json *j); -bool ioma_json_raw (ioma_json *j, ioma_slice json); /* already JSON: copied as is */ +} ioxd_json; + +ioxd_json ioxd_json_reply(ioxd_ctx *ctx); /* into the reply; sets its content type */ +ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe); /* into a raw pipe's slab */ +ioxd_json ioxd_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ + +bool ioxd_json_object(ioxd_json *j); /* { */ +bool ioxd_json_array (ioxd_json *j); /* [ */ +bool ioxd_json_end (ioxd_json *j); /* } or ], whichever is open */ +bool ioxd_json_key (ioxd_json *j, const char *name); /* "name": */ +bool ioxd_json_string(ioxd_json *j, ioxd_slice s); /* "...", escaped */ +bool ioxd_json_cstr (ioxd_json *j, const char *s); +bool ioxd_json_int (ioxd_json *j, int64_t v); +bool ioxd_json_uint (ioxd_json *j, uint64_t v); +bool ioxd_json_double(ioxd_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ +bool ioxd_json_bool (ioxd_json *j, bool v); +bool ioxd_json_null (ioxd_json *j); +bool ioxd_json_raw (ioxd_json *j, ioxd_slice json); /* already JSON: copied as is */ /* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ /* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. * Every call that must wait suspends the connection's coroutine, and the worker's loop resumes * it on the completion, so a handler reads and writes in straight-line code. The HTTP engine is - * one such handler; ioma_run_pipes runs one of yours on raw TCP connections instead. */ -typedef struct ioma_pipe ioma_pipe; -typedef void (*ioma_pipe_handler)(ioma_pipe *pipe); -int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn); /* like ioma_run, without HTTP */ + * one such handler; ioxd_run_pipes runs one of yours on raw TCP connections instead. */ +typedef struct ioxd_pipe ioxd_pipe; +typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe); +int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn); /* like ioxd_run, without HTTP */ /* Reading. The live bytes are the ones received and not yet consumed, always handed out as one * contiguous span - in place in the kernel's buffer when they lie within one. read returns them @@ -337,30 +337,30 @@ int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn); /* like io * without being consumed, so the next read waits for more rather than returning the same bytes; * drop consumes; keep consumes but leaves the bytes where they are, contiguous with earlier kept * bytes and valid until release; copy is the plain read into your own buffer. read and copy - * return 0 at the end of input, IOMA_PIPE_GONE on a dead peer, IOMA_PIPE_FULL when kept plus + * return 0 at the end of input, IOXD_PIPE_GONE on a dead peer, IOXD_PIPE_FULL when kept plus * live bytes would exceed the pipe's buffer. */ -#define IOMA_PIPE_GONE (-1) -#define IOMA_PIPE_FULL (-2) -int ioma_pipe_read (ioma_pipe *pipe, ioma_slice *live); -void ioma_pipe_examine(ioma_pipe *pipe, size_t n); -void ioma_pipe_drop (ioma_pipe *pipe, size_t n); -const char *ioma_pipe_keep (ioma_pipe *pipe, size_t n); -void ioma_pipe_release(ioma_pipe *pipe); -int ioma_pipe_copy (ioma_pipe *pipe, void *dst, size_t n); +#define IOXD_PIPE_GONE (-1) +#define IOXD_PIPE_FULL (-2) +int ioxd_pipe_read (ioxd_pipe *pipe, ioxd_slice *live); +void ioxd_pipe_examine(ioxd_pipe *pipe, size_t n); +void ioxd_pipe_drop (ioxd_pipe *pipe, size_t n); +const char *ioxd_pipe_keep (ioxd_pipe *pipe, size_t n); +void ioxd_pipe_release(ioxd_pipe *pipe); +int ioxd_pipe_copy (ioxd_pipe *pipe, void *dst, size_t n); /* Writing: a slab, sent on flush. reserve n bytes to write into directly and advance by what was * written, or write to copy in; send is write then flush. -1 once the peer is gone. */ -void *ioma_pipe_reserve(ioma_pipe *pipe, size_t n); -void ioma_pipe_advance(ioma_pipe *pipe, size_t n); -int ioma_pipe_write (ioma_pipe *pipe, const void *data, size_t n); -int ioma_pipe_flush (ioma_pipe *pipe); -int ioma_pipe_send (ioma_pipe *pipe, const void *data, size_t n); +void *ioxd_pipe_reserve(ioxd_pipe *pipe, size_t n); +void ioxd_pipe_advance(ioxd_pipe *pipe, size_t n); +int ioxd_pipe_write (ioxd_pipe *pipe, const void *data, size_t n); +int ioxd_pipe_flush (ioxd_pipe *pipe); +int ioxd_pipe_send (ioxd_pipe *pipe, const void *data, size_t n); /* ── run ───────────────────────────────────────────────────────────────────────────────── */ /* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port`, and block until * SIGINT/SIGTERM. Returns 0 on clean shutdown. */ -int ioma_run(int workers, int port); +int ioxd_run(int workers, int port); /* The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted. */ -const char *ioma_reason(int status); +const char *ioxd_reason(int status); diff --git a/ioma b/ioma new file mode 100755 index 0000000000000000000000000000000000000000..4190ebf8f1fd8afd821548f89c379968ca84ad69 GIT binary patch literal 143904 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 literal 0 HcmV?d00001 diff --git a/ioma-hello b/ioma-hello new file mode 100755 index 0000000000000000000000000000000000000000..1a397eb8ca8e0a620e8d5598dca96a78ec55d014 GIT binary patch literal 264320 zcmeFad3+RA)<0aG1)4=FDr#J5wQ&*!O%%q2MbjjKDyWPZ0cBhULKcXIB$ISQK!Jwt zmef-=X6C_>S!H&|aYmd`SyV_^5_A+JZakoX=xCKe#SJ1V{ri4zRVM|K=Qs0t-#^~> z^Rf7ls(bEs?z!ild+xdC-dUCo$xk`TBY~Gwhh;TXMq8m(D03 z|KRb7zdi4fciG|O+nrC;x5i0-(tF40Haz)u=Ob~a;;$r~oUg^nck;W)NuPYP4nFG3``8^c>Sv=#<`1Q{!pQ)QsalcxgdPB$jOYf?$y*gP2^Dqq`rYG+tAAaZH zKhxOlUnZgmz;l7P4{;|yVN`Ic@*nO4 zp3(<=Ods&seZVgPBB!eNr+vT=^#T7=AMlnw;Msk^*?*_PXHFmR2l{B&Eq$bq^a1~M zALW$v(O*yWQO@;!z^C>BKckO&|Jg_S&OXvBeZVj21AbZ`@W=arU)u*hjeVrg?E^ls zk8-m6NFVAW{l|U4Z|kGKO8Y2(Yaj4)`+(P?US~?gSMT#BK2OEBX9CVK_Kj!eOi0r5 znT^4+hTzP3W!1IP%$em)WizX)Ys+e?7gb7)!G@a3T4`S8yz;pX;x(_HuX%OzD@Cw= zp;TYl&`{SPmCdee2ukzHYHI4rQ4F)xFPvFE_fDzYhBXE&kP=Z<^$pdv!735gxUiAY zQdL7`rBq&1*I0=Jz^D99M$fD&tF8f{tg*2Y7>W>UubjtJwXSkz&YXWz7*)K z!Rk6RVP09iG^Y~nsh(FIlp5>G@2teDGRUvG`k*wsy0${9scsCSy=b=GsCl7U<|CGM zwN=u*`i8n-WqFX80z(uRte#gXHB>q+ET3ChL1eHxQedL7C7U6!<7f$#Akv?5Y#W-de zkBe}cG{gyq&Z{0kZQxud96Xod6lplZe3E)-k6v}94X=0f%p^R+fqOgc_#`|T&N>Nx z)^F@|oiEyN>Ku-WBmlcza9ba-(;aZZGi{LgYr5cj)=ejSJ2?lFvgfc#?LETkC?OV|t$TF8IJ6s3f(z z;DcQ79WMA_7rfI22P5@7yIt@hJy1zH;DXC8xaoqE&yvq!7u+r9yIt@T?sLJr}aKV#nQAR5+ z_=T?Yr7rkIF8B-=e3%P9%LVtj;B#H@i(T+~7yJ?zyvYT>)CCW_;C>gp*##f&g15Nf zm$~4pUGVR?;A>p)EEoJC7o56m@>%PGUy%gjz1{^M;exli;3Hk|9WMA)F8H^f-%{XP z3Vcg}Zz=FC1-_-gw-or60^d^LTMB$jfp01BEd{=%z&9!IseI8fC348C80jxP3bRJ6 zHJFm;fP`e&^mJ*$}r#K*FpS2+~Z3n$-In!ixCCD^8}nlK!y$2LO>b; ziLXS8-xBaCh-ZFi1MVc?AOUaMfT;w$M8NYlU>E_d1UzK}7839%0S^OEb)`HkD%#`v zl7|&Z631`g<_+Y(z)gYafoapHD$5RKVf&~@u&SQBI$0? zdb=^9C5#!rm@kwOW`cP717q!AGlQrw1Jn?uiuj(ooW`-#-o~wQLU!ZUIw8Aptxm{p zT&EMV8+X77*^N5vgzUy(KL#~8jadZQpe)!ufbnW zN$dkTItyY@HHv*D#$vCccPM(1-)kN_mPnMu5_0q<2u)RQ*YqzHeS4B$6yq+h`8tv) z#`&tJU5V`t9V&@ec@(|IpP}jRnZNjwant-65dDh2RgR8DC7S-ZqQ9gVLBChYepSo< zSkX;2|Bw|brRq#U*nukz{esmK}#VB9R-mmG$Oc}MP`Zly&j&_0M zs@{Q^@Ype-S&9MLDn_^f8I?%4SB{QJ$Csc;ywsz#9Y|AHRpcX3;;^FsR3y|_x1s_~ zU%vw{_LL}kwJ3VKroU~KKum~n8!)D4#&#{4s2cM!l=3Z_Ug6Ksr}_O_yl6WLsPSj2 z`Ujf6y~L=LO7ida1A%2MGqT;Q<$n+|H3LaB1G&(5{!Iml+YD4Cl#yxP`~~`y-H8z@ zNADow<$$Zk;tVA|>Qyh&nQz-^jdU#)Hpv#r|A34x4IJvP%btXF(vw20-3H?96r(yzDepwm zl}|$tK#MXF6bz{7U0VF^SJ5RJx?2BNiT;(Uzut9DFHeEUUN!#>IT}P(#Yk21=Vpf9 zFEK(HiqVvz=~u+Up4M$NlLsiBappKEq@+GJg3BmZbzJCzK+Zo&m7DzmKgIS3WwO+ zVj$n`&oUo6jX56?(l57lLk6;J3geHWe*}U-Q06AgRW`}aRP+xwGtT_okwik@8f#se zxp^AHg>0U_6)jv(zLLMUTZ>otb2dXdfWYsHcu)x4P~^{3@{9aA^75si^CqU=3=AZ# z{8RHyl&Zv6`6+pU3e_S-f1R>ge;vb`PNhjXZN7!Hxx0uEyURTIc```l%X}HZO+FL@ z>7waDaQTmreiL~a5W(sgzUFPLkaAIo#A1{r`e+6|Id3mOBEg;eh`lX&&_X4C z!C}?7F87EUY4@6+AP%xD^nqeP9GH>MnDlOchPe=5xvh$^O3d;V$`wP!v@gddu<~Ww zs0`eCd*HUf?SUT#W^M(m7qJbWS!aS{dL@T>F(@pEm5+QF{yuAxU?~hu1w$FL#j&LH z5S#?K`Kx4}bk+qa;#JDOpQGr3EQk>OM>(24qSLw;8jKJIAVBnYpv?yM8XA7iqTaEo z8YLOItU(5YK)nEFdq90Tu?;I|jR-D_K z`z&(gqJtA>js2}8eb$=;@Y9J-T;Q+dcL&cxTP{K(bX9Ob;(#M>w>od6e~Xdv(R=vH zKCbA8m9`JBSK7K$70mxH9S;sg0U!LvF2I{OVDm#VKk*BX{{!+$p(~~+49rh2@~0tu0FIh#Y+# zpVL*n8)Q=Sqf>KtjmIhv@SRa!8{S9KTj}kS%R7fO34He zab0}LMO)BaHa!4)9WZzJl9R&u2ro-q$@pasu;{ zlK;9Ky%pra7#cNJKOFfm5YSr#ksZFs@$&-mgw|q=t#L(qdmv&W=JP=01z#Z2&8W`{ z^4fz>De(XbF&ihin(*Y%)bOzp@{03Ot}6fTCHW^?qPyhiV0KKT70I`U_L5N1_b6<2 zt81g(4v;8!*R6V|n5cTkE6~?~{{4csc__qs82NhZ0|^~08lqhrt6Bm#LxHqc!m9oi z7Q_0d=)f#R9}Kk>>addk+9}ox`{n30=qP8sfY5Mur+&P5y|7QyKQZ@z!1cm*F-e|@ z6wn~l?0srERDf9Pl8aT&l1f~I0&m<7t-TRS``x1Zw|kX*D`YVNmIPpeYA#*6$O4JrUM6bL^kY|EKI(+_C+hgfx_LktN0do^uXn!dIkFS8%1 zD-a9KP>eJ*bq#ZMO=(e$vA`Vax}##>2E{20%@A`nm6e&uYS(9wM8{YSrnOA-@1lR~ z#ul>t$TpDCbZHV?@3HYY&;!rO{h;ej@NbF!wbg~3J@N(fbcPbSP72Ocj8T5oxXquX z8CPmXl@}y?4$Hf(U4A!L_jawr7u5gv1=lFX724R!%n-0!3{~VH@HA&0qQVv0D=dMU zep%NqTVMd;&!zjRxs&_O?&D14$OtEBd5N#RC%6 zH7TAC6}>S_8QYi>I{j05NnvJtp--xkYg*;g3$ql%2(#Pt9ZI%|G0N_O6e(;|^oSiH zhB!nC^sDevMGBn(j=o*dI|H}%$QOYRaEbmCnZrx(fXt#RwPwtz2U4X#HBa?yn;ai^ znU;T0j&=}Z&uh?f%my@8F{b7zMq!iu}X(2u5+D)}GF%daCCD#O6=U8pp66@uZrs*!#ma<&&L_+Kq49fhTAl`w_c^fzwK zRPsLwT~CsMw?R8rdP64226}yB?GT+!ik5<+(A5qr`pxx9>dko|Ws}9lA^AixmU

zamDjG+w#XQ;@Fsp_CU9^+rvH(^v|^XA`@xKe9(i_u2u32GaAMqPboFN)VsV&YGa_6D9RyC6wel$CV&(+S#Jp3L^&Oidr=y~32P4i_UHpBG0RHpO@}3>ysoiGF%+*# z&FS4i#)eknk@^@HlzKPh=J13J04)Hi%hobZ&*>=e@<>%xkzO!(J&)7rB3G5ZY#S0- zzeEKBF)W;c*VNwn0yk4wVG&YQ4XuUD`}I^|k1wB|6WbLkFp4vC_hO`+tr*2vYmM7Y ztAp8&cI4llx%7R-m`8yU5*B;c(ClfSys`@jXvX5KfLNJn(5m8tU+;-m42;fJbi$39 zCGp_dDN24@sEY=ihy|2kVr2pM%sG{6ltRrq^{2}(~z9C zV5}d{K}jqb4p_G1Rq9j zRo{X}DXdnB- z&O(MiOVJnS^|ZIWzhpfG@>}PiO=yQOnI?%I9zSZepjM4PkE_HSIrb^Sn`WRx?Q*|{ zX*jtI*+UA&)A!&gkfPrSc@1G*=r!*^5=}4nApp{(-}L~+^qoQg*((4$k6LL|Y&+0TNiCeAPc4;Chl#Wx1OI*apJU^>wdI)% zwANK8#(9pBVHB3?9oer_JdRBXrsyd!Cl-q+FA5hJ6lx8T$OoR#PBbmCN|KC0Hc8@V zosO2-RGEpcGspbv1pNX{F&h0vMq!qI><+0o_u1TMH}lXL){MS)6NwqObUolgN38E? zgxBJ~^h;|%$YqD{f?`z0;^jnGE~q)L)7g|O8y)2BIR`l!EqHVYPd=X*2|Q{?bX zB_0Or^o!=PPkt$E<4Q-=&#vcMTF#F8*WfLT;8FkKOPK5ezoKJ|7GX^uckKFl)K3Nn zWxPrUbPTBgdwZoB;k*5c6dZ&XCxjoTU@E!WKNqva5j50@_|kyYuJ$4%s)BuSu43Hj zZI5ID>Y;Stk-bQ_M~-GOwUG(9@sA7eH-D!bU5@IEXIk-BGvY*7vn_MkFWUUA?}!}0 z;`Bh8ylz^iKc1Ek{a46WRo^8&>nrDaR+2V*;MbChgEghV{GqhFz2P?y@qG$99 z;8I5bKfy|?^w>7M!iz^pMaHFa^emu=ff|71F~1MHK)ZBikv?mL(ox_;r$~{%_*r0R zEGcBPWFmFsA+Ah4%Z??GKwj~Cq*9FL490+8bt4BE6n!-Ty2!u{2KFNiF?Pqwv7aLn zh8U^bHpD;~kc@aIN{T%j9H$shuzU6AC?VrRU+X%{%}+u&=Wl@&8=D#WBw~4>HSW|! zX0+PDw?lLhxoh;u zv(&5TFDh+s4Kn`TiYk=U{~}vrxzO&O374~T72UgmvtP0|^rpeO$W*2O7yH3_6g0Q> z3fOcyXOYRHhxKbFf;#W_It|GU6vC@L^_ zyw$6(azF62rH}|4u}X!qIQpeBzQzx&#EUDzr;ymyL9|~?1(7Zo4uJ@j!Sdz!+vk z$o69+9Am+}t{~-ZZ*}@z*vi3n&?Dg2-fA;Ztvg@ny6{uk$S(!A8<7$CfaSNOJ=P3} zCn$Hss4cNO*7HyABq1z_tWV#9#a!edhAu1|o;{k;kXdBR_7%zN?(pjZzwlxogb5@q zcxiEtyzauOb73df-%;af0ZS*=^N)2k{s{gHFQ%@{Q?17B1o%^y1RsASJT638FLw z@bF^D*L4?8Mq)Yoq$m}7cQN(u;!mjG;-Hp7qiHAqD?~2l>fj#5 zxL*{YzZB^{9`bce82T&lV{U6ltQm#_ezQMeA2Z@i*AW;B{>3&!mzk8uQ!#F*K+P)z zD`I=MQ^^;r;Kut@*jl(P;_XVSYFY9t!5m$WCGAeo$B-}2D8%ZN*}6Jh(iHZan~HOf z1g00~eh`?Z#fR7521~F|&ri|d4z`Z1y~A#8E5lA}uV-sFV}JJ)t-ai7ZEst1Ta(<2 zxjBqtKv{RYyY}_kGYVn9X!L5vojKS~SF^Wk`F~-K#+Z;R8#oKw<_WH%E_?$W3ll{_ zlHSP<({z!G`cpm#yR^faiB}cqU090p^NNf+3+(c{eoc9+WgnKCxwH@7u58AOj|^pW zZ`akLUi}l8t&8Fl9t?!L(--^zW@}ijmHhn;S1N69rzz#Tgkf>O%UIt9Zw<(sMh%JI z)EPcDU_m?HNY}VK*{?Ct-vvWygSIKeFYABAn3S0Rd{`F8E_hYhD9oVHKo$9SpESZ! z^lY#-*-oy~jLQR@1VU5rg0zkCjH+rpL24=b$8ZNw@()v$fDvUv8}?2`1olHGDEcj# zC&-judmy%nAbOFyBugDzk`sFL(}29BI5Pm@D-1OOiodR(fr;$)1Pn2iaeQ#wsKv%8 z*TIP6BM^Q@3=lcyMH4mXCC%9Sq(U3pj$tV>1Yg8vaTa!+z1Xv5zbn~W)%;%(;l|A; z@NcsJVQ~}vzvsmMCrxaO;OxNcWPrKo%cbqs4^bQJb;YHqCoh0$$*!mCr@j48G2sl{ zczq9ngSXgJ`M8HF=bnlxf=^T<&T5tXosBh^TvXi-l0NiDYM+qd5tO&Ou=U0DF}p7K zEGj4s7>hAxSqUskUo<>{s5_)!f0grF=uZe$OTqc*2t~r5YDskjb=SSbU+oaxi>fh= zqOuB9*7ak%Sd0$Qqqd=Hk4NPjkfrNy$hY}?ISu-)7zmLs~SBapP+e1EXeUW;^*vr4~D%m>-% z9##OYWHBoE5oG=sO51y=;2u_>q;9e+XbV6ka#yg@R*CaB3zfL17IkouE^=1sn?wcQ z;aGO|V*)p+`f<^Ods&euzO0vKLNTL z1$9J$Y1bQTZ8|M@x#HOljt~8$2);ZpS|Gc#$&6Vgvdz~cJgZvPLq$n+?ZISr`44+1 zvwLqsaq;orxdoHiqSv4WPsbm@kCgK1HvqmN3|b270e1739cn=cEg$T({9ZrDXg~+| zy|ala&8_dCJy6Jnr3j8prC5;9e3i?Ek6OcbL160dz?zwdq*y^0W`)Kp?iu!$9dZM}p0XksFm*>%z6|g$16jhcUjG*2W+ONij0?MI_*U^BS~; z<4@QJX;E-n643Cu;msQ{F-vfT7>s_imzwmYn32Ket+3UDEIGDr5N5^Ae`Z>2smig- z;U*T|yq;k!&*3QBk>4At|UptMlJD4(dC2|F@jHlOOKz}(GTT2JK_4Y_BX3xR7a4fpE z2&&cB+Q0aXps~fDIM!+gHiLhl^APRqjAFdOy8nqV+VfA5G8*LCZJ9= z8-8saL+r9k;uS+b(ee+=%j;3TYOHNRHdMo1pmR@AFiV78wI8%}mdX+fx2T@uYWDN+ zNJze_yt0cDST&xJ%eK77?w7WoCH35SQ@H8;HsNw<;67GeFZ#+Rg&Fs?Jy$ksDT@?S2IC+xW)t_}OJB);SfO;Gww`JO5i zqv#{xqIR1l+TMrD--w?m zo)56m5^2q8o``ALRP|TUoB<17P>d0N)$^sWWCyQ1^VF5}$W!^rGhsu4qh6P%xfBwx zJ#=KOEd&^xJbiobaqziR^~o8;GlVSTXvo(#sCBlD(zrAmiX&Bx4#( zZAm8Ejxx8y?@`NsAKV3ly2D-DX{$z`o#pgdAiO>drot%7Lb(V%B!*<{Jcf+=g4mJJ zY}9*>e9s5{(SMnC|9NgC4uY!(`^}XvQ6a#-otw|0qS?DrFta}g6tK1yC{W>wbif#| zolYe_iUP^n;WenYB))bHkb&B*pjDiqqd&$7cWQ#Gp`yPa-N}ikx8%+P?#-h23I7d$92nr5NEYooKyol^9Eao=tviFQXEY zUpayNcH2{&65}QD3zLWhcNGiE4MN zSej>dPmYfmU~|U=7lxcsK6z1KcT!=e#EfG-vK@wgFi51`hb@8AkE{9H<=9Hh3B*lw zFE)=emFzDyY#5X(kuO1%SJJ^4_JZSG!Hr8$r^AgbOw0Z#me9YDoBx7@;IIwkut0m5 zlL1T>=K!i0u~q=NM!5z?-@#x<-c4uyH4U5zy)C?1WRjy>VNU8z3~y8X08#;H3ojw zCsme{tZb|tjeIlPC}tZcN1IN{mY2*n9;CwPg9{3YqPD$14ulyzP>vph00C-4&mgHU zws(S1mJb$o|G28QEnXV&FA>T^yx}XQ{0RI;M&+;p{>ZU3?Dl~l;tgNABZfzgrOVM> zBI1}k;(3#anv1=9XU22*br|x;s#zG zIW{nOd%WRuH}Hzcu|Yw&Rek0Lj))u^9K0sp@TnU(GIH#+;6?F&DQ}8wP*r*9R;_iU38ilu~^)qCC0za|jFUW5Fer+Gx*eL5{saA-QZD&rc;64RA>n&FE1> z|JsVeqzy!!QLcv_=13B%94>z@myjMKW&Ff%L@D{ zd*)*y>LH>zJUznrZapE^5J`W%NcS1@_isE?eAzg2Uh-g%b-r zi?bQYZ13XX_!3%^ldA)MVf_ap6TK(Y?Bkl}y^{Fj{Uj{>-CELC*g{a2qZ8PRp^=lI zDpfiNK+{R;sqN5Hv8w<*^^+6y)OKnPSpS@T+*$?C<{p7D2W30*pqIBx;1|h$=fd?j zur0U8I?=NpYYY-(oo_IIY;-r|a$a(r*g3q(Tae{XV@P2|Xw!v#A1N;=g z?JKAobL4}ABwdp zHgJi^Y0ejKNVq42i{lN)-Qi2(4PU#%mqw1I%CSyZ1+5o(Y6k9cK1IK-NXOxe+r~h= z-*#QM7XKkO3y!Lhx4X6M{c85HBF~GF_qrnque|&QnxWt8hJIYEKMyOE_XcCcB{%3J zE)BqpcF4*>bnX%BF%-=i+b3K`1HzEV3F>0&7R2z&m%A&lLC8MENqe#A>A(g^M~V6Z zCW*WKmsr_|-bh$rgP=iw4q!|x2t)o#)=}^swSiobC$NE0B+SLV+JVUTCI;_D%r=h4 zzO~uOca4*eQ77dS<^KWsNTg!@S^c^~`5|yOl_k<`ID&kl)PJB<^X{z>=DjOm>}NQKGHr{DW3VD`#9z^-b{1i@`k?sWi+tHbcuDs+v zMLxW>-c{sDZ>p)A)-Y%4CQd@wxKcfDn12O2s^{0Ogk--N`i*O&!$Zn5lYT}#7{{gXFu*gAl^^=5995!bio}( zHN<8GEcim3)eN5;qxK5dmYfW{wYcWbQL$7rp7ysQOh1?cU{_*1?k9PXZd4B89c?5k zrKksBXgY)>+b=L z!KTrQv4xMWfkM6tZlFz8acNn?rC`}Mc7#jI66tMbqW>jUd|On95H=1D8IshpoA0zZ z*;3O0sg%{KCn_k44Z-E2+!BvX;@noN7Nj(TK$Gi7@|R-VM`vZ@0s1O~j}`~09a?Q@ zmF+LpYvYU@%2SLLOm~9WI|~dZ)a578B-MC^#pUiQ&fTjDyEZCZ8oqv{9NmX#s$}s| z=OAuv1bf}S~nfT;60``5^!9*h38rp|#BaTw| zU%EzLRm=DtC@{28-JEQzUgP(wn|@|L=RSi{q^>i21rnSI;e-F?(n&n4h4WVW0s7O% zM}L03UEK(5`#{VDza!4*KH8zYv_s8rZ`fh;O|4}Mp$$FyDo?9r^;pH_*tuu{wgmD{ z=DR@eR^rK7-o;GCENJb<%Yg2!K<9-Ck|a(7(BZ^dhZ!;{@1TqY|Bi)~$DSsiVgoJi z+}ZNXAye)LAe6PA^NTH4ON>9%gM6y-*CxE2RMw`ReBwMAFtFX?P$oYz@s>;-TN?BR z&5Xh-7D5iyn3Rc8412OBPdY$b&pj_;P|#>L9=)o6Glr$R0e*@U!$ zlnP)s;a(IC`#v(omI~g$e2H!!?0j>-v{ZaQEjAtydUOzZ$9wp@L>GL6GX<*t1X)Mb7kC5h zlQKN`bGj#qa0tUDoPS!VUwENsU~q|pNQb?P?&5um_dRe1m(&8`-bODLU6{&QGmyre|lM-BnDZii}*O1)irxCz_A zxEY|S)KChXLa}fAT*EWrChi6+ktXa0uMIb0Gx#hxjTXScsQ?a6dTD9b&&?k~T*KpB zURPhF7?ZJ)dI}HwWALzFcF^9Yg>PBvkJkb*MZdaZLUNmS!eGa{zC(D|dpun~?ddPh zH+}4xxjb>9r8Ijnn&PAHE@0spdoIl)>Tk*dG;XsH88wFoV14BD92!305Dos~#LowM zy`o3`ypzS=+E?^P{9#1UbGI39j`7>jo5G$-hloYCKLju3aGVcH z7W`cq+;_$dN-I|MFHHC3n1XP^7c4B0pFA4*5Xb+1IDa1?!{%q;@6ymNSNQPD?deD$f?M&YBW5&$TQ78%NAagg0JZUmRc&uriib! ztFW;wzS48$*tO!T-<5Jq(0|j7{o@UtJT57(xByW&!i#<*OUqA|4ggom(R(>m!I`nI zfEl_ErWka59dO9qrNvkIO_3NUe~%+E4TJas?_38vAEu`QIl2w`RQ+YO?d|ju&&$*a zqHUlclKFxIMb)v#5LP>&43YQS)s8}x$g6XFrSw8RM9F}pegl%$3!!NRY0`TkPC5O0Ax=5{dm%5A3nE)!`oN($ znq2!Yxyp^+J!PQhxMA{&dysJ4fKU$mxa*~HOXcX_$t+1O9FED&m2dvLylPU=Ox0F%_Y=(G@>(xGg>*Mae#jgPoyaUDvpH%N|FO_mS^4>|fb*0?&Za zE&Lr2e4D(AoG?>UX2F#?UGwZx^hI#6ecA@;4UkMXLryqJ(CaZ;?W`cspgb2FVB^0# z1}uI~c-%P<4SUcOv2MVijFvFjlV^vIjS0PlZd7&L|FK2YdFss;lsMy%u0);)s37cX?1+Q-L zSa;bUsa69%K>OHyHX#=oAmC!z%m_-5!r4cyf7prpTgCQAKWm)*k#1dMf23KL^Mlvm z5QS=i0()dX5T*$ZR#!N=WMUnGbB=(y#L`40R^WEvQ_2t1MN`93Hl9cf=EL8niIxz! z;Na*<^t7QEaXg?HOT`x)a$s*A3`sWyj^i88g0kClppQpcec^@h#qJ0+fr?Ul0Oe&F zfdVBzP}(poypX3_vXF-pxUWYg=_n{=YQ^}a5K)@(dm*(pVI_oa-9uIT!^eOv_4=#G zAF!3`Fi)VTw0MCB>b(}HDLCry1W3((gO>kgqT(S!)y+w z$!;LTM~?mg*P^WFq?x-HHt*aI=+51}eh(h#>D*P9YY(r#9uM5RF~d6R5?o61AzU77 z4-=BblGgk1$l36Y(Dxw1)S$soFsaYr7h>?+F~O0@a|C(nKY%V0WfrK+IOxbTfM4{N z?->dEml9tH&zc0>4%%Q-1N^AGVjaKQK1#(Aq_h5#hi}SioFCVZD=*5MT+skLjG$|0WBMMOf!aQp1oT3KIP(l%2T8l zAM9AC0H6)nr|39oxvng8qTXR$o!`MMwl@MWSE)?}>1s(ay$2|4S)pOz?yMB|$n9%lp- z_*J25B|imc8^8yy&ZYdL*M=Ht^=V`86%tckPJc{I#}xO09L*p@;RHCAA7}mZDttq0 z{rM*7F8cQ7sNZ`wRydK*Jwj3Z8fEhg=#0tn!Iy&XyT-a|I`t>(hcRbLeCY4F0i>+f z;_!^f|DWI>c~feMqmgN^kQu^-54JLnefTk+%cfw~;9yTG`C>y9$2ivj2E!EY@$xHh7*jgJ zJHP>ant$o{p<z;}Dpe+xm3o8`n&qA1KuU{X$*zd^?d zVVH|1viXb=n#|vj6azWjiZ|)eO%cacxj6pAm`*1qlUX9iQi4keJ>Wp|Y-nn5E}@4V z=nNa07QB&AF6CKvlMPJ|jw3X~fv&cp{eqVf>T{s$ZD{{s2BA3)bT^NxP>P64{UF6a^Rv0j#1&eXrcQHA{FkBCf601QZkMDq0A6Q zoVpC`FXN!#56}x5)CiH=xOr$XPIJ!&U+Di*^*4I;X~*!_A8KFtX)z)&A*=&#G%}Ie zvB^Xf|!~ZF4|@<7!@N^ zi9FQ`INEmz8#u`H1CcED2Q&g9vMuK+y9ja;QcgigY=z~virW@CCN;4LUaKI-Mqn#P zM245n1@@D2u$ogkCS@@N-Yh{1o)gAFJ2~oskZ7L-8-YDLBR%(yc!7c(jbek-n1qRZ zQmMRr0Rp@-foH0g@=R3~w?CPS<_2inLfV{SinqoiVbY#7%=mBG-e{HMnQl$@W4_!5 z7o{n_V&0^%3qbok$!;qB&Uun^sI1iOuov8}^$=}m(8r+L9}@ffsxb^lvPA{0xCxBS zMVCj^ik{5Hm`$4+`J3r~UOHweT06v<1@uyuY!Ucuv#d$1v1y-tcE`o<4~T zyo-dbj|yWfy`SmWfY;cRRQR$zEl^4mtKXHc!KgGUh;R;R{*`ZmXP|!KP$cs{u*st6Ki$a%=?vC~zcx|8Y)m zu982YAKZliD=|tlN{m^VRuuwvJB1sxxFxVxAyj)5KeSiq*+OYF?!LO4ey#DL!?cS# zl{Pa)yLh)Upc_aa0;bAHyBC(0#^;5{i}ecpkKp6P&7EENw0J*Xk`#)O6JFv2!*c&c zF(zhlRix;6kDX|nUngd^PfVI$0XFVoCpzX=4ATj4)iserfUQyJ0wE`&&xj#WSZc6) zI6|TC?2woLQ6#V><6V@D_X_}p;`Na9-?-joeoukpxcI}Fvy%$sdR#2aAZkT{Lj`~Z z{sc3`HwyfmjJ0f$x2{%>S)c|xutZ$YiQ#L#4hRRbVq7?G8VKUjD#R2w8?zq={MC5l zMvc|*QKyT^EX=dmKYou~FbnX~w-O0xCN-cb_#NBIiL>S*Y44OBEx{(fyz((z?SWa# zp6X)1LrBahNrR~V0(vVBDD_9@Qk3`1|Hkyn1#4_DoD{5D5e>UscnPPW+bCm0Si5Fv){VOGtOFki$zzrdvp+iLic8tVV+;mI7zVqUiwV9LN=tqX3IT#i<|= zH>_reH>}HPex}FLkypUxzb!}hAxM0oh~OqK9eTvOU6)~8jT;Ud*|;m9;(E6P2dnv? z!LEd)0Xoa`CfqlI7s^i-T_}yaEI4%B_)sTOC~^_*#1fIAx5Z&EHGgm8Y$g9wRX_T@ zxOSnW$rIuKxL?WN*SJK9PZ1tI@X8tu`@qKq(L`uraTME||3p2S-l=gqgB3%K92=&@ zqiKh+lGSvtrZ?gL3=Cl`23Y1qgBK*DhBcf16->K>QStvIBa8`&D z1e$E#h_VHGC^54H7um8jTt}vQTCIPfpRtIw&7knZAji`pz=sPE8Vu+P!S#f-_ah*Q zOH+(VkOR0SiPO7qImfQ_VEA2bF&F%n%_z)Kt|-j1{s1`xrJY)s$2tuG8Y)Kb1Jf3W zVP-F8?!1IGCCm|zB@zR+THl3pogWbCONmsf(iswyp5Aaky54JK6E-k;d zRODBT|K7n=hPVx<$NTe7xS<8GHH?C|r1z(8Crpj7R5=<$ie9(R@Kaow(qjK+Fq zG@OP04ka}rD$%zV~t4gR106(JC)RbuvGI}C~soP*da0igr!S_g+VjX|AMUT z5mw}}`k@|2FTj!V8?XuWpWSZpzu&g;Fls7-S?d7U3@pR-HadtM&K{;x%7>R5Ke*L8 z6Z*WoPQk_;n*5((kv!Or>po6#p1xX;Dy*PhA=SaJ8tR}>$Do?qE73K7eIU_kEri#h zeBax^jGTSfUT}65K%78)0dbZRtGR+atZJL)!WcBe`V!tOiu>NKkN>@UyHJ8M7#?** ztmg_ZXKS%Y*S7%!>kP~WPT2v`Hv49{q{97CG5X2tmY}bAP1!N~G^*YTgq73{-RmF3xoQ45lL zsiioKDl%5-8$^TYS_oZUUZ)m;RY)54mALe4W9 z(t2)DnhRKNs}_gB2c&?ZM}Hsw(k1aZJ~h5H3o$xQX1&)9>x|kl$%iD;ChGobhY&an zE7@NxYiq_wo0Wni-LJR(A0TN_QFA?{0ppB^N#L^HSo*# zQ3{!ZfP<>9Ao8&0!2sWdwgkhXXGA@dr9&7D7|>h>rzqYTP2+M-{8-T7I&u+eCWg9!xOF064N zR)Ch`dA~}Y&E;JIqB8)2?Y0ev@h9boG@z7ZOgjsuPMU!x=7|Kew*>T?6(%%_(s8`{ z^htBkye7nx5;zE^>W_wjgA#{#-A2@m`yL=Ot=Uh;SpUJ5YBuXERyxbbWFL`vVS_=6w&q6fL3<()SA|Qjy3EAx1cuQSgpxexnPiZTAZVzP;hn-nHNIA4F0xFPRG z>Jz_2yfobih@51w673fw8z5F8!+@Bjw$1^%B>#L`Wrf%EY~ib z5C4)IM&RzoD!o1nJr@7IPptWIK?B_|aS>V-x)9D%zK)oW?1m>W_CeOz@CS?ne(*un z+xQNipB%XIx(8YTz;GG@Y(ymG7xvaZYL&A=B|0%dWWx6i_cCUnFU5_CFv~eNCh{%? zhzLLV1vedHp``gUotq8=ksSlX!2@&T{b14`-hxS6NYsl~*%Kb_8`Ez^Pe&3^jc>$9 zd{RcFd$4@ZXnY^tZ%+IvvKeyn#>F`hKC0e|n;1idWC8v#$J;0wfC>PR5^M96x+NSVBU=}7=mpLlRSkafH%9~ErkD$S&gN>SYk=K z`N#i8B6wVSlL|&|s}SZ%w?t&XNPe$d&HgG7x9_&FH4T)!mZeR%YgvzPWDHAYkqsbk znaw{DC~%e~YFD`V6W-Ijkq|?Q(dO+ZBn`a<9?EnYjbU(s7zP-N!ON5OH99#PxAu++ zUhWESKd-qJO+w1hz6y*njwoP)&VcC;<++^JNH;jGH352}(^`}nsAP4E4=A#euN`OLI^-Y5Tm3Z`B0>A3zEfI z5I_-9Rn(0!T?C^=^!w!Vv_XMOCpE$Tk%on8n8jc-U4J!l5T20#>K1!oOouHmoUH@Z zfLoDKKNz;><{ziB#7FIJgc0Imu_qH__XQ%4vYR|kH|9R8PZuJE{2-w?jPp3}-_&$m zQPxqML9o&h%LGV#>Oy*S#CWlv0Cb3A`5B0;AlrM)8y|*PVp-e;p=^R!65^>!Z_3&X zNzN$+0t%ukrB^^Bv$@d`r(!dbLEfi`ExI#set(=$BVLeD3Jq) zp*+Cc1dDOJl=>JpSm*k1z;GTKspuK1@c_AwQze8kO;YUzS)f=!4xoGsp2Tc=SU!D5 zEB<%l{{gW>@K2CP(I@1n5g~=xB}^QMyo(;~0%LNr?uU&O;*-@oQHx2M41?Nyprp_y zAf8i#{hbNg7~*hJ>`4^k=tFcg&)|=xWP1LoU&M*kpwS?@4Ft8`IM$O6d=xqM05-_b zd1R;}{bQVz2V1SY90+su_ihTfauB$ZOcQ>F?1F}L$gu(7J3|~bz-|9UR|u{NM7j&) z=!-~G1lJblO4cG>q!JfbH)Uc{!sG-~+Pn<$V`P`3m?ZDHM_8U0BMiU$B1V{MoMMFC z%M|XZ8kak9h?!&%Zltb)U~n)F;Z}hdFRG-yumerACr0vZ4tFNJZ*wa<}IJ8+zSEG=` zI@;TB4!Zc=F`(vP){CkflVK5rPv@y|6t}#)E|oncelg0%ll7V5!2CpgW;$i}2qD;$ z`ixbCtPX!Ux|TIkpk6>ehV%U2(3jz7#C@Ql)7k~SJ^KBW9=&bQ@S9sD{B;)LR^|vD zcgJ6dLeTM}oR0tQHzeySsL?0&`x5kflt%N46ZJG6BXPG&)o;oXWxMq>>sT-SVVlUQ zh>Q?36YgHsZ4J-*K(xGwy~dxa!Y!Cz-pjd!bBJ{fh7;84R`3%1fVcEoOE73S3oCkF zk7Y|4EU!!dF_+T1t!M>wp=FU@qjP}=${R^OgeBGdubwJ8zaZsNzetyBr%OjVN{!Cn zqyF_|<)oHR{cwTM4{?!v3iWxRCEnz-1+Wk&P!dlR!l=0#)!6f<-CvaG_KKD(7jqpD z5^52yg{%A1Zh*L~Z-wq?@*BTzfJOK=EWlSVjz8vAaQAJ{!sIi|Dpg+6X6tQ6dPhD| z17Jcu`yB=ahJsiK1Pq~>LZ9X>T<3zq)ICcv*B?N6d}zi2>#@4Pt@t4-Gv}dYit~#cvrsQ=@jmMX zq)zHH|55)wh9&t){p*YhId&d!b4G?euVNjT5YlP@VtS+^PfDCZDn{Q2ubB`2sb?Hk zU=2bo3inDQyL{i5Xe=0hu)Q$Z0%Dbr;gbW|PHgQ%DK;IT{I(*CzB8~<80qjs1#0R# zih4Nbx_+Xdhn0JNqJTC}U1Y8*)*sl09F_+RNq>k{2yCK$5!h6KPjje{~n;5Rta zi^Yx8d&T-XcAGUB!&k63j}?=zyMM!M@8eEql7*|9Q{3$=ezR^Da#(-F9tP$KOwt&h zx1mbwDA*Zm(-7tfs}g4E_^2~f{FWqsOwXDNn(@XSaqrz#O#C?#oA<9k-@~+HJ^UeX zh*$V$i3{+>RdKX8>jz=G!_VIR3OR(CAoc-_#@IyL9A-oRi0pbB=Gm360j!%pJNgAq zHsVK}BuvrdU2F`2@8swrbQTOum^k4x*e@U^%6C&S^^ckbRkf}0<@`ON=aZI4=ePH4 z!(ox$CWfH$@&R=KeuBjOdovMuU!Vvgn+NYfV{S(ESeyB2tf7~yW04WYrXITz#0k0? zgH)JjG=|JoXo00+m&g1sl%wx2GI9b(_n8+0%)ZgrAHr6E{^`-ZusEzo&Gs5=B`9pq zY==fWt1Wwan~o%A4oX5BFwmiBegs@WLt!aB(Fls#&nEq71Z^4!bJi@6m5z3p67t*T z&@RjTG{%k-HcH4yplAMwnf4RQ1#J3s^ei;CRG1=?cW+OJ^um_ZYB&>_g-DYmtd;XV zvp#hhTRw)FFGFTgpP0X2XUY7Lw-=yNqkY!-h_=U#IFHJEy#HZ|?fVFR=z99pz%-oF zzA13CqJKxxKMTynsY9GT#P5dL=U0&)_6+A2u}SW4pKmGfEd{=%!2ka#;K6i%!xX8o zp|UJkSs{I|&R1xk6_85m=2uquN-G=YmDS?xK+Qr#27M*)+N!EX$_Zr^z8fol6sl|t zO4Do0LczIp4b_VfF|n>;c6CKXWvxg*u`X0wA(d1jy28f-0yQ;t3y=)eRMk|M2PI87 zaf!038xT=iwy>rSg-@%i^J!%bb1EejhZh=Z%W8a6D;wrlHu#Dg8tNKE>FT`tn#y^= z4*3{aU0&$}GV{x-YszNVR06R(YwH%&O4W7q%EtKSm7(r(X@pOzsh)jRb=_6vbq#e_ zmP^SyhJ07& z07=idq*L6SF~0J-q1rnuE9}g|0l%&m(3-l&%9CJsR#w)JEUT%W&xlc?>Yz{H#NcS( zH%UKGnp+7%_=aD3dE-E7cuh^k80R~QsEye-@gnLDGLnO#Byf^?v5)7URk{poh-puKRZ+<3bB(k)|KB`8I)#MgXL;iNA1bwkyRS(#Nc?r z4(0ZX#b-4J%gXP}mgdzr)CF^R1v}lA6-%b280c0zm@53;F zXDz77K?C^kM*ho2c{bnJrHZ6g6v!NL;PLs@6&QqeW*-DW$S3gdWr^?VTA&y#s}Z&J z606ZyUk3iI$R6WsD64L)^i7yPac1ES)4w;(mo>7eCoulXE3f3pUI2W7h>byG&}K6X zBGzV)s7kv%Hlx+mSJtu<-26^{odVqNh%QyJEB2YBe{T!gL^!Ugkg_6)#AQrS z)L)R=kIzx~-x|WWVjG8KOdOIqSst{&8}>)j56QSEW%7{BNNP%8;E;^K5bxwcDd8dBt?eTJ<4CdwebWp) z`Os3b1OG2TzlaU_2}3gCDHDcd-kVx9#CK0x(U7c2`s5)wDTM=vWEBqa1%_lI#e^Z= zNrO^{dTdx>5;l2|q@b)!lzlJE4YcA(NPS;Q@sP}wsS}3y;%O6xWZj!yG$iMqet{u* zk^Ym0%u1bvV)6hA49P+gRBcyKJSY#@D^NxOc;wHd7b5OW0S5OFw@6w_)4(B_0fEiL zL8|>-JjAPFvr@{$|24=v3jE9dkdO|vP=#i;3N#uT+z>7;C5hsA|VFPkb+46d-~m*9#31DdS8mfHe@0G5g1|vPF)Ut13mOb z<5P};mVoroH}HShd+#tQiv8`oYkGQiXJ=>GB`$f%sN{^IphN)?1Ox*?5ET$4iDXbP zfgp$|0xBQ|OrR)Y1am|Y5kZd%Vg?n(tmp84?&|7c(Q|(9`#jfsJ=gQc>Fc^@zIS~? zRaaG4S9kUFr0hPNkMFga*o|ffSH-XM=f`Y6nuTu7{KJQTbo+Oe>SngzIj<>fnztruP*XRrzU+t~i>lbsJZQ^+HI%VpV+-JwT2X%*vOH|0`{yGKIC= zAr+ee?-22BVHvZD^AC>GTCN=AI#BhjdasG@AiA@p>zJ26o4n6QY(si0j_D-FYS>4P z)W7W`N7cVt`rkA_$CRIrq3QIurs<$QP!DMA*t6vD;dhY#)_=~=^q*5?-xKV>ej#Iu z#t_*rP~V;Jcg!ogF5V@t?p5l$vlFrN!q&=k)-EakY8?&KVJ1!8!)ph$%-Du;X+LtY zm~{5*;&dq&vqN6b*c~}`Pl`urpYm8>^DZXFm&B;-`p|W;({vozHtU|Z-VDpzWKPZ7 zV$ML04J+Pg-BQ}G`|*Ee#o@z`a64aRxL(J2@nh1~w>u^`6`h*5vYNjo=ik;kJ(IQr z9v!|JYsbqZ+qxp=d>!X*zlcd)%{{tW!f~t(zDx0~Dql9bi`SF1HKgetuQv77^GRDz zS|$3;U(4MwbDY|8cg@=p^RLxl^7livlgg|-9wFYW^+)m@Oxi1?T}N7H#(NzP|3lq$ z$Q$Fo^q;aAO4g_5HKLmoAIG}e`maaqNgEFz-d*|sHIL4Dn~J*UZEDv&Z%eP(z5jN1 zI;XB9%q(KYcN{)^yq;UMZTgpSws@Pa_x-biyiIqB}M(z}o2{Hk}I+WPPOpZn&X_@KO53I9fuwa0V_fGfyx%>XveJ84Ub}Q??YrF3j z?z@xwKGS_);Jzoi@2lMRP44?H_r1}5zvRAmy6?~3_s{M-QQhV5zH7Vh7Vf)~`##fs zU*Ntcy6>yp_f78mF896BeZSzElzK*-y@r1-}R7V-hKV_%S3H)H-1Iql}#-6@y*Q|i;Oj{dnJm>EuFT*Us|+O ztNq*tam6j+jLeGDkgA=6%JlV0wRws=dd_5D#$=j7+YJ@J&-66jn0}CE2r@N8A!j1= z1pXzED-gzk{3#IG`%@9#LU>-Ob0De(|4M{7u|42l52=Kp8{*lOw(vS=R}Rl>jY;ga zvh~rJx@cMlyG2qowEEeltodL}2Lc99In;3u#yg#)*lQi)ifLoj&%}zP z=(G{Vx`a5RY%F|B)qa8+bw1G|fmv}UdeZ{cbqK0EuTn_W5J+pIW1M>2I$ zeTShx-yL!j!a|XL5Is}M*FCQ{ ze!W1Mg10>HZ0AqgV-pNEX;Vb$mIMJtuoKfY-FOkB!Uz<;63Si^%h z!`}K8QM`o33&5`fc@Nq6`zUc0{v**{Hy>B?#+QQRg8BP!W58I zqN?#e&G?}45;rAHc~YN3y$R&WB+C=^kTy|i-9e7!z+8M86bPDmB zDs0W9xs23(==TD1Ipi0FLm(jwpPzhr<(OfnK-N^2?&`V-6drwct2$;Lsdu5)c`v@i zuI`at!87b%Z%mF;oot3YgMOn8L$U72?B8W7$RlYpkJQgme+taakbfflCUOU)Fvs)C zg5W{txXE_*UUVY1?5UVs>}tVyS1aV&^yTDi!|G|5TEK?wfzVY%VTU8=aiw62b1oh> ztMntD_h2UK&5HVD(rm$R3O*ARg0)pq9&4~+o@uIHKa_+^U}b75Tdn%6F|YMkPk5HE3?-iGfBM^ zBvm^r?E)B~y4 z%3xnYQ<sIA8j#mva&0(iFSE<|dO8WQQ5vHmS z>HN~)PA_PtrkZN9sR~C@Cfg+V`8oZK7o6#|(VS$WOv}H$m06zC%ux!Pzn#QOD8NWi zvF4j}a_#84q-lVxw`I%+=6J|$2rGcK(z{85D-&^9#ig~o`Ib`WhP$~A)BAwk&6f~f z0Kp$F|D$(vPi8mIGVN@+yb_ncN{8vdN2w0Hd$Xsjo*zRkou_^YV)sGyDRKV+{DF`h zQWGG1$gxM9V&2CTELB+ahkDFdG&L}(DpM)^>7=xUodD9;K+GBbV!ryqdxNYV`#tX# zSAv-L6F#}i12eat@y%U;X09H zifft`Bf0G$K|7bB`U^*ipL4I_Xflmr<}A}F%(}FC*blD8jz|q$!BS<*#?{es)xoOh zaE@%FK`&J$Sw(gBBL*ue(+ZW#%QfC(2#69}sve@Lzz`;lidoNWTe*FWPo^M*4j#ZFzD=`g1God3;84 zBERmu*@cXIZE3G`SrhQWZ_lhjbs-Uk0rM1OGQwpduR!J@Tr08zax21ekt-k@5bhJX z4)P(wZjq&sUl6_*Sr4gPl4&-ma5B@1eq@}OV1gdXxEl!_(VPg(nUG5mMv4r9T#GPU zWHclypI3Dpm*C?RSKvMR_WsbeLT(wr@}$xAG8VU+IUxLuM16Zw~96r z)jGnj1!anu*F|=|wM$GffjO4skI?S|*_wCOIw@+m)hfcD$yN%bxo5HzM;EYj&&mkp zK|)q`?%5jF7}&XI6BosJ52KIfo=Z?K2GQKpPIMp5WcZvi{5_oL-i_Ivz-IO&!ebyI z3!B+{u(yEC?72*4+lyt^l)ls$M43@nW%?Sgp{uKy_X)=7@+SC*IHoG9-dMK>32FRe zNLd4029m0o70#1$D3@jFq)E1?(&DNbTgn|6Zj-yzxtfmK(nW5*SDAFGBCct;(e(Rk ztiJ?o$);rYO(uu>${}TfP2^xsMD+(|zW~!2Qoan+J&=%@e+DTh!PJj+88Ulye^3 z(UC`|v^8FW;d~h@(U3NDi$wliF7Q;)&O>#CRh;Kz1 ze^0x+_urWLpOAQf=wAc+_a9_9Dayy2qJqUt(gfVZ`xA@bfhhq=m!+~nLMDDiQtH5J zfnb(%SKYaKQ|M!(!{$dyMS6S@qm7r7-BwC2n3)pu+i#|SC01oIvUO}`ynLsNuH(&$ zF>1ThQMDkaX3DL(vsn;UO44t)#>OLyK1u)Ql@aL`%O20Dp7fXA6DDyPp*-XlSHyIG zK8mSJobnA5wYtrX*Un{emUA>KdQ%O46I5L(LKl!-3Fot%o#9nD%-*X79Wl$3W{T5r zz3Zf^E>_;OL`$rKTU>f(Hri!ywPawINJ9?|KzM!vBPn!?53g{|%%F zyGkHiH**GOqSR89F3E>5vo~-~z@#Ox_k3n#symYCwRYp4k9N$u^v1jw2&<)?>lj=_ zDYU!iGX(u$V5?;!!Z?tSg{_twU~_@3meVqwuPgefTE0bn0Ax;u*}7gIdrDXyTRCIL~w%-2<`w7^3PiE>; zccY_vKdU0+6R_QJB*JjOR$9l<=8Q`u^|ng#7?E#}pD9>RlDm$dYZ0yn_V{@#Q|QN4 zXm|YFih8;1Rp5094}gR$Y=K{aJq2um-_7LyYOweh)~Q$_$PmS&zMV)k#b4^)(sZsjK?260)%rOof{QvE&%S70{__yZtI5Eg^%TJ(YKF1MH$aFaDLwQxVX zZ)|G>m$7|HvHuosxIkRK2Z0`400zMnh# z&c#0WPoh~-q9&h1QRP)32jE`<>5b4{WGZAE!gC^5L#lILDh>R_kckKvf%>;XO!7NE zqa1v@P!g{c%l`>ia~Rb_Sl$Orih^xJcmw2@gPcbB{X&EvNjV6T>Nt0}!usB5?ccvl z-cmxv)p2ZxDOE%t0f|X+SFdRgYYS|zdDyvo-pz8S*Njt1)E@?8(;wJgGY?@lu)Ri0 zCV%fWO0~V_1?-*!w%6=J*a>W}+2V4Gd0Q1?YGE~Hre3ojlh1(dH48g>Zi^%ab-P8q zCRvS^1+Ld@%fyYOzxJ9!jLU*zy=Jd-`b)2=pNj!q7q(ELHC+!xc@&?P5e)MS(-I{|W~a6*#MHt??33+pSv3$q*xx!+G`lTy(qH>qO-!o;*WY5!EapWL^Fq5t zqf}Fj8-rr~ti>dQrqH3*>}u#FWt#H>TqSl6PyT=r_L4G8zi zUX3-si``w1^Ew$sjkO!~yTCTqI%nc}k;D~;-I!Y6M*G;t`X2M|K-gH#PIV^U%?j%p z%d5>q7aQAHr6KtsAq(4BjbL?wZLCvV1moR}K5DG%P|pR$8>>WcHz(;lE-4o}AMUZ+ z&8%3a+$y75gVPFN>OkH^cuk}!-UEuj7B{|_Lo2wAj|>DI^5>?#g!%Iy@6-Cohg{1vb03?BsPx$(;o5;!dsw$E`uYd zct%RPT}hWNo29GZ?5<%#%&tqP%Leu$xSva$1OhMnz=>N|Gy3+?$pNaeb8a*!SY@fU5I z;a`eyDk*J2_B9+!PrFcz1KBkC&ir%LYB!@9kI7hI?tol@FiT_|WHG`bQ2A}=taGZy zKpr!h#kEMdj4H8z(%-cvEF-t@xlPuGY|rLCZ^qM$Q~&W@!5n3K0h;>=ycT%bd%4^D zWt4+gT6VjGs@l=-(L96ACJ_GU#%0jmrWvh`0Tr7NrxD57b+8=smY4V-bR>%!xeJ+jBz6}O=P5uQ)`oJe!^riwu=B;NnNU%Zeh6y=cH7a z;3Y0FK}A)7o*-C_%SvFcF&{!$C!%Z2=MkO-L9X+Ut})fR;R6qas@++cj4pE$XB4|7 z25=8vwY;4$+Z0!|ycgkP5!Ln~gzrJ(#3aMAYP(EdKBAbur}V@S)7%UrId&{@ff)lS zKqw(H4N?Q48VDA+GL){V>0KY&72VSr_?D?n_2xU1n0K0jk21%b79=;ry%9(#)jye( z9(wxs5 zq$2V(U~Yr-JB}qykb5u0-^j=3uw5YitWp-OALMUE=v>e9T7!b!kO7o>K2ul!Bgk@6 zuLl0t5L2JK>yYFP>#^-l#%wWf4i53|ru0yp%oC_uVpkuS)sVRe<3t{W#8^@LLF6UK z*$_P|Z?;30A?R_=grfN$k@6AjCE$MrS=rF@Mg#u`$mNZwLE!%r@+rb6BH4^WhY|h& z*^3~Bu7q5XtAqzDELOd&LQ}OdcVK{5Rvr8!X@5w*E^Q6?sc6~*(-1No;X;uUAX5+~ zg3#}v{QemnLv>oe8_+D2sr*(U+%6)&#}OU_!AGu0?g5dcfBq`fq1w8aIf-iqd&k9= zN{{8o{}oJ)qQ8p&%L=IIyAXDYDEe0jUx1+HX<@K1x}KPeB399UPIBs^(28q`;2%Vf zYoBe@UkUPa6g8jL%mcv$8LS4kOs=`6Y3W4Aa<3$y4iwsxu$tBQJv z%6~jUD-o6d41}H__~&19irJg|D9GD2D8ndF!D6tqlwyyEY zmYV5RZ^HePN~Is>afu#b*N<$(GJGqT;M9MNEKJkBqtNa_Lzz2CIGurS0c<7(N5ipup9(iTK0M>^4y)$k@W%2yA@5Lzee~{M4@BNum!=uqe8n=P1yV@e%P-Xsd_4zU>;3j z1DC`#AK1Xv5UPqOaBGB?AlUxz1G|Xr6tRR!9*82Iice=?Blbr)Q$!KRAdCjVwtnIM zWh#7Cu?la0q!-yLuiHN~jwZG7ER*clh>)t6D+o6O*vyt8EEQ2^4>(#h+^zV_zDDzoO@K`cK#jLpsF*;41(Iayi9fSd$L9o{8hT&@%>f76gkNukOgey zY6w+9u>YvYEZvqW){6E>RrH(z&P;Ql)CfoP5L;LBva8CJ#S4}f(_~WdFC4hu^Om?i z%582Zxytb3JxuBNXiR9rU)C|RVL$w4wA`N%f6=T#em2UJDQ`pImxe4txK^YH@(jX8 zP~ky(*BVtqZ&O%}<2n8e3Fb9E&TPqa1e1i+>5oaVr;x7^7Psa;Gsr&#c}ZFSh>&*z z&ww3oOPJim1hj15sI(1I1ny%BPge%7pfd01<3yI++F(=iYFJxm9m_}<+b!PL6y7Ay zo8`2ckLGwb1^)ezjtK2R_}J^!nM`>vjTi54l6J^a+n$Zl8NjyfT!a}S>NT$*Yyn5t zdXTC0?64qSykDl)lbSXkbeVArM462=$zHTUTvO+SQtXuZAb}46J7rFvL~j5&t;7|eBdWx(}#-4VvTYQiy`;79>)YAz#wFb7Hx*?nj zyuzu(OlP`QB+-mvm?4b!S7CA<#)IVG6|{wpWruWV`RyR%NFNPsLpREF&e^JlVWwOw z?2a__^%%}qAp2nQkW9{tWqqMZFT~m&eYat>0@xN>hj5>WZ6So0Kyab+c2{1S__Ig4 zK&p1OEk4uuNaCDmxA;Y-WLy_Z_9E#6!n~`vx=8vH;djMt@4VebQW)3E=`$b<5ni!u zdyom0OIhZEn-xo15^N8uQf=8qU=BdqBeWIy6*3Ir9N@<}JXavxAd(N+jqsjGMaYi` zUxWNQkUP|Y>LOHYM+X6ZGspmhb3n;m^xK85EZlfp|0u~h0c3I&bW*VZ&o~}0{shBYl1fi zwm>yA1&X9hfo^aG>Vs`h;0pBNs;EHC|3iTy3l*rd3iQVV+_QJa_I*_(niW?u2AdSU zbUeXF0#goh2f}jDFt;YmZ^Xx2(APow1f?uGI6d9T3frdpXCVB5>HzQuLdu_l9q=!L z^hP)pB)ia2x(y1;o%D9AqdaO#-NUIQ-Vc=-%Ew#`uL9;0$ZCY!M5aQXK-dT>_jDn2 zH^VOPhf~btVLer@HHWiQI`Y#&66F{3eo%gom{M<(pFJ?%A=ul%vpqO6OnBM3VZnZv zp?dIV810i`$qDSvXqP>AU!8PDxJzDqv&lP^)1aAy*)KT!1k6H6qCFvjSpg}7P)g)( zNKJ(5z~2CAj?h?SGei$}oC->++OEiC8cF4&Oz$wkug4QjRd^xxLxHWz=?GIrRF&5u z=m{lTmCF%s0hO0$sxrDqS*$`Ox(c<|2dOE}TED2sXFqiW&ftu;)}`x^Xy(%Gk?C$W z&E&{^G|H)T=r=8@_kTGBzkyP{KWplbQx&S-@1=>aw%2u)n-rT39y&hfwHYZ-}4f&UxiVTAP{tHm=2L&75Z-ud{%F3T|;NqrXeW?)W->_XTf zau(zu!nY#BAlck*NC@)H9ZO0h#oX>ndsZ0Qi=CT}D{5TP;))WNw=ah(xK{xAQy>!w z<4;9sPD)dy&VgK|)GHA>lhPizE&HDPJn!W5LT2obgz~GEd!MdoHlZ1YO`m^ydML?*qja)gN3cn|SU3q;S!7Xhi)m}S> zxuSV*%BN*4{U~SGu;rAJtCq8iv>#9jSUJw?=FmuA*{pNKP>fyjH(hhJYj5|)scg5H9j}+W4($2yB z3J@;RPS5z1R#>-4yBPf9lcMz{kcWMLO+pNBmO>>};lOu=fRj}~dGc4LSK#TRMA z2O9RfR_Fb+*vH$(lKWLOJsi^Z8iAH52L{e51;j&o4F%-epUIQHJDS{pcIT7Im8$o4Qn5n%;%GBQU zSbC%)s0O>^&{YvsgXbWer3k4LT>h%3dDv#ohpwKcx#&mgiG!j$9sWV5hjkf4y|M=*}Z~W!L6%XPi5(!imO+ zdswV=Dfa!aSo6bWQp}~Oz9aO0kiHzk&G&UP3+5wTN0EM_5z-67 zzb6F#21wh}aRm9BAz#RO3&KaF`~&!}L%u`U50cdmVs}wk2A+T{K^c;MS&f>eF{*-| zH~@1ZL<<4kL{5d=gfLg6FXS79y&~s9I`m?O2h1qQa)j$eCPRKe_*~>l$f;aCv;-{q zu-1%lhsdoEuQ&GuAPE)6UrS1RQknw)QOH7sIU>(O-a>dDq_;x&z3nc(a)w8BdJX{! z?lk$UPeu79ss?@N#=!gtc>-a*i1$4;g7BG0E~HgoOo1tcT#j&=NKMFV2wOxNK}vD! zDhW&*$N+@XM7lsWBHS<12l6|@L6O0b*8Lc7L4}Dw5L)FMYx1{haxq5mJ>(XI zn?;sG?m@Uq!MhT z_wB%|p?=VQRH$$6%nD92g|FjXLx&Sgdo%(0M@5L$_}fDA@B8zkiHpG?YP*gT-kPI03#E9s@# zulV6u$x(#r*-{OJJwCO)&lY6j!NsirZoUtqbfF_f&+=z)o?;WJbvD z3Nf|tRSiy>;+~7inZQnQm%4+Vw_iA^Ff1~2sPO6bDVRu7E}(FM299~pyTn17y8Mrst`@D?j+Xjz)lceL3j>$$w{1m=Zp?x z@Czz=75M3y8v3t5wI8F;fc+)Tu8iF(6?9k7RAzcmGj|{+z|KU!ab|QnCzWw!WG1>* z<&leSvsDM-OtjG)XX0&CXg3pWioP+3>jxGIY3vNN8%gbfoq@J+o?O+Sk7l5EqrOv~ z(OXySZ)L_i+nBdoxoj=4&l^37-DAK$Z}btu`yzVYDBxaz4|1+^j=Jm0dGmAE270(~ zDRsci(9dCoJJsC{S5oNgZxss(6jgCFOB!!?H(6&bHkX9E9(Z3-sQ5rX`EoDv?~1Al zd6xvH31lq7P?3`$Zy`Jn67uoSB&GUbhH~H!f%HJ=0+I_JX1?z-VAv}lgNA<1Sv?4I z8>)HO%mxW*{Ci1x1GWX^KMHB9)Qt$8n31&s`I{jZD0K_MG*ZR^|8>Y`2p@y2-H@y? zp51uijIx}aG@mM!*^dv*w~*=xRX{=({;#B*2Wt)T%?5@gQgdSneu|G{hcd(g`|G47 zE_lq_so-OiCunzc|9k-^x)8PZ&!0lrB%=H0A0zAr;cup*2-)5tMVJt-ubcC^LX(5m z9&19X0PEccp$CYzN>eD){Ba@WRBg9-W54+ulq5bEW&B1J{Wd-(;x`WD-wjEXB=sJI z`J~LV5tC=L>%X~J3{hCboA?z+olf2(P_4phIWQ9;FCaVv5;F6zAjM;X_bVx>a^u5d z=tXQNHA4O+Up}rAEoqBRUa++@K5KXH6=U__-8||MVKiv4DuYp6Ci&Kq^geoARcM|x=kOJ&{+LYdiyG~u=KVMwm#CclHc6JDDC=f%)5n} zh!66UIaI6p71iyO?np*N6vk<<;8dk@me1>79Q^{${q{w@?VvA6_y6>7Xj z2O?&0yGicvO>T`ycn;Mwz_fw<17Vj)7s&4jKZ~3JDLsO|2@(pBJAjlj3Kv}Jvh)6_ zz_WOtlY%zD@>pPlc0uSMqM#Qb3=vV#SqRfWLe62(5hO=J{V?d&tYuwF@-i%M0_Jka zBM9q3Njao4rHCXN+it-GlUT*B#^qz9?8IpYsGRSd!Vbae(|k-uUlIBp;^=99&cIC>W1F&^^CBjUQP=K)E4!z2N=JGir zT@_~R1+z`^UtC+-h21T9J_GE+ZsfxnlJm~^L<_syuzeHQdo_CyK9aK@Hi%qe87Xp( zRpY`@4;}o5?JsiHLkG#x%rJm`=%6k_5wH&(oQ`msh#oo^f-qP_4;@TG7zfJhp@YG$ zj7+)hW*j8vq2ycQ)T3e0Gvz)meJJ2<~U0wYcs}Di=)Za~yEbC9G=$JKbr5&v$)VPg`ZI#|(NS^a5TmeU^>uMR)7$S;oC%$qtq`yFtTv_0-3r!SZ~( z2P>S8**OSPMAX0DLU>(7$LwziKY@gtj|`Sk(0CX$I#_El;j9Mi!P*w#1YiftTU{v_ zD4diI%k62f+^+ixnZfcroCbm5PG_noBcj989{RIpht4fs414HLz-2TjcIZFs?EZe} z;}|q_ColId(WLLa9mdmxcdAETRLWV8wB(ETa35m4(|WzsLk9cF)jC+Wp;|_^OM&?Z zS+f5XRhut^~QH%O(@sD4LCChp?~T6D$j zbtgUkc&y;2K}0T#>JT3LfT<2?PaQP{rU7I=!fcV_A-^LW00{-~JCM?vn8$(SOH}Tm zOa@n>kKYz6aU;Wl*@^}d3wZ`%qsTXqa+gtcpsFG~gkORc{J4DLvW?3o{}-q8 ze?=&mBQQ@G(AveBK6me@1~_D;vIlS4b>MN(my z;6-;j&cw72;Be8Mj-pK9NGgaNa!tv^xn!c(%nZY0C@6NZOUIjr57s)-xnq1^f z^Q!0c%&){`HdwU9URj-y$no;0=^xI@=;yMLOUz4`q56`{Fqhm)|h8~0SIse9<2%Bh%l2A+LsMRPYy(7hDa z-Ban0{!Cz3_xOK$?;?jaRkdV#E@tsN zV>QD?QZc){ojZjo5+3#*)kXwu+;@^SOMu_1{JKZA0lSBQy+`#T!t=mOY7wi4BsN}k zC@+@%bOXsQTwA@ETc0OSr!g z>X2e<3AYk9Wr1D7jT~a09HJ%MQ&6`7wvmS+43fPXx%G5ges57(rz?zLW7JNc@^fjgRqgG%QW&fg>{X*9{q#BHu4JyTR=h6DXlqmnT^Zc;`X9@k_4Ah5&ZD+n)%Xn5R>@Gb}p z1Ddw~h2b%B;dLLXzG!&-nQ#XcU&CYhS*&RRd*qa)Gic-Wta5Ni&WW=a*ML28S~wG? z5l*7-*o`BnojRb7oW7X%2H}zOj+=%t8&p_#=)7z@gchrB#14En5#T|f|j0*cL8JPGVW?2%P0W8cWx$ETXI z^M;bK9%BCp`}cu;=s%{t1@>X~k_h=qD5;0p`ucj@ncX~X6idDFu%dfeG}O3_9=q;R6-WEyTxa7cb62~-E7qnfoCYt zM+5a@OcsGmce8JNzkwqu+-54b&yyExNAx23JF&e3*cZ@kM9|fQeF5D&2ycO$wa(eT zfX+@O7Q5Q!dSBtbPumxEeTVTk^49W*I^cD=}0lyaHbAT zJVoiAi4sXE7d1DXJDG@aMT{#_uAFmvIS19U7j$&2ehJ$=e$HBB*SJ_7=l-uf2&-r( zYdO12@Z*BLDz0|;Rm$=*usgg9VW)_8_)CP(fmg7UTFWiuz`ux{xCQbX$-jV{QOm;e zsywNgj+DCAvv<_puo_(J(xbPpYKBtoTEe`2OXyuP{PLzN{sI))S5svmXQ#7J{9vCW z#pBpUtU}px8zvvc-R@I4T+0BvPqh(hifEr&AT$GEBX)EJqjM-i9QU71u#H5!|&xBQRRe!DI;y_}a^2~@A_)1SQAdyNa>XQcC` zV@vG{%8#UCQZ&;Ns$ellmxJ(oxaod1gf*nB2DWKBsA4Y&dXB(F-R&_H4*}aW?;^Y- zqNe!_VIT0a)(~X7D**S86=8Uu*+A+~=nu(ZGbGOL#ejJoQWl}4$WBNDgnA$`N)7f2 zDJQ|&0NY^uGqEEnX?Kl$(z)MJ(!Vy?LFW)Q*r$$V8tgufx?ZLOO%Y$TYnuLi#^_wf z8a(5hy0W&IH;clgJ}5hq+Dk}IkG8`fwKfT%7p3b40(D+(KS9*aEjgrZT+*_iqivdJ zA}&_M50g*puI<}sX5lgom=7V#5N-kqS*1TG#kSD*2pdR#2xP0Khr4hr{$Q9pDer29 zQ*FP1$rfO1`y+(+MO53rBm69)+Ah47DK>?so)JXS{cHz?S4gNhSL3d!g+8~4hBI;_FAdCWR z*|%}FRF4g}@9|H46r4K-%X`qw!D@!w9)@g0STFJn0AR(9ZYou@~oelwSBj6u-5IZh6gv0^zqxZsTqwYvFz#^PV^g) z@J0G|KVEZQ#yg(kW>+ZDU3aThgtnCUMD2$Zc0YQ-P6xs6f16eN{~;?i;@8eA=5WzXc1>I04ON6{d1qaMo%-|&Y?jGMBglOS zYem$jpGJ6GM16WE!VZv-zwOhX!#)MJPq%gPxm)g}WSF7)bYt@RYoG4m%)&n1%CW!n z=}sEV=|s^0QdWI)rgorQ!lOsV)d}P3d~x;7gjBiedAaI!qGey#yZ&M$a zp01n6=^UPCA>?e3kisud%7d_#AYB8Z0WaOa3hQTNzntP`rj3fX_r5|csr0gn`5qcC zTV1cY)5q)^gHwxx^H!Iy)Pe#bJ!j35{5)$I3L8h5OCC`am=OEu@(7HGel|onJrScg9iS75UMlj9Vx& z;fooMbCKhG?<#I=pSbR2+Igv~oJo@JUy7UXgSWVsI=0xLQQ%Jj%Rr^Tc zw<4tutQH7vbxwM38b#;94z@h?N9(_e+SZvAk6@WAOGWsa2g0Y zI^RtHrsk9W!aJjg1s&+rMZquP^E&A~NqQt}B39lse(&in1YXI~m|_-Kn|q-a)_ z`Z~FXY)uEOUSe-w0Ofl?PIE2;Lr)%PBJq8+J3!X?`~`x>rEt569Z$_jn$e{Giuz|@ zCPA|1(@G#A3;zmI%EC%3^+M-;RF9yR`ZHQ?%oI10YPp6%ZfS4Eg7zFDF z(r-aD=GlwBC`PV}k^6M8Q{~hw{A#SP1a@k43&PDJni{P|xEpw-^-n_IXLccyq7zH* z=G?gcRmlFE(Bn8frU?2sp;r-J7SX>6?M8S{ME@qVAK@!t|48T$gx^H;M?$&u%4}f& zNGM5DX^VN0bYhs0`6Hp~m=*#1M?%dI8j0wSgt{Vh5z!wBosH06M1Lf73Bo85{gKe+ z2s44NKN4Dma6L#hbs6il{4LeZs1W_B5M$?A;Uqlg6lY~meJ z+fiaQfo}tLlz1HBF%Zmm_D7Erd!jMU%f5ojUyG$S<2|mRhboLGXnYYGub@|wiYB!{ zqsSSM4={cUWUtHNTH^Z1vld-0^;24RSIy&Ss-P(e%=3^@2z^09R{mS0)LF>=O^|&6 zav7>{o2n>%lkZH$@nz64DN# zjmYgQg*)(GL6(Jz$^FzyD_M~kjg`K1IcrNpMq>gcp9V@xoXf% z{1QwxU*NJn`h!7T+y}YUsiorc@zlf4t1?6Qg3yas`RKaS&M&$bJAFP7s*`^54qM;s zQ!l61=`*#enC%>phjUhYgwi21Dpf*HvgGResAd&rPA4|AFQ` z_VaCEK8Khk9P^Nbto-juX+=r{kf$iojNyn>;7XmYo4kvNaYc+PQm&j+Clo9GQuLH6 z>Blm~Z+BGjpT8*#)-X3LK8G~ViMNWAYR?_Nxqa}xwc3YP;kjc3g}VsYbH`+a%RoXF z_S|s|>?#oa%XuGt?#R>ZcLIoEBI|W(q!o|ElFkuSPkw`{UkhYkd0CIk! zCup-%k({!w0>e2%*1*0j&AOfE5UWf!409KeIuzf&z>I^eM_4T~4PtKgyzfM=fsBI; z0SWo~H`ma`4q3`ghHHR-FC=~oE8-CQml)w6z0gOz;drK>Nw=R)Nc|D z$@`;>YhYCk#O*IHq_r8IKvGj+Gt6?{yr8*QhWDbrN1pDN7X^>9yH8e9o((fyZ{-VoYjsOx; z9Qli`SDXWjTyk)K(Nz+|d>Jdz{zX?cSXB`8kE*`39UE9lx0}uV0@st7oGaLdbO)`A zD)&aXHc&t*j^uu^b71+sSnh2xJW<9U|XVX#&MDyT}v!My$INrxF%z=5EG6^Eg0LDSdYp5Am`bmT4IcIP)p>D zb?um2IxMZ`+LNL>^HwXRq=c`d6H(4 z>W-J)%7e%tA%*RZi(vCXXD@qC>96a0y8Y!n&B|&=dYQ7) zzt?TTY9p}!UiT`(iy$E@`|ox8V0%H(-$gj8FO`0f*ipBRWuzb~&5KEU9REOogTNlb zR#!SNmlIWHQWHrfog*`9QvnNe8^bw{rZ%J`BpfBzozW4gTa>}!U^VNnrUh1K5U-~)Xa_kTVF*ZfhiIkMuIfx@m$G{VwdJDwvg5HB zD;M3Dy%J%zi0;cSL0AmJRUKV;YvXO?ioicN>7MLe=-0?W_hcVM*dU^NvM(Y$FQR+0 z?;*Sk66^5I)v8WV(#8ABjnvM%)1@~qxrLbI?Z?tS&Nk+~q6VRRmF13uS&Ql`qJ9SK zEx@xgW&BY2%nNd_#7tMs=60GJGkevX56J`es<{ZE3h>H3O1Qo~VoaC4&kH$o42y7nh5l$A-m3eQ3ULdT=mt7vd=M@p*s-&&Sq3F+( zgKBad!Wa?N^fqyBpv4ZOr4jalqq9^QL6JwsMe7GYLHr9EJQ!FnwGN~;RW{>Q`p4zHJJ%6;E>+r zG)JUUTvexh6KLtsEX8ai;U59zS3|Z%(VV4!2Z=ADeIDfOb6WjJCz)KvDE51ll#x0_ znZ!+SENc|yFUKt3&4nvRajzh8Co#7xZhfbRY_O2I-{`yRvi#LUJXCI`AKaR70pN@;Kx~gqEP-1xSq|&O1c%8Q{G0NIeUb+XiXs znmH=%o9u@FE{X+MTm$&KQCJ^m)|Lcq=}$=1(O>QxgyBvbjp`|~%Ka9Fmovkuv;r6` zaO4Dg;&lJ_5I&ZWI^=4h9=d+`XD)s1pF;3tycgs+_r}(}ul>7-@SQJqwEWenc_zn6 zIbmVF)Q;qRgpBKI$c~Z^tn|G5fR_`Efa;<-Q8!Yfr=lPljz0_wq+ihGY-5tD%|7Q+ z;<3lMLGnFsA1~48OQh)uq;~o!(nnk$!?XE#PbL#&vVwo|EHS<}ADdr+-lw#A`q(Gq zr}-#VnGxZj%O;#)(Fs=AWygA`US3Hj1;Ia^jemiyukep#OLgXiy~WJ|)+AL_dB4aM zAiKlYT%Fc(NnX<;PEd_xPdR6ZE@*2P&k| zgFxXn6iv|DBnl>xJQdOw8-FsS9buY)$^!O3&dWWcH$(gUu|Eco2=h zpOiac%Ypwhtn*UBa09F8stMonC=X&orh_AOqXMJJus(3{(-Pl z!&7a@T|ZY^`@bk=GBN^ zZ$HaSEKb6=+snH844z{TUaxl~IDx~}qA03;>h}zL#Zs;oRnXIwq)q7KwYiRB)<)5g zvK|M@H!Nn=%vt%3NbHKX6R?$#SB*+|KUo`hTM6f*7zk`7T#InEh$>+z!cD;bEsNs0 z$4@gA5Su|_p#O@|7X2(uiC*fZVhwdBd9i2AR!-rBq>k8 z9s&LY$cG5;fxy(!Uh&eGAlym2Kp4wzNH+=>s!FO)m#7z79g*De?*%1H)qCfYsk-{_ zMEn(aN!_a+<(ybaP`PtVLBL7MOhA>oi=zyfS&-@oMIc!29FD#~T8c`W9ujCp=##0R zNv_l}?_7m0X-W^eo^iM*DswI$?eJ*@5>opYk}?l=HSotl?m$=t3Z_FY!9@4U{TYyl zNnH=J3MkkbmkW?srij!RP;UX|7{~#HFG0|@Zdl57T#|4o+C#_HV4fWnGO>0$ zDKB*Jf?q4_SG}kLE8NYUEx>~rZ}L`xj87zGYW=qgRj+qG$6#MaKB*|OZalU@O{djb zEa$^^jOi|zuJlMNv1rrO8{^qUHM5IqH?3JC8~=i4RKQ~P^dP>x)PO1^YzttUbF14! zW>l(;awh$*ilFA~icKeAoAW$`K_K|iIUL=buTWdsG;_9x>#KjMIr}11d$8HA*S=n8 z&o8T-l&OS@reZA}cXpH|$IAfIyxO6I4*wHThXa|Hiu$l>=j<^3NbN+i!`gAjdf~Oy zL9`d~jKtw%x8P*n*u4akYsmL1;NK2ehH#U}J&^SX4}yY+A&*dP?~<|q7-Tc4PlK?f zPddiM^dc#$IK8nIqyei=Q@*Bo{legy)hYs!B`*pJhj*oI1Ka zJVs~l=TLN}936puMa!M8JS?PWXPDz@NBX1g1MH4WN0=<49a(~~7zB?y$MCnR9C!KT z6GXKb4c#-9d9cgb>hJyR@c+ux1nF6$zUEG1rT_;ifEk->rjfddEba&98pw|b2Sjd! z)L-j)wLn7V>6N7Ti&oC???sqH@N zJ&%4;FUG7&NW;T+%< zJo7cTDJacUoc!k@6G*-oqb0kF+NJXez9sNY?>F>WB7vxDDH+ ze=eu(a4V}5S`+R6uprKDI&(c`SVbnc0J9wOD#DA(^#+%#hP|CO*FJjIhKDmox^T)* z?`Y}o=Pa!11-UNUqsPhO#yTm7#$LItUwht4mqpYUPNGEqn<##w0N;b)L1(es*13IC zdn&5v7fCxC548nPH}W`;m%9Gga6ex|H$K$)i|(1>rEYVIw@_%+NKSgv$X29X27I8H zg_eY5!Q(>3EH*m}jl4TU3xX_E>K&=*(nspY zB6Yt=om0n!4X^Az{EAuBbNX1I52KI0U-Hq6k96->INkbtwuSknYjRPS6U`L7<>}Iv z(?9LDJbk?78uPR*PdBu@Fr@G%He68@E{iOZ{+AIQXtmJ~#nW9ZZTEKQot|K67e}k> zFH3G>c9Y(Lko4Ez<1(qPzo*o+CtVvM>0c8mYU=bp0n|LzaMcECo(b!&lneP702((S zS*VkHTTYigeR?)*+@NuhSBIZJ7cuB>C&d0&jtv>T*}-xY{@gko zf;-DKCOMv+)tiZI$#^h)^aL5)gh4z%{*%5;w(7x3d$!O%T$zJ`+T-LKs=Mt@cb;AGZ_9*~m? zUPsY0+q5QXTdV1rYr3FmSMULv{<)?T_1e#|aPo2SU8 zqs@Ly+Uz1)C##v2_LACXWs{?JX&Z6{x4de|6~*!_8X`7?JbhI_ytDs3PN~-j*eZ7V zT)u*9$*HH^IWH*BIMU1Jnr(OVi~^Yy+8ym}%UKvRRhu(+u%#)AnX8D}*OF>6yE|uE zv$`=e56^y9!}(DAc9tbfn}?t|tAdKyga?GQJIhG1#Vz6aDqH+)|6iz6%Za|N#K12| z${IIptT(9C4l`t~DF$swleB`O|tVc|emnhArKaP+1 z<|_U8Dj_*pi;s(e-J^W3>>9!>jUULql{DMO4jdEq?h8hH2ihD$o1Hc4vhm)5F6UyA z?`8KQ>4t>*+ruP;MaxujX`cK2|NV3Od3v9U6QBC9^ zTx(w*KnX`HXWhOa^=ngK0bO?G<}IeSiLOqbhUEGb6(!lmTe4JN->}yB?Rlo6D|(BZ zsg!c18kK8GE1avOsOl23(RWROcO^#jT^ZYV_1L}(1nj#qw(rW= zzAIzN^cpkxAZFAWxy`Q zo0(e<$~CEgZONOZhHOX$>@dCkH4i;zmTsW70;^}b#i>E@W{Xpf;!)I>_L%y}K#xgR z)T}{vlkGOWL$W#8<*?)Q!k*J%&*?2t{edm}!W^kew(OP8GhpZG9j2C*oq)Zkw@9%T z$Cj_se+KM7y~8zcz_F!0Qn5iNU=QjYSx1}Eg=+a)AWH4e*zO%&=;x4K!}KQGk9x;u zw*ZT=C-s(Au}G#R>`FoRl)a=99z5I_^XT8a0VDV`P9wEKdv|$`8#lq3E9;Tpw$mWa@kJYzp+glu)QZm zea4xMTOd-UNZ|ao21p@A>Dd@M%1ALa2!>K@`Nrc-q*|%U&h>C-q$Wj2bUWj5jg;~e zK{jAUlUh`8gqk9cKzHI*s;G4pz8GW5Xm#zO$n1Lz_9gZJiq_Pw!cS8@E<;|lGpK^K zvEx>mXjhT_An(LzckyJT2F?aDj4Eyhl8xbADbb$d=Kz<2HO%NOvS%oH!3-+uZ6em- z1z$iP8691m3&OG&oKDI<72WOy&l2k|YH_@l)h8ckqGJ>r1#II+6CF^>(O&R(QVtd` zgp>i#RDT!c%0}yg*}!8PHiNQ0P1yDp(T4PMfCFbKiWzN8KM5phB0s=S`$I^gWzjOr zRCfpDnz|Y^ZK?Yyu8xTufTYM&T(a~9HHP<5gr2H?6qg--A^T_cwLiUQ|JJab*?2@Ns*HC0Fl}P3te`eMlJbun$zukh?~lB@JLhBW;CB?*CN4ISBT$9}J>hq{m%_pt zw*Kndp?*uY)^q7SaAGVN+K>O{t>#l2c9fQ%Xe2&Tf)TRkCh< z2>8{&2m7jj2Dlvb2HWuK@aY848+8`>o13Z{%SbzdH~rwaN)nU5Uim5 z1Hwvi^9quh<8TjKnrUu8u?Tt1(;#FQprH9oq!GeX=^08szC_cqd}jW;BCyItA`sZf zgn{atK~_$52P@f3PeD>*R1Nzd<19i-q9@-0IB@oZ)rsCbn^)FpAu?K#obxQn`tq#8 zf>Q%&iGJlNnd(!KHIP^pTtnG>?j%-c?Xz$kiketm)(5DQqt?~^M9QXm2Z*zY-N6s> zi*6#ZTc6AJ7EJ7Jr=GyHUkDRe_{8sC0bSkoD7UGbhpW^*fh@e_=->G94-9N~gLK18 zmRVRL6Jb4;mV(*eH>hDA2~3K!spO0#*(MEhC>tMpCba-;-n{{39LIcCw@MU6nJ!=F z#cJV0GxZ~ANuHSAh2)EdWm1DZ9$UJJruL_9U>+|f!iJxkkE#yF>p1YwpH-#krKlzO z6ndQ`Z}FlTRz0oL(Q9NTi`#{ZKaj$Up+ZF^foZ9D1g*=+g{=0}i#})uQ#5a=LMOX` z*%GDLIQ$;XKXf>s5FR1WR{j?Fljn<;_AC+%`}|YLlwP2e(WxtkC8)in9W<~vb?0Z3 zQ;UK7V^Wm=D6@Dmkz44b)ik#+#e)9#XSoKisKsRCTTbd-rn3a590zrJm!rld(I9OF zlnd~5@@mP@h&CqcOP_hJXKB`LpUoMZXTw`F+^I-%IjWiA z_9(pJbbvFos1Xix>UYBXlidw8fzl_tg9_7}$?kzP2mGf1UUe#HOoX~4o6&#N9|g{` z`>54$3czl{xgnIP?2e;@a{q#jWp_5+eW9wwJf){`J@fzPfn6F{%F|rXGgpExVPT?&B_d& zeLg6xvooglGD$*ZwMp3%EYSU)qjo*cmxqO~I=FCuk(A!UhS~)QMwUeaJ z{2cuBoYm?bfAVI)ourR@Cz=;37Sz6slH6ex9*JkKy6X<7eOTcg&KOm=9#m6@)!j8h z-91*Fs<^jO$P>-|6&3kz*m0esJ?JeJ71!As(Ux+ZGld@0@?GZ~K-=B*;5d}(RP2pT zOz*V((Wtr$t*DPHqAnaE>cSDCE*uthp%vvP!F|yPhg=$pt>sLAo|9yypP31rFwZ(c z>vVotT(qABPUCR96t9_rM#fxTe`__Yx&cS@9p>R#pONXNuAeX~VQ`RoFfjz4dZr`&h>Exe)hOpS%u_VqSn-WAjf!0;xKZXP3ERqza+nsD-PSHi@Ft|#TSBoB z4nJ#mK=w9Us4rJ!Z?h%Nz1hROUOwDi3fv|`!`|EeY56V;%eM)_FBa{@<33AusbrOY zy}80d=*v$*4Q{k$d9I>wqpe2u+vZQ@o@(XB{jZ}5d|omv03<9%H4Iq^HzE3@-P@2f z&>OiGXm>->$s0hWP5D&XR4dKrPN?bOtNA8Oj=&rDyw8BnV_r0NCOoYV5}#kM7x@XEub%+4eLIz_kY}5YpO(-x8vRkrYJ=U$6w?;R8pi5m+tc* z_ea@p=!^X8cMA?k6Lb4Eq4uTxml|x3N1JHQ;UkeHU0+7h3MOcMc)yM zu6hG*NnE9U=BtpRi|&c5TBta!)2FMZ@+niK=dV%6PW6xwb7iD=RBs!$?O;N^acL9{{tE83MW#^CX-m#tv*^0XslYl z)~vUKo#g3eL;h886hFcJyHP>-U<+H+p=v!}u9)WXY2r{_lGWH$;!y27qMJ`X5$SW- zUlpgr7mHMC5)FE>m0!HB3qcR-ar_rys4H-AOrk?RjGMfLeK) zIWV+xtvN_b490!njl^DR+QDR84y;)jmxFUJeQ-oq0Gh0cctv_*ul*>FezR+;kn&Yl z@}$PONIyQ5GHDVq)4CX!Ox-SAuSZVWgDWz1@-^V;`{8K7oPwouC;(teHmzU8b1J(J zEB9qeTe@@;P`ML0;Pr$_m#&8_zybz?d=X=7H&#^!M+4BxkNpUeILC3+@dxMX3m|inWhQT z76utoAgb3OLmjG~fBT<-@wE*y#76`fVm8RoV1o?VAy9&fk%pL!G{kJAA!Z{D*&|6{ z!woSTZiv|sLwq-Q!cb{^L|CCQ$X^Z~_eL_>h=QI~i9ZT@1W;j?i8FHG)fct_uFdwm zf*%A{dzuKCD)u*(xPf~sQu0jC@)Bq8!0#FJDB#+1AKoTus%%*GEu@$z+r8h{N+fII z3>)};y&nUs4&$mHu*Gtv+@F}UEDRd>lN8BD88q;R6e&j;H1H=YG7x2W#}9)BQ3ehC zX*mj;?J;Oji5YmDAMTwCAaj1;jf}2(Ho96u&JjtE0fS1sz#AD|^=x#t8)R!z9-{@b z)PM~s&qi07gIGa|MW>qdAWApg;uNlUv&BiPcoa3Ev4S|=;2+>Jl2UEM1c&e^%5k0_ z1_`1J68H;LZ(z&1Fh{DAmbDTi@N9sUO3IGM5W%7xkrqcwR0$AxHo(f90Y{5>q>>Ff z9+v=*tYZ$M16rb&0IS6r6Q@T1D0eD;s>1+l7nD@7mt9)Lz^7^A6VqQ-MYioJ?`~u- zuVU-lo$+jdl?Y-2aSHHPx_dzAQi{v_yP1>z*CO@7#Yl-B3nbE1OV~s|#0?&4X}k@{ zn&`in)0(~m$cE?)B5jIniM~ptGjk7ewwlye@WX#CLDIN40WNGFs}>J?me ze@YX-8NQB;YWW$G+`Vv#--?82sX&^T=W$Ua7I+`QZrr(C5{;h=f?z@u?_4)Pw~+r2 zNL&2dL3we_zX1DR1$ar#GXM)5VEWr4B%Ti1$T%cM$Pl3eOyM`ME`CXlv`d*!!pJMU zFv%1yhqATvh78 zSRW*V0E=wg9nwh6ro?!2vmJ7C|3`)cwq~iNV=|inX>Vleehv#uLP<(dl6Iw7k3@ag z;o}-`O7+cSoF!o`Z%p1nvT9B{_=%wc-Ks*ml_ zqc#B-eqwu8Fx_8+LcXStY<~*|J+J8l$mbB?wH6X29UXpVl{k&EyskkG|89VP%d%Ad zAq0B}c3cm&&dN3B?>wIfX8!?*e>cxOhn@6$CHAfzIU}3`{;OkQ9F| zJGYz*?iW)k8O0B-WSL*==pd}+d2uXTpe@gfx^NS)Jh2xK9RjI;65!uy*^EoQxh1gl zF&)5s2{MH9rPyPwuOQ3%@G%`I3J0mN$0k#@Lw`P@GLp_(^J5*-B%L*D%~QG&#aVZ< zd1|^gD^ya3%J0^?enu4lYocabEq8Y@)%hH1_nxLb1lONz?p27w?+eFEE(@G`9c-l0 zp2RiT=K&{9rGhI}!Lex3f@X4M`BMc~_A=FH+qgQe!3I{|ElDlOY38;hZ(^#tE-VMC z>iRUR%0B?E`AV9a{VSp51_hDfk|jlwO%ScdoNYRFx9wZ&V3!t>}YLCXOk57#nD}_AVYBH96iX!9Z*&5=)Fj8 ztLx}_6aed&saE=JdFZ!QW<`EA2=SLVkG`0zW_&+1V{X0rfKkQR+;)23-ivd!-*DEO z1-4Ztu7+8$eUhYpKIGk}i|a7JM9P=1RNZv?BFp*^QrIgK>MB2$_Igx?33mJJ%zrmKi$ub$iC_0$eWleSn{U z{i@s7_!M9qe1V~EUn`Mt^y~KZJ`b$Uj(*(<**~CXXuSt!$dnA+S3m_X+aCF|hlY zL9kodG^4{rcV;dF+rnY6J4+1-$HDIYnumdKhHjv?tQ`m|P7R7T+kDDVJPOx;IuLdb za6M4g*@3WoNcMZ66OI<#a40Ms3cCwbbzqCVFh?po6m~x|7IqI)qr$jhFtcslBpx9kr#kLoYirp28RffgxO80q?#<}m%U7Z~ddCp{9T4u7!c`*)^#5v@4 zPtdlMBV6*vUXJvDdjh?2g%9zJG6D8{jn~}P zcGC!JQZ9EWa?^#N2QOPsJI|(xk@Mcn!!J`3sTRYV`(rn-o zB=|d|oh!@8vmo<7K(@=tM2<{xd*lweg?g6ML{VYa$PjamuI2jSF6m{?F>223@&H92 z8{=Jhk33CeX}kl-L$VK%Wop}QDbbu2K{W(CZsITHF~y12vf@TPPjhs<#gr( zuH6rpUWYfKwkX~qVaMd~KFaWM!gi{OQR8T{+Ybt7cwK)+da!Br@y6>e+Q-gR*yN2W zzD@?2Or%HmjFsdul*sEXzJ;7}uzCafmeIv`fON~>AtKrR@Z_!g#`t_TT_Yu?7XvupS}A=8u)lhPxnAnN2QcQZH8)hk6b>I^4jYVa zMQbR6Wrw^_k-9_L^pVu?I4rqHx8ta`i$tGSrhnt9=ySJ9YGORJW2@AYBhAOuRvE*` zRC+z2A@*Qt^m$ulHY>Wwu78_k_}nqg4@2!{*;Em-S(+#$Pnylr&nHyOKk0OHy66+E zcmb^0B2~(3+KvPBVqwwn_7{`qO|V!du+(WTwaWp!shZQX#d5g9bkgB6Kquwtq{C$n zS$*C!M@p9WO!XcZ15Yg#jakI#z~$1aT1>3Sx%3(v=wr?a(qwZSs%<+0_RUd?CRZ$) zBYQC`&(Yu8gn2Sq?a0lc^W&Hdv-&MS9IIApLFaTNXh>M8&?{O|c2`zdf1k(G%CM zG9OeiHOYSJ!zy-DvFKX!ZWt~avl_|Xt0_)P6EO4D9$JY|$R9PF9)*doD^z_6D5A&X z?S&+TjN{E47BtS2XhbzF5cG7KJ_-O)*3*5gxa2?J{5;=5H<7-I$Hpe3g+(F+i^9C}dFF?3=N0z?$2C^b-THYPKAtM3wU8i5#jWIXb&i zM}HJ^RVb#h1m^Q|xJ154bI$LgISJgW=TGJ%$&^k&p0`1*Jc?vG%G=OI9oFIvQ`BNT zL9k&SVHR@3au$-dpJs=Ljdy|jgp+Zh^b=}SdgE4Db?lB|xyQCpE(wkuu&cWjmrm5lcKnQoX%Wt)fqw~jgmY=YvsrRh3}9_71G7PyoGa`hBRvqDoLk>Z zA_l~gbEiFl^j0*f2Ha|xT6<^<{W`Ti6&~l`s?Vc6+o`oTBKQ>8sr48;wFUvF)`6W` z2X<;5*r|13r`A|I)zf*MFf=^j64+_BH{yhgcRRD~2^VifD9RhaqNa0s?GjkzjhL2u zBc|ovBuvho>uOn4@5KV(ujq8$+g$_rhB`jqylq(7aCX&k8b1)^-@y-x4a@B`zM8Pt z+6LRXbS)le ztBY4bj)`(b(mSr$fqK}1K_{|XNPD2vDV#%%93w+l#x+la(%(2UNA#a|uy_G}aK0l^Ip48Alf&~J zgpEGKaK2+et1mp?!MaT1fCYX=obOBgs% z^i;zRuaKoXb>!$33xrLSE3uf;e+)Q?GAx2AJ!&sJ-+?JT5qrJ^Q+gJ%tmiv0rDu*k z-{FPlJEA<_feAisu;)84!6%PB-+>7}dF=TPuSv=5`3}tXNoLP?V75=hp6|eHpNKu* zfyq7v*z+CeREXH~9hmqN*&1bCc`Ww+eX}W@o14SNZ9MH1sF~+;Yj2L?!HKZ>rk#}f!W^n zddP_9Ujuo^?VYIKROvpXyJ<*E)#)VKt;LO%s*h=J+mpqq7Eg zYlm8IHsP7fJwYC-b)A|I0+xC1%a8cmwb z&Jxl*Op8woh5ie@bo%tLVBIumOVtuECr#~!^f>_s6W)4SF!geS+ovT!cm&9i~4ANZVRH znq;~?R_1`>H)T+DYCht2EL*oCo>M~eO7|!dIBm=sP$cQBBG2bzENa$x@pfQe@G0H9 z0RG72n)ZU^>e0A#FkvV=v;wgE5(XRDDZxw(yW9ovbarY|z3ANnO}W|G^&s*$;Zk!J zE*hmbwL!kw-$m{>QOta6P9>d%GgkTbn9lubIKQ(YeTB3peU?r666b*SntXjAag;U- zh51gO@{KbaRiE$A@*WGE%dp^=AJhVFcW#B-^W&3Iuxk5vJll4m819|mG$sOO#X?=j>|@P zBOzU&OiDXUOi7tel_h9L8HvJ&S!n}(PFiq>=H&v=SIL>6Daf^uR+Mo_ua;w>rAD@* z;!E;XNUoI$C}W+x06F!t2_9^apX1snW6-#pX5Y4R|5_mXPBd&_iiO_!(O^BHmrn&v+8OGwyPu7R%o;;IRYcGVmTGZzBC*`3~sk%CDhio=iiD4v}xd!}H}U@X`Vqf>jIU z1=QD}@*>g?6A!Iyk^CMuFP2uohs#6AJwgtHt|KJ{uA^iIn!n zxfs`_aylrNNdqijF8hFfh0MowrSNmPtK@&>DJ2)@W9E!J-{1e5VoBnufmdz@&wX1$s6#}W=SIDREfjp z)8s;w=yaKZy4xa8A^mf*5%SNFwW#;c%hzG&7vv(yIa79_EN96tk#e?7h4!to1-$3T z7h&5MoqbJ z(yoe^p)u%`WLj`b}~YYT;}0GQ4-QjDrVm zkvd#&l>C2g?wZi&H@-;z5~ z_Iu=X*l@3`g5>*TDaw1l1W5U|YzFUlnU60D6@Wx|uB+C1^lpyB`83j2%mP=6H zpU8Ki_iwTgTyMyD(EMF)K`GvpCvbgBro*fMkQhqwPx%*U{v{ux)Njipko=C60lzE% zhL_%x%TSj0f>jU@qPkBs*3tD2k&t> zsj5^u%%Hb?3L>lON<)MjP`IjkeWQbS0ZguH?n$x_&ieO5Wsr@|2XQIr+zq+TcIYg0 z#kT;)BpD7VbSvVSLeR!paox$s9cK#dvGV}CAEA~D9SRq3Bugpik0Q;P4atQup_oai zjl#gNnBLK#aNnGQ#L-sFaj>w^XT?y5DR|?jq4M0l;O)W$<#dmS_X-m&{B7LJg-LM+ zR^0n&@sLel4u2LVTlk+eVTy$V@=mqz61b@_&B9YjvzLV#Q7P|^0mP)CJ*E&K^uRAE00AI`$ewD1nvIm^QL!^?&JE&L=Mdw_+9D1WwvFG5=? z%(3tTsM^AT3L};8zpAy_zUvadJU{g1c8yv0tWQwQfZ?s6-OfZFAj@xB+ zIk!+m8(JK2iZdxLbO2!nYJ=w9kAG|O#BAY8$N4GnBF!$IgNvzu1fAR!4%bYoNQyeU z3Mt!*O~K#LWLX)-X1l!V{2uM2SXRVyevZanY)LNxN8s$Cyw)^leM#pJa9gn>L-wq5 zGTL>qQ<0MMK5C%YrAXN^a7eK`Ljm2+&nTd~L}av6h0+#BY0iN2AUss;srv_{4LNU9 zKyOB8m(E%w75i1%Z0G1QkTHtPcjnat8BhU7IJ+oqu55Xt|c--bGA5};DX`=&Dn~OF0As|s(m)GcuR9y<@z}LFwR9)Ll*f^KqT3y%7 zRgXa5cu-xhi#l0n4@yzp&`iS%P8|J9b)zCh4Og@xTS1OE zcmx+t+`S2C$Tj8KL8K~`o?kjL^$-N?a2U@oEvfkea;|ZPm~(XPHXyqk#`8SRO`==9PJl{VDkP`CzixO7hT^fM%Oc-K3zvb#Q;r9K|Y}u0Qn#bYJ zlUL9PjXaEYDRK#napV--A+B7FuHBPa=tX^b2I*0$0%cTom!V0{LP|uQguFnW08Lyz zL=#HLt4K-8)liX=*KtkD7&PmQ`~?Nc$_zA7Oo<-_QQf)u-$HTX1E|T?T@-K}-~{L- z>Ml*vF5_GUGwOCI5}4}gNb?pUslKy(FZd^)2n*WsO}r^G3}-jkaQ3aBi?Ez_&dUY$ zZj<>IOsU^rvk#gTS|EiOXH`0p^k439QHrTJGg|0}%Q#>*YNyayWNlPS+^?7sm-OZD-*TS$G=&lWmi6u*nL_uOQ4IK(5%4F+CroC?qZgCm`a$k(HKrNuzurLrPwZe=2KoBido^h#D?qtYsGc93f_UE`f7e zgEN?_{oz!`rn_R1rcRjDwpow&e+Rko7jT2MZPrn8eAXDk9Td}yAjamscCtiGd~aOa zdS&_jFw1(4OIw!p8Za>BUqRM%we&z#lNCK(qY;*F`Y4KyGZxV{eF|d{xlPN>fx0M? z!)Aj8Io4@z^BS`-$J&^-H^k)DnxpKabTq)@Eol14J#H!UH?A`is@U*M`CnjaR|76( z&ZgCyO=pJfCb!=7=}Gj_fJTMyP$>VgfIC4e>Kh<$W~`>6RcpGBuQ)G0!qiP`k2l47 z8g81#BcXk=kmMbJafSv%JiZeR5wMmphvyDp+$UIBU}&(zh6dvd4R*|}--TN)&d^}T z+-Y;+<8Dl1vE;?j;Ax;Py^e&&tuEOy5&i;l{`br8d>b09wV^=}Ff{1f(4Zg21ebx` zw=uWOkqYYzJ$)N1L=Izxe)tBw5plq}AaOw#dX+~tvKNrG^6t8G2w#XyZ(Y@86ls^S zia*0rV(&*ti1L`m=-godO_c8(3ST*-N6q>*Jsag4hbk`|Dz^5Z+0YHqS4J5#!)|Gg zj)D*NiBokDodkXRDjbX64&Uyla6Eb^=x6GhZ#Mb>Xl5x~GWkCPSyrG8^-*sfej+g^ zat&0(b|J^aQcx+e$xz|Mmf-5f9)c(@HWBH5Y%{Kr*i%T4nucBY31+3f3+5~Z+6!eW zWRi0H?129ky?=IrCkz-pVyV?QM|s zpyVBUBB&D$NUnmmcchKp(f2XDBNJ$!ZvTBp<|@s1l;>D2|Hn$dQOm&czbD!(^tE8` zSvgKKXx_K48HjAea)7R;n&1)0O|C=UOIH8$75y(s`>_6(WTNWl7VMW~hSG48@=J0U zVeh0(#{*vbGI`HdS*NL8+@<}p^bXtmvP>Jc_hp$sZ13+z*!#N?_Wpj@-al0ArT_R| zaIB<5(Osf#l5s<=_`75b^W?)M^JXYaqwkV=!$#jFD~64}OHLm)`flkRHu`QkVA$xp zm(c)2WB8n%PW<5ETfMnb`iH%_Ql=|RvscQZVY64t>S422%2~r^uacf&vscOF zVY64sl3}w~$vUN>XII-7c&KMr%T(*xtI)=`h)>1M=K+oY`54w^omQKpPZ6Ux9MkoN z%a{yHkPbl7V@q@qdPgl$&xjKBge9Ugdq!B*Gs3Fg5mxn9tl}Yu`BJ1+`lh!9cC(pN zL@^fI^i*Ue)|X4mK!U&YN4WP()|8)BOex8@Vds`)royb_k}PE5)e$8*jxav{gR;C! zlKrE2(D4?3cQjF#4L$PiUJ5sWDDv*1tOEC=PQokbUiV^6-^iXn&W8J52ZfgJX7WdE ziy<-Vu*Y%2*78%dKsRg`>ROVhYqKUp19H8feu6r02BzjbF~XcDtT}9qktew7Yt=q+ zG}Y$$0fL{{&L`)AWE{H~>#Ln<29YMZu>TdQr_RZpxvOtt+N7$R#|(rTBEh^#$TtDuE1 z5RbOXCCK2rD_jm$LfqvpCcv7`p$cFMFabNsR`Vf7Cmf0_#stLfQhJWHiod^ODDv6k z?v<17b}$kic=x#bNIGjc0SFJj>+U1zZlIoUHcxuH(!x#viB)sbc(@Sns_c$&VIuy^uUWItO&ZMyYH zUPvt?%m}*^lwJiq_;)5SMDE7(4-n>7EbsXm%C8*yx8t3$r$8LOqEmd1WL%z()T`Oy zO96C8Q?yjIk4mJEYqjgw9Zk`?!tqS!j;3gR;S9n{p(8lNmYgfvv7)+9SF~fL68)wt z+OaylO?5>(RxuN?PD(_B zG+L))z?KN=9!9=#eu|t#td24QQx|j&kYaloPm8YjElR;v@np9mcu8r{b|@&?xGLTr zy9WdjE{b<3SVQp;($AYf*Tj=!LLpoePYw(V>AeON5iSdkwnDfh-e-kSK3-})o*M!q zToIq3Y!S{!Ct8r};gjMQQ~P}|b;zc2HGHxKxfnjhf&tj3T98ZO(=5o9@VzX^h48&C z$aV1P7UVMc3=47;#P5qw_@at(Yx3vvm3rUkhIKFfk!0N>w&T>n16f?WQdZ9%Sn z&#~YGXaxr**?;}Tu;PBsNRK%yj| zU3JkrSysd@dM8@~7RZTXoi*7S(0;GTMj8~^%Cd1TCnv`REKRA%W@Q(>lLrShv|MB} zvWwoyMJlSNNbig;vJ6=CHsgWN$fuUGL;6=gUU@^G`DRFrMDGA}1L6UM6C{waOPYBfUZ1fUZV488VyXCcw?| zHge0-1j-h99x_|yEJ$mU-@u-B`6Xm_$Y#)V$}Vtq$$vvmw+uq>D9J%WkK6^CUKs?} zXgL-V`eZC9`y~g;F|r-J12PsggAzsVSXqjcaqY-0=QhGyDtV+-jN=i5XW^&mL;E!YTZzi9j zy+$|xW~vmin}0Kf6phcuv2K0{0R*(&tPExxn z*rz5xhKp|g&D6RIbMtSux|Xkf?6RAGa~<~~EsjuGuB%}gZHjaAZ?0PryZJXas$o8C zvYUT%Jq^E4u;ASMo9k`h7IeG$H`m|HHfJ~g=EgKrn%(@H8)&`<=Gx7_xxwZbcTKP&A+)Jl@Lgdn}2hYo71o%D>-id%}r6tQn>jyTT}Z(_@v8j{>^ss z-4?uQvRy?M$;3C9Y zcqXNrf3tM~CC0h=H(Q@(Q#JYk%QmEs*6QQt-)v)=b(u8v4*{b=*)ogr|F!RTC)?2Z zxFqQUD$~a@_Wja78a2zcWnV|S{}wKtAK~KiV*F2VZQ%ZR|3jj5w$Fx^(g0X~FyP@o z4S?mxMVEoZXaFofG4?oM8vx5sQp5(p@Yyd1jLlGMQ%kQIz4S?nMRpbbV0kHhc>ihAtOaox~{Rr9BY_)oW2Eg)j z6xpl+u>66EZ76~bfaT}v`@*+s04zT*gE6W3q6Wb7hXg->G#dcRFUb5Hhz)?{k4#+- zG8+KPFR6I}IW_>6Kf3l+AT|J&KSs^50kHhBG2Zqz0G3}GXBYC22Eg*m)VAFk0L!lk z_CP=w0IQ1DR-s-dG60tEO*d!&>~7@yOin%tfwU?diutzzZqNYOvxGDN_FF(o$dijo zhyd6x!8nQuJ}Y??o{eS_Lt%|qrwR9rMt-3tG8M3#gIfW!DI|%k#Z%ak|H5^6ojePShzcT7J7ce@l^KegAk?qcZ)>iH`4 zi2MZvj&xIlyasLf@)5=qzTAQIh&+dDeDWrwK(r|@;GiHd-hcODz|^1<&Quaovo#L} zjAuGsAgKASPx;3ATMv-$#WlmaB$f$Xf_H`;2%*{1`@um-bGjg~^kK-i4~8?Pk1{i| z$Z%dH@^N7es66KulKrRZdEUCldjS$^4~rj;tSLe5p)qeWw3nLlyt7j;fzK;72j?Q! z`4RbAGDiaron0E`QoeN2^Kt@+MdqL+j$D8ud&0?LMD9gyAZ^G^$`qvMWC5I3EnA_v zQJw}(i|~7bqhveM`=uS}V`LWKvGNM8HEZp$M5@4xl+ri=6;6`?wE24~J%_ z#@NrE&s28l?lMR*nZGh?@7Qg_$s}@@Ap; z&?;)XB}v}DF`0l~FkwP1;%(tfN#rY8Z0>G5YR}Z(0VTCX%R6zHfaI=TcA#9Aw3ngK z#`W%OQn4E`!8fLY`8XB6=6~~=fPv(Ov6_D_^XW^Mkn!6A*6t6(oBnE*e}e>ru*qd7 z=@K>mMbN(2F=IfLlRPs62AS(lRguq=<5S{*QQhWkn)M#DZiEDzPt^EqYJ2y>ADQk* zW(8Ddr^kv_pkbv9$9}t*qGPqpyHK2Nk4$C?FUIF+Df2O^Cp9H9pUJ!!pTn!n+qgN> zZIN{qYMWQfcLMsy*)pEXyk+1p83Wm=!y?yJgxER{O1QI9hs4I4gDQb~RDJIxLMF*=$9wo6^+U|ni!bPds znl-+XWoj2AwdH2f(-;Rac^Smu9ZP6GsmV%wT!lC+OC7Q@4KcRSZOj@T1#6|?6dBr6 z>!8-x*O||Ukh=^*wRMd))7i+%ICdX=eJqsht4e-cQDTBxdS$O_PFH?AoZ80?1V0~z z(Id`;w*9=BbsI%^?b#S5=XXHT%lcf({|w&wOA}pJm49Rq`&IKSeiaVRzN3qXKpMXU z^0vov%$N(2QG}wOsAAK_IpQCy7*iUJmUP=ssc`M8EvD_Z(lSuzYcm*RXV~QOTab5` zRnJ!o-D|-B1otUerN{d2Pm^!PogmJaAoAO3Hf`8*^7_^0!5T`c(v0uwLrSz-POZ8m?UIVq=|j_La+_?Mm$<}YnwJ`V-AE$wARCpb51Te>&zr07bsJf&Qv zC@O2#eIe7VR%Kdw%4*X#YYJzLdP44i1es9q4d%cMY0<(t-Y8v(1~u-jka?V1lzkc2 zwvFpq2BIui6xzm3wbi&1ABSX*3cjEBVAhbqA{|TG)lQ|+O;9>Yr@E%)0myBu)`m1A zq^cf0OjS}Ux~5jE2)9AFO@L;e3WjXBO@MfIXS;342tL}3)E!<$xIaih;^F?NIlR@X)dLKVoZZhbcJMClK zDx=Ll2SH3~emh;6{TU2N&7VFW{Xt?apn0}lp8?Lre{R?A)g#JH9t896ER3`4I=w&Q zh;rO6{g1Z$5J13v2ywd)A#RT-$L)56xZQRT54RnRIHDZ4TM+yaN0j{$N0j{$TNC^d zM~nM{wmV^$_Yf|S$~T175yn@Z@Eo>Bi~SKti~SKti~SKti+wJ{hu`Jv&w4$vR@@;G z{W2dR?0~|0;_#RGyho^F2bAG+r3U$NyDE{@GsyT>+H!K^3^Klzw#p|v&miMlX&(UD zVLZMxeGF+m96~1I9fwP{a?qIX2#a8?0bfsJ;f&12?SikT5ea1E*V7`nop8|jbug47 z;Xz|kl_mUo8oq3cbv(X-17A<$E58OzJE^T;kD9zKxcK2gV}-fafUl<|!PQYYXw0vx zL`EDmj*L8LEbLZr(D=7%AUF5mpm8LLB1w4AxD`lA*x+!`_;ScE%fsj-D+i4wJZO9$ zZoGRWJZRhno}bFdgT^xQps|Dpjo*RN-w4+laL|~@D-s?wu0x%^CgDNj8EC`*kno@} zkq?reIcS^=4;oWKAj$Bc@lsS+R+67RXzcF+JH95z*TQ#H4jS{@K@oJRm5<4x@!+8G zR8R)8f%Kz_)S8XhgT}J}my%p-82*@C@-qjGli@*Qe!a8oCArox{4u#C*BWrpSZmko z)U^h}qX2WQVF+ay?IpR^fP==1@PoC6Y~`SF5_lv$Xv`zIwsGU2@oQT2@Srj4GHL2q zEbo_q2e|5BPpU=B`pvi|J#gHl2acQUfn(30?!9+lN}i0=+>D0=UbgJfSy>*l)E!U!=wD0e^LAhHq%jw>IOlaU{klkkIbENoexhRDhX<#Yo@<%4n&9yrDa zx-M zbb9ji^JiO>LQkk%4Z+xD;N!YVDKF{7H?AaTi zXKxbr?2XT}H;Lw+PKb-!=w#eRC+maGYmq41%V>CA@dbd5gi%H!9=? zb8VDSK^tY9%+&i}>X0gNZIn?7Y?M(!8)a0`Mi~{fQAP!Alu*v{6O{ZIqFqsdDDkVq~BvZ05(bj5f+h(A0ZJ zO+~Kod<~+EnkGD7gD4|29Fu3-K>+oxrzaPGj`D1jaTa}Mql~K9Mi~hfsMXYGmtBuv zY=VHu<#ARB)|n`OMVuLd$uo^(mx}!C(q8~8s1h4xBt@5vGBV5L`;fqwe~o2Fgd43A zWjq15tJGqwgD4|ujBs>_C?gRO9<4!?kp*(tuOrGx`@P(?xCS}4vaH@&h%&MWr5u}8 zgD{$fC?m}%=h%$8g-2@;Wu&N{9KAC-$1)6TviCc-Efk+d0wDA+jkZHX`n zrmP8R)hL+qCc-F~We%fYmU)~;!A4<$^Jt0)qhJ(=?=xZ;i4YkxP#ZLtuidgHkJl*J zR^SDijYDgoDcdL*M+rHSqNtT9*v%Lpurd$@<1@|(kJcaxM#K{ytw9uQ36MZ|v<6Wy zc5O-dLl#I!hU{74(Hca-h?Im!YY+t^QWk?j1fpOR&@DV#gD4o0(ZZuOh=LIrkOy0U z^wixBo+07U8brag3l$!%K@^PAX3NoKAY&AnFZ1ewghy+HM{5uTy9;E?ghy)-1>>*{ zuUuq#!lO09qcwMc4?B)*$@F=X{`j zKf+%uMOJvU2H`InUJxFwLHLVE(Ri#7|IIeAv}N-U-4ap37F_fJrczU5FI(L}p+zQbEh`wmm zo@~Y)bs;Tdyb?u*0KSRme&OPB6%y$ZKLpySUFpVm2C}` zrB8sev+*i_OK|ou!PympmqBnAz9xxL2^?_NFu_?BbC-bNOlxkpB|6g*#W-X>QzkRj zcwI0fU4ThjBr?;|ZIMyhLedu?d80(WWs^5bH93!KL*^ZHEA=@!BhipZ>{cWWrSW_nWD?0XtmU&Ug zyiodwnHS35A@f2x$XanoO~ZKL_8AlPK+eC!`uD10mHo(eEjmfS(U-vjyr# zXGw3gS#M1GA^OWqm)(F{#6nq5Wd|<5Q`;mFjevl@$ri_?kAP}zpC7gKzkMBEo5XucncZXha3&X zbqEg?*hFb_(zfP?;)w`P=sSTx<8k0!{df51eGfy9D88(idB2Y`O?4M4_|>{f>Z@Zk zwT7R3&AgnX)O{*>FHa&^;#$k^a=KXHZJ=C!KljHxG^}!eJZL5G%dnYUdIw)u$=fxK zc~~&a?An{Qm-t!6uc@qt(iAxJzATd=ll|fK->dLlKf1zq{Ujx5{T0e`@k^Ebi#sd% z7Y}NF^$wJ3+eelBZCWbo-Dca0eq%Xvnx6BSgvXLvewunY!#h87+Em{84UOx}=hd~1 zaP8LcEKTiBD94!(7DKZu@IOZ9tK1dT_nhM&mcqFz6SIAvYb8x0oz-GD{Ch+Wi+j#$)-*hRe- zyQl{OF6u?>qF%%<>P76LUc@fyMeL$p#4hATM=ah&M=ah&N4!(8HHcpi1Hj02yJ)x^ zw*g7f6l}(F+!qLQU#xdX{UBk^HhnwWjB>W=+u3H6vrXU5Hlv(v`gXP%Z?b{^Hc@xJXJwEPgT&)Qx&xH zR0ZukRY5yXRnX2;6}0nI1?@alK|4=X(9Tm8wDVL2?L1XMJ5N>6&Qle%^Hc@xJe8nH zJM-RP$?a}fEu)>M5;S@5s5Bas?uHGP#5GOd0}&h@*9?quKD%r^<#V1IERVB7jJ^aSSb06%bnJg59l2g@MkVF;AtEq|8CDidR68BWt~J5kPJ{z@+YXlc4TlN#SnPg{mJ| zE~E34A6mqdCqeayMFKeqvxD6g;hYiw$Rb&}A7qbOq#z%`(8nxN5>8|vw@8D083LZL zW|vLwPm^K6({fqGf?rxPYr!)Xu@*dQ5o^J(ERvL!h?4!(uH-Po@3SB7uA#EdR1dQeMGB>1~T-WifKz zu}DGg0`jg!O2R4rdlFDhgKUTB_obdS(Jk$8$Olr-N|HXlC4!h7BWSt1V z_3Zr=+Kl%Uye8f!V063RYxma!ZCN+w$x#`MmAsoz09&3_3iRdma?x2Dr}O}`=zjXlX=l9H$`3Sh&6o=qif#Lv5~J4iH&@XNNnV5 zL}IOJa@ZZev5w4-fY=?su}($oj^9|9B4yq28yoo=k=V%Bh{Q&|MkLl#_hU%2JAPxm z8S0s#JAPyRD$VZrjg3*n?)Z(3e2qwKu$M8_yH)`5#@cn?mVoMu7^W2{eebksTGvYph8 z+P)pXKX9^ zR0rY2dh^tHnrq^00!eP!cwFtjdYJO@E>fE0rK9n7E*)_HdN}VvmEvE9awH#AK?$^v z2M;Gjz$o9tZETGu-iEF`$*m9fs)TokCEQz9>9wb$A?{*{7R4(j?&?uQ#Y7%J9ziP2JS@JXiGRuw{Z;V z;OUKf({6mt=XkTZjh$718O9b{jY)1)S*e^Is8Cx+E7bv1u)2i`NWV6u=U$aIrRRoR zOW)R{4%!(#;?C1SN_tb>aUxq9- zc_XCz>XDSLCSuz}Y6cTYow3w$`lpv0AySj|Gh{v|A{CgMAONdzoc;i&HZ&15BTiIq zs>1_7Cn`LV!@q&E@yHpm`@ng=hT{p>PE-nZq5=X=R9rhzDQZYva@lW!klXil=bi}| zP_NQY>;(bi>4g-P>(>3^gMjSD{c3WR1BTLTQV#>}4j4%<%4~=}jr>{Wr1`v)xq?_dq{1m-q^mNP{QjP4$qh|xmYgY890IT#9$hG?+D-uuL2@Xduw$taej<1J_ z&PqMYJOh@-AptpkvPjMk1f)ID9UedTwt`VtZ@Dc^E~+ z@Kq_UN{2%2D3`Jp{cl#~w-*-{nZ_}#c>aYi&a~=j^*r&Q0zsxi`eL`EBmI5L)Er{}H3TR2& zq%F2dX%n7pN>e}_1yaN(n&N|DgaV3=V#~}pibG-4aa8JKd|T8Rb;PRUsPh~D-|t%c z+(+7?%;@j`<3n%G+0V7tT6^ua)?Ry`0LKDQf}hMyAf|0vGgsCGb=_%mImVVZqGB*j zHY+MVjprGnX;pA@+G8L11(B&jiOfGSX$%mnsocdENs+zbj zvIHe}BDgQI1Ppg{cOpzy1;%{>CMdZFA)r2hdk{8b41v1`fzMOI_&f2(eNv^7&jDi{ zeZ6!bV63CBmktDUsQTmbeJn%O!RSQ;LCN(7<=>VGoU4_FPT*XvWZJ;FTCd@=bG6Rq zvval10xsRf=H++m!f(0(c@p0fOsmY{Ip#6GCzviT_;Nrvi62~Xe$y5_`g)51A5$yw zL%-=m_$%=}!Ccn}{ieaZLL;-DV@U7>Xq6WY?+MyMA#)wDh=-m)`Wzj zwTfJ%;XT3S($vf6LhcGXecYf2I0Hwmk_sF2@)o;oU!wMJQ!%mVF&Tq;Z_~nT<^?Pv)`(Nih*QppQ_hG}&WKaa zh*QppQ_hG}&WKaah*QppQ_hG}&WKaah*QppQ_hG}&WKaah*QppQ_hG}&WKaah*NHQ z!6}#jNgalDm%k6tSGWiz#fL^H5d~qrMktXm$qE;t#Fuoe84*f<%c?FyNvc+O6D2}P z>Q=Z2C9Uitl(h1USb!j;W<(wrNlo~v`cFm|5PzoUNrux!rcNO9`lO%P47V+jen|Gl)M*1(DSF3M+jeO5H@yh)B@uJ`JO}OLF@;%>#JN_)+^G$SC z-HdVS_k0uX__KV^H{p&y%lCW}uL`-ftKaiYygI{xKK-6=VqNMEG@#$}Oix@MdR;5n^`>moS2nv;PL19JCPq}awYX3Lgm(|I1j@&@c485Z}`OH&+%vQBn5fy zK?>$#@dr?GJQLz1^7tR)XZCl|N9OHmKG#x@uUeD52F02yAzcZ%CB(5>o>WWfNwww7 zVtIQF^V!~nn0yyD0}cKX<}xi-OAWqiX_~FpZ=p{fuId^=Gli#8)9O)Ag^o1{I|DX6d~eZpO9* z6I*d3>kq*wL!Sh|XMk4>b1GP{(|yxJlm z5gJQ9d8dmqyVSdec@m+q)DvP)#&8Gx$5>8u9oW$akSFzvMf>JOq=C$C)95FBMh%*;EQMaOkdJq%p zK|JM^Yo^4!a96IG67%8==O5+dEx&Tjl$aXEnHsy$uPM25&6HfNW_EX=i4Tsy24&6+ zO_Fb)X=9DjE7w|{WfMGx<*r#X?wU2?aPfDUc_(m>Yt}~bT$PyvWXG$*sn7vDUPTtq zCYcfQcokW^w)ROphcQEY#h&UqHh1fqp#c=A0n~B<8Z)$l0=0q+Lrem_dd<)x3iRqV zLyM?FEh0m^C)BIg4DFs!uU<2>dqTZ>&Cu=%_3AZ4yC-a!xfFesU$=$>4Lk`W22WyI zUC9hTmSoyr;!!RDBqp!;GTT#w z=K}rky2O4Ih+r;(3 zf8ovl9;9E){}g^b|3moo{e=(}#@~pzE-AT~9+Z7uQK)tHsO+_vV+ZEL>V zw&u%iYrfpJ=F4qszTCFv%WZ4E+_vV+ZEOAqu%J}>a@(3Ox2^ed+nO)8t@(1>nlHDl z`3Hc%YCi$*Q;jdTt@(1>n*T|p)cT)9Zk;c;t@(1>nlHDl`EuKuFSo7va@(3Ox2^g8 z82SYNz1Wdz@#VHPUv69T<+e3nZd>!^wl!aFTl3|%HU9zBn&!)GYyN!nJHwaT)_l2b z&7Th#X8Us6n!f-g+kLrh&6nHOe7SASm)q8Sxoypt+tz%!ZOwlp@NlNDx2?75Ig|T= z+e&AL3NKDnJCtk?RysSBq)%2lJCrqW+Zqc$j7Q#^0^Uq}kG;65!RXHW|1YXqos+=k>YJF8slb2SpzA8(t zugX&EtFqMks+`&MakQq^SLLh>`%&wwvRztJ>#K6Eyr}h6S!#V%&To1Ob=3N*T$KD6 z#;Mj<<)ZOigVp+~JVSES`l>uba&Cn(QgR0yC6VQ<)$hAhHH2Ae7}Of88e3}dtmao$ zQ%e(G)cmR{HNUEwTL{0JUsdDfr8d^W02WK)ST5uG73O4h_6{_{uP`TTQUn?+BNCE1 zdC|ks$$W|<$nq=9$=Z~t|MC^)WSx}K!_mq56noXf(aDCIx1pJNu^B8KNW+#r*%tg5 z>g&lyBhNe>ovLeO`0h+S9G#wW6lwelbJ|_RCf7Bj-9>D2I66I}xeGAiJB^U3>6y*H zghr}|qtmmRJCcyLdTgh?g^Z_%qtospHaQ%fo+k*=!_n#aE$5()9*$1Ci`e9FblP3S zCWoWb3tM)eQ#~A=UL-GiI68es%L(944@alZZ23CC(ZkW{GiUSVKT`~%W->~8Njx=m2u*V4q})Yp_zH7s zdM(v*Jsh2yQOjQCE6k~xwco~bLyCu^@nI&&J;ZvYRub>gMQkY^j!w<4{Rj%S##1-2 zWONZ*>Wh49uNCUXXUXAcKF`2&@glYq4@alw*Yf(adC^yxQ%xaTlshI;m+B}~Sl=>>NrM`;ntHNKQHT6|wU!7qvj`}LH?y5GA-zv&pRi8nQ z`YN(lH#Xws0r6F2Un}6KuOj=p1O1UDY<536?~j zy#!Co>8ogbdz#Oph}F~wyYTGq!(@s1a#fozSGDdd2(S)k3`hv$qf4a@JxMP zgt8px&oszOgB<72H0C)y^*Dc~NphykasEt`EI9Mz`{9{!c}^ic&Yx+PI(nQxGhXUk z;_*0tW`Y#cFz?oear_g5lJoB@ z6pP~uJbA$NcdPWFwc!HRK%Ll1ZcHa92Ip`CHaR6hu54zcX05v?YY7G*uCCa49ze`& zUBv_uoa1@)FtcS(ln{^r0TCY%ttC(L%AeSH?r$es_}RliWVJ7n- z5dC+~LXf&%oqhkvEKWE9Cg6l@k2UvUKn-nrqt_2v;!+?#;8V>0H@l;otg6k2dq*Q~Aknr~$m zzCXo+y-X(93i~{s*InpcgM=?3C%+Ld4Mb3$C-N40)7AshJXQ9E-a?|LkzbxU!^^Yu zgz<2toaxDwXljJ;SmLEAI~p0!xzw9Lm>c^b{Znio1G*Fq%;VwSiP9s#s*WBfdK08a z-ib5Oo6ppk<=j4xx8pTsyaOPV zbzu8iua1kR3QMNaev1A6Y)#l6CBTr#UIK3X?VFGiZj3ekwv|n%cf|gyTCkmcKltz` zA7k#0Skq6Yik<@PrRgVgu0exo4)=s8;IYa7x&XV6N@o^N@m1^n>jZoJ&` zZddIVsg~~Rzah4#mh6ft4Rq~ziuq`4M;jZf+X1<^GbOWSGA| z`08=^;;njD1Rxyob%hM2DZMeau9_v$(^cr{m6Mr|o?aOdrc(*CfR`mUO;51wrLK+X zlMCdTKIVY+1;N%^6INSu*?rdVt4WBusq_skL+gkGp8xa{Q^K3wYc`9TXDnv4wO2S50f6 zD*1od>;}A@&8J#YyK35Mo%*zy@PSga4;OGfv_fy*J_yPCk%Irm@uwdDumKVCZuQUO zV21El|=Vq%;H(D;Sk9&a!BI;iq4N7;(;-u&!qyeH4K zm)Cbyt*crK1cfK1d8m*mPqk~Sm|A%u4uiA3Ds7l)5N+%#CA|ZTbfG3LXspm)ST55p z<+4=(fv{BT1G8$zR&m|s+EJFRtZcZskp=T(3(5#;3#l?HR0g*)EgB@N*0Vdd#g~Rc z4F{vtX^e`1F$&ckDB}tV(q%JWi*?!Nc%pDLiLphR* zys+3D`M2FWyRp#4w8mAr4jEAbH|OR!*2*^YHy0(Va-K<7S*_hB*aq{ms*RvX<-DpY zS0KU4=~{1^G>22dCe5!>X01R_s8U_THZfh}#sM*s1Jvj?KUKzCE0DYK5)X9(PL-m7 zebp144Q@D9%k0vs;%FL))CgZp29LI5I9gjl99IP%XvT=bB3j3n79u$m`M#hy0tP@D z9hLOT#^cgVTjAX*q6+UN6p@+*I)-H}W0;AuaignBf>~8gebNDBEwqv^2a_bjry>STN1T?C ziPM(gL?;Te%2?HkSAi*_TaB_uPN*D7E3!j=Y=4TRTAc)ird8BH@^S1c`RWTb%NQwQ zYXvLnzft){YKvHe>{0$;7ZHDqE2n>Rk^bYA{u9P>X-kpnOJ%9Vr+Zb(wvhoQjum>8 zzwq`?!=K4Q=E5|eqVs5KJ7>R8j)kV3%q(L`>lfGqB2Xk>SqaA^vg9~Afk~o1SiVB} z%`I?PkIDuK8YM{nv3#PmFH~~tP~kmQ@=Lo!D8# zP7@+tXes6vnXOe>(y)TCWLqR$CQ>?0D(Pf=1ih$I(U{mb={KdEYo`{ucA9eS^fH2i zA!ZckJY3#_JSQuts6n|R@8S;V(!syMldL)ADAC#44p_Nl3zkT}xdObyv53P$H78am z_M%ngTGgOWyK2{?1L&_DRht+(vSdRJMhL)IA_Pq5G?`I=yKIWi zEF_~Lto}+G7!3uM=Iqhb*%WW!>u6}voNh0lS96Q=YM#!k`DX~R7N|U58246GRbe4i z=}r7CqJUcr-Z>)&MOr5a{85f@0N9aoago8{FFtubE-g*MM>)tAD!G;wCaF{6;J8=e zx4back{PE`HHc_MO#}2Syi5=`PC1=p2DH!?v8#5s-26QIVQxe6GV>wDJ^{Wt}FiPO*?_ zQde2PN*nsFk6zITtebMCXe=^ClQPA)5;g#Z$p%<29NP&gM3ORnJi%L)TLg(aL5bEP z06U%FP7nRHx)d3Kq_mZ{rhG7w68ohjs#6V$j5bD+ig0U70)0XnrxO%req^IMkzO!S ziyTo|Dt{<1tAyH8fqf+-+`~dG%yB`F3Rd(j5`1D96MqcK+chI ziiD42bL@x3)#&hNeI(TN;VP5eR=uOQbmxv1OL5l1#U(8!%sNd_m|JBAVT`AvJrV50Y=MN6DSV(EM4*;P&Z*J50mWxOw`lDs4V^m=Y`2Qn8x~No;o^g^OJ+sK) z@HduD9aU_WV7#GQUj+W8g4qBvwO%E(O!8%dGvO`H(+*Cq({DiFSjCInil zD4&4Q6xOCA5t)!#RqU>^IHRkgo(uC57mya$2hKU%#lx;4o>lu5sGYm1e7a`G&U(yW zW$v0tFyu}#GxIt#>C-4hN?ox-UEfKjqCqIc&>7YsOn~t@!G;MP4Ix57lP)CCm`yPOQd5=(z!J`nvj^SVdf-hOhtV(bKUHZT(Dtrg*c7L&=y8?jz>hY<$M?v`MaWg{)Eb7 z1*~Fbkhd!f^Gz4D;!I3NOej?%Zo)PKiCkzVtz1pO3hPZK;{Br2&rJ^uAX*1%l$=sA zT4UfpAxxMRoDN!6XHjj*{L*!#F5*tCZYW(M7#ffO5T$x{Rqjr&E#%6mQ$rwcOGd*{ zv!aMswJWMvCjx-%6sb6H^ts8Wlq}fAV;0cJ+|b^fd#;7Et+kvn+lq`iQ5kbm#9q+? zce27YHInMn3c|Pm75si;H<0;es#Gp6Vy+bBa>PH8v%knU&a+HaQzY_OIb2{EDp8_d zyMpRjZu7JvQBLU#JQkW#B}z)PrIfH$DxC_jP#8ZxS z${Ff3{8U(42?Nd75_6_isohrSOd#WYI>joiQ=~u`#OkUCykz-R`4EoZWF!-zC4 zbw-o}R2i*&SZS5mNfj1CmdGUlPlT+o!YXbSLq(2ecQ%qjX-XJ3ld4sgF-cg|$r5R| zAWKe?82LyD5qcFOwdLYD(tqp5iWHSGV!3gfi{oyH^xj70U?)imC>_TUKys*=%?X_2eQ`Pf;Eg{{l_)X(c=iE+qdi$i)FOt z37DuRz#tl-d@j`q+Kb)QNAsg0B4T3%kZYicjO3I)=`iBHF>)v3`DiKQ7>h2Y2~oeU z)fQ#;)>9cvZ8E>8Cd#IR*jp22CbS?7pos`2^;2AUV8FWKC5&FFFR=lca+ZH zcxDWf;cJvA*7kLd^(IL|7pH{0|%%4 zg-pAPKdbojIp&^=y7BvwYro8L{VexwJmEt7Si--xosUSb^#adY1k2eZ9=wBbKQNDY z?bhaUw$igri174~9^5@@t0%VGWVOu(@3T3SZCGU|BG(VDaHUu@=(34mIm&qUjH_(^ zLYrJ=8xEYhpl7n4oyJ;b*KsN0b>eoqb@q(FiyQP|{&uL>+I-x%8>MaYNsk#d=95Sd zhf(4RYwK3q8uS)+qT_Y8A@DjoS@mX&DsMyN?0ZZ5`mu1V49wf9d}IY)pETFMoe)t?6e=HHY!k z$EWOJb7MFXkAqz1!65>Ir)pdGg7uaWPc~SWvl-7e5}V1T;GWDgfSVIvmzr6*JzmZBo|s99ISdg%8*nz|{D_3=Xh(BVNu!A+Li!$LvM? z13E~F;j$8h%sY1YL1U8t(HuF+dxHb4j7^ z4Ut4So9A>i@ALq4-u!TAWB~OK*h-Yl2MF6kvtX^@O5uGQ+-DafXIw{@UEF~`_-ipg zIWOAp#ba-dQ@LKMnYV(&$IGKjB8I+Vn^6KY<@Y)d{>b8^o06g z4I4CZ&^GL{I=;J|=Q9FUP z%vbjSd_IK({5?ug-i>~z2~^>ulrNE|c%H)#j^1m~+DL<~|HB z5j++gCVOn_bfeC*)lum{emia5I-BgUi<#7mU=I8_&YuzX42cDV#RHPyGn7sclODbR z5MFP+3vIXp9n1wUdA4z+dMNY|e zwxY7xIxJx2O_HLjs=ZYOuGxBAS-I2BM?IO5?-%jiwA!v(ZL=2&bSVG|rp9pM6{!C2 zU`3M$7J!iv2+#^!NeIk~I4gj^!^laS13-6$Np{*Qa}kBJnbv93froh>m}E58!NOR{ zl1bb)M&yA}WZ)Dso_X`$PFrh!8RJA@`8VzrOji*in_CS=sqL~k^ZE`x0Zwx*vz08Id_s?47-^;zvms|&fstln z1a$*b?Sa1i1aM6*&o(htN=8|rD5mCYGmg`#QxN%^2$2f{b312WM*)|=Q(Ou{yMWMU z^9B@1cLJw%MVyWooC>I%$RKoO2(be(kGJ|x3-l*~Yo)Jmv#(mTgfWbk5bb+Iok(mz z8sH~bN=qaY!R#6p4x(?$0rX#GUPA=6D}vZ-#f@Zy8%_waQ=nZwfG|d_A7c^XJYCvh zr*+0d8vs)jB4~4IV77blgq?B@Gv;IZ0%Mzz&|vz7yl4X%NmDZdnUy6dA4CaNEiCwe zDh3ubU_Wn@&;x?aIhjA+pac2WF)|rhEo}xm%Gs_!5DHodhQsJA8u;(_^h)aOJ}1$m z7@BAoPDW-h>;q18?6Zm0A_`5gR+9kIl~DyO5+b(((+@e{fVrE!kkad3@QxE{%WU;( zJB$1q+@poT`&ZhD$WI66eM5&Ra5*s`$MMUV?VGQH6bY~$FedFob6`3addcrV7k5(V zljwo@DWtZkRhkAOrcYpW_2z(I9P!Wgh~(=)2Izc7alNqlz@ zU}Ie%YAt?&#fy8TrLmm(W~|fB zT49@@KVOJaD{{gGqma}lU&?&P(KRIFcVld&$|*zU{|xEi$mn%|vA(P01m(w#gw&e1 zgX5DT7V2fWBh&;a%}KpRAQtr>8ty#8-HDb_`^6zvufxj0!OMbDHeMoZsu0n<0f0JF z$6k#pH+e*DV3v9VVLQtu%q5p zbB~tj8b)$rpQQa}Pv-~=1?CODw_FKBFCV?tH@MWxE14izSDu+0-&@M5LAuk2F^UoOQ`TLQCwcyYYmHu2&=!2$HV7}!$ke@YKS^IVYg5|kL z+*4g;JAwH}kiq(M2$R`}M}wsh(yNq&G(Sh5|`sSAWfSWK-Db3sNRK+4w`=) z8VR87dgfWQmM|Y58j$CX)>e6IKO`&s{s4-YEPz~tJ38&OF2(yNhTJ0D0VNii09Il1 z=upSYT!^bNRkN1~T68U5Eh8vdh)0zTo(82-=ADXPu6-7oE7;>W((~rs0G{hQ)_Z9S z8Q&vmp>qICrh5AifgzF3l~2@(;!uu6LxDc=X*ZO|U-nQG{z#`7JB}lmALbiqJWZzk z$`Dp4(s3T%LNE%S*Kq1TycZ_-YMJ4wHVohZlvNqjY7FLIWL|y+0`nN&z8-^_#EP71 zNz>&|#faqS|k840eEg--~`x{KF_tK~H^x#z)c8m@CR06>-{nTunWb@9IUT zm}F1D46DbgQ1c9CD_NFWHmnnod}#KgLtcZlTV)blRSt1#*jg?!=;9!_;qO$3hv{t_ zJCQ8L)!ze0N#}`xNeI5IGwV7b5&-NZm=DUmJz|E=M@_I=QFf43P~ZlMW~v z@*WjtxVB8=sICL%#^WgTARt{M_>PdUjL6`!v)ax>JCj%2s!ls^6&n=O3m+Z{7w z^_0Hub&_YbZNoc^#9GQD${(`6mZGnTYuZ9|;F~Ku>;yBF$fBmYRzQ#(ln{Fd4mu~z zQ^9|o-rh;T_Jla$VjP$OXoBQ7%p`dB8hdSfQQN=1V7MW-$`cs`J17DDm(s1#EFT3i z&g&ElXgLiHBJsVl%0J9izMx{FgS`1ttQT2oNIbf?U`T*9z6=^q!rDUGeta(}TWyX) zc>o?LhXN#W`J7~)jX8Rs_ot`#nPM1&+`Br#)~T*`(a${d3b@jMaoRNGO43>VDDbez zP+wOxp<19d74g^2kt9q@(SGYLj2aki#d3j0VUUrcz$lHhz)aEPMDVO+GmpjS3emqX zz~y~D_-Xr8V? z8^X(jxdu_1Gw)QfrPF!~r}rq)@*@#kR|tWSrjDo?GD{Al6SVfCj|n)4#!MBx1nV%X zcS`Xl>6-o>n!rtFXZt9C%FqK3k7Q?_wdmnvF6BdVkcgzK1JI?gBQ+j381==TN+A+7yWu)#&2)yloiomV`LT_Gx$tcKcGJ{=% zg7v91BH?~BQ`>pZfVPOlJAKVQ?wG7Rj zL~}2?##;KX_&5)_k8U9lrvn$caJ}6MFc#RlciLn-wmgvi(_2Q?6?Zx|a}PsE1?cYs zFFUAVyr8uSogJ{9Z2C1=MrcK8n*ep4I0j^I<%hRG1<7lR%97arAnnoM+oJ|k!K2Yq z4Mrus2Q3~(3HaGWzbMdk7CRuw3lF*l?`jsZb^!LEV(=%sMJ-P`-wv5D8QkpbiVq3Q z>ciyNkEtV*f+Ow_{SMHFl_-zthN6@vnY?xF=l~G^%kC3gWGP?A_)4)ZujOnA+A+4Q z`A_f>u(=B)8A~^r>>T60r{LA=**{&_Crx(QM$pO5mT!`l%R~iXdWpFjcD-CCgsb=E zGa;7lKfr_-9F~6ImHeZ*#BbK|P7wDA88p1K4`FglNj!iZo_ZJOeM{ePVFJ zVGOUEEctsxmus1=cj#yO`5!?l%7XivO+@?0Drx>(Y$uW!s z(nCUYj6al2p1BQlfE#w0S>ao(cb#osgKE0AU5lr8gH^c}!D7qV3-D0)jJ<&M2az<$ z-RGov7dU8!m|5WH%K%*-yN*p}rjK>PnkxqABv(Rz#gUN>$Od~Tj`G8N7t$s8WS&>w zJ2=f$4HqguFm!^sNBJX)rui}uREp;HVEO!=~W)TkY$1N@P{_+!JolGh5Lu3f`BW_o%w+-2jL^D?PT-d z-lMkiZaaD2QGaQTYAahVw39n*3yiR;1Ddj&t;4|1hR^A4i|lse9lLzY65G5>%bKsj z!%`&`j@rcX0vzuc3I!>$qbpC;Fcil>@@QS*vkoKVilO8p z+O;~qoqSw9ec?oPA{^7#4t*nD4(g^hl*|j^j$CFtv6E}wKQz#BNERW_d=vBiEHrMy zef;gz^1U{3ThXAt!vP`6n)w}+wus`l>zBz|$oYK(3UGJK4K`Ioqio5jEjkAZ^{UPp0DXrDqUj7*9r&4)_1oW8I} zstIojq`#*#@Zt^>o8y^Fq0nRI&Jh&>Pqei1w&7MzY?Vr~9o364Z$QGy4hg$S(qL`p#Ta<6To|^g>%hN%#LiYuNw!1JM8B694~9Z7lYMB1t!NLPBmyEKD)0+2@($5_5a5Ntf+mXl22)M%Rs}*3uyEx? z*$^+!y`n<2EVpUh?txb0%#{q4rwTJb^+(K=`T-l#wfz7C0&RM^owJI+Rot!`R85Z2B?;ZSjqIGj|Se7um)g ze=fSgH=NXa5L(-lMFr|PRiG#t#U>xHXF_e|>mgN}2)Zgv*x{bE$|8;`JqKyB#YL%~ zH1x)M*!g8w=5lH-bytX@QQAqnbuF*(*&q_vuY5E%gd> z?ddRhkQgKY+_1o3heC$dK(D3?Yzu79b6K6nLKVX_gKO!bqnc>W(%#@YMK_=|JhejW zdNa|{`f4#>=^iPeHSq%~%Ze#(TJ}{~Pd|>Z2656n=TrCb%ty*}*)FO-)_f5AeaC?Y zb0_}=;!VsS#q6PL1qx7pMXvsE$w#~HL@rZ zoo37paN&i;)%$H@^(<-V-{7&aaO8xrip*?STulg=p&ANIA)u_#$rn@^<#L@iU&ClB z&4>0vy^uzJJwz-qeH0qo6HIqH?60&_VP+z1vUw9$a}kx);yO>(;zZw;F;ktpSH&D$ zi~FM|scil+CT(H@Ts5rPoCE?FdwxiRq(q|>Ais`|Cm^;?f;f&!?V{HDfg#bbPdEho z+|+vk)%>;iF%mduI*Q8P`^RY4iuZ4psLAgiOO$Vd69~sKaIyLK7=?xf%d5_kc#iXe zD>YbgbZQbMy$qc`kK=*$9I?drm6QCbqA7=}BQh>9Yaa4FL>y2&LKy=* z09{wRNPcq}O$TX0IyPh7sft%}({vu%`;g>9WS*ktDOTo_dzL}Kg2)`|qO0%flHQ6- zu>Cv$mQ>*y@ z4#q@td@mV~`#vA_;CyJr{!tWH+1Mwl z;uu;_^FGwnP49ha@-~EAgJte7K zQX@ljSo0m=2{<(G-lM|(xL<7Gz#d)Vq(GJI)S2)5!#JsdlsfaCh#b)Gz9(?hns-EL z;_<^a;uxKheFo-)@8Pfj4dEnQmy~rGSl7W@WYdLV{Yh@@fjD3kZ0i?MaV0&8W)z*2 zw;Rex;dm4+6;;1t)60l_@$DW0A0ev1Gj(0zA*ewJ8fCb(2B(50p~7N7wdT#I2VPMS zb{5b$NIJBbs;**+b0EpK+<#&`=9oHG zu|aPuefZg1z*kkIP~DHKvB{> z8Yd1VbcJ>cg4fA0-0!9u4riM*I%31Wv9rt#WD}E6_evIOe@%dRnJf>^V53l|UF`x! zWX1~Qo#?mPeC8IicC+;VR9u#%6UabwPv4@Ndn&B8N%%$X?~-BraF~h*2l^6r%K?mt z0+4}Qvq@Ex;MF!=vh_KN#`KiOH+BmOj#;lZgzFFfAO!xRI`*hQCW}Kg1*w8Mo_Qmj zV#tuz&99+xYvOQ8TB}PN=qgDRl|~Gm=ZBzyrA&`t66os;51~S}c?E}@H6O!aj70F? zj4F}j&)&jK=bZT{(qS}I!Sx55uVEiv4#;+_NNog&q!4IHt*{2+$;wPp_ zR`Un~HdQ#&CLz{v1k7E9ZD3k?toJhmH@!TtjXfW;HFF|doJw zWzN#3zeL>{^J#=)RGA%zogjI}ut|jP2|#EcT|FUbIrDXFx<|XPUH0NGyQGVu0NmaP z%`wAhPVQ}#Ho!4B$%|IN$79LK9$4)({r-t+xNXrpAumWU2(6rZSk1rOS;BQC=FdSdxSVFcd^Z3uVD@V;Sme@h-bSq#D#4 zhLH}q*J?Q~=q(3h9K^9WVFp54Xcw%-Kyt8_Z0zkIl9T4A$~Nce*$8?_R@()r*3!ux zv05_%TBGJF%*Q4M;gGbD^&mNzt$Z(hGj$gR$Z2dsVKcn+wAK z1v4@1&8^JR%$S{K1n;uhm)z{8J1E-h-k_V^`Pnj_k~2`)NrQZIr+{wm`cs_FdC5&@ zPLn9u(s~Ct7v35i0#OlYWuCmnpF`&L%u(SHe-hT81e`lGXKUa}TnqX10i6D721m5x z`N6%1G2gxs>i`w1%)y&EFPhDFET_$WlH)zHs>447e<}m)t@-uM66e(ny~UDvp?TnD zE@MxfLi(LHpi9own)?F}-%gx^k(bjfEkP6Gp`nn)!9iOBL#ENM?bnt;L}?#ENp41Tp3$ z*t2nuM+M-}z?h377GpaAort}1?Zb>8Cy}vyDM7vf9QHcl_!m|YmB8`^gki9lT+iGR z_F@H8s8ZBce6Hd86HtqY2fd=^0L_|@yGhVLR1q{H`#PWF)HZ)BstvYyaef77dT&1j zra8D5I>U!Jc@Ua|gPnDz68b3)MDK^AeVA-@Jce0&#cJ{4eFKYmuOSe-DuDs1ZV4|R$-eN+|VsNzy5 z+m&GyBJ^%bquf{)!19Rgn_>vz`O>O}E0)WwNt#FjM zLf;1>l23e`Y7#d1Q@(Iae!wkiAKkP@T_nsmp)Zq2Z{gVo36a35bxd|LD8da7Ne$Bt z(g>fDbkWrVbTe?e@h{5OfTv6!%wAOSM(}<@;+Ls0&6ZM+K_288l@9i$_cf_na)+3# z)Vd$k1QNjyM!cN9k_dm+*G}lJh(sXRVDLn+-GKqE5UeW68WAqb%0)q^eGL;AVbbii zRy0t~HJ#8BcUDl8sUgB!=Gs`yzx0z|qMk>=%KltXy&4%9B7fO8Ni^Z0xS#!Hc#oq? zD(#qe=mznpL>5nvV(~|^I}kWvCkH1q0mlI}R)+^;p`P{HGjOIhf$55uVLOB8cVC5& zelt%NN_2<$|0>Ysur!BWf{_s{4X-7!M}!$cWIdnfo9ijlO85biC(#Al3C0~Q(dA-B z$=(5*#rE-3bdWuammjftoN>U~f+rl9z!R6ne868!SFiDQ4u&DXGFXu*Ht^ zWtcVC!*ClGRKj&4yvqF@`C~;jd%Iyc=z>{9+5Xos!+={_e{{NnaFoXk<^UV93$fkk zS~@6H!Re$d4l?46k?LrmYE+h@5QmeX>6^b6cH1v$)TvVD8P&U23p@HI4xV)ywg+ z6EU=%d>>)Xh@F624NQu6FAN}Mt>%`qbK|GW-C#Pcfz7G z+&{Ob;Dvi^ufLdD&{Fd}&OyLZ)U%Tx#8PIUP$CB-eja`^O{Yr@$GGDh08;Hz#E5j- z#Q+FrQHpyV59_H5DzO|J+#_E^VFdwEa^XdG0*~H?6LMrH00VE|2O)jSeLjxOUZQtg zl+a=G*!T=1^HHizr>@{i`(6XdX2kGhD0M+U&SgXix48svJ_qJYB1@yG`}bHpiJ(OA z6krU@M__R_An3XAfNeQq!*%K$JfNETu$}6jer~6_XfZtDY#0ara-L4umYl@~VrVv! zp>X1?A&1_#)7zGZ4Z8`jG&%DHXAlI$BysfyV1XNRptFv0KeVR_TxY87gylkI8qmLR z3(jZ3kSnqKh(<%);PMtxM!c}iCLgo)U$xbp2lS37aR$mBt9JrM9CkX;$bf6)HgLl2 zVu_XP` zW_T3w{hgOs&p?aE(Ssb%gcnrqddSlSg`pttd%JP?Q%)qXK{4BM<{kw=lId}|mq5!| zm|p^&N%LF*Ks|!=*Gvt(<1!ca18ElP8w_lQ+wwqa5(YEc$;0d}bbO-FF{e3Gx6bVLB7 z+B|L;ZgBNd~qgU>uMu6Y$yUd7f%qm!(hEd}1#|oHlr^c+%>ZOCXI* zB=|{jyd9&04E&dyor`nKk+D*oe#DG$e*~EP{O+T~viL43L==fX-c1}buJ=?p6pQ44 zjzf1=qy&f2Wk!GpNEC?*489c@#PtOy;8lJb4Muo96g^u2dgOQo@NICbiQ~1#JiB|? zxx^zUDkfgo2?mnh_;VbUVe@|t!n@q&mqT&zK4T;46d9acq4_Hac?)qyI*5l8>np6; zQCc~4Sb+?(?GpJq40 zA9{e&H!wU#=My;KdXT?A=0uE6pUGAf;;94k_aLA6Qpr-{OqIy2a%ZYu0L8l&R34w= z<}3J8{Yf>*PdfwbWn3C165E~8DV5kI7D)NsQDW--6chPn-%s`OyW+f)gPgj3ci2i? zy>bA8^)2kxxBDJEjT>xu#H{CD$gRcYJqNcTu4>7xw*Y)}#De03&8z-r#<*2>{Y;$L)nC2M2xz*LF3)797z& zZnxRH^=XAF@gHWV1G-~;iL?tdse2w`{5EuP-r$ls=vZ~PVW&NuWUHaZf8S=$=0i98 zHsi#BaLov41XT>z*gb`y{Onay5(qjQvH5Yp^$aA{0vO6+51pK#_TNF^oC9WPX51qr z(NnlmBf2NxQ&?^%Lc$i~5dYT2`e|KUx#1SZ{kXJHjPzU4KK=LLF}cSuVcxaJ<5Gf% zxOZUHEwL3iU~vWTo})(Ieq*O`lNQYOeE`vlvpVAMIxLLpi+7H}vK9jOSKu|slJqdj zTXPS#H{<4qNNa{>U46T4z7C-S4d%H$C)CV9Xe}-dFhom0Lhg>M20mFUv6JXL<=A8)kt52{z4uX<9&HR>JYM{%WPCb z#>pjkW`WT2JUa{Eu7t_zPUSxhQplA+D+6;FAr`zX=E;|R#mY%10>|F6g46k;9^rxr z^k3QF=KnkFFf7p@!S0L<(O!c2g1By+A-WliCajDzbaDbPx+(-y*vN_(7 z0*@_XXG<@eLl@?|;Ddy@5=z3Y%Mp*e4%T!E(ch;sxrUv7gs1_U80&i0@pv*KOlVY@ ze@3cYantd?y)o|*TYZ(Xd$(`}_hx<&Dtkx768MxJi>)u4n9tEFxG_-d{8iP5-Xl`IJJnArI?+9 z5NgFl2<|fE3^<3c=a*o|(%k{Hp6X!kOWt5Ob{+^ppmyIQamJqcoLDO8t~D?pg1D_7 zv8`~t79;PzP`s!S)jo_OkT(>#o_P??7ujL^`&$N9V+U+6yvWvFWEZcsb%SdM)#rftg6nPVgSP(Xwsz3YUu$bSaZ=%GjhxzH!(ZCPrgC(r zo&KC%e3qTQ#xB9_jn`RR6T29e$6eGJmRxKX@3i>~>~u7by8th|(w@88E*uyI>VOw4 zI`#3SftZO#jw?~bUDhRo-dIRC<4+)^#mp%l*1S|S^I;@cb87<4eROXZDA8g*OSRH` zY;T8oHr9?vfMLOlFSs&&*x(>?%dmxeJj~ZotA5SueZ1`sjr|O-)n*GC#`y@Rfa6kO zRy{6pU^uuZSG-cr?04J9b7^|yB6}3aVca{`>T5Mj0>&d)!n_rd6{ji=?e(ysJ!1X} zH}^!L-s9VK?6}pXki^Y9Z$#2NWT+4B#ev#Fev7iyMuefGAO?y6GdCVywujMtAB$Yb z9zTRj{E%Y40PfQ1_6fN)4(zatV?`NupuR{Oa4R!|JF3{fslt6+Sm)C2sueByg0q!b zQi?%L2iL1%)C{LUo>22jxdOD~xe(Two=)a$Dkclx76^|b@?6v&##4IMnT?XnQ~h;w zi-!xw$>|5CVze9K+{Z+DQm!Msu@85|14$r_YI=qn#_fF^$fUU4@C%cV6H$h;Hl5pnt`5D!K`07E;w1krK- z7cN1093lqk+@P3bzJhbMfb=2pBRQ2uRSWpmaL-c>R`0j(JuFOW{uMl$cmz%F-ya?b z?=9KT;N6t42@xJ_6I%-?{(u^!A-W}+n5!W@2hgr3A-~uPDO@9oaA3C0vvfcX$4DpH z9mQ8{_W&qJCgzz>N^$N;x~-|`Zn`?mwfwS8D6H4g)gi0~w>Dv~2koJ%5AP){?B~j^ zuEX8xBnVxI@S9Qt!#!yt9K>>yphvkPTb?YrN3OK4)F;HaVlMs!cS`fdOf+!FpHZXZ z#sM~P2Ar@6_SYIMxOv_GA`UzOauX!OQrasl!L zN#cw7iAWuUcVW#1B8ZqEcsFk5!y<{rahM>2*Re8FCUzD?1l)~#h0=$Sk!B#WOo|O) z7rC*NVCx;KxUb-(D@z#!P;#9p!&!bo6N;RMJLEN2obENy>|qv}RmU zi|G-G9twEJ6oP*M1Vq4>gd>hHA_@}l5#j}W>XI=Ri_;L{;KFhUu?K8PNLe>SEn=)1 z5aX&1lZkj?qu%Pz7GO58Cbp!>opPhyBmtkQKTFt{~WfQ8faKpZ!~n19jfI31Pebm*<-954`}DgdQaYO}4D(+ChE zDV%Ujnb*JyyT=xMuTyWe32SuZ~3758DFpx`gsmEU4 z@cqTc*93P9=j1K2VIU{goF};bfEMGiY~c@1QJD87)r3(b&&}3mR|{E zjl=QGPL#}>72s&}ja6I(8h!c89Zzvf67UoEX!#;YCo`3ULj8n!B^Cd?owncNVzz1o z-K@09yDT>P8Bhm-RQmy&^e5(FKpsFOP<6!y9b=9`4%dvWrzJBA+g)WES%t59-Ltyu$GW)VVD*a@-jw z7@Dc#10W$fnYFN5LC2#ahzO1()h6?AjQ=Nvo`;v7x^upk;IaX@?0LQN3@9EH+ol>u z3UYXL__CPg#Lo9=I9Jzr_gTLGzZPYLVhL z_8$hWa8vW?frCPe(+w|21p?cU$>dWLClqX`$^@INzQw^0PpcpiHY)xyT{SXZf(vWv zWs!8O$_8QZa#gm&n4GWnR^M}g4nZ>y^8+&=7S`yE-C0@deyqfw4|rid6&)I2{Sc~3 zP5VoIkiq%LsC(&MU%ajyT|wWF$wSuY!ycoM`F0r6NC?dDVuwL_iR9!AD;7dpo?_1J z#zq=C#Kz_gsHiI7igg7U0*;O|qO2$}U*MFHb;jUsboA@tZvA#q_nrm0iqv=oiIICj z=0F(Ev$Y(`hch9~BQ) zQ>XMfpGc#?odnZ@{g}$5klr{cKPo!(M2DB00=x$BreH>qfw&bQrn#IH8_|t^ ze$RtyiaYnW2} zm<9E}(JIYr-WS1_b;ZQh;*VHfD%Sgl1U?k3q_#Oh2xXYmL*hlQ1~72(Y>N zi9 z3f1PFrLHTSX-z^RJ{QBTS$U2a0n9~XsEGTZWEFygrV9!aZ}#A^M0P&MCN?{J<3Di+Xpg%RMYIFX4n3u`)(&1ECQ*awsovoF5OotV8@wL!fhA6Le% zLw?S$h(UH)I4tq`mPxMUQBW!|A0{_$b)1B9m>=JFn8T%Zvh14A#k?ax9kRIVlY$+~ z*K|E^>larMUuA(lVy^4r3#?Im{t1N>by5_SW_m~PF=+sRLs0mVBs>%)Y3!pH8P(@4~49r(8(yVr^BDyIeB zXD6au$5FcqpL)cW{D56W)l<>bv$c-IDAO>-Vchmr93MJHX=5zWFx)0e&D8YzVX1-Y7rhE zgUSgpE#IFy3eKjCd~#?Y9Ocd+koK&2t3WN$(H{^709rXq2gR9)M~y5ewyX77BB;3A zaX@xEg#U2tUdjpg(RT#;Q3Yf>s^Q%$#w_e-;PX2}JRsmQfKCXu`%C8CM}*s#it zuEdWWq9HADg&o24F$juyuh`cJQ#g?3g1FNSH7xX z1Pk#yDQJ+K@+7%9_Tk|CTmxpugget3mVz1G%WzDfQp+htQ%+WK9W+0^URW6~wT+P*lnI&C)>?w3B!`YYgw2R_@GT5lykW7*#P6!=507w>J0~m z>mI|7!Fq>>j+e6@jdh=T8UK#JUz9uwq@AE3Vfn{OMT5+Io`|HUBe%|G=tPop+IE6| zH0+6?5%!FOsnGan(tJ9afs&@9`3z^^VJ-I*W+1j&cnmo3^KZ;O7f;?O zp4jr+@b{E0hscQS!@pPHUn~AaJ*-0YLN7J1#hdg}!Cve>yju1W=a-kEHRI=D{*2(q z`!Ieg;EZWsq@PL6L93~)-#Y{=J7|m7DyK3HNF-<3JFmZZy+Q9B8$JL#16hRUQW9jVBq&? zB*N5fcrL@%^g*NuwknCO3L>h4Wb_H1(9$O@{m-DB|26ys>-p2opD*y|FZpu~>IRqc zhghxHhP1>l@KZ4hY4L6NvGN6O`Ed6UW^l{_#~hrA+zS4L9CJk{o)RCyQ-Z`u5E%*L zA#n~eJo!R6X;VRrRQ!lF$W7i>yb?Fv_Hxf%UPTtGD4y> zAV5Jjj#r}8Kg^$__%TGTeBRt6ay`yIj}-GrF^_1rM6=815%AmU!PESCCw_>M0|eq!QcGk@D{?t=BeX;) zDae-U34o?3TXfhmQ^=HKM_0raks_#wlg|_t{Aj#_c@OFmxHqtkmj({CIblx8B$?S| zz{N?EIB61`mL|)PYe~g`AE_5;;uI*s9tYCk=|B>GZAI=WK}nrUP=wfIloF;TJn>cR zOjwlw7?LwiDB_$jB6;KFX5!=^{+<#i31q}t@oy}#PMSQqO9%}4*AgX`AXE@6<<&79 zN|ub1CF6uG;G`FkTd@|e9zm@T*q%n4mYi4d1wH}PqxgGDP>a0f$QSWdnXGHR105)s zWSlss8NRTBAHpi4Pe4~{j)8j2yb^9KjzkuUEo_RjNeNESb#&cG3plXgE^4Q%aOzrAPs#vM16B&>Hy>o;zBeMvIQ zZQmiSU9jq+OV*sbG8o*_Vp~^+|$>ybL&RDcJJJ{WjVl`bLOJfIh*DG zS1oLv!+*Vf{d4+v^z?1tQGD*+h)TVetU3?B-Men;+qh+Ce_#LLt~rB!H*D?OG-sfD z!?vDX$lTaFXUER|fu4;6Tl@Q#_YQ8`hQ!|PfjQd-(CUV3k-=iy26lG$?E>Vx2D&%C zo}*ab+r4#L`B1j^U*8kkv2*M7vF$wrTlzQ2xXxR!@Q)r8N3&~S)AG%IgQ&$``%ekY zOO8k&j0V-e6AfbMz*w(lY~0qpYfF@kF(ac42eEJYiU|B5OW#0mY)j9!ZT;H(rv5?jKy0vY*VfH_ zJ)2rLZt30`+rG80f9Lw^dv@*uYP9Bt{!KTbrELx)h4KZ+UVlB1v9o`0peI6!^tiL< zy1|}Z1F`kz_V;horUr;O$&5x5Lz$g70j%y#>v#1;$lkSW>qZAR=T+Z&<^!hK;4UC< z$5zZkhtM5ccl7L(%=P>e+c4O>en-E9 z8x&4Oi9)Rqv{Z`iA9WCDT(D&Ek~Z*0c-Xq+dka0`2Nh4-LMWDH_#f?QX%e=9mk`;x zZD3U@1+_6hwQ_E1=@N*YYoQU3`AtyBF3~gtVgQ*-r51>w3K24vmNzY5h~!1f+O%&^ zJiZA-WkJi_C6tu;!W?Ks3~UIc^!@^tpg>XjmQoZKEm^wM34y2r;Vi^q33NkS(+LZq zLNHz-^{M$wyhTtZOO`M8klmINl-goPvS|kfeQMsq#Y>h$hA?P2GQ5ekrBlmO4OR6O zm8r7I>bi1_gC$E%rXa9ltEB62>ckC@g2qAWbv6)%WClkkDi)%RP%~(Tw2B=CzJmt> zdBRE^1Tr3%EYMC(*QX(Aq%?vei8%!#mxeLTUAT&Du}aJdEE+$5rI88DUvuYE0yy?e z)6f!h6gk)qrP>98R2yc*_Ql6*g{cKgTASy>0#LbIpkuABzO=RxqfH1EBpQNln7fqp ztrlHm>TLCv&s_#4AlJ1l-5fh^(BBw`qQP7_@?F}}-s;Vd>AslSnTJ_d(aN+dk|Zpcd=0~OO`h;oeQ1TvTzv$oI==&_zB)3 zrxA60j>GVryBHvc(9-s*^^gJn+TGZ6CY;Ic{ zYKAN{i>g2&6?_V~sO;2yWU(k4AtK9>NWFXFT+s;DlC$bW%S&6t6j}teyl}aY(MCf^ zhOL`@I}I1i)GJ`aogib1w6bo9XG@#6vURzcoUI^(TtOhBkZNmLvdm~jS|RPQLZG9Y z=FeTaFveSjMf+M)FlCSTmM=U}VdAKyLIaS3$-26EVQQYYVB!3x1)NUWniLqd%;TJ$ zq8Kf2lFDcvdd(O#R60$Z0ipR}_E63j;@EKJQeE%j_b>!zs`Lk~{2w9hwOg92-#PDRhsluD&IEL%CLw>2$D zu~pjewkDZem13(lR-~*cXVH*JUTgaz(zSfy;<;_kq%tgDLG3+v5sia|YVu)g7yWRhfHs`!Gc+xiJS(zml9i*wm>Te6lFYB zQO!ap2s&6!re78;Tr{_RDLM_=w3IBU4jjg$D^iQ08k@~5!y2H>$;m}63t?2xjAj%bS3- z4UO>T&Vz9;ctoBB%VNN^NW+>=G&;dG0(K|50X?&D?lJ@x>44S6+%ga+sFV|Ftj!Q; zAVmX3dkcevC;?HPOU)QJEi_=zE7E#NT-FX+7E`am#Dr8ph_zuti|q<_x|pKqk7Xxv zfz~{C!Pty$Brh@P(1dR~5x{N7i_%N2lr^BUc^5(vF4hICFjT-XhmtB`67ira62r6; zmq2HTK3q-)7?#AvKo%+@hES?YvFvSvNn%WFVwhM_SssUH!{YL1n=ZA{`c9FfX*tuN zNE5Uv%^?w`PgLSTH3yhb|?VF0!+0p z2R#c$OItZsq*GFLWvTkfwdJJ~Qgt=ewWSj(%2IXZFcNCLc}vh)D<~#dbwPa*babk2 zdTK&>BNQ4I4hvdROIznjMt#N9^4dBH)=e(2td!8y@~PFeGgCFS)%E3N^%d1snqM}# zv^F)hbcPl*m6uK|Pfcv75-`Qn;NUp5oY5&RMr~!q)KnGzRMeXm zl~;m(DO**@pp^$@hmBG8E$qqzyHkdnGO-DL2-0u|KNl$TXZtSHlVDhst6 z6%m_RS>9M)IVM$BS~eL4DrS{CawshxOcYp$+Kclr5@M2o4l64MNpWLG_Ksu4ct^vt2wJiomRkaK+=8rGMf`A;Fe>{{UQ!1;`2jjuJWgkDK*s< zRp1ZVM&+r@7a2Lw$OxnmUB-&gn;covp(kL~hhi;Dmn_3N4pcX_w?L*b(V3BG`Uh(Z zjwh5Bq@z+5DtU^P#WB9p46LaI`zDlE)|UzsF%h<*2^=bhk*W4^ra|cNiYka<3XTA= z08|%n!Nav8t0XoIxS0q~E}zf<22PT62ytzBO{G-Px&&)h(YP=Jmo>Moro{m6Q7@o5 z^kX2PwL@F9vgbT3iQ)NJ-b79d#))+^tI9lhBVpTf<&4Fpm=RF8SdYLrwqPYo@BvE* z%MR6#()p$JP!{7G>dok{npIv~?b=AK3L_popdM4|XHKoGuC5X4*~+QYQq?u(RT_5# zEkjX3an+SiO)G(hy2-Wm4gr)^dFfOaEoECK*H%|mH`HNHk~%pRl-H)FgPVA82-Qh? zSxtkCkEZ4}t}v)B(_*Az2H?_q9YID-0VgCqJu)yXs!A&rVdKH+anC^}-DnjdBLJwZ z!PJF8$Q1%oM5jP8Ro6nMtE(nrzD%`?Hlo$wMlxyvmnK*lm?1oyQPz+#GB7u>ae@~d zOEs2OHt3*ZO{PrEBvnW*I!54KRLKI%D#;rtS#6#pi__;SSc)w%9+=ry`2Afh4(0(UN>o4LwQ5FEWt1@&TVO#yV^rQ<}r#dT$r(%Ybq)* zGof3n%At}c!NsDj2cw{wjMArz0jowV-8h0M(XGPeD6ODaVuu9k9|{L?3(% zIi^CYWhYy;_27n!p~mUewNq@DOe(LRRGX@mS;@f|#&D2eR)sPtoiL$RDi?(^x|5cw zsBTObmMH@>UKOSuJLii?#TqThMyDETjFm>af-VU#9eoaER60}a7{Lm`HTD1K`%w1Pm#ER`}4XtlSj6_y(( zRi}JZ1*BT-gox3pZH0(nSq1|^#a=wL9E+-b(xR&)y$)s%3FS%+Doy4;!srCs07EaO zEE5X}zNJ;RN3HDD*6C;+otg*}D^=T2Z@y0RB)xV4C?4|q8DpE9pRXR#6DVz@d!V&8BIh{Ho2m5f~yL4OGou& z$X7dvih0Uz*03>FKp3tmom4IcVvJE;&8Rx-rKPkP1~t@;xQmoQrL}6z zrh8x>m$7guW5FS7X=&q(@pWS}wZGLmZA~x(z>xM)2bn>cVee8jNN@#)FaxTI%W7xV z)Ei6L5mPf6_M@~+MxLgp+Rcct~)dY6R4jHaS?%n7P*bkdxP`3&rjwZ=^+#-Nw1x|)ir*lgT!t;U*+ z*)>7UF4~aVr)h#R1i*AKgbnK%3|44DnnA<_^;|Q(qk2|W$Bj#_e#%NQbyzM!MW^Rj z_3K%>tc{r_3pp?|(GB%1zN85rh$gAMvU(EQnwB5{ioA3fZFM!J)1i!LsL>~m&|vu1tQvUrDbK+ z+@LU)=J?Xu+6ub_<_aOk6s~unY;?NKw2m|Qp)9VO3_wr_t6nJ*`=z{Ua;jp~xGKA( zf;}d=Mz>5UH>;)guLttP{&d0l0{1vE~U2&HDpZBu0ivc!8f9dLqnrX>M5*_q?FZcQ^oqh`p?)uW;s!+ zWI;rx)=eVy>}j|mR7P~X8cbcNS8G^xBF_v7Xx)(%`MC>52{91m30U-7E@ciSry4Vp zbz##4uQ$ko(gK0vT^5AOK|7Qs$<9-Nn}=OFk~YWsGg)Tov%*{CXqZE@!R zf+a1O3#ETm)?grrVKz$sj+Vb;1i-mbxWuAqC#hurjQR@9=B-%6EW+xzjmub<2nfNKlQrubk=stmwR?!h*og8BQi}l6LWlqebOk}}`Z*6&MLPL6yM_xNCU1w=2VpxutR%p_Spqoy{6X(T;Q z3Ja`H$qjW{wt84VxUMrA=3baG)Q<2fdm_wIcWwEk@);SODr;jJdW3cyrNuxa*KzWH zai&Btls3lZcByeZbdXsVqb1}Z#1|q>Uz$3*kX%}uUXPe1RjL-!q;s$Oy1LSgQyZ|l z>$E(=!iYO7q%!Rp(otVoKB=^9rjQEtg=#q_j9M#$?~f7+SAzhUUX`I^y@qU32BTHe zFgd;guCA)2Q>%@}H&zqspb__{x`+Wjxf*?!F_V_T0hgLyUNLEMecDMd6&`^4>MFQ? z#b<^d>)`ESGo>#`Ls{jNRJ~a_qkVPdGJ!KE?#dIt8BWl2T2Y`H;Q*wQlw-O!loLZm zO{3a2hnm_K%I*++ zP;Q$V8&>n1mNhS3NIxJBme^GkI=j3c&Lr!PPNlqwnCmB`%IYgkEmWo0_Kuy6F~^i> zjgtf{apVX=n^(SSiOPwVF?-1v<4}RvR#w+62!-LBqK@Fs9o2UV&L=Fgu&KsXKbDFM zc%TW}FW5%W#z}k`_I<^Z^*xWFN;vZss*MhPFS8)I?|3pLBC4YnB$|8UbwkJ~Avx4eCs>y zj%(?MTuPWWf1RyP`l4CPoH z8_hV$$3sPPTb8AC)#;^6Hehe2YDy`#SLVjf3%IiF%W(>W8!0VbEBwXcN|}ez6T=|h z%|<;*AxFsM_zB0XoQO@y7P%$6V$#$a?qTbmW}1wNaOBQNO)te{pH8fU%T|etrNJ2q zBQ`awECz@@pLjVvY-mjc=GZk!ul)udEtP zPfD_cl?n@V91 ze>t2vG$UJ^7tS}$#|lPv)G!CbHo!@&rK@8U(fOT{`Mz#)b-gPBcRsi3aS{${E8YT; zBiNTSuuG=wb$ugSGdvH0lasL;q=Z!dy@fdOm*(C?EV^gVxbs?d1E6hX3Wo#c$3Uh| znNR_bmAKS}a?)a$H@+Neb{;C4Cx^G;JxQZxtFX7gEzVeKeR(;KZE=Rg;Y)5iI$RAC zYMjx9>Djs|Q_GuSZlF%x(w3c%*x*UmR|k1_$SUBgiPg$Jw?p6Kk|H&s3}TWlJXL&% z<%TBsI%&lzWDR`67!z#cDpOXR*y+Mm)m8}5&-R31I-7*aC^Sr~X^7W6(bP=IU{9NN zT9rgsZHz5T7p0q6hS8O-g=@6Z`q8lz5s(xNaBK|LmtqGr4NSR)ZiuCDi_|K`6ER>Q zd#PnjnDa@OD6@2FY84LI4y3j(r%{jwQ;JmGnQc#%R%ufjZX#?sl|d_3<#lM8;Z_C2 zA`L4;MI~S5fvTEk7-hJkA8fJOy2ct0t7N0brO(Z>2Es*!3meunKopbHJm6J5JwrIG z4$BPtY&^{8@Rp{f9m^G4TTR7O6^**`X+~bsGsCG)%V5Uh(Jv1(?dDg{^ z5w0s@sLDlb#6HC-(hRl18LA>ZAThct;rdoCVOuALL~sDPYeRWeS!s>R4RtTv18KrY zh>S+E2^MdrV&I7>-J@<@+Js%LbUFCV%Hge50n~{hmMd#@?9jmYQN@ofH7=RbrVv(k|k1?q44FvORR`az^+-Gm|#0}QvXf`+djk#EOpALs_LrovR}w!-8i*_ z)^b`hjWHvW`q)WtEwsSYa;WQc(nO4X-6ORXRE~z2pvy6KtaBy}&LQS#RyAp4i`^zd zS33djGjm#)lZ~A7GJB$MzA1~W22+2iCdz(*9FG`f-BO9pqvW(>y7X2DP&d7nE@S8ybYK z0?9L3a-`lBF?h7$E){IkgXl&Mun@*k6KvF3n~obUdT4bC-n_BW)llUCYhd|RW1Ahv zA#83s4_LUlTHgTUP(?LXQmns;6Y99@WzU^-Btx7vBFDyg(ix5V+dwCFN90&VYI%#T zElmk_!`!fTsdP+PTa$_dlip(P!lqik*9im0*LZ9`kZA1S#b!K*tqV@XT3b;)eOjt? zV(b(_3yxvq01=incrQaIQB%LS2#1B*F%HnLW_ZD}>HBM znXj@k$+TuW)gpe~i4&B@-HD1}#b|lSDZ_MeJrq~>qtm>VjRNrF&G;G&Fg9^yX+&@(mdE4Z^{Ns&S+WW~ZJsYO z`DRhULxr{uye(5N{s@9sSC5C$$n71TDT6Y_`I0svfyd6us%vJ-xgjtqT_IcH$PlXG zrQqs8%9Ux0aX5XUvsUy-9(btRHF`u(Hj-JK1mQ>rOgSS@WwBnETrm-AS>2LCugSZ% zHrmX$O_dKUQa7cd2FHA1IpRQ{ZEa0?`4pjRd})2zWDlncVEwSxT6k9Y#Np#|%s+VP zLT7nNB!6&}h3^#+hEcA_80L|(3hdGvZ-t%)fn;Lkp>~A?>0VkS@G#$J%>0)xR_puN zc&9q^eeA>GKgK5N{3Uaj9*M>7yaVXB^A2clZ8-o3ua@F9i39ZA?ftNy+rDZ)yb5@L z9971fO{;m5V)=pt^xfCC-~o6KtBHuj?Ev$NstJ3O`yWpSmYguc!j^lt z3y@^Shh*Z#@X-j+USST;72zdt1P`CbH^BE>viwLHRY(yUN%7+O^E=Zx>Of0Bs$2j9 zP_%71iXn!#H4y07fCIR!+kbvW+eIG$)-vV*y!wK7-T-x4Rh9$$pXy> z8U)yV8po(dKz3{KG+TA)5Z!;Rh^F6DLF8X|%>hylnh+z7Ty(_GZC;|3bWHZP?bB9=S^n?q-8Eg?z%}koxx@@g8X#=|asiW!g6DE+#UpqDN3S5fIqD_;(l$?1Hp=7bWpx>ylOC>t$zayG_rt zKX8eHV@sxV9eNnd?)}q<>%uXjV_R(`cakmGyPQ`e_v(c6^V3V7LC4h zfM5Wo!Tzjpzr*}l5|1XjbbLlK>^s8$ABAI?ZylHVpiH0sK`UtQKRkPtx567T)DJ5f z1WU4~!BMQyQ7)RsWsyefTzw_rXvxU%D!*ZCIC2#tt1j_1c8QOR{~E%l{ks#IaChR{ z1QNbYYzQR5Vv}c7I7;IouG47bHyu`o4585GF&n14FK>Yp0-&p)_3A7X+SVTd}EBZcGn6+Nwf5PI|C+#M{+Ou|1P zW`Nib+z}xCj^Jw}JYNUjB7qg*Zo2d@R$m<`u4`49gwyjk>wP^WCXyobTG4UP6M{sv z0|5>+bcS95Mo2*cdh>^gt1((o+%=+?liOJiJU97$Z*%hd$<4{|bPP8alV(RTxZHH} z0eOQTivu<}_&{Y8Mlboc(Ns|Fs|typcQtZ+=k&yFi84QY-;@izT*z;3H3YB046YMh zR+u$=Gbs$~A_R^_2cQaDGFMt9Q2DCkDex4-;26CY#!S09f|hd<)6pNsEq)~j4g-#8$kwo1kD}(T(t8Z()AF#t zCG4WefRPZzkq7NI|Df?j?Q1)i1G|%!9M3jEdo;Spao{`9%8y{KKrcPv!&GX0(F=bS zyaidI6_4Aw8W> zK@W>4=3X)}R6DR|^z~?5_NJYUhOTqn*%u<(*UV_z3#yKBt~rw2Vs7n z6Mo{KnPBXa#1(vMMdoj`-#870UJ{+0+yk{#e-D2y@~@`3cCU{My=(Bmh3E}b)nctC zym&e2l`shf7FO2Q6e~cn zcr?*m*dg9mv1GO%R7uNe=&cKPobBqykP6FR`ZwxO^+(F~yj>IE~CHvXF zR7p6=U^olv*EVYphjmVFFo?GW;8>JByf`Gy~Am-2hS0wT) zAEY&aw5vMP#L}^%bI`l2+CMg3qnW-sz|B^;*)h1;mXxDho3g?C>?6R^?f%Q@Mg!GB z4urjQPU0NQ(~)IY=%Iu76}SgmcfwgaDEQw)5Z3WdEQbX+RxM8kBjyHOZsrT`l=wYsFIh zS=xeZw4nE4D1+aKMC&kRqD=|Cp@17Yf^fcr+sCxjLZRGnK@ffAD(S@z@6`t#jtV|C z$$RDoeXkZsr|dPxZZ|}P-Z7~1m@8>~Tp3;yYR_L2{uDxwKeuHe_qMFtbrJ|~&$?TM z&*I@Ty4d03x+i!QmPYt$u+yx5b_Q<|`CH-pFpu!(15?Kb;U^Kq3wM&*@+XA39y+;0 zN}^K=Ix7y780Y*P8MI_=di|c0F=-!)Y7eb2v5FJGBYH(TQhfqwQEy2sXMEPC7rzCL z@r{uB#uLI#@7;59XQ;-kO%LA(sK$AKng^&a?>!k5>Mw>Z*gZvrjzf}R(`Y5uhS?ROY)qR+ z8+clXZ5fsz%6DlYnsiu*D>_<;CTl<`moq`q;`S^p$ve8B&Zc!m-J|~xsk68Zb<~mZ zUvz-$qep4>Kbm;b%-c^Up5wTAE_jK9=%rwX89qCLcbNWo_!&phud-fA&qhQXjdKX^ z<-Gqu;xVpxo(=xM$9)`hjp1`yFUnE}3)tv#2cLvFoE!+xN|2Sbsh-hb(VrdIU?8|K zaUGDmhQxBaW1{ZfBhl)GJq8CS!8a+O#{x9@twEuR-WB$u{3A3Hdh^kw`HNNOJn4VP z)!>KzXEX{w^Z#O2iJ!xdf{|c2$WG}^Y+2+2NZx6E`lA@qu}TD?(&w}wUg2)B~!4Cp|y z=8`>+(%OecU#~7wJ3Cor(x${(La1n)$q2n+pnupow3E*9x0tqX!3SQDaAVdTMgiZE zbym`LM1Y@hDMeF`);eLaWX;j_c}^06V>gGJ!!V~HPs6h}CpIU-f-QbVe2agbpUYCA z=3nQ35o7>-0S8tb;Oy|BC=P(SF)(us4Fh1{&N5-oEC!&VqMy5_HlWAW`9ERD{U-Z! zGoy3>iMFjP23~=)VFH`57}?P}Q%&gg0Gl=^eq*IHy1W#H@q;fTYW8G7mRn?0R4lVQ zGG!&!9nKsn5X+2YnKoc+7!}cY2$GwQ77(wBG7*bfnjl738jvHMc5*5HY%R@Ec&!2Z zuPVrKsvs?Hqk_;gE(Ii*xgz2C10PIdxFc~f^~HtZ2BRoIYLw$(#-pdUC*bs`3-1hW zfFhEXMExB=cN#>GB)*|9jWtBaxvVk3`>Wum&_hU1o@~+!HF|WJVDic>yHM1o8P#1L zb3a5=4g7zVZ$~KKEN;s;He2C8)20(Kd7rqRa}8qaeIPtm5!M6YJtqAgqNd=`wSgh=ts@CrEa9Nx9Qm_T zbpE8~%LGWU=n)4+m*)z6@~SSp&VLjS!PEh!2i#OWjzsMQJXQfwrJp=zf`a$V+MKL` zuNfNTGlRJsDoaRi^pdL#Ud`~hRrqr;zL_I+C6^c!eG$dt=uHFLLk3bZ+vN75pka{P zXqbD2afd1aXwpWL7kVSX@sZyH_rG_FnW#_kH`37B7+!2vHy4Lr<^ZJ6ILb z?F;@3dyUNI6aMt@YX25L4<5f}c>H7@zs0}LH&gn3{x?4OK(Nyi=O^;u`g36CC$=OE z*p|c#fr53YKDxSGDS>81$&;~v5@xre6VLMRqE&R4|ArqlV-k z&SoIp5(!1OIgC9i2jh-{@3Yl|ZFJNGbi&^fX9d}7Mxrj%bXITy=Z_D9Pl5<Ig@J~(P@qE@VvoJXaBq!0aiyF}-m-t&~ z6aXNe-571VcmRq>wh0T0pe8ym z>fsoaPX?`AqeDa%cG2w)*@589${%u&Jn#RSkKg;B+Od*FJTXvP7vOD>g>0B5(di_Ip@$tQ974yhCk-$7Zz~PS^9&NsJ{UtU8eongpldO?-8)8| z!2>A%qVG=9Kq^?B zF1m7+DU6<%|CNNu5F5e_%lQ`m>ml;^QPwqCc1&E8bwPyTaB=h{9}j0=3AZ&1CzA6G z{k_+E%zHBH=dwarA|RB`^B3V{<>CzAWp<>;kaxbH`D!l3Y~P zP@v)xs{nh7+aPv$+=41FYjg%l(?Ic5dI+4RCwZu8g2)EgOiKEiv_feX^;fjZHLNEp z9CZx-Z1wSFVRmowd;{MLQHVyuM0;y)i;3n-6!2d3kVy)?NkBA*c)~Li?_txM+4yBZ z)C)wtLe#S-J3@58(FH^Y95Ra?G+8jA-}XoS8+l4WnuE9hI~-xaM1aYUsTl6ReI5$ecC%ZKTMH5$3WMOIdr%AhfXY7 zondWgIa(W*952>{Ke$2A7fyiT`aflAzD;BAH?a3-+K%_4@diHh@{3kw^f1bI+4CkH zJ>S-`=S|k06EVG^8!c{pZOPKYildFL&Jmzz!~@)od%%Ct*d-6bA%aCfC&>D6gm_Bo z(=&PorfK1b`#3P~Q%pEJBADFr@n^2q2x1a#p(%P9PhW}2BO7?2EeCUut|h+{Sys3Mgv^z*MvRx4>sMsHr#(K!ebAXaN{gK zL`Ot_b;yPS;JA}Tn}MWs`Un`B$E|gnO2}L1Dkugki)pNekNQsy*11_ z3Y5*k7lmOq(Uwmm8V*Dk`pBuHJ(QW3fnhi>2%xS>qQ5y>U~!stbcp>y+T4G&dBBNfX_+#<)y^(Nz?-%=M!i#<0?Smrk_IbRYCOqEnnf^$4 zrvDrLgH2z~3E$|yi}79kPZ=ojQwH8QP$BOdc={g5Iem{yxDk5E9#1g##2!B%D%oAr zYf@um|B^>`e(8VV2b(^e1Cw4z$68cKueYQlK}fH+q$5E{ueYQl;qiWd>jz|i>qk<7 z%#ezl`v!u>deA7uWeiMG6us`a_-+`k#9W4RG_OU;O|Q?1hB9`4x7WI9`ZdLWD%Q}( zKG*iq&`HkSFFB^{CWP=-tT){LJE; zit%`@_ZKkl!ms*l9Dv8O1Aa9SvpSk8tp!8VrFP_DORo?oihG~dM?)8(kcOTeuw|fz zt{wO*4Rv6gB_ji+%(^)JF#}6wpyv@aC1^(Y1#6Lni~8*7tDzlzUoHXc%O$%?M1psf ze9QQ^B^$vGNI0oLoFu@{Xw8T&nle4ybZcsBIQ??ETQ2v10u{sfPx5x;2}@A5BuE1# zBn_01V3(sUof&(&b{u&s-Lj)EDMSCTxCEXY_^ft}qb|;3>6nf^f;P?8Hc7{5t)_b{ zS7Y6j9ky@i4`0C5ez=N(tNnAjWrLAJ86j>>CVyQrS?nU@vcizjNia5&vgEd=li}%f zVU1KJeb10(xh3!4c*a^_duKa)XIdGzty+=uhB$yfjC_E=N$b0g<8OrI+L9X#f zVaG_4qKm3EEA-}4muxEhOCj}<{2+@_U#A@=qeU^cSt;N6PUFz5Ot1_ZyD}k8jiEr_I8FeE=knvK^w$u+eTE$aLxEklQ_` z7zCYIY_vExxFb%ROHWL;v;jPb{%ULW4&;1s;DrImyfFA-5UhbP{V=$j@r?yP!a--i z>o3CH5b}ekhlTQ{z%rgPEm(~b(^6*56is(Pcn2X2^0k#WnpAGHfLt5hBR6P{lk3t= zD--7I4fjA$%taF?7slho*o{GUm4P+~|7^5(2UfatQ_1tD7*F~Fi;Z^d0hexyJvANB zETF|~6g_Zdyh$!SQKmf*jWeUOqkP$P$k%Cc3@$xUX)w$->r?EQfydp}W4hTjCqD4A zWJG49MB9FUG0BaohpfaQ2H|Cnq`9it=5Dk511uAz^Y?_+wU@lwuoyDE7+_|LH3mZA z*b6!A6cirhsLjh+;hpFWNX~?xI4|EsW(^<_$w~v2)J2kuM%&&Oy5k_wTr6^mDN?9K zTvWIb%P&w<{51n^^o)%{&txbBm(G4xt;uHCUzDJf;1_yWbuJF>jK2SE;vWeX)BuOD2MMBTF!sTd%7DQm*(G| zkH@_QFBE{o)=G$49Pml#`A70DqyW6z{oC$%oLO)gk7an)w2VK~sp*i-Pp8-r&mjCq zzvw8{@nFh8P%?0DkiPf9SaQ-F-A?Y*!A58iO4(T?RFQT#`W2C5h`LX*iOu=kZ!}D9`ZMhj%BQ zkeu%#=ZVBGnDdLo>yk7QNw4Dt93*|1_?W;SC;l!uZ0_H&L4q7^jj%Gd`GVjQyvY?_ z5SXd>kg*e(d%BOu(9{{dX_2A_Ii^k zWXPMn{>+p=_xiM#ZRMxE))ygZebJ>wh84FLJ;0O)iXJT@5F7bu(MwEvspx%4A}ii6 z`kF~!7hO4D{y2fm_4obNs~EtvE?@t)Dmu77unF69=P3{!Smq1;d>< zkPL-}6Ukc=i9@%BTN1Y<5{F?elz1+YIGiuJy^}~Bu{C@LueZU32-l-i5=Y^XH+$u1 z?G>i~qUWD_vg$we{98{F@;7u7iMSLUL^6JgZejiRqBBU(o9F`8|7ovFi%8Gy;5O@j z6f7n^?}M+TgFIz@FMyk*XD3()dSGPuVVIqb72$4viA0Do%^%079kncFQ~s|ZFZ!)< ze&GNVSzlDd7UM74Uo?cR9&#|-d~gk0TC;@hUb0@;zTUq~*nSyy4cN?|`_K4n_A~4b zGk@Vjbyd~*x6?`f2FZl%Amj(Y2xPKI^FC@Mn z7v4yVH@va%u0rPD#V7FGRrs*vKV0~1A?tg!@NI#6yYORy`hW|B*7tOemjv#m9={j3-}iV|;NImEaPRimC2+fXd@XQa z_c%?qT~F(IzKGxXd;;$Lo|p6_zDs)kxF_pzAbQX_xwoU zKI-{pPw?A~!Kk;JLV7~`^c<11BCt-vPr7}^x#zQPUv^8UVt6O*95n_tV7w>oG{k)} z`-{$Wh(`j+jd|;c>!t4R<9(R$)BH0ykHvp6c$h2eQt(lZgwDA!@1;CEUP5tA6%4Z! z!z_m&R(d4nR;djyUa_`1g*6`Nd~<>VzWwA1Z{^eCv(M&nY*+~6Oy&@@1EUM?VHl&1 z&?_(D1OkU%b{}T@$!84o!59n}ipj4`JPk_kWOsui*YGB)?0{2V{K>`}&!k|a$s7QJ zPXg|6D&>>G3ts z@Ld0Vx}&Xa1MbHNQSZfw+Hej16}2;+TLKhm8i}&0mG59m)&~)mdQ*sG$^22_l zM(neu>|W~jKFdV&l_FYIkp+Q-bw3#r25C5Xn+j#$0wxffNrL|*Y2opHWIWoBH3Tl# z(;8shzh&yo?wn%W){&>1M=;jpg_k|0t5w|cU6#D)(?he!%V?0x!kNpkNd3=RYM9IF zSV~GB?Xqv8E9WNvCtO|rB)GvGhrS`W9G*ym$}dX8e?!~u8~;ikGPzRW>oH{z-VE#MB)0xnLH7R&ZO5C|6(OikaGu@`5*fd_?UAb=7!JwbqPsWhq6fU zlBl&KU0EQgQ#xL5=h^U1=`%$Y>{HsQVkOGcchiZ@28^ zAi;|^W{|uUY@@q=TX-G4QrCson?q^Whfj4ggGWxR{A{jb482hi-sEn?A(~OA`B?}e zbVGP+m_DL*fA%BUE*96rKXsH8CWT%c(+dlSC)bd6hKHZ$=SpM^8xnpSoE@e!&jyjP zTtOVAQJ#m>D$x-j62-QKCX8tE`guzE;M^Zs-mGK#zNSSyiiCc2VA-G`8j5i)detVw zITbXog@0i%dMyqf#~M$Mwk;$z@{3+NP6MIWn*+D^Owlt*o6JN7{K5fZXD=)o%ME>K z1JyZEsq2Im^x0X#6e!IYv|fN+nn^M%!ZxEQ;YM zIE`YpA8?K0>B(biP0|J&88E?3SgV`hpK&T(gNh3X!|Z~dC0?}7(KQE5UYEdY`8W)c zc#Mx-iF4J>X}q20fm8B4=7e9DXrgV~k3^o}vSA{$VPdu63xf-H6TaA{vmX2gdeQxk zRG6RP<8Wk9u48};D1h&?~#;k!S=}&lQx)+Dw ziU}Zm5QfVek%SDOj%YeVbb*FrG%88hRG3$T+HG?r`WiaJP3c3_OAhkRWMsn~N6`UQS+7?__tw(_~1= zOctA{*Hsi232dSd+~DTxLg5g;R)ra}(Uk0m9*jpb&zmXJq5%%a9-PWJ@$50o%w)s% zHGzE(wRwjwu%VX|uO)2wHQY|5pyd3irhfQKS$}A1;6cZDR0Rqt%M3ua8Z7Ck6yKQH z8W+{#6qD#?1Hy}A=7c9f0%))%?=i{7+x?DF{nPYB%kX*10n8I1i@yjTlb4^_P#Oyx zVC+HGa8KIYgK~r8uTelVPrc}5WjcyXf90@n)9W{{1y`L2P&s6Ihj{1pXU;V{Q1Vk0Ix)K9>%F^0{=ty90po-2vzA ziP(92p0zh(XYKvzcMRC4-}!h1Qa&DWF5kdqL(kpkp?v}R(7qRa7a13Q_lA)s0^;{`qUXhh6!c%i~3FX!zziqs{`+Fr%he>yTnc&AKIDtitm|z6`qoX*eO}yYaRHy zk(&}5^DoIq;wAZ4FeZGh^H3ja?BW;WV_}5T#XQGdxF0k=1C$C4{lNd34gSpEnTTd? zPR;&Jj zRJ0OQv=UUb4DKFnxM>@F&g6lHh*U$wsUf1&5HU(91EGpbMvsS^u5)M^QnU;yT817C z?~fGj{^&ZoIIqil8s|Nj^>iNOYL*HHUfqt#XUAGm zNPvhKurr)PCjmK(XQ<0vqJhvG0Q%?fIQum?D;unaqv=+>#TBf^QKI|!x<-At!^f4I z^|*5L_tYc5=PB))@B{yH-Y)i3;vc+L>>t6FFla{EE#b`wz;f{KX2-69fwpok=>h$N_pB&diO+$|!}0E$S0 zib#TrNP>!p!QCLzaZfxNA{q@5i-w3qLTMZ-BpKY+k*%0G#uXDoPbD6KreWw2bU()Z zP3US(cs>W+I7_>6RvLXr#2DQMF+v70LP{dXzLLnX-?b>nC?E<65Q7AWKmsh!z;231 z+b*AoCJPZZOe8i;JT^>JCM;Zv_H{$*FpQ5&{i`r&kdu7Er03{~As02G7>CH(BtjKW z!X6ea-ZYkUoi2?o^f-t(b9_I(d5t0CC!(AFS4f4GT8JT8SQ4zjki|W{yhwN0{=tf1 zYq%ZrG`9FwuxYWVN>Mx| zO|??swtG^X-oH5gzbmM`z$&P&Dq0=zN}9KR>zxakTQC(I1YcriKv+h5yV_Tj5NU zeb@hpdhY4O^Emn-88HB!zmyz38XL>u88|6AjS~_#veQ4?SZ$%kOjJx@>c z8V0n(4w4=^XtMOsWb^`hXx38cp`|BF4`EA4x@aS=sE|(j315MphSBqD#9!k?i#?< zhFbw68i_y|5Oo4krx4~GMFxar2@u&JvDqD(_wHO)d)!1wld>=$vAX?|Z@mhU2`e>vF_z&Krt6k6G z9scmAiQCw+M_?~^4KhPPW+(_R7UnNH&8_`TM)98vf1GbHZQA!jtl9-6df5TsMxgM4 zeJzM)zz2Njb5B+sJ?C;=3tLa zS(*kZ>Zu^(B7HXV)ubX$f$*zZFuW;>GY{!slxWgO=v|eA7dbGCz14erUkyD|@@|QS zb`3avu!de3{3jE7ZLc5fEore)Ph2sSJCer2+>yL02d)mHHYvnyf<$hD#BPE_ufYub zG3;06ApaI@P-nJixzM}B&)!^!-L}nr!yop(r?-o2*z=A(yYUph?viZoE0ZcqN9$chzqLNJ zw~Du0_tZ1}-tA`_KkT((rtvz`M8M++R`xUp{oQ`v=ECsu-dCpSxU%<8dgls-@S`I0 zx!yZ^N2>}E9v<%K{c`UdhPg{PD0~gob%9Tvc5H7(&D^wD`P(dLSQ3v13CDw2XkjVE zEEav~8oWL1wmLC(*d}jCZr?#TU$H&>2U7f4%AbpV(>oJpN8eBSW~O{yazX!$Qiiut zb~EdPqVrzjq`R}|DSnpW@xE_T;K{rg#Ft!{?I^0QS`KDy3N#zZt`5CELT=H`2`tbh5uW@S! z%!^+q-eCNV#Mg+!K>M1P^uvw|E(?NYm>ZYz&j0%Gs^EUaVLsd+JkI#zxHB$jhI#Ra z;Ez0yzoYoC@-Ep|#aH$Y+E(FUZSU)P1Ma%sclAd0UA>=@EzU#$+5XfqanN4hf9RXP zfA!hBzu0VPt@!j~z5$0@_rxtq4cDaMc%B+XX@%%A7Tu ze~AcBhy$*4h&2mHt|+=Qh9s#VX{rWWT4t}Yp|6WJ7h9@2!?U{CYxtLNtdzg#T&E}G z%8>lox}jy0nJ9n&{mOxIy83OuPy69<_8u4Rfg%)L*yAyfoD{ZNU%nZ8tpXa0vWU|L zR_S=rHxB(!x_|n;hm%C%d;R|0FS(L03y<6vrsy6U_mF*WLy|nAtJY`~_hDm+nzI=z z|`$^gk$cI=)8So{Tp-Mnny@DPKBKZQ^{vA^!3tj*aN$5aKG@^O*y{rF^zZ*rTnk4BxO!jbn(E%dhYIny zd%#1uGct|egrac{dN2ph;KR5(eAqN@pif)O^UaIb@O1N<&2rX%GY;VK%=z{HLp*dY zNTPo@6ur=v_e(CtE0`T~dIrr;Cy@6^2?L#SG2_2qvZX&}eEuT8U7i?pcwH@gr(|P) zv*L@gTuy|#-h{nj>x$(_U2m5BDOOi37j?Z^@&i{_Jf~K3)VS!nE?M-&%0$}+Q(Fls zCX8q@&(N7A7heWJ^dfdeI^4G!%O0 zaiH%EKMC=8D*7g~PeFDZGR7Y%5|2L>y%6us@P+6ddI#UZWm#nImp~l@?@Y&_oZwa? zGr;{p7>hmy9O-E1qBuwx44R|qm`Bl;c$|%j#Q~NqU8lfj@C8LMefRO);15?C#MGl1 zfEn>jKrIqk@X+gE)Uu=Pu#Us$7QGK5UPiUuueB^B;&@<@xE# zBMZVK=WF$)hPB)D$a(()CJ@^YO(G5p-(Rd97sU(b%)Qf8m~CrFrw9P#?qZ{U_(i>A z!$0}k^mG?W%P*cElPdu3f;6PH&n`^x5W@|LOA{2sOB37h*$S845mooJm;uwJiFC9h zWUrV=33ai!jQBW#=>||2#B-u;ReWt$Fqkl+$tz6b^=J?4j@F&Z2enD|?$if1U><2z zsL3ix87a+_B<$AYn7PjjHAPFr{ziMc8EZO7pMEuca98_xQ&T(_JeiBwE!}R!H)+DZ z7wo`=z2U{hSL3i9t}u9mr(iA__{G4OP+G*%cO2H9Q0+Z$g_gpiBYZ4)5SwBQUEA&I zd=34j;JHE#onL%;v4*bf{|XEm!fhP*(Lf1hSRbq>UI$GBRDvPL8t@=`Jct_)BF2MQ z@gPbWjIu_Ya-tF)dRcPh{&~7Zal=t`X=KkfaZXJr6sn!=nzjh`Tp^D41Rn(&`YgCF z($K5Xsks{ZB=4i{8hWtc!a@ywP;!;I0Oi#IcbjWZ#6`2anrMslTLgZyE<9Kf9;^iq zR)Gic<3Z%i17`FL(C!ZDBE5z|$d`*OgnS7J`4STHB_!laNXS<>lFtyilUdI~$EG2wBymz|eac9A~g?PMGa@hdp4Y+lnIUa9WZlBRghm%KG z|B}FEqBs*8Jd7h5Tt>bcU{eZTd5T`-ytDqL zlAEo0hAPrM{QgR~5rT9{c50J!{vaQE6N>jE+?j{f4smiS>gqvuO%I=#yHZU>? z&j-H`;s9R;PlX*oHbhrPnMq)QqdBuOm{DHgNqn!#+he!}d&ZWU&0g=KSaiSPzSp}K zsoEE?Le_vd_(@%ZljeUP`ImSX;6FmYExdm>1$IL|8T6mj0G0{+3=gBbR%y@S8#6HJ zU%>@eczogCXM7$XC$2YQdvVsMFx@DgZzu0Fg1WBv&fbzn92VnePA1BUWx=3+c9*WB{yB^3M>?j~aoC#&I;u%N$?{`{p*?+=N z5Owixx@&F_bJsu5y$ZhwXh4=R`K27vV41^9D!thBT zJgr>CpgJK^)%LFtiR>P-Mv10e;U&**zvp)oF_dPT^g@k3YWlJ&CRa9%a)tX^t75nH zMlU+K>UdMHc?lxFSJxl1?6t>kUyj(LT;Ibua!;|Yj&4E<} zL!F!uX2mYe1P)SCL zWxN;Fxo$d_OM?5dc2FZ;n}b{ZaUQ<+FR8rkF9SHnNhuYNvv@pCJh8aJ7elxIf6DCr zPyN3zo2~mlFdGB#0mG)Tm=K}i(1PUUCaD19KwsaBPIAn|e8B5Y>%t4N_=P#b=NpC8 z3sFpm=NMQs9STpP&m97MVlT`)K_{TolfU8YxTE+M-H%OLux@dtLg(4^JUbWK1iS!B zd^o}l6U+*a?~FHo5&o;}XOnn5ReV)%A&>+`F%Tt1pm21TP-ZUd>D;KC3-9cH0bZJ5 zdk-?{W-i>ZUYh7trgau7u&HJ?JP>>22UZ5Hk1H(yMz5QK|J6xxf+{bI+bA!c1f$p7 z608g>s4H*@3m)$kU(Gk}RAmTZX)t_~R2`K0_hZ3N2jz9We%nh!?-j4_tD#%^ZonNB z$Tc2Rv@MOIEQj-$Uc`Du{!RI@=zGOq6l3#V^S&s)p?5k@EuO!wBR%3uNw%sl3m0_o ztRki!KYD7N-oOME@E@0E}!{w9mjBEmIXWW<}JIYC%Tj-eCGrQG%nWQJjEHG_09TR7dP3wX^ z(Kgr1|HUsPl~O8#q{Z#pDdd|!(XFRx$h`i4XD_-^dfnAaUh)g?>UH&SBwRiG&fze5 z?i_yacl}gykD*#*gWR=;0bqa8)n{lBK1=%2ew_CRFFSoC?}@yy-P?0(_))=)ysG1& zy`S3~uOoLAvt#DCE~XWFvd1c-RuFHV9xss6~(d8cucy*1+V5$XuLeV=Xn zYH0huFKft>YYoGV|cz>Ud_OU|qb5}a-)9mT@%tsH~wCm(8p+;~bE*w;{cDrX2I^?4Aq(w5Q zWYf=G!2^eF+OpOb!neQyH^y-MfMD$gvN36!d$8_PxG2vF#Iu9s21z*DP^*_J6QxUm zcN5Wa1CXaGXD=6(To)yNK)ZO5TqOyoU5aGE8 zvJjP<5}2#B%X<%%r=X4J!bRJAsGvouV_d0h2v?6{v<15;R$Lc|2qgbvc*!*=B$%~X z2)K2_O&izXvZ%o*KX?Q-YM~Qs?g)~b5f{l#zGM&%QT#5Nm_XJ5y-f+d9?+OQh6I~l z=9Hc;$YTYFzikk)53+cu#!n{Aa2bNuAH6kcM-Q&XN{%#Ho@9wF5{-4Es}^FvY3SCW zpov2_mctKt^gRM@@{=M~da@~k_k&~@MoSzHy6*olef(Sk764(>*xOqWCD7o5U`(Ywndn*q8 z+_?9XdrK&Jn$c-JBr24n{&)#Anc(=0xPz5$?SvZYKmhAvfNJ4KlQ$@4?Cycr8}{0` z7kCTXz}8a`9)0*Q@Xb$NZ)lZEVEp8>CfYANx=aCHi2+DIzVBLxdHq(1YTpV-Da>G- zQ9<6s<3V!xRu3OS7-Oj7?FaZ8vWq4r^6SW8gH7SvthHeXD**U2K~+x28BD4x=m?J1 zxh7|$$=L(tt%rf5txUzT3s)FrdEhW~4$lo|k1kxXR&}OL!-2b`E#qll#Z!P5lKYAo z?LBgXTYjt@S7A&(WvJN`U$SqtU9QVyJJYbiFF2xM;)SCh=E<$ghh09*uZ!&D$01u6 zPT==P8;%3eaf@`(G4?F2@H`LNtz<2CUXYM6hcyUx=Ht`)+rZVUbH34SW7AKu70HvBs4P41F@)a!hF zA0#@!@FMhZUrM;>L`VWgQPDYyp)gpxi|^$phna*6IP=TIpNOWKG&ARW#o$PBL(nQ` zo0D@)?gVXLI!f0>a180G>Qs|}sgCDMvT%t#yXb#S^3dGibvKp*B~|{$ zN3Quj^d^I&|-;RbfP*R*5)bxO}vBXjjU&AjQ+aU7kFf# zND)QKmW~ZvO^Ts|`V4dT>(>hLAF}pK7+fVzovafTa|+Hg0_I7)kM&QW-pJZOqx8Y# z)A)W{_(^gb-jNNrUyZ)EMHi}1$WPw-|-cx$&;dDR6ebVxQ7 zg7=Ne`^Mz7OigJSk7sn^`5Fto(?WFC#o5nh;43aWO zNtqK9rXffKDYzF-)R`dq%C+es`c-#jpNbD<<7t?Q**8XJ2Hx@ypcRL$DbYVO(a4_xGn-^Pdn&( zbih~HmzfVqGB0$UlMI?yZ4Hy%g68I}VYj}}~%r{D*ml=;8dApi^U`n8fB`JaR&}qn8#{MpP`0Zw$VpA-`A- zk2kD2M5dGEF(x|7=;&zlX606gNwJ?v#-zB{RSLnyG`RXJHLEBXJTSMsG-OcCvweA6@erf2eL=-z&@R#~e{hFHpwM036)Cwj=h zVJ+U_B!F3c_8r(^$JV3|JfaUyu5Jl)zb!~xle%C%;+UfLjBlrE5qe>5b!O2TPa#<# z)4NcKJ6Z|1lt$Sm9XhDP{d$I=tlX{%%^kH{LPu2;t=J8rwmM5F&ZS(SwCp81Cpp$c z2V-u63Y}=8bm7s4idHzrmSPIKh!+?L;C%+LPSHGVq7yZ`-9*Q$VqRnv-ek>PYNF#c z+H9h7@Pc*jvqeb^y^CoOpPh3tY&A)W_IFvEaSL8}M$YCOntLpDl*{4;dEw{D^)73J z%Q^%(Hzw~%q7XW1mFbKrV!XwoGP|rZxp>8jta;T$@j90(*l5&6md^fMWcA+*i!1<^ znB*g{$a2ehYmi1OU7`J;yEg~Fq+Y)zd=LhAh6?YpK%*AG`CAs~tfrF#E>V*9_2?|)HXmvt$y_#n!zM3*^WE4)vWoGe0k z!`l-N>%58gF{ij3$Z>cx-+L7)J=UaCoY6Bih5;kcgCa9F0ax|n1-em#aa*ss)qjQo zg@>5@dBj9>5M1vnIy7yf_keF=C}Mb>t8_qn|!=`4_t z1QG~~fCvGSunU50qJRtVDb8rqNji%p-EDVAK!^FFqNvECfTALzg0jdABcKeU7-Sq2 zQNab#alt`laU4;RK}GoAy0@zC?Iz9q^F06eJpVTjt>oT%>zq?nr}ny4r#f^-*}$Um zTmcuu$l_B*R_PP^9Rk11&_5(9L|@uf&LLQ?!wsg0k|Y=+7Ne9~UkL<(HrEIM+gf?< zD<_U3#JLTLaTNObH)MVbA%a*4D@nKJza(sMUn}q~5RJG>XCEFFt6TprfpObH@u8qh zt<)$)tkjrpETutFJJhEIeep^;?IZPt9_3a76(Uwr=8Gs6DvfRy$i;f@yLSs`3%%AN zv6*Vz=E9nXiyuAHo4|KP-V=L?H%A}vZOi|qtJaw&Vu|w>7__Ef-QU3T6<&!!%_0Yk z&l}6`2*&gyzQRH`BQTwUTc$Q@eIiXtx_(|e9f!lP&drJWizM!-0yFG_;r?9M8gRfQ z@fAFuPY7=>Ru`YpqsMsuBPK`HcNBi@Xj-;m3RFbl&hrdfV%yVrJpZ1yRJSbhc*ZCE zDFe5XVXGKE3vxo^jg#tcg4hs(%Sca!&o zSARL-UB$QVA5Q;?Ul^}f-EB$+E^or!qu%-4%ltY2q6n}^LoLuz(S*O?mb3M@(1+eH z_<`Cly!WJYdkiKMOXRu*{lzWd`VFi$B;#_n>TF2hCQD$)8`fba&=cN`Jcy0nE!^Zd z|2aD;vKqu?k@p!d*Q5N!h3umiogw7>OY!GJ#8UP+nMwp-!FtTQ3SmeA`qL7K6YIn` z@vBFiURY8%WeF!oH(iv2 z%SS-%f_k|)ITwBO-&TkJF!5BB~ zw9jS_7vW^V!?5Y8FESVv#UQYR;&RN~Y$I10vaS(KXgBxUuvhHYG}pett{17W^Jj(>v2Ap})0D<~p`&N5`@7JDrDQ8H1FJ*43 zRV;7+$96X&#hXx@K1*?KP^p^YT)vg}cC^f~4)(!~_m@)MfVDUMy%`RqpA+N3>9`u2 z5xUPJ)Oa_9>hEIjqBR=GA6@7KL#SR!A=XJsqkN4wBLf-q56?-g5%Vv386su66Nzxf z1VGFf1M+?z8mJdA`uQbK8Ojh%CK@kiR0Yw)syga1AwlC4p0$bW*n%su;yrmYXmcJ^ zqVO4@RYv#Sv*j<@n}dosixvdM9-P>iW4H7F=N)9=Q8ILf69u+pW)m6f|~ z>uhld*Utw+s{SFu=Ke)E4RyJvh)DHSv3OS?Qhn_V^}QkBE-8*zmHHrlxJCUKBpefD zZ=eS-V*9g_mxj`k)5#d0Og!IEhH*=e`?Mh96AlO+B79YzmJ0xTd(ei$HV8gm<|AVK z=QKU@VLu?hwPU7g#4UaqslVlxFx*9*OFQ8RbUqr#{MJ?sqTG!l9PE4KnaP|h&4AN? zqxf&sBhXR~Q%oY=3R<=!nyC-EB;GO=ck0QY<9c4_J|%wwa)2hh$`2sC>i8C|(dJv| zg!V^%YUC~FkNk1Uc`t@Rir>QfEw=3Nj-JySZ=A(=<6QAwejH$Z&7`~Eqz}0J0|?gLzrgIC-u)m0i;1X;cc++u>ef86JEkg|I@NcZImQ(nlv9Pw9imuL#z;eJWwj=mo|* zJ~r~%M{9mZ)6e!rST182KH?%tQJCu#UFQ_X)F%xlTvupc>9DwU*m=LAP3IB#3HL4V z7}s~eZ4&zBLU=AHmf?CRyA>5(NmKUQnD!S16O}Ht(Q?}wpr;ke$eBXvUFph6O!M@V zB8b`!rpo{g?=7JY)aR599qB7}`q)0p!L+f;E1Q{jOC{J1hW!qL>{^AS(4DwBlxf~Rl4b~uNvyNc^R|U{ z+F-}&t+#Q-2K@+0ur|ESLATS#L1qrZRsz1Tzl=sEwJv1Z zekDDHiuy3ENcnqct8Kf@5)&62VDN6UyYkKWc?F8rn6g5+$!nw4+tpWidn`Pz+<}Iq zZVE)$irXgT zhW~h`ZB}l>zk?F)B(E2Ts_nGb{)U6zb-eGOzdDXPXfNG~aBfg^t*BEMDnZGpXeXxw*2-<1;%mx!@U)ksz+fPtKuJRj%da%z%pTgJ?eTiBQ z)v0*8(Zy0>FQ!etNQx?;_CuMrQMo74EEw#hy{;czOnXnkxwOgkE|A8dk}(Sx`tG#T zoA$kk+R|YXMq`n~w8e_dO=*|LyIZuuW(!6C0K&2_bD-b23#z$B;Y9AC^pWFPv<*Xt zo5CFsHe9(4z2A7T>F-YERanbaBn;gPAj;#FOi4#KoWZp3l^da@Q6};<0czEbY1@@} zqy>3pb@Q}rQ(+CEX^+_G_qZ&VX>TjE2UXo;qh+=~#G#o~HC=$G6{&;V8I;wA+M_}( z7-6O=ttI7MM|a^8NAw9xxW1LA3-{Sl+LiR1+ikd3=K$J1+_%SEPYMF2tx}{TDLf5A zR@qQ`cH3YMs}Yi(Ro;W>x65qQgl!ct@%5e!hPI9)#!bq<2f+>k?S_p#E1F4RRAK{- zj5MR{^fK*h#oLBThSL$pS|@FA-shqZTwB~{cz^GBf_u+D(>tF^2JmzHC?KXt0WQ>N zq1LR=0irv!d(ZTSlJij(M#;E_>3-WoT(MA$(e)iwep3K%MtV)8H}yUfY(c#*6_k7ZfQ*IHc zay!U-6FU9vi0K9kIHDdlFF5GFR7z?|mj@A?a;H&oUmAp}vqwP?o{RQHxn0!qD!PS> ziNglb6T0kamr2^w+9L{baOk`x zQ0Lo|B^jbIjA`cW@u!_M%eBx&ds9A1!9D25an1IY9NeYNDa=c( z*V^eJ+!w817EL>FGc+B@IFv!(;}tJJS)|<4kLCc{6RnP0hrwXU3+m zqgli+V5WO;+p>PeGVR5E%ET{GMh7uTMmwFd2h$zid(oa)Zavm-A=d98)^8w24OI*` z(5LRBXkOYWgIBS4A^Y+9V3jH@dfRFXCXZol{Pit>D>0Re37v16hotyYgiuyf@Oq=PK@jx@wol1w( z9LHxww>$51(h}#BE_&1Tor~Uguk+9b&ruKk;Ms}TPOXq!QCe(&(vJNc2x`A$7SUmP zNuyU_ET3jOKSDN{q&bwMsQ20FguT%Lb0|+ZXpLiy`m+hiY*5luDRne1I)Bqn|F9po zV~Tda12?WLSAW)m+PoOA41*ZVOZcUDRyYsvItiP12f8S;gMN7+)843*$w@(z{;{17 z*b&A`$4?M%-ikMtUwEhAcE_}VRg%Mj9nI8#E-I&a^BfvqjBFYejWM!$Uxku}o8qbO z5E{b&XWAi^-X%8LjGZxbuj4NW+Png-CBFcTY4Wx*thrNO5e632doa^}QQ^3#8?HY5 zlkHGD`o7)LLGnY6Co>-}iSz-C#` zVA|rqC7CZeF#Fr5(LPO=@l85?lm0IREwpcNzyQu88g0<_Xmmi^z(fCQdNa|Ti)Ds5 zs(sB-ZQ!H+S0M{C-&&b3{b@3e6KUp^52pz?Iy~y6LnYs$N}Bj5d~$ijfy*D_Da`8< zR@rqc`%E*<+>bQ|)+_8AQPjp)%Rrr!o=&X>(GAnk)xB(^zr*SoGSSMte+iJTPNIyHjaqoP$)u;IgL4VPtJTk3sRm88-M7!>tLw(C(KTyDPlgCEyY0Z zNJI+30z^Ng`qtL;&%)D%G`sEGw)9Zj6>YJOF;miDePJyxDX-XI!0;2;)WvXIdA6qR z{b--TQlFu)J?SM2HJG< zY*^M%w7BbjxnsAJ-gEAA(oyG<6grjqvzK;fJdsIXW`CbeCt9yBz}1GYphGw9oJFw{ z1t!kEcWiRf0dCk#Hww0$n={i*fpJq~Oq-)Z8A)H*n;i6t<0p+aIp6cp_S7aXEzUTY zK`*xcp$$C)6ZshI+$2+Q1?_fx?SMtBg@o%Lo+j*gS?;7J=TRqp;=U(^)~DU(rHy$D z@@Yr@%GQ|QD$a5AgJS{F3j7DtKj`uAz=brrEhOC%62|k>WFY;~Pyg(|^&#_#mSLVw zM{zWO9`}6bp{02zFg7(w^FaEYLnpv2e1??3C}Rd}797xMZuVi+0E@jGw8VebbSpSa zdtQ7w<++?PoW4$f4YTwMZkJLpYfmBXBs9eeGWy9CDxitDqT>adHeLz(6}|013J+)Q z$if&}(P3Etqs-wqOVJoMK(7{aE3^X^S#)zO7_zDAg|2%9-R(Vy!Ki5%1${SGi(awB ziO<%CD)psOCZ@=@X*aHh#0_L~Qs}PS&(V;W1~W1+%B1r{SWUgt zhQ->sSS-~(#()gQFLcWpObaT}8l_L9sZ(j@cQ)L4{jx^)dOr5hhpnE2#5k%_G&KKL zgoRXkxh{%nAE;m$wU}+A$KBt#>6@I_F%7U9aNxEZbjuAW2fvZ})bp>&yA+=y4cDfJubah<@COe*G~2PJWJ`AK_=3_2fQ3w9hp296mxBkB%!L z6!TO&5(9ekV7fv7z^!qya>*m&Te`dC={G(&kVlJ&;Y7B67+XJw&5u-DJ)O8GgbMpH z?U?E;9SD{#97ba+nAYM>85pKtT~A`QM;`jc4jJ-hqVauLQaH$&No~4NZw&iZC_ar( z6xw52xmrP)bpH9&y_ou9SZ_rIB+t(B$xYX;xc?h7irF%dtMt>cR>VWz3~Jet%F1ZK zn54eSYlIR-lwC;Yb;E2;L9MB9wH?Uyg?oqCng zpo?hKIP_CW?XBot+sDZ8^@`6$Ud-G-u~}lCMI$hy`dHo7zo@g z1Mfj)BQdhON4g&+YILK_znZ?ffHoEEEudvZJBu`V<_AX;b>)~0O*SyBa_eLmekehU zY&f&C#7*;xwqTCBRN>RW{zT1Nd?Y0!UJ8g9ueVg%k zrX@BVbgjq5CJUp7AL-v@*~h1br|n0GzQd;VgNg%%hg_|IT8&#z!ecQgF~2hCivz@d{|Ghar{L6_H4WDyFq zJo}-SiJnX|PkdZQA9Q|{4gq=e8A1T6AoT;J}&d;&d$!m*~O@Vjla&WXJUe9JdhI}|=t-|CGBE|!5Hglm{4H)s>Pfcgw(nq^Bi z^&F^gvDPxdX2nJi z*IShyJ~7@!^eN1qv7=!&TnQ$^BHk-*%zjHn&OPGb|P%E#r+JF)J_H?3`2Y?Me8y$vEk%gc+dLDwEWiT113_)Lr zr;W8{hjtqPbgBP3;V-9`dtVL+`~rbD_A~&Dvh`m-foJwM+*<{HiNJT482D*{^Uo_> z{_ZjZUu`#@*J}rTF6}WIJyqA!Fmyn+- z2u2C{%Y}T8C@5D6eEo2P@Et*aoxtUH@e_jn28oX`2)`2a4FYex)Bp@ffheCZ zO8HX^LMdmvz#9cV+G+Uj6u8_W_yMnQ`0WMG%c0zhJyb^-`&iJ+3GKjEhQ|@$JRdU! zovf!n2s}^VGJknJ>2p|30)4XhZ_w#mvOoVJUOsm< zmtKRakbNtLfAL)B@c#t;oGstiEsf7{ncj0a*F+&Zr-yTTFzQ5dJ)Et6wb*2Gn{S2e z9B%0IoF2~U;s4iqakhG0)?~)od@E$C=39JBJ&3ZcYzp)8{Jr zfz;YOV;p-9H}v^GsfXtBWt;xpDwj=9_|CNxIAbjsTOF5C>|>oikJY>xkADvw)MxzC z@twIjydCf&dm&3~uX-k-ADaZfJ_&vcmw!fV80)BUJfAV~eNd7-m_*JWxg5kZaee9a zB=nyp!A~T?v+#j66Y<%c5T88Y&FQTaIFC=_cyctSw`a1VM`VhO=eQ(trX;~{NrK-C zoQIoOK9?q;e@@UR&eLBJc;Yx@ZxT6&lHfll!PAky&FQT@aIWXXd@oKyKP(A;Z4x|~ z1czmZX3OE?B=oC*XW8>{&s=;yZc0MGgVW*pfuf>q+o0lHflk!CSbR*F%>i z_`oFic;LKTCAKryCZUf3=lPYmo-i*7{R&R6YbyTF)+F>FCBcs+!9Cb;!t;eh`_@JT z(*k&h_#kyx4^D5#uBD=Q&r;xW50BMnlrG+Z^ad%x=Mr77YJ5{L$$$Jacwl>2YI!x zyrH%(hG!%c;*UCils~F!BY5iZN#wDLi{2mk@ESj zxN79YiIaV!CXF9Ham?l8eZJz}1|bp`nZYU=BCIYH3j3mAsOe1NUaUS8QR2!&l{0+h zGh%@#tEg!RPW9F3%3%I!{@R!i`l>|YgOyONKh_XsRdo%~8dh0bT^oxc$$FxuMQURK z77WFFRiOsZ^EX{>0imgI1X`+MH38_7MFQb~U#cS-h};x_ieiyKfQ2I=e?=@5@kJVf zEF22eK@knXnDNS^6-QyHZdxcZ6u0C8Bhy^N$`l^s0kw{`X&y$cVWxQ|{6 ziYto!6@7d4?NiwgymhtZ6+G`EF}*-3>e4diFAqgx3gGNMUmy|*hJ1CQ3V*CN6pZ&A zGjW{H)at}>!?{i;`pfH(bB6v=Tw?wzuB_M$UofoL5m+SDfUH2=dY6^@1AY6HF;rUQ zc48=y5DisK4Ta-lhWx9T>Z=aKVzu>Vl6xbCfl7bO&y`eB6R7l6gd6lSqk`_M$_&Ep z+pAwiuZpS?re`RN#v*lrghX;(AtY$pSLLs*Q*z2!eZAjIk)iBh5JF3PRhCxuDJ?}D z{85x=)B-Cbr$l)MVP#36yiaLh0Bb;Xs0Prhq+eN}_key3sf(Ja;vDsX`ih!}3SC0= z2{GWctRjvI+s( zJ|0>8pFmL=4f$&P!Ag`4BShujyNvn9Tn_Ha+Mur?ibkUT%yjs}wa`#muZrG*0hNAM z-cTi!)~BR=K;OQ7`m;J-xf61aw^qE}I&Cq=q3}gQbz-IRdHhK(Q3v574h*!mlg@d7ayL#pl2#^M zTM?>>#lq+mQM{3+@~YCx(g6c18R}y*%JT7sLN>l}&4f`$!6h3Bl@i{XNrl{iKGpO< zLxIlW%;Ze-hkX^X>B!8A>3&|H{dKiB$LmaQi@}aYD?t}%OcIJTD~`^nkNL~-j75xR zjeJAr6^MjcG5WPYadohv7%GQ`V>2ue@A)fx)K&^;*u`Ud@WF{rUgJlXSzI|Ih#-t- zEMoZF6o^F80>(Lf@QVcM{G36&g)yio=B+9##%pmk1{cM#z;yiOZ7qmGdLvjIs1aRJ zO(ld#7idvZ4FN{aWbny%gyXNTtw79pOIobcqD!ntPX{be-cSunf3O<;r*PH=t3vYK zUtS&w+$3FfsA}>Z>XWY=MpZH0p$cAomB2`_+Hf~B;`_HCJ`T0vpT1mz=M|Xe^PhYc z7*6$<(^`KW;lPkr@rMP!d=^=W@s43?+^;WOR{jNoUp_m?SHu7K>C+*Z{(T~R`IO;fdZYgmu;@YYb}nT+R!gG&s#nK~~a z`4j1-TR#5*UVcVQ^2_rXVG+Kh1Bw2VZu$HPC@;H`U#??M7yL(s{-hctpUj7~;N>Ke zU#@G{Yz2rPjOE4sB)@zb=cG)2wZ7P7ux*axK2x6_$mgKO6ju5-P0Zlh10w zFT|-wi6{|XUO+8B$tR&{N%${XYm}%PJ4j07naI!GMoi=B*1uu!_v&Kc=ixCK#IoGW n{+Bmzvg}$V>_29plO==jObnl|#Wlx2;1>hs=kKh)1Sk7HQz+>l literal 0 HcmV?d00001 diff --git a/ioma.pc.in b/ioxd.pc.in similarity index 62% rename from ioma.pc.in rename to ioxd.pc.in index 7291be4..ee1b1bc 100644 --- a/ioma.pc.in +++ b/ioxd.pc.in @@ -1,11 +1,11 @@ prefix=@PREFIX@ exec_prefix=${prefix} libdir=${exec_prefix}/lib -includedir=${prefix}/include/ioma +includedir=${prefix}/include/ioxd -Name: ioma +Name: ioxd Description: HTTP/1.1 server framework on a thread-per-core io_uring runtime Version: @VERSION@ -URL: https://github.com/MDA2AV/ioma -Libs: -L${libdir} -lioma -pthread +URL: https://github.com/MDA2AV/libioxd +Libs: -L${libdir} -lioxd -pthread Cflags: -I${includedir} -pthread diff --git a/lib/http/api.c b/lib/http/api.c index b006585..ba4de42 100644 --- a/lib/http/api.c +++ b/lib/http/api.c @@ -4,7 +4,7 @@ * Nothing here touches the runtime. */ #include "http/internal.h" -#include "ioma.h" +#include "ioxd.h" #include #include @@ -17,7 +17,7 @@ /* ── slices ────────────────────────────────────────────────────────────────────────────── */ /* Is the slice exactly this C string? */ -bool ioma_slice_eq(ioma_slice s, const char *cstr) +bool ioxd_slice_eq(ioxd_slice s, const char *cstr) { size_t n = strlen(cstr); return n == s.len && (n == 0 || memcmp(s.p, cstr, n) == 0); @@ -30,7 +30,7 @@ static unsigned char lower(unsigned char c) } /* Is the slice this C string, ignoring ASCII case? */ -bool ioma_slice_eq_ci(ioma_slice s, const char *cstr) +bool ioxd_slice_eq_ci(ioxd_slice s, const char *cstr) { size_t n = strlen(cstr); if (n != s.len) @@ -42,14 +42,14 @@ bool ioma_slice_eq_ci(ioma_slice s, const char *cstr) } /* Does the slice begin with this C string? */ -bool ioma_slice_starts_with(ioma_slice s, const char *prefix) +bool ioxd_slice_starts_with(ioxd_slice s, const char *prefix) { size_t n = strlen(prefix); return n <= s.len && (n == 0 || memcmp(s.p, prefix, n) == 0); } /* Does the slice end with this C string? */ -bool ioma_slice_ends_with(ioma_slice s, const char *suffix) +bool ioxd_slice_ends_with(ioxd_slice s, const char *suffix) { size_t n = strlen(suffix); return n <= s.len && (n == 0 || memcmp(s.p + s.len - n, suffix, n) == 0); @@ -62,7 +62,7 @@ static bool is_space(char c) } /* The slice without leading and trailing whitespace. */ -ioma_slice ioma_slice_trim(ioma_slice s) +ioxd_slice ioxd_slice_trim(ioxd_slice s) { while (s.len && is_space(s.p[0])) { s.p++; @@ -74,7 +74,7 @@ ioma_slice ioma_slice_trim(ioma_slice s) } /* A NUL-terminated copy of the slice in buf; false when it did not all fit. */ -bool ioma_cstr(ioma_slice s, char *buf, size_t cap) +bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap) { if (cap == 0) return false; @@ -105,13 +105,13 @@ static bool digits_to_u64(const char *p, size_t n, uint64_t limit, uint64_t *out } /* An unsigned 64-bit integer. */ -bool ioma_to_u64(ioma_slice s, uint64_t *out) +bool ioxd_to_u64(ioxd_slice s, uint64_t *out) { return digits_to_u64(s.p, s.len, UINT64_MAX, out); } /* A signed 64-bit integer: an optional '-' and digits. */ -bool ioma_to_i64(ioma_slice s, int64_t *out) +bool ioxd_to_i64(ioxd_slice s, int64_t *out) { bool negative = s.len > 0 && s.p[0] == '-'; uint64_t limit = negative ? (uint64_t)INT64_MAX + 1 : (uint64_t)INT64_MAX; @@ -126,10 +126,10 @@ bool ioma_to_i64(ioma_slice s, int64_t *out) } /* An int: a signed 64-bit integer that fits one. */ -bool ioma_to_int(ioma_slice s, int *out) +bool ioxd_to_int(ioxd_slice s, int *out) { int64_t v; - if (!ioma_to_i64(s, &v) || v < INT_MIN || v > INT_MAX) + if (!ioxd_to_i64(s, &v) || v < INT_MIN || v > INT_MAX) return false; *out = (int)v; return true; @@ -146,7 +146,7 @@ static void make_c_locale(void) /* A double: digits with an optional fraction and exponent; strtod does the rounding. Too large * fails; too small rounds towards zero, like every JSON parser. */ -bool ioma_to_double(ioma_slice s, double *out) +bool ioxd_to_double(ioxd_slice s, double *out) { char text[128]; if (s.len == 0 || s.len >= sizeof text) @@ -171,16 +171,16 @@ bool ioma_to_double(ioma_slice s, double *out) } /* A boolean: true/false, 1/0, yes/no, on/off in any case. */ -bool ioma_to_bool(ioma_slice s, bool *out) +bool ioxd_to_bool(ioxd_slice s, bool *out) { static const char *const yes[] = { "true", "1", "yes", "on" }; static const char *const no[] = { "false", "0", "no", "off" }; for (size_t i = 0; i < 4; i++) { - if (ioma_slice_eq_ci(s, yes[i])) { + if (ioxd_slice_eq_ci(s, yes[i])) { *out = true; return true; } - if (ioma_slice_eq_ci(s, no[i])) { + if (ioxd_slice_eq_ci(s, no[i])) { *out = false; return true; } @@ -199,7 +199,7 @@ static size_t decode(const char *src, size_t len, char *dst) if (src[i] == '+') { dst[out++] = ' '; } else if (src[i] == '%' && i + 2 < len) { - int hi = ioma__hexval((unsigned char)src[i + 1]), lo = ioma__hexval((unsigned char)src[i + 2]); + int hi = ioxd__hexval((unsigned char)src[i + 1]), lo = ioxd__hexval((unsigned char)src[i + 2]); if (hi >= 0 && lo >= 0) { dst[out++] = (char)(hi * 16 + lo); i += 2; @@ -214,7 +214,7 @@ static size_t decode(const char *src, size_t len, char *dst) } /* Decode a slice into the arena and point it there; false when it would not fit. */ -static bool decode_into(ioma_slice *slice, char *arena, size_t arena_cap, size_t *used) +static bool decode_into(ioxd_slice *slice, char *arena, size_t arena_cap, size_t *used) { if (*used + slice->len > arena_cap) return false; @@ -227,7 +227,7 @@ static bool decode_into(ioma_slice *slice, char *arena, size_t arena_cap, size_t /* "k=v&k2=v2" into pairs; see http.h. One pass per pair finds '=' and '&' and notes whether * either side needs decoding, so the common undecoded pair is a view and costs a short scan. */ -size_t ioma_kv_parse(const char *text, size_t len, ioma_kv *out, size_t cap, char *arena, size_t arena_cap) +size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap) { size_t used = 0, count = 0, start = 0; while (start < len && count < cap) { @@ -243,13 +243,13 @@ size_t ioma_kv_parse(const char *text, size_t len, ioma_kv *out, size_t cap, cha } if (end > start) { /* skip empty pairs ("&&") */ bool has_eq = eq_at < end; - ioma_slice key = { text + start, (has_eq ? eq_at : end) - start }; - ioma_slice value = { has_eq ? text + eq_at + 1 : text + end, has_eq ? end - eq_at - 1 : 0 }; + ioxd_slice key = { text + start, (has_eq ? eq_at : end) - start }; + ioxd_slice value = { has_eq ? text + eq_at + 1 : text + end, has_eq ? end - eq_at - 1 : 0 }; size_t mark = used; bool ok = (!key_needs_decode || decode_into(&key, arena, arena_cap, &used)) && (!value_needs_decode || decode_into(&value, arena, arena_cap, &used)); if (ok) - out[count++] = (ioma_kv){ key, value }; + out[count++] = (ioxd_kv){ key, value }; else used = mark; /* skip the pair, give its arena back */ } @@ -261,36 +261,36 @@ size_t ioma_kv_parse(const char *text, size_t len, ioma_kv *out, size_t cap, cha /* ── shaping the reply ─────────────────────────────────────────────────────────────────── */ /* Add a header to the reply. false once the head is on the wire, or when the table is full. */ -bool ioma_header(ioma_ctx *ctx, const char *name, const char *value) +bool ioxd_header(ioxd_ctx *ctx, const char *name, const char *value) { - ioma_response *res = &ctx->res; - if (res->head_sent || res->n_headers == IOMA_MAX_RESP_HEADERS) + ioxd_response *res = &ctx->res; + if (res->head_sent || res->n_headers == IOXD_MAX_RESP_HEADERS) return false; - res->headers[res->n_headers++] = (ioma_kv){ { name, strlen(name) }, { value, strlen(value) } }; + res->headers[res->n_headers++] = (ioxd_kv){ { name, strlen(name) }, { value, strlen(value) } }; return true; } /* Set the content type from a C string (a slice can be assigned to res.content_type directly). */ -void ioma_content_type(ioma_ctx *ctx, const char *type) +void ioxd_content_type(ioxd_ctx *ctx, const char *type) { - ctx->res.content_type = (ioma_slice){ type, strlen(type) }; + ctx->res.content_type = (ioxd_slice){ type, strlen(type) }; } /* Declare the body length, so a body larger than the slab streams with Content-Length. */ -void ioma_content_length(ioma_ctx *ctx, size_t n) +void ioxd_content_length(ioxd_ctx *ctx, size_t n) { ctx->res.content_length = n; ctx->res.has_length = true; } /* Write a C string. */ -int ioma_text(ioma_ctx *ctx, const char *s) +int ioxd_text(ioxd_ctx *ctx, const char *s) { - return ioma_write(ctx, s, strlen(s)); + return ioxd_write(ctx, s, strlen(s)); } /* The reason phrase for a status code; "Unknown" if unlisted. */ -const char *ioma_reason(int status) +const char *ioxd_reason(int status) { switch (status) { case 200: return "OK"; diff --git a/lib/http/engine.c b/lib/http/engine.c index 3abb2d6..f3da6a9 100644 --- a/lib/http/engine.c +++ b/lib/http/engine.c @@ -18,30 +18,30 @@ #include #include -#ifndef IOMA_PARAM_CAP -#define IOMA_PARAM_CAP 2048 /* per-request arena for percent-decoded query parameters */ +#ifndef IOXD_PARAM_CAP +#define IOXD_PARAM_CAP 2048 /* per-request arena for percent-decoded query parameters */ #endif -#ifndef IOMA_HEAD_CAP -#define IOMA_HEAD_CAP 4096 /* a serialized reply head must fit here */ +#ifndef IOXD_HEAD_CAP +#define IOXD_HEAD_CAP 4096 /* a serialized reply head must fit here */ #endif -#ifndef IOMA_DRAIN_MAX -#define IOMA_DRAIN_MAX (1024UL * 1024) /* unread body discarded after a handler before we close instead */ +#ifndef IOXD_DRAIN_MAX +#define IOXD_DRAIN_MAX (1024UL * 1024) /* unread body discarded after a handler before we close instead */ #endif /* serve() hands req.headers to picohttpparser as its header array: a kv (two slices) must lay * out exactly like a phr_header (name, name_len, value, value_len). */ -static_assert(sizeof(ioma_kv) == sizeof(struct phr_header), "ioma_kv must mirror phr_header"); -static_assert(offsetof(ioma_kv, key) == offsetof(struct phr_header, name) && - offsetof(ioma_slice, len) == offsetof(struct phr_header, name_len) && - offsetof(ioma_kv, value) == offsetof(struct phr_header, value), - "ioma_kv must mirror phr_header"); +static_assert(sizeof(ioxd_kv) == sizeof(struct phr_header), "ioxd_kv must mirror phr_header"); +static_assert(offsetof(ioxd_kv, key) == offsetof(struct phr_header, name) && + offsetof(ioxd_slice, len) == offsetof(struct phr_header, name_len) && + offsetof(ioxd_kv, value) == offsetof(struct phr_header, value), + "ioxd_kv must mirror phr_header"); /* The engine's per-request state, behind ctx->priv. */ struct serve_state { - struct ioma_pipe *pipe; /* the connection: the head is kept in its reader */ + struct ioxd_pipe *pipe; /* the connection: the head is kept in its reader */ size_t body_read; /* body bytes handed out so far */ bool body_done; /* the whole body has been taken off the wire */ - bool body_whole; /* ioma_body_all kept it */ + bool body_whole; /* ioxd_body_all kept it */ int body_err; /* 0, a status to answer (400, 413), or -1: peer gone */ size_t chunk_left; /* data bytes of the current chunk still to deliver */ }; @@ -98,7 +98,7 @@ static bool token_present_ci(const char *value, size_t len, const char *tok) /* The three headers the engine itself needs; p == nullptr when absent. */ struct picked_headers { - ioma_slice content_length, transfer_enc, connection; + ioxd_slice content_length, transfer_enc, connection; }; /* Lower-case ASCII in place, eight bytes per step. The bytes must all be below 0x80 - true for @@ -122,11 +122,11 @@ static inline void lower_inplace(char *s, size_t n) /* One pass over the request headers: lower-case each name in place (the buffer is ours), so * handlers and this switch compare with plain memcmp. The switch on the name length rejects * nearly every header before a byte is compared. */ -static struct picked_headers pick_headers(ioma_request *req) +static struct picked_headers pick_headers(ioxd_request *req) { struct picked_headers picked = { { nullptr, 0 }, { nullptr, 0 }, { nullptr, 0 } }; for (size_t i = 0; i < req->n_headers; i++) { - ioma_kv *hdr = &req->headers[i]; + ioxd_kv *hdr = &req->headers[i]; char *name = (char *)hdr->key.p; lower_inplace(name, hdr->key.len); switch (hdr->key.len) { @@ -147,7 +147,7 @@ static struct picked_headers pick_headers(ioma_request *req) } /* HTTP/1.1 keeps alive unless "close"; HTTP/1.0 only with "keep-alive". */ -static bool keep_alive_from(int minor_version, ioma_slice connection) +static bool keep_alive_from(int minor_version, ioxd_slice connection) { bool keep = minor_version >= 1; if (connection.p) { @@ -208,13 +208,13 @@ static struct cslice status_line(int code) /* A bodyless framework reply (parse errors, limits): an error path, so plain snprintf. Best * effort; the caller then closes. */ -static void send_status(ioma_pipewriter *pw, int code) +static void send_status(ioxd_pipewriter *pw, int code) { char head[128]; int len = snprintf(head, sizeof head, "HTTP/1.1 %d %s\r\ncontent-length: 0\r\nconnection: close\r\n\r\n", - code, ioma_reason(code)); - ioma_pipewriter_reset(pw); /* whatever the handler had buffered is moot */ - ioma_pipewriter_send(pw, head, (size_t)len); + code, ioxd_reason(code)); + ioxd_pipewriter_reset(pw); /* whatever the handler had buffered is moot */ + ioxd_pipewriter_send(pw, head, (size_t)len); } /* How the body is delimited on the wire. */ @@ -227,9 +227,9 @@ enum framing { /* Serialize the head into dst by memcpy of precomposed pieces plus the integer writer - no * snprintf. Every field name goes out lower-cased: the engine's own are lowercase literals, a * handler's are folded as they are copied. Returns the length, or -1 if it does not fit. */ -static int build_head(const ioma_ctx *ctx, char *dst, size_t cap, enum framing framing, size_t body_len) +static int build_head(const ioxd_ctx *ctx, char *dst, size_t cap, enum framing framing, size_t body_len) { - const ioma_response *res = &ctx->res; + const ioxd_response *res = &ctx->res; char *p = dst; char *end = dst + cap; @@ -245,7 +245,7 @@ static int build_head(const ioma_ctx *ctx, char *dst, size_t cap, enum framing f NEED(3); p += put_uint(p, (size_t)res->status); PUTC(" "); - const char *reason = ioma_reason(res->status); + const char *reason = ioxd_reason(res->status); PUT(reason, strlen(reason)); PUTC("\r\n"); } @@ -299,7 +299,7 @@ static void put_terminator(char *at) } /* Mark the reply dead (the peer is gone, or a head that cannot be built) and fail the call. */ -static int fail(ioma_response *res) +static int fail(ioxd_response *res) { res->failed = true; return -1; @@ -309,13 +309,13 @@ static int fail(ioma_response *res) * framing: a final flush with the head unsent means the whole body is here (Content-Length, one * send); an early flush means the body outgrew the slab, so it streams - with the declared length * if the handler gave one, else chunked on HTTP/1.1, else until close on HTTP/1.0. */ -static int flush(ioma_ctx *ctx, bool final) +static int flush(ioxd_ctx *ctx, bool final) { - ioma_response *res = &ctx->res; - ioma_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; - char head[IOMA_HEAD_CAP]; + char head[IOXD_HEAD_CAP]; int head_len = 0; if (!res->head_sent) { /* the first send: decide the framing */ enum framing framing = FRAME_LENGTH; @@ -337,8 +337,8 @@ static int flush(ioma_ctx *ctx, bool final) if (res->chunked && pw->len) { /* the slab's bytes as one chunk: size in front, CRLF behind */ char size_line[16]; int digits = put_hex(size_line, pw->len); - char *front = ioma_pipewriter_front(pw, (size_t)digits + 2); - char *back = ioma_pipewriter_back(pw, 2); + char *front = ioxd_pipewriter_front(pw, (size_t)digits + 2); + char *back = ioxd_pipewriter_back(pw, 2); if (!front || !back) return fail(res); memcpy(front, size_line, (size_t)digits); @@ -348,62 +348,62 @@ static int flush(ioma_ctx *ctx, bool final) back[1] = '\n'; } if (final && res->chunked) { /* the terminator rides the same send */ - char *back = ioma_pipewriter_back(pw, 5); + char *back = ioxd_pipewriter_back(pw, 5); if (!back) return fail(res); put_terminator(back); } if (head_len) { - char *front = ioma_pipewriter_front(pw, (size_t)head_len); + char *front = ioxd_pipewriter_front(pw, (size_t)head_len); if (front) memcpy(front, head, (size_t)head_len); /* one contiguous send */ - else if (ioma_pipewriter_through(pw, head, (size_t)head_len) < 0) /* bigger than the lead: on its own, first */ + else if (ioxd_pipewriter_through(pw, head, (size_t)head_len) < 0) /* bigger than the lead: on its own, first */ return fail(res); } - if (ioma_pipewriter_flush(pw) < 0) + if (ioxd_pipewriter_flush(pw) < 0) return fail(res); return 0; } /* After the chain: send what is left - the whole reply if nothing went out yet - and close a * chunked stream. */ -static int finish(ioma_ctx *ctx) +static int finish(ioxd_ctx *ctx) { - ioma_response *res = &ctx->res; - ioma_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; if (!res->head_sent || pw->len) /* nothing sent yet, or bytes still in the slab */ return flush(ctx, true); if (res->chunked) { /* streamed and drained: just the terminator */ - char *back = ioma_pipewriter_back(pw, 5); + char *back = ioxd_pipewriter_back(pw, 5); if (!back) return fail(res); put_terminator(back); - if (ioma_pipewriter_flush(pw) < 0) + if (ioxd_pipewriter_flush(pw) < 0) return fail(res); } return 0; } /* Append body bytes to the slab; send it, head first, whenever it fills. */ -int ioma_write(ioma_ctx *ctx, const void *data, size_t len) +int ioxd_write(ioxd_ctx *ctx, const void *data, size_t len) { - ioma_response *res = &ctx->res; - ioma_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; const char *src = data; while (len) { - size_t room = ioma_pipewriter_room(pw); + size_t room = ioxd_pipewriter_room(pw); if (room == 0) { if (flush(ctx, false) < 0) return -1; continue; } size_t n = len < room ? len : room; - memcpy(ioma_pipewriter_at(pw), src, n); - ioma_pipewriter_advance(pw, n); + memcpy(ioxd_pipewriter_at(pw), src, n); + ioxd_pipewriter_advance(pw, n); src += n; len -= n; } @@ -411,42 +411,42 @@ int ioma_write(ioma_ctx *ctx, const void *data, size_t len) } /* Something bigger than the whole slab: format it on the heap and write it in pieces. */ -static int write_formatted_heap(ioma_ctx *ctx, const char *fmt, va_list ap, size_t len) +static int write_formatted_heap(ioxd_ctx *ctx, const char *fmt, va_list ap, size_t len) { char *tmp = malloc(len + 1); if (!tmp) return -1; vsnprintf(tmp, len + 1, fmt, ap); - int rc = ioma_write(ctx, tmp, len); + int rc = ioxd_write(ctx, tmp, len); free(tmp); return rc; } /* Format straight into the slab. If it does not fit the room left, flush and format again into * the empty slab; if it would not fit even that, it goes through the heap. */ -int ioma_printf(ioma_ctx *ctx, const char *fmt, ...) +int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) { - ioma_response *res = &ctx->res; - ioma_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; va_list ap, again; va_start(ap, fmt); va_copy(again, ap); - size_t room = ioma_pipewriter_room(pw); - int n = vsnprintf(ioma_pipewriter_at(pw), room, fmt, ap); + size_t room = ioxd_pipewriter_room(pw); + int n = vsnprintf(ioxd_pipewriter_at(pw), room, fmt, ap); va_end(ap); int rc = -1; if (n < 0) { /* a formatting error: nothing written */ } else if ((size_t)n < room) { /* it fit */ - ioma_pipewriter_advance(pw, (size_t)n); + ioxd_pipewriter_advance(pw, (size_t)n); rc = 0; } else if ((size_t)n >= pw->cap) { /* bigger than the slab itself */ rc = write_formatted_heap(ctx, fmt, again, (size_t)n); } else if (flush(ctx, false) == 0) { /* make room, then it fits */ - ioma_pipewriter_advance(pw, (size_t)vsnprintf(ioma_pipewriter_at(pw), pw->cap, fmt, again)); + ioxd_pipewriter_advance(pw, (size_t)vsnprintf(ioxd_pipewriter_at(pw), pw->cap, fmt, again)); rc = 0; } va_end(again); @@ -454,34 +454,34 @@ int ioma_printf(ioma_ctx *ctx, const char *fmt, ...) } /* Send what is in the slab now. Starts streaming: the head goes out with it. */ -int ioma_flush(ioma_ctx *ctx) +int ioxd_flush(ioxd_ctx *ctx) { return flush(ctx, false); } /* n bytes of the reply to write into directly, flushing first when they do not fit. */ -void *ioma_reserve(ioma_ctx *ctx, size_t n) +void *ioxd_reserve(ioxd_ctx *ctx, size_t n) { - ioma_response *res = &ctx->res; - ioma_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); if (res->failed || n > pw->cap) return nullptr; - if (n > ioma_pipewriter_room(pw) && flush(ctx, false) < 0) + if (n > ioxd_pipewriter_room(pw) && flush(ctx, false) < 0) return nullptr; - return ioma_pipewriter_at(pw); + return ioxd_pipewriter_at(pw); } /* The caller wrote n of the reserved bytes. */ -void ioma_advance(ioma_ctx *ctx, size_t n) +void ioxd_advance(ioxd_ctx *ctx, size_t n) { - ioma_pipewriter_advance(WRITER(ctx), n); + ioxd_pipewriter_advance(WRITER(ctx), n); } /* ── the body: read on demand ──────────────────────────────────────────────────────────── */ /* A body failure with a status: the engine answers with it after the handler unless a reply is * already streaming, and res.status shows it so a handler can stop before it writes anything. */ -static void body_fail(ioma_ctx *ctx, int status) +static void body_fail(ioxd_ctx *ctx, int status) { STATE(ctx)->body_err = status; ctx->res.status = status; @@ -489,12 +489,12 @@ static void body_fail(ioma_ctx *ctx, int status) /* The live bytes with something unexamined, or more of them; a failure recorded: no room is a * 413, the peer gone or the input ending inside the body is -1. */ -static bool body_bytes(ioma_ctx *ctx, ioma_slice *live) +static bool body_bytes(ioxd_ctx *ctx, ioxd_slice *live) { - int rc = ioma_pipereader_read(READER(ctx), live); + int rc = ioxd_pipereader_read(READER(ctx), live); if (rc > 0) return true; - if (rc == IOMA_PIPE_FULL) + if (rc == IOXD_PIPE_FULL) body_fail(ctx, 413); else STATE(ctx)->body_err = -1; @@ -504,7 +504,7 @@ static bool body_bytes(ioma_ctx *ctx, ioma_slice *live) /* --- a chunked body --- */ /* The line at the front of the live bytes, whole: its length without the CRLF, or -1 recorded. */ -static long body_line(ioma_ctx *ctx, ioma_slice *live) +static long body_line(ioxd_ctx *ctx, ioxd_slice *live) { for (;;) { if (!body_bytes(ctx, live)) @@ -512,19 +512,19 @@ static long body_line(ioma_ctx *ctx, ioma_slice *live) const char *eol = memmem(live->p, live->len, "\r\n", 2); if (eol) return eol - live->p; - ioma_pipereader_examine(READER(ctx), live->len); + ioxd_pipereader_examine(READER(ctx), live->len); } } /* After the last chunk: trailer lines up to an empty one, then the body is done. */ -static bool chunk_trailers(ioma_ctx *ctx) +static bool chunk_trailers(ioxd_ctx *ctx) { - ioma_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; for (;;) { long len = body_line(ctx, &live); if (len < 0) return false; - ioma_pipereader_drop(READER(ctx), (size_t)len + 2); + ioxd_pipereader_drop(READER(ctx), (size_t)len + 2); if (len == 0) break; } @@ -534,15 +534,15 @@ static bool chunk_trailers(ioma_ctx *ctx) /* The next chunk's size line - hex digits, an optional extension, CRLF - into chunk_left. The * last chunk (size 0) also takes its trailers and ends the body. */ -static bool chunk_header(ioma_ctx *ctx) +static bool chunk_header(ioxd_ctx *ctx) { - ioma_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; long len = body_line(ctx, &live); if (len < 0) return false; size_t size = 0, i = 0; for (; i < (size_t)len; i++) { - int digit = ioma__hexval((unsigned char)live.p[i]); + int digit = ioxd__hexval((unsigned char)live.p[i]); if (digit < 0) break; if (size > (SIZE_MAX >> 4)) { @@ -556,7 +556,7 @@ static bool chunk_header(ioma_ctx *ctx) body_fail(ctx, 400); return false; } - ioma_pipereader_drop(READER(ctx), (size_t)len + 2); + ioxd_pipereader_drop(READER(ctx), (size_t)len + 2); if (size == 0) return chunk_trailers(ctx); STATE(ctx)->chunk_left = size; @@ -564,21 +564,21 @@ static bool chunk_header(ioma_ctx *ctx) } /* The CRLF that ends a chunk's data. */ -static bool chunk_end(ioma_ctx *ctx) +static bool chunk_end(ioxd_ctx *ctx) { - ioma_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; for (;;) { if (!body_bytes(ctx, &live)) return false; if (live.len >= 2) break; - ioma_pipereader_examine(READER(ctx), live.len); + ioxd_pipereader_examine(READER(ctx), live.len); } if (live.p[0] != '\r' || live.p[1] != '\n') { body_fail(ctx, 400); return false; } - ioma_pipereader_drop(READER(ctx), 2); + ioxd_pipereader_drop(READER(ctx), 2); return true; } @@ -587,12 +587,12 @@ static bool chunk_end(ioma_ctx *ctx) /* The whole body, kept in the reader: a Content-Length body once it is all here, a chunked one * chunk by chunk with the data slid together. In place after the head when it all arrived in * one kernel buffer, gathered otherwise. Once; then the slice, which is also req.body. */ -ioma_slice ioma_body_all(ioma_ctx *ctx) +ioxd_slice ioxd_body_all(ioxd_ctx *ctx) { struct serve_state *state = STATE(ctx); - ioma_pipereader *pr = &state->pipe->in; - ioma_request *req = &ctx->req; - const ioma_slice none = { nullptr, 0 }; + ioxd_pipereader *pr = &state->pipe->in; + ioxd_request *req = &ctx->req; + const ioxd_slice none = { nullptr, 0 }; if (state->body_whole) return req->body; @@ -606,11 +606,11 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) return none; continue; } - ioma_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; if (!body_bytes(ctx, &live)) return none; size_t n = live.len < state->chunk_left ? live.len : state->chunk_left; - if (!ioma_pipereader_keep(pr, n)) { + if (!ioxd_pipereader_keep(pr, n)) { body_fail(ctx, 413); return none; } @@ -619,25 +619,25 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) if (state->chunk_left == 0 && !chunk_end(ctx)) return none; } - req->body = ioma_pipereader_run(pr); + req->body = ioxd_pipereader_run(pr); } else { if (req->content_length > pr->cap) { body_fail(ctx, 413); return none; } - ioma_slice live = none; + ioxd_slice live = none; while (req->content_length && live.len < req->content_length) { if (live.len) - ioma_pipereader_examine(pr, live.len); + ioxd_pipereader_examine(pr, live.len); if (!body_bytes(ctx, &live)) return none; } - const char *kept = req->content_length ? ioma_pipereader_keep(pr, req->content_length) : live.p; + const char *kept = req->content_length ? ioxd_pipereader_keep(pr, req->content_length) : live.p; if (req->content_length && !kept) { body_fail(ctx, 413); return none; } - req->body = (ioma_slice){ kept, req->content_length }; + req->body = (ioxd_slice){ kept, req->content_length }; state->body_read = req->content_length; state->body_done = true; } @@ -646,12 +646,12 @@ ioma_slice ioma_body_all(ioma_ctx *ctx) } /* Up to n bytes of a Content-Length body into dst, straight from the reader. */ -static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) +static int fixed_data(ioxd_ctx *ctx, struct serve_state *state, char *dst, size_t n) { size_t remaining = ctx->req.content_length - state->body_read; if (n > remaining) n = remaining; - int got = ioma_pipereader_copy(&state->pipe->in, dst, n); + int got = ioxd_pipereader_copy(&state->pipe->in, dst, n); if (got <= 0) { state->body_err = -1; /* gone, or the input ended inside the body */ return -1; @@ -663,11 +663,11 @@ static int fixed_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ } /* Up to n data bytes of the current chunk into dst; the CRLF after its last byte is taken too. */ -static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_t n) +static int chunk_data(ioxd_ctx *ctx, struct serve_state *state, char *dst, size_t n) { if (n > state->chunk_left) n = state->chunk_left; - int got = ioma_pipereader_copy(&state->pipe->in, dst, n); + int got = ioxd_pipereader_copy(&state->pipe->in, dst, n); if (got <= 0) { state->body_err = -1; return -1; @@ -680,7 +680,7 @@ static int chunk_data(ioma_ctx *ctx, struct serve_state *state, char *dst, size_ } /* The next bytes of the body into dst, reading until n are there or the body ends. */ -int ioma_body_read_until(ioma_ctx *ctx, void *dst, size_t n) +int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n) { struct serve_state *state = STATE(ctx); if (state->body_err || n == 0) @@ -704,7 +704,7 @@ int ioma_body_read_until(ioma_ctx *ctx, void *dst, size_t n) /* The next chunk of a chunked body, whole, into dst: the rest of the current one when a read * stopped inside it, else the next. */ -int ioma_body_read_next_chunk(ioma_ctx *ctx, void *dst, size_t cap) +int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap) { struct serve_state *state = STATE(ctx); if (state->body_err || !ctx->req.chunked) @@ -734,17 +734,17 @@ int ioma_body_read_next_chunk(ioma_ctx *ctx, void *dst, size_t cap) /* After the chain: take an unread body off the wire so the connection stays in sync, up to a * limit - past it, the reply says close and the rest is never read. */ -static void drain_body(ioma_ctx *ctx) +static void drain_body(ioxd_ctx *ctx) { struct serve_state *state = STATE(ctx); char tmp[4096]; size_t drained = 0; while (!state->body_done && !state->body_err) { - if (drained >= IOMA_DRAIN_MAX) { + if (drained >= IOXD_DRAIN_MAX) { ctx->res.close = true; return; } - int n = ioma_body_read_until(ctx, tmp, sizeof tmp); + int n = ioxd_body_read_until(ctx, tmp, sizeof tmp); if (n <= 0) return; drained += (size_t)n; @@ -757,23 +757,23 @@ static void drain_body(ioma_ctx *ctx) * version, headers). What is buffered is parsed first: after a reply, a pipelined next request * may already be there. More is read only when the head is incomplete. Returns the head's * length, or -1 once the connection is finished (431 or 400 answered, or the peer went away). */ -static long read_head(ioma_ctx *ctx) +static long read_head(ioxd_ctx *ctx) { - ioma_pipereader *pr = READER(ctx); - ioma_request *req = &ctx->req; + ioxd_pipereader *pr = READER(ctx); + ioxd_request *req = &ctx->req; size_t already = 0; /* what the previous attempt scanned */ - ioma_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; for (;;) { - int rc = ioma_pipereader_read(pr, &live); + int rc = ioxd_pipereader_read(pr, &live); if (rc == 0) return -1; /* the peer is done: a clean end between requests */ - if (rc == IOMA_PIPE_FULL) { + if (rc == IOXD_PIPE_FULL) { send_status(WRITER(ctx), 431); return -1; } if (rc < 0) return -1; - req->n_headers = IOMA_MAX_HEADERS; /* in: room; out: count */ + req->n_headers = IOXD_MAX_HEADERS; /* in: room; out: count */ int parsed = phr_parse_request(live.p, live.len, &req->method.p, &req->method.len, &req->target.p, &req->target.len, @@ -781,15 +781,15 @@ static long read_head(ioma_ctx *ctx) (struct phr_header *)req->headers, &req->n_headers, already); if (parsed >= 0) { - ioma_pipereader_keep(pr, (size_t)parsed); /* the head stays put, where it was parsed */ - ioma_pipereader_run_begin(pr); /* the body's kept bytes are a run of their own */ + ioxd_pipereader_keep(pr, (size_t)parsed); /* the head stays put, where it was parsed */ + ioxd_pipereader_run_begin(pr); /* the body's kept bytes are a run of their own */ return parsed; } if (parsed == -1) { /* malformed */ send_status(WRITER(ctx), 400); return -1; } - ioma_pipereader_examine(pr, live.len); /* incomplete: the next read waits for more */ + ioxd_pipereader_examine(pr, live.len); /* incomplete: the next read waits for more */ already = live.len; } } @@ -797,18 +797,18 @@ static long read_head(ioma_ctx *ctx) /* The rest of the request from its head: path and query, the query split into params, the * headers lower-cased and the three the engine needs picked out. The body stays on the wire; * body_start is where it begins. */ -static void fill_request(ioma_request *req, char *params_arena, size_t arena_cap) +static void fill_request(ioxd_request *req, char *params_arena, size_t arena_cap) { const char *qmark = memchr(req->target.p, '?', req->target.len); if (qmark) { - req->path = (ioma_slice){ req->target.p, (size_t)(qmark - req->target.p) }; - req->query = (ioma_slice){ qmark + 1, req->target.len - req->path.len - 1 }; + req->path = (ioxd_slice){ req->target.p, (size_t)(qmark - req->target.p) }; + req->query = (ioxd_slice){ qmark + 1, req->target.len - req->path.len - 1 }; } else { req->path = req->target; - req->query = (ioma_slice){ req->target.p + req->target.len, 0 }; + req->query = (ioxd_slice){ req->target.p + req->target.len, 0 }; } req->n_params = req->query.len - ? ioma_kv_parse(req->query.p, req->query.len, req->params, IOMA_MAX_PARAMS, params_arena, arena_cap) + ? ioxd_kv_parse(req->query.p, req->query.len, req->params, IOXD_MAX_PARAMS, params_arena, arena_cap) : 0; req->n_route_params = 0; /* the router fills these */ @@ -816,23 +816,23 @@ static void fill_request(ioma_request *req, char *params_arena, size_t arena_cap req->chunked = picked.transfer_enc.p && token_present_ci(picked.transfer_enc.p, picked.transfer_enc.len, "chunked"); req->content_length = picked.content_length.p ? parse_size(picked.content_length.p, picked.content_length.len) : 0; req->keep_alive = keep_alive_from(req->minor_version, picked.connection); - req->body = (ioma_slice){ nullptr, 0 }; /* on demand: ioma_body_all fills it */ + req->body = (ioxd_slice){ nullptr, 0 }; /* on demand: ioxd_body_all fills it */ } /* The engine's bookkeeping for reading the body on demand: where it starts, what already * arrived with the head, and - for a Content-Length body that is entirely here - where the next * request starts. */ -static void init_body_state(struct serve_state *state, struct ioma_pipe *pipe, const ioma_request *req) +static void init_body_state(struct serve_state *state, struct ioxd_pipe *pipe, const ioxd_request *req) { *state = (struct serve_state){ .pipe = pipe }; state->body_done = !req->chunked && req->content_length == 0; } /* A response with its defaults and an empty slab. */ -static void init_response(ioma_response *res, ioma_pipewriter *pw) +static void init_response(ioxd_response *res, ioxd_pipewriter *pw) { res->status = 200; - res->content_type = (ioma_slice){ "text/plain", 10 }; + res->content_type = (ioxd_slice){ "text/plain", 10 }; res->n_headers = 0; /* headers[] is only read up to here */ res->close = false; res->head_sent = false; @@ -840,19 +840,19 @@ static void init_response(ioma_response *res, ioma_pipewriter *pw) res->has_length = false; res->chunked = false; res->failed = false; - ioma_pipewriter_reset(pw); + ioxd_pipewriter_reset(pw); } /* The proactor handler for every connection: one request per iteration - get the head, run * the chain against a context, drain what it left of the body, send what it wrote - while kept * alive. Returning closes the connection. */ -void ioma__serve(struct ioma_pipe *pipe) +void ioxd__serve(struct ioxd_pipe *pipe) { - char params[IOMA_PARAM_CAP]; /* decoded query parameters */ + char params[IOXD_PARAM_CAP]; /* decoded query parameters */ for (;;) { - ioma_ctx ctx; /* this request's context */ + ioxd_ctx ctx; /* this request's context */ struct serve_state state = { .pipe = pipe }; ctx.priv = &state; @@ -864,7 +864,7 @@ void ioma__serve(struct ioma_pipe *pipe) init_response(&ctx.res, &pipe->out); ctx.user = nullptr; - ioma__dispatch(&ctx); /* middleware chain + endpoint */ + ioxd__dispatch(&ctx); /* middleware chain + endpoint */ if (state.body_err) { /* too large, malformed, or gone */ if (state.body_err > 0 && !ctx.res.head_sent) @@ -878,6 +878,6 @@ void ioma__serve(struct ioma_pipe *pipe) return; if (!ctx.req.keep_alive || ctx.res.close) return; - ioma_pipereader_release(&pipe->in); /* this request's bytes go; a pipelined next one stays */ + ioxd_pipereader_release(&pipe->in); /* this request's bytes go; a pipelined next one stays */ } } diff --git a/lib/http/engine.h b/lib/http/engine.h index 926edb9..26cefdd 100644 --- a/lib/http/engine.h +++ b/lib/http/engine.h @@ -5,4 +5,4 @@ #include "io/pipe.h" -void ioma__serve(struct ioma_pipe *pipe); /* requests on the connection until it ends */ +void ioxd__serve(struct ioxd_pipe *pipe); /* requests on the connection until it ends */ diff --git a/lib/http/internal.h b/lib/http/internal.h index 60210be..7cbb7b2 100644 --- a/lib/http/internal.h +++ b/lib/http/internal.h @@ -5,7 +5,7 @@ #pragma once /* The value of a hex digit, or -1. Percent-decoding (api.c) and chunk sizes (engine.c). */ -static inline int ioma__hexval(unsigned char c) +static inline int ioxd__hexval(unsigned char c) { if (c >= '0' && c <= '9') return c - '0'; diff --git a/lib/http/router.c b/lib/http/router.c index 2ff6813..b3a180a 100644 --- a/lib/http/router.c +++ b/lib/http/router.c @@ -1,6 +1,6 @@ /* * router.c - groups, endpoints, middleware, and the segment tree they resolve into. Everything is - * registered before the workers start and resolved once by ioma_run; after that it is read-only + * registered before the workers start and resolved once by ioxd_run; after that it is read-only * and every worker shares it without a lock. A request costs one walk down the tree and one call * through its endpoint's flat middleware chain. */ @@ -11,60 +11,60 @@ #include -struct ioma_group { - ioma_group *parent; /* nullptr only for the root */ +struct ioxd_group { + ioxd_group *parent; /* nullptr only for the root */ const char *prefix; - ioma_mw mws[IOMA_MAX_MW]; + ioxd_mw mws[IOXD_MAX_MW]; int n_mws; }; -struct ioma_endpoint { - ioma_endpoint *next; /* the registration list */ - ioma_group *group; +struct ioxd_endpoint { + ioxd_endpoint *next; /* the registration list */ + ioxd_group *group; const char *method; size_t method_len; const char *path; /* below the group's prefix */ - ioma_handler fn; - ioma_mw own[IOMA_MAX_MW]; + ioxd_handler fn; + ioxd_mw own[IOXD_MAX_MW]; int n_own; - /* resolved by ioma__router_build */ + /* resolved by ioxd__router_build */ char *full; /* the whole path, prefixes included */ - ioma_slice names[IOMA_MAX_ROUTE_PARAMS]; /* the :name captures, in path order */ + ioxd_slice names[IOXD_MAX_ROUTE_PARAMS]; /* the :name captures, in path order */ size_t n_names; - ioma_mw *chain; /* root, each group outer to inner, then own */ + ioxd_mw *chain; /* root, each group outer to inner, then own */ int n_chain; }; /* One segment of the tree; the root is the empty one. */ struct node { - ioma_slice seg; /* the static segment this node is */ + ioxd_slice seg; /* the static segment this node is */ struct node **kids; /* static children */ int n_kids; struct node *param; /* the child that takes any segment */ - ioma_endpoint **eps; /* the endpoints here, one per method */ + ioxd_endpoint **eps; /* the endpoints here, one per method */ int n_eps; char *allow; /* "GET, POST": the methods here, for a 405 */ }; -/* The chain cursor handed to each middleware; ioma_next_run advances it. */ -struct ioma_next { - const ioma_mw *mws; +/* The chain cursor handed to each middleware; ioxd_next_run advances it. */ +struct ioxd_next { + const ioxd_mw *mws; int n; int i; - ioma_handler handler; + ioxd_handler handler; }; -static void not_found(ioma_ctx *ctx); +static void not_found(ioxd_ctx *ctx); -static ioma_group g_root = { .prefix = "" }; /* no prefix; ioma_use's middleware */ -static ioma_group *g_current = &g_root; /* the script form's open group */ -static ioma_endpoint *g_first, *g_last; /* endpoints in registration order */ +static ioxd_group g_root = { .prefix = "" }; /* no prefix; ioxd_use's middleware */ +static ioxd_group *g_current = &g_root; /* the script form's open group */ +static ioxd_endpoint *g_first, *g_last; /* endpoints in registration order */ static struct node g_tree; /* the root node */ -static ioma_handler g_fallback = not_found; +static ioxd_handler g_fallback = not_found; static bool g_built; /* Exact slice compare. */ -static bool same(ioma_slice a, ioma_slice b) +static bool same(ioxd_slice a, ioxd_slice b) { return a.len == b.len && memcmp(a.p, b.p, a.len) == 0; } @@ -73,7 +73,7 @@ static bool same(ioma_slice a, ioma_slice b) static void *must(void *p) { if (!p) { - perror("ioma: malloc"); + perror("ioxd: malloc"); abort(); } return p; @@ -82,40 +82,40 @@ static void *must(void *p) /* ── registration ──────────────────────────────────────────────────────────────────────── */ /* A group below parent (nullptr: the root) at prefix. */ -ioma_group *ioma_group_new(ioma_group *parent, const char *prefix) +ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix) { - ioma_group *group = must(calloc(1, sizeof *group)); + ioxd_group *group = must(calloc(1, sizeof *group)); group->parent = parent ? parent : &g_root; group->prefix = prefix; return group; } /* Middleware around everything below the group. */ -void ioma_group_use(ioma_group *group, ioma_mw mw) +void ioxd_group_use(ioxd_group *group, ioxd_mw mw) { if (!group) group = &g_root; - if (group->n_mws == IOMA_MAX_MW) { - fprintf(stderr, "ioma: group %s already has %d middleware, dropping one\n", group->prefix, IOMA_MAX_MW); + if (group->n_mws == IOXD_MAX_MW) { + fprintf(stderr, "ioxd: group %s already has %d middleware, dropping one\n", group->prefix, IOXD_MAX_MW); return; } group->mws[group->n_mws++] = mw; } /* Root middleware: every request. */ -void ioma_use(ioma_mw mw) +void ioxd_use(ioxd_mw mw) { - ioma_group_use(&g_root, mw); + ioxd_group_use(&g_root, mw); } /* An endpoint in a group (nullptr: the root). */ -ioma_endpoint *ioma_route(ioma_group *group, const char *method, const char *path, ioma_handler fn) +ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn) { if (g_built) { - fprintf(stderr, "ioma: %s %s registered after ioma_run started; ignored\n", method, path); + fprintf(stderr, "ioxd: %s %s registered after ioxd_run started; ignored\n", method, path); return nullptr; } - ioma_endpoint *ep = must(calloc(1, sizeof *ep)); + ioxd_endpoint *ep = must(calloc(1, sizeof *ep)); ep->group = group ? group : &g_root; ep->method = method; ep->method_len = strlen(method); @@ -130,31 +130,31 @@ ioma_endpoint *ioma_route(ioma_group *group, const char *method, const char *pat } /* Middleware around one endpoint. */ -void ioma_endpoint_use(ioma_endpoint *endpoint, ioma_mw mw) +void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw) { if (!endpoint) return; - if (endpoint->n_own == IOMA_MAX_MW) { - fprintf(stderr, "ioma: %s %s already has %d middleware, dropping one\n", endpoint->method, endpoint->path, IOMA_MAX_MW); + if (endpoint->n_own == IOXD_MAX_MW) { + fprintf(stderr, "ioxd: %s %s already has %d middleware, dropping one\n", endpoint->method, endpoint->path, IOXD_MAX_MW); return; } endpoint->own[endpoint->n_own++] = mw; } -/* --- the script form (the IOMA_ macros) --- */ +/* --- the script form (the IOXD_ macros) --- */ /* Open a group below the current one and make it current; its middleware list ends at a null. */ -ioma_group *ioma__group_begin(struct ioma_group_args args) +ioxd_group *ioxd__group_begin(struct ioxd_group_args args) { - ioma_group *group = ioma_group_new(g_current, args.prefix); - for (int i = 0; i < IOMA_MAX_MW && args.mws[i]; i++) - ioma_group_use(group, args.mws[i]); + ioxd_group *group = ioxd_group_new(g_current, args.prefix); + for (int i = 0; i < IOXD_MAX_MW && args.mws[i]; i++) + ioxd_group_use(group, args.mws[i]); g_current = group; return group; } /* Close the current group; null, so the block's loop ends. */ -ioma_group *ioma__group_end(void) +ioxd_group *ioxd__group_end(void) { if (g_current->parent) g_current = g_current->parent; @@ -162,30 +162,30 @@ ioma_group *ioma__group_end(void) } /* The group a script-form registration goes into. */ -ioma_group *ioma__group_current(void) +ioxd_group *ioxd__group_current(void) { return g_current; } /* An endpoint in the current group, with its middleware list (ended by a null). */ -ioma_endpoint *ioma__endpoint(const char *method, struct ioma_endpoint_args args) +ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args) { - ioma_endpoint *ep = ioma_route(g_current, method, args.path, args.fn); - for (int i = 0; i < IOMA_MAX_MW && args.mws[i]; i++) - ioma_endpoint_use(ep, args.mws[i]); + ioxd_endpoint *ep = ioxd_route(g_current, method, args.path, args.fn); + for (int i = 0; i < IOXD_MAX_MW && args.mws[i]; i++) + ioxd_endpoint_use(ep, args.mws[i]); return ep; } /* Replace the built-in 404 fallback. */ -void ioma_default(ioma_handler fn) +void ioxd_default(ioxd_handler fn) { g_fallback = fn; } -/* ── resolution, once, from ioma_run ───────────────────────────────────────────────────── */ +/* ── resolution, once, from ioxd_run ───────────────────────────────────────────────────── */ /* The next segment of a path from *at, slashes skipped; false at the end. */ -static bool next_segment(const char **at, const char *end, ioma_slice *seg) +static bool next_segment(const char **at, const char *end, ioxd_slice *seg) { const char *p = *at; while (p < end && *p == '/') @@ -197,22 +197,22 @@ static bool next_segment(const char **at, const char *end, ioma_slice *seg) const char *seg_end = memchr(p, '/', (size_t)(end - p)); if (!seg_end) seg_end = end; - *seg = (ioma_slice){ p, (size_t)(seg_end - p) }; + *seg = (ioxd_slice){ p, (size_t)(seg_end - p) }; *at = seg_end; return true; } /* The endpoint's whole path: its groups' prefixes, outermost first, then its own path. Written * right to left, from the innermost group up, so no list of the groups is needed. */ -static char *full_path(const ioma_endpoint *ep) +static char *full_path(const ioxd_endpoint *ep) { size_t path_len = strlen(ep->path), len = path_len; - for (const ioma_group *g = ep->group; g; g = g->parent) + for (const ioxd_group *g = ep->group; g; g = g->parent) len += strlen(g->prefix); char *full = must(malloc(len + 1)); size_t at = len - path_len; memcpy(full + at, ep->path, path_len + 1); /* the path last, with its NUL */ - for (const ioma_group *g = ep->group; g; g = g->parent) { + for (const ioxd_group *g = ep->group; g; g = g->parent) { size_t n = strlen(g->prefix); at -= n; memcpy(full + at, g->prefix, n); @@ -222,10 +222,10 @@ static char *full_path(const ioma_endpoint *ep) /* The endpoint's middleware, flat: the root's, each group's outer to inner, then its own. Filled * right to left, like the path. */ -static void flatten_chain(ioma_endpoint *ep) +static void flatten_chain(ioxd_endpoint *ep) { int n = ep->n_own; - for (const ioma_group *g = ep->group; g; g = g->parent) + for (const ioxd_group *g = ep->group; g; g = g->parent) n += g->n_mws; ep->n_chain = n; if (n == 0) @@ -233,14 +233,14 @@ static void flatten_chain(ioma_endpoint *ep) ep->chain = must(malloc((size_t)n * sizeof *ep->chain)); int at = n - ep->n_own; memcpy(ep->chain + at, ep->own, (size_t)ep->n_own * sizeof *ep->chain); - for (const ioma_group *g = ep->group; g; g = g->parent) { + for (const ioxd_group *g = ep->group; g; g = g->parent) { at -= g->n_mws; memcpy(ep->chain + at, g->mws, (size_t)g->n_mws * sizeof *ep->chain); } } /* The static child for a segment, made if missing. */ -static struct node *child(struct node *node, ioma_slice seg) +static struct node *child(struct node *node, ioxd_slice seg) { for (int i = 0; i < node->n_kids; i++) if (same(node->kids[i]->seg, seg)) @@ -255,18 +255,18 @@ static struct node *child(struct node *node, ioma_slice seg) /* Put an endpoint into the tree along its full path; a ':name' segment goes through the capture * child and its name is kept with the endpoint. A duplicate keeps the first. */ -static void insert(ioma_endpoint *ep) +static void insert(ioxd_endpoint *ep) { struct node *node = &g_tree; const char *at = ep->full, *end = ep->full + strlen(ep->full); - ioma_slice seg; + ioxd_slice seg; while (next_segment(&at, end, &seg)) { if (seg.p[0] == ':') { - if (ep->n_names == IOMA_MAX_ROUTE_PARAMS) { - fprintf(stderr, "ioma: %s %s has more than %d captures; ignored\n", ep->method, ep->full, IOMA_MAX_ROUTE_PARAMS); + if (ep->n_names == IOXD_MAX_ROUTE_PARAMS) { + fprintf(stderr, "ioxd: %s %s has more than %d captures; ignored\n", ep->method, ep->full, IOXD_MAX_ROUTE_PARAMS); return; } - ep->names[ep->n_names++] = (ioma_slice){ seg.p + 1, seg.len - 1 }; + ep->names[ep->n_names++] = (ioxd_slice){ seg.p + 1, seg.len - 1 }; if (!node->param) node->param = must(calloc(1, sizeof *node->param)); node = node->param; @@ -276,11 +276,11 @@ static void insert(ioma_endpoint *ep) } for (int i = 0; i < node->n_eps; i++) { if (node->eps[i]->method_len == ep->method_len && memcmp(node->eps[i]->method, ep->method, ep->method_len) == 0) { - fprintf(stderr, "ioma: duplicate route %s %s; keeping the first\n", ep->method, ep->full); + fprintf(stderr, "ioxd: duplicate route %s %s; keeping the first\n", ep->method, ep->full); return; } } - ioma_endpoint **eps = must(realloc(node->eps, ((size_t)node->n_eps + 1) * sizeof *eps)); + ioxd_endpoint **eps = must(realloc(node->eps, ((size_t)node->n_eps + 1) * sizeof *eps)); node->eps = eps; node->eps[node->n_eps++] = ep; } @@ -310,12 +310,12 @@ static void set_allow(struct node *node) } /* Resolve everything registered: full paths into the tree, middleware into flat chains. */ -void ioma__router_build(void) +void ioxd__router_build(void) { if (g_built) return; g_built = true; - for (ioma_endpoint *ep = g_first; ep; ep = ep->next) { + for (ioxd_endpoint *ep = g_first; ep; ep = ep->next) { ep->full = full_path(ep); insert(ep); flatten_chain(ep); @@ -326,7 +326,7 @@ void ioma__router_build(void) /* ── a request ─────────────────────────────────────────────────────────────────────────── */ /* The endpoint at a node for the method, or nullptr. */ -static const ioma_endpoint *endpoint_for(const struct node *node, ioma_slice method) +static const ioxd_endpoint *endpoint_for(const struct node *node, ioxd_slice method) { for (int i = 0; i < node->n_eps; i++) if (node->eps[i]->method_len == method.len && memcmp(node->eps[i]->method, method.p, method.len) == 0) @@ -339,10 +339,10 @@ static const ioma_endpoint *endpoint_for(const struct node *node, ioma_slice met * the capture, so a static segment wins, and the capture is tried when the static branch comes * to nothing - including when it reaches the end without this method. Returns the endpoint for * the method, or nullptr; *seen is the first node the path itself reached, for a 405. */ -static const ioma_endpoint *walk(const struct node *node, const char *at, const char *end, - ioma_request *req, const struct node **seen) +static const ioxd_endpoint *walk(const struct node *node, const char *at, const char *end, + ioxd_request *req, const struct node **seen) { - ioma_slice seg; + ioxd_slice seg; if (!next_segment(&at, end, &seg)) { if (node->n_eps && !*seen) *seen = node; @@ -350,16 +350,16 @@ static const ioma_endpoint *walk(const struct node *node, const char *at, const } for (int i = 0; i < node->n_kids; i++) { if (same(node->kids[i]->seg, seg)) { - const ioma_endpoint *ep = walk(node->kids[i], at, end, req, seen); + const ioxd_endpoint *ep = walk(node->kids[i], at, end, req, seen); if (ep) return ep; break; /* static children are unique: no other candidate */ } } - if (node->param && req->n_route_params < IOMA_MAX_ROUTE_PARAMS) { + if (node->param && req->n_route_params < IOXD_MAX_ROUTE_PARAMS) { size_t mark = req->n_route_params; req->route_params[req->n_route_params++].value = seg; - const ioma_endpoint *ep = walk(node->param, at, end, req, seen); + const ioxd_endpoint *ep = walk(node->param, at, end, req, seen); if (ep) return ep; req->n_route_params = mark; @@ -369,11 +369,11 @@ static const ioma_endpoint *walk(const struct node *node, const char *at, const /* Run the next middleware, or the endpoint once the chain is exhausted. A middleware that does * not call this short-circuits the request. */ -void ioma_next_run(ioma_ctx *ctx, ioma_next *next) +void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next) { if (next->i < next->n) { - ioma_mw mw = next->mws[next->i]; - ioma_next inner = { next->mws, next->n, next->i + 1, next->handler }; + ioxd_mw mw = next->mws[next->i]; + ioxd_next inner = { next->mws, next->n, next->i + 1, next->handler }; mw(ctx, &inner); return; } @@ -381,34 +381,34 @@ void ioma_next_run(ioma_ctx *ctx, ioma_next *next) } /* A handler behind a chain; a direct call when the chain is empty. */ -static void run(ioma_ctx *ctx, const ioma_mw *mws, int n, ioma_handler fn) +static void run(ioxd_ctx *ctx, const ioxd_mw *mws, int n, ioxd_handler fn) { if (n == 0) { fn(ctx); return; } - ioma_next next = { mws, n, 0, fn }; - ioma_next_run(ctx, &next); + ioxd_next next = { mws, n, 0, fn }; + ioxd_next_run(ctx, &next); } /* The built-in fallbacks. */ -static void not_found(ioma_ctx *ctx) +static void not_found(ioxd_ctx *ctx) { ctx->res.status = 404; - ioma_text(ctx, "404 Not Found\n"); + ioxd_text(ctx, "404 Not Found\n"); } -static void not_allowed(ioma_ctx *ctx) /* status and allow are set before its chain */ +static void not_allowed(ioxd_ctx *ctx) /* status and allow are set before its chain */ { - ioma_text(ctx, "405 Method Not Allowed\n"); + ioxd_text(ctx, "405 Method Not Allowed\n"); } /* Find the request's endpoint and run it behind its chain; the fallbacks run behind the root's. */ -void ioma__dispatch(ioma_ctx *ctx) +void ioxd__dispatch(ioxd_ctx *ctx) { - ioma_request *req = &ctx->req; + ioxd_request *req = &ctx->req; const struct node *seen = nullptr; req->n_route_params = 0; - const ioma_endpoint *ep = walk(&g_tree, req->path.p, req->path.p + req->path.len, req, &seen); + const ioxd_endpoint *ep = walk(&g_tree, req->path.p, req->path.p + req->path.len, req, &seen); if (ep) { for (size_t i = 0; i < req->n_route_params; i++) req->route_params[i].key = ep->names[i]; @@ -418,7 +418,7 @@ void ioma__dispatch(ioma_ctx *ctx) req->n_route_params = 0; if (seen) { /* the path is known, the method is not */ ctx->res.status = 405; - ioma_header(ctx, "allow", seen->allow); + ioxd_header(ctx, "allow", seen->allow); run(ctx, g_root.mws, g_root.n_mws, not_allowed); return; } diff --git a/lib/http/router.h b/lib/http/router.h index 72adc26..d3245b5 100644 --- a/lib/http/router.h +++ b/lib/http/router.h @@ -4,7 +4,7 @@ */ #pragma once -#include "ioma.h" +#include "ioxd.h" -void ioma__router_build(void); /* the segment tree and the flat chains, once */ -void ioma__dispatch(ioma_ctx *ctx); /* the request's endpoint, behind its chain */ +void ioxd__router_build(void); /* the segment tree and the flat chains, once */ +void ioxd__dispatch(ioxd_ctx *ctx); /* the request's endpoint, behind its chain */ diff --git a/lib/http/run.c b/lib/http/run.c index 8b57106..63ee773 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -1,5 +1,5 @@ /* - * run.c - ioma_run: one proactor thread per core serving HTTP, until SIGINT/SIGTERM. + * run.c - ioxd_run: one proactor thread per core serving HTTP, until SIGINT/SIGTERM. */ #include "http/engine.h" #include "http/router.h" @@ -59,13 +59,13 @@ static void raise_nofile(void) /* Start the workers (workers <= 0: one per available core) and block until a stop signal. */ /* Worker threads, one proactor each, serving `port` with `handler` on every connection until - * SIGINT/SIGTERM. What ioma_run and ioma_run_pipes share. */ + * SIGINT/SIGTERM. What ioxd_run and ioxd_run_pipes share. */ static int run_workers(int workers, int port, handler_fn handler) { if (workers <= 0) workers = cpu_count(); if (port < 1 || port > 65535) { - fprintf(stderr, "ioma_run: 1<=port<=65535 required\n"); + fprintf(stderr, "ioxd_run: 1<=port<=65535 required\n"); return 2; } @@ -98,7 +98,7 @@ static int run_workers(int workers, int port, handler_fn handler) return 1; } } - fprintf(stderr, "ioma: %d workers on :%d\n", workers, port); + fprintf(stderr, "ioxd: %d workers on :%d\n", workers, port); for (int i = 0; i < workers; i++) pthread_join(th[i], nullptr); @@ -107,13 +107,13 @@ static int run_workers(int workers, int port, handler_fn handler) return 0; } -int ioma_run(int workers, int port) +int ioxd_run(int workers, int port) { - ioma__router_build(); /* the routes, resolved once, shared read-only */ - return run_workers(workers, port, ioma__serve); + ioxd__router_build(); /* the routes, resolved once, shared read-only */ + return run_workers(workers, port, ioxd__serve); } -int ioma_run_pipes(int workers, int port, ioma_pipe_handler fn) +int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn) { return run_workers(workers, port, fn); } diff --git a/lib/io/bufring.c b/lib/io/bufring.c index 57eceda..a53e4fd 100644 --- a/lib/io/bufring.c +++ b/lib/io/bufring.c @@ -20,7 +20,7 @@ static void *map_pages(size_t bytes) } /* Map the slab and the ring, register the ring as buffer group BGID, and offer every buffer. */ -void ioma__bufring_init(struct bufring *b, struct uring *ring, int worker) +void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker) { b->ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); b->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); @@ -40,7 +40,7 @@ void ioma__bufring_init(struct bufring *b, struct uring *ring, int worker) * sits in bufs[0].resv, so writing only addr/len/bid leaves it untouched. */ for (unsigned i = 0; i < BUF_COUNT; i++) { struct io_uring_buf *slot = &b->ring->bufs[i]; - slot->addr = (uint64_t)(uintptr_t)ioma__bufring_at(b, (uint16_t)i); + slot->addr = (uint64_t)(uintptr_t)ioxd__bufring_at(b, (uint16_t)i); slot->len = BUF_SIZE; slot->bid = (uint16_t)i; } @@ -50,10 +50,10 @@ void ioma__bufring_init(struct bufring *b, struct uring *ring, int worker) /* Stage a buffer's return to the ring. The loop publishes the tail once per batch: one atomic * release for many returns, and the kernel is not re-reading a hot tail per request. */ -void ioma__bufring_return(struct bufring *b, uint16_t buf_id) +void ioxd__bufring_return(struct bufring *b, uint16_t buf_id) { struct io_uring_buf *slot = &b->ring->bufs[b->tail & BUF_MASK]; - slot->addr = (uint64_t)(uintptr_t)ioma__bufring_at(b, buf_id); + slot->addr = (uint64_t)(uintptr_t)ioxd__bufring_at(b, buf_id); slot->len = BUF_SIZE; slot->bid = buf_id; b->tail++; @@ -62,7 +62,7 @@ void ioma__bufring_return(struct bufring *b, uint16_t buf_id) } /* Publish staged returns to the kernel. */ -void ioma__bufring_publish(struct bufring *b) +void ioxd__bufring_publish(struct bufring *b) { if (!b->dirty) return; @@ -71,7 +71,7 @@ void ioma__bufring_publish(struct bufring *b) } /* Unregister the group. Call before uring_exit. */ -void ioma__bufring_unregister(struct bufring *b, struct uring *ring) +void ioxd__bufring_unregister(struct bufring *b, struct uring *ring) { (void)b; struct io_uring_buf_reg reg; @@ -81,7 +81,7 @@ void ioma__bufring_unregister(struct bufring *b, struct uring *ring) } /* Unmap the ring and the slab. Call after uring_exit, once no in-flight op can reference them. */ -void ioma__bufring_unmap(struct bufring *b) +void ioxd__bufring_unmap(struct bufring *b) { munmap(b->ring, (size_t)BUF_COUNT * sizeof(struct io_uring_buf)); munmap(b->slab, (size_t)BUF_COUNT * BUF_SIZE); diff --git a/lib/io/bufring.h b/lib/io/bufring.h index 88031c1..0faca31 100644 --- a/lib/io/bufring.h +++ b/lib/io/bufring.h @@ -29,14 +29,14 @@ struct bufring { bool returned; /* any return since the loop's last starved sweep */ }; -void ioma__bufring_init (struct bufring *b, struct uring *ring, int worker); /* map, register, offer every buffer */ -void ioma__bufring_return (struct bufring *b, uint16_t buf_id); /* stage a buffer's return */ -void ioma__bufring_publish (struct bufring *b); /* the staged returns, one release */ -void ioma__bufring_unregister(struct bufring *b, struct uring *ring); /* before uring_exit */ -void ioma__bufring_unmap (struct bufring *b); /* after uring_exit */ +void ioxd__bufring_init (struct bufring *b, struct uring *ring, int worker); /* map, register, offer every buffer */ +void ioxd__bufring_return (struct bufring *b, uint16_t buf_id); /* stage a buffer's return */ +void ioxd__bufring_publish (struct bufring *b); /* the staged returns, one release */ +void ioxd__bufring_unregister(struct bufring *b, struct uring *ring); /* before uring_exit */ +void ioxd__bufring_unmap (struct bufring *b); /* after uring_exit */ /* Where a buffer's bytes are. */ -static inline uint8_t *ioma__bufring_at(const struct bufring *b, uint16_t buf_id) +static inline uint8_t *ioxd__bufring_at(const struct bufring *b, uint16_t buf_id) { return b->slab + (size_t)buf_id * BUF_SIZE; } diff --git a/lib/io/conn.c b/lib/io/conn.c index 9815ce2..6aa7247 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -26,7 +26,7 @@ static int await_op(struct io_uring_sqe *sqe, op_t *op) /* Ask the kernel to cancel the op carrying that user_data. The acknowledgement CQE is ignored. */ static void submit_cancel(proactor_t *p, uint64_t target_user_data) { - struct io_uring_sqe *sqe = ioma__sqe(p); + struct io_uring_sqe *sqe = ioxd__sqe(p); sqe->opcode = IORING_OP_ASYNC_CANCEL; sqe->fd = -1; sqe->addr = target_user_data; @@ -37,7 +37,7 @@ static void submit_cancel(proactor_t *p, uint64_t target_user_data) /* Take a conn_t from the pool (or calloc one) and reset it for a fresh fd. Two owners hold it: * the handler coroutine and the multishot recv, so refs starts at 2. */ -conn_t *ioma__conn_new(proactor_t *p, int fd) +conn_t *ioxd__conn_new(proactor_t *p, int fd) { conn_t *c = p->conn_free; if (c) { @@ -83,7 +83,7 @@ static void conn_unref(conn_t *c) } /* Free the pool at worker teardown. */ -void ioma__conn_pool_drain(proactor_t *p) +void ioxd__conn_pool_drain(proactor_t *p) { while (p->conn_free) { conn_t *c = p->conn_free; @@ -96,9 +96,9 @@ void ioma__conn_pool_drain(proactor_t *p) /* ── the recv side ─────────────────────────────────────────────────────────────────────── */ /* Arm the multishot recv: one SQE, then a CQE per arrival, each in a buffer the kernel picks. */ -void ioma__arm_recv(proactor_t *p, conn_t *c) +void ioxd__arm_recv(proactor_t *p, conn_t *c) { - struct io_uring_sqe *sqe = ioma__sqe(p); + struct io_uring_sqe *sqe = ioxd__sqe(p); sqe->opcode = IORING_OP_RECV; sqe->fd = c->fd; sqe->flags = IOSQE_BUFFER_SELECT | (p->ring.fixed_files ? IOSQE_FIXED_FILE : 0); @@ -128,7 +128,7 @@ static void note_starved(proactor_t *p) p->starved_since_log++; if (now.tv_sec < p->starved_log_at) return; - fprintf(stderr, "ioma: [w%d] recv found no provided buffer %llu times (%llu in total, %u connections parked): " + fprintf(stderr, "ioxd: [w%d] recv found no provided buffer %llu times (%llu in total, %u connections parked): " "raise BUF_COUNT (-DBUF_COUNT=..., now %d)\n", p->id, (unsigned long long)p->starved_since_log, (unsigned long long)p->starved_total, p->nstarved + 1, BUF_COUNT); p->starved_since_log = 0; @@ -164,7 +164,7 @@ static void starved_remove(proactor_t *p, conn_t *c) /* A recv CQE: queue the data and wake the reader, or record the end of input and drop the recv's * ref. -ENOBUFS is not an error: the buffer group ran dry, so park and re-arm later. */ -void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) +void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) { bool more = flags & IORING_CQE_F_MORE; bool has_buf = flags & IORING_CQE_F_BUFFER; @@ -187,7 +187,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) if (result <= 0) { /* peer FIN (0), an error, or our own cancel */ if (has_buf) - ioma__bufring_return(&p->bufs, buf_id); + ioxd__bufring_return(&p->bufs, buf_id); if (!c->eof) { c->eof = true; c->err = result; @@ -199,11 +199,11 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) } if (c->closed) { - ioma__bufring_return(&p->bufs, buf_id); /* the handler is gone; nobody will read it */ + ioxd__bufring_return(&p->bufs, buf_id); /* the handler is gone; nobody will read it */ } else if (c->rx_tail - c->rx_head == RX_QUEUE) { /* The handler is not draining. Rather than let one peer hoard the buffer group, end its * input: the next read sees -ENOBUFS. */ - ioma__bufring_return(&p->bufs, buf_id); + ioxd__bufring_return(&p->bufs, buf_id); if (!c->eof) { c->eof = true; c->err = -ENOBUFS; @@ -213,7 +213,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) wake_reader(c); } else { struct rx_item *item = &c->rx[c->rx_tail++ & RX_MASK]; - item->ptr = ioma__bufring_at(&p->bufs, buf_id); + item->ptr = ioxd__bufring_at(&p->bufs, buf_id); item->len = (uint32_t)result; item->buf_id = buf_id; wake_reader(c); @@ -221,7 +221,7 @@ void ioma__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) if (!more) { /* the kernel ended the multishot: re-arm */ if (!c->closed && !c->eof) { - ioma__arm_recv(p, c); + ioxd__arm_recv(p, c); } else { c->recv = RECV_DONE; conn_unref(c); @@ -239,7 +239,7 @@ static void close_socket(proactor_t *p, int fd) close(fd); return; } - struct io_uring_sqe *sqe = ioma__sqe(p); + struct io_uring_sqe *sqe = ioxd__sqe(p); sqe->opcode = IORING_OP_CLOSE; sqe->file_index = (uint32_t)fd + 1; /* slot + 1; 0 would mean "a real fd" */ sqe->user_data = TAG_IGNORE; @@ -262,22 +262,22 @@ static void conn_close(conn_t *c) c->refs--; /* the recv side's reference; ours, dropped last, keeps c alive */ } while (c->rx_head != c->rx_tail) - ioma__bufring_return(&p->bufs, c->rx[c->rx_head++ & RX_MASK].buf_id); + ioxd__bufring_return(&p->bufs, c->rx[c->rx_head++ & RX_MASK].buf_id); close_socket(p, c->fd); conn_unref(c); } /* The connection's coroutine: run the worker's handler to completion, then close. */ -void ioma__conn_main(void *arg) +void ioxd__conn_main(void *arg) { conn_t *c = arg; - char gather[IOMA_PIPE_GATHER]; - char slab[IOMA_PIPE_LEAD + IOMA_PIPE_CAP + IOMA_PIPE_SLACK]; - struct ioma_pipe pipe; - ioma__pipe_init(&pipe, c, gather, sizeof gather, slab, IOMA_PIPE_LEAD, IOMA_PIPE_CAP, IOMA_PIPE_SLACK); + char gather[IOXD_PIPE_GATHER]; + char slab[IOXD_PIPE_LEAD + IOXD_PIPE_CAP + IOXD_PIPE_SLACK]; + struct ioxd_pipe pipe; + ioxd__pipe_init(&pipe, c, gather, sizeof gather, slab, IOXD_PIPE_LEAD, IOXD_PIPE_CAP, IOXD_PIPE_SLACK); c->p->handler(&pipe); - ioma__pipe_close(&pipe); + ioxd__pipe_close(&pipe); conn_close(c); } @@ -285,9 +285,9 @@ void ioma__conn_main(void *arg) /* Copy the next delivered slice into buf, parking while the queue is empty. Returns the byte * count, 0 when the peer closed, or -errno. A fully consumed buffer goes back to the ring. */ -/* The next received buffer, whole: the caller owns it until ioma__bufring_return. Suspends until one +/* The next received buffer, whole: the caller owns it until ioxd__bufring_return. Suspends until one * arrives; 1 with the item, 0 at the end of input, <0 an error. */ -int ioma__await_item(conn_t *c, struct rx_item *out) +int ioxd__await_item(conn_t *c, struct rx_item *out) { for (;;) { if (c->rx_head != c->rx_tail) { @@ -298,7 +298,7 @@ int ioma__await_item(conn_t *c, struct rx_item *out) if (c->eof) return c->err; c->waiter = coro_current(); - coro_yield(); /* ioma__on_recv wakes us */ + coro_yield(); /* ioxd__on_recv wakes us */ } } @@ -310,7 +310,7 @@ int await_send(conn_t *c, const void *buf, size_t len) size_t left = len; while (left > 0) { op_t op; - struct io_uring_sqe *sqe = ioma__sqe(c->p); + struct io_uring_sqe *sqe = ioxd__sqe(c->p); sqe->opcode = IORING_OP_SEND; sqe->fd = c->fd; sqe->flags = c->p->ring.fixed_files ? IOSQE_FIXED_FILE : 0; diff --git a/lib/io/conn.h b/lib/io/conn.h index d5957c8..05afd47 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -53,11 +53,11 @@ struct conn { /* Awaits: call from a coroutine on the owning worker. The coroutine parks; the loop resumes it * when the completion arrives. */ int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ -int ioma__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno (the reader's primitive) */ +int ioxd__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno (the reader's primitive) */ /* For the loop (proactor.c): a connection's life from accept to the pool. */ -conn_t *ioma__conn_new(proactor_t *p, int fd); /* from the pool, or fresh */ -void ioma__conn_main(void *arg); /* the connection's coroutine body */ -void ioma__arm_recv(proactor_t *p, conn_t *c); /* one multishot recv */ -void ioma__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); /* a recv CQE */ -void ioma__conn_pool_drain(proactor_t *p); /* free the pool at teardown */ +conn_t *ioxd__conn_new(proactor_t *p, int fd); /* from the pool, or fresh */ +void ioxd__conn_main(void *arg); /* the connection's coroutine body */ +void ioxd__arm_recv(proactor_t *p, conn_t *c); /* one multishot recv */ +void ioxd__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); /* a recv CQE */ +void ioxd__conn_pool_drain(proactor_t *p); /* free the pool at teardown */ diff --git a/lib/io/pipe.c b/lib/io/pipe.c index dcaa928..936d944 100644 --- a/lib/io/pipe.c +++ b/lib/io/pipe.c @@ -8,39 +8,39 @@ /* ── the reader ────────────────────────────────────────────────────────────────────────── */ -void ioma_pipereader_init(ioma_pipereader *pr, conn_t *conn, char *buf, size_t cap) +void ioxd_pipereader_init(ioxd_pipereader *pr, conn_t *conn, char *buf, size_t cap) { - *pr = (ioma_pipereader){}; + *pr = (ioxd_pipereader){}; pr->conn = conn; pr->buf = buf; pr->cap = cap; } /* The live bytes: in buf, or in the current kernel buffer. */ -static ioma_slice live_span(const ioma_pipereader *pr) +static ioxd_slice live_span(const ioxd_pipereader *pr) { if (pr->live_in_buf) - return (ioma_slice){ pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos }; + return (ioxd_slice){ pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos }; if (pr->has_cur) - return (ioma_slice){ (const char *)pr->cur.ptr + pr->cur_pos, pr->cur.len - pr->cur_pos }; - return (ioma_slice){ nullptr, 0 }; + return (ioxd_slice){ (const char *)pr->cur.ptr + pr->cur_pos, pr->cur.len - pr->cur_pos }; + return (ioxd_slice){ nullptr, 0 }; } /* Let the current kernel buffer go once nothing is left in it, neither live bytes nor the run. * One that also holds frozen kept bytes lives on as `pinned`. */ -static void cur_done(ioma_pipereader *pr) +static void cur_done(ioxd_pipereader *pr) { if (!pr->has_cur || pr->cur_pos < pr->cur.len || (pr->run_in_cur && pr->run_len)) return; if (!pr->cur_is_pinned) - ioma__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); + ioxd__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); pr->has_cur = false; pr->cur_is_pinned = false; pr->cur_pos = 0; } /* Reclaim the bytes dropped from the front of buf's live region. */ -static void compact(ioma_pipereader *pr) +static void compact(ioxd_pipereader *pr) { if (pr->buf_pos > pr->floor) { memmove(pr->buf + pr->floor, pr->buf + pr->buf_pos, pr->buf_end - pr->buf_pos); @@ -50,7 +50,7 @@ static void compact(ioma_pipereader *pr) } /* Move the current buffer's run and live bytes into buf, so what follows can join them. */ -static bool gather(ioma_pipereader *pr) +static bool gather(ioxd_pipereader *pr) { size_t live = pr->has_cur ? pr->cur.len - pr->cur_pos : 0; size_t run = pr->run_in_cur ? pr->run_len : 0; @@ -75,25 +75,25 @@ static bool gather(ioma_pipereader *pr) } /* A buffer that cannot be used: back to the ring, and the reader is done. */ -static int refuse(ioma_pipereader *pr, const struct rx_item *item) +static int refuse(ioxd_pipereader *pr, const struct rx_item *item) { - ioma__bufring_return(&pr->conn->p->bufs, item->buf_id); - pr->error = IOMA_PIPE_FULL; - return IOMA_PIPE_FULL; + ioxd__bufring_return(&pr->conn->p->bufs, item->buf_id); + pr->error = IOXD_PIPE_FULL; + return IOXD_PIPE_FULL; } /* More bytes: the next kernel buffer, in place when nothing is live, else appended in buf. */ -static int more(ioma_pipereader *pr) +static int more(ioxd_pipereader *pr) { if (pr->eof) return 0; struct rx_item item; - int rc = ioma__await_item(pr->conn, &item); + int rc = ioxd__await_item(pr->conn, &item); if (rc <= 0) { pr->eof = true; if (rc < 0) - pr->error = IOMA_PIPE_GONE; - return rc < 0 ? IOMA_PIPE_GONE : 0; + pr->error = IOXD_PIPE_GONE; + return rc < 0 ? IOXD_PIPE_GONE : 0; } if (!pr->live_in_buf && !pr->has_cur) { /* nothing live: this buffer is the live span */ pr->cur = item; @@ -111,16 +111,16 @@ static int more(ioma_pipereader *pr) } memcpy(pr->buf + pr->buf_end, item.ptr, item.len); pr->buf_end += item.len; - ioma__bufring_return(&pr->conn->p->bufs, item.buf_id); + ioxd__bufring_return(&pr->conn->p->bufs, item.buf_id); return 1; } -int ioma_pipereader_read(ioma_pipereader *pr, ioma_slice *live) +int ioxd_pipereader_read(ioxd_pipereader *pr, ioxd_slice *live) { if (pr->error) return pr->error; for (;;) { - ioma_slice l = live_span(pr); + ioxd_slice l = live_span(pr); if (l.len > pr->examined) { *live = l; return 1; @@ -131,13 +131,13 @@ int ioma_pipereader_read(ioma_pipereader *pr, ioma_slice *live) } } -void ioma_pipereader_examine(ioma_pipereader *pr, size_t n) +void ioxd_pipereader_examine(ioxd_pipereader *pr, size_t n) { pr->examined = n; } /* Forget n live bytes of the current place. */ -static void consume(ioma_pipereader *pr, size_t n) +static void consume(ioxd_pipereader *pr, size_t n) { if (pr->live_in_buf) { pr->buf_pos += n; @@ -152,12 +152,12 @@ static void consume(ioma_pipereader *pr, size_t n) pr->examined = pr->examined > n ? pr->examined - n : 0; } -void ioma_pipereader_drop(ioma_pipereader *pr, size_t n) +void ioxd_pipereader_drop(ioxd_pipereader *pr, size_t n) { consume(pr, n); } -const char *ioma_pipereader_keep(ioma_pipereader *pr, size_t n) +const char *ioxd_pipereader_keep(ioxd_pipereader *pr, size_t n) { const char *kept; if (pr->live_in_buf) { @@ -181,7 +181,7 @@ const char *ioma_pipereader_keep(ioma_pipereader *pr, size_t n) kept = (const char *)pr->cur.ptr + run_end; } else if (pr->has_cur) { /* the run is in buf, the live bytes are not: copy across */ if (pr->floor + n > pr->cap) { - pr->error = IOMA_PIPE_FULL; + pr->error = IOXD_PIPE_FULL; return nullptr; } memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->cur_pos, n); @@ -195,12 +195,12 @@ const char *ioma_pipereader_keep(ioma_pipereader *pr, size_t n) return kept; } -void ioma_pipereader_run_begin(ioma_pipereader *pr) +void ioxd_pipereader_run_begin(ioxd_pipereader *pr) { if (pr->run_in_cur && pr->run_len) { if (pr->has_pinned && !pr->cur_is_pinned) { /* another buffer is pinned already: this run moves to buf */ if (pr->floor + pr->run_len > pr->cap) { - pr->error = IOMA_PIPE_FULL; + pr->error = IOXD_PIPE_FULL; } else { memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->run_start, pr->run_len); pr->floor += pr->run_len; @@ -216,13 +216,13 @@ void ioma_pipereader_run_begin(ioma_pipereader *pr) cur_done(pr); } -ioma_slice ioma_pipereader_run(const ioma_pipereader *pr) +ioxd_slice ioxd_pipereader_run(const ioxd_pipereader *pr) { const char *base = pr->run_in_cur ? (const char *)pr->cur.ptr : pr->buf; - return (ioma_slice){ base + pr->run_start, pr->run_len }; + return (ioxd_slice){ base + pr->run_start, pr->run_len }; } -void ioma_pipereader_release(ioma_pipereader *pr) +void ioxd_pipereader_release(ioxd_pipereader *pr) { pr->run_len = 0; pr->run_in_cur = false; @@ -238,27 +238,27 @@ void ioma_pipereader_release(ioma_pipereader *pr) if (pr->cur_is_pinned) pr->cur_is_pinned = false; /* it lives on as the current buffer */ else - ioma__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); + ioxd__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); pr->has_pinned = false; } cur_done(pr); } -void ioma_pipereader_close(ioma_pipereader *pr) +void ioxd_pipereader_close(ioxd_pipereader *pr) { if (pr->has_cur && !pr->cur_is_pinned) - ioma__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); + ioxd__bufring_return(&pr->conn->p->bufs, pr->cur.buf_id); if (pr->has_pinned) - ioma__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); + ioxd__bufring_return(&pr->conn->p->bufs, pr->pinned.buf_id); pr->has_cur = pr->has_pinned = pr->cur_is_pinned = false; } -int ioma_pipereader_copy(ioma_pipereader *pr, void *dst, size_t n) +int ioxd_pipereader_copy(ioxd_pipereader *pr, void *dst, size_t n) { if (pr->error) return pr->error; for (;;) { - ioma_slice l = live_span(pr); + ioxd_slice l = live_span(pr); if (l.len) { size_t k = l.len < n ? l.len : n; memcpy(dst, l.p, k); @@ -273,9 +273,9 @@ int ioma_pipereader_copy(ioma_pipereader *pr, void *dst, size_t n) /* ── the writer ────────────────────────────────────────────────────────────────────────── */ -void ioma_pipewriter_init(ioma_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack) +void ioxd_pipewriter_init(ioxd_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack) { - *pw = (ioma_pipewriter){}; + *pw = (ioxd_pipewriter){}; pw->conn = conn; pw->buf = buf; pw->lead = lead; @@ -283,12 +283,12 @@ void ioma_pipewriter_init(ioma_pipewriter *pw, conn_t *conn, char *buf, size_t l pw->slack = slack; } -void ioma_pipewriter_reset(ioma_pipewriter *pw) +void ioxd_pipewriter_reset(ioxd_pipewriter *pw) { pw->head = pw->len = pw->tail = 0; } -int ioma_pipewriter_flush(ioma_pipewriter *pw) +int ioxd_pipewriter_flush(ioxd_pipewriter *pw) { if (pw->failed) return -1; @@ -304,21 +304,21 @@ int ioma_pipewriter_flush(ioma_pipewriter *pw) return 0; } -void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n) +void *ioxd_pipewriter_reserve(ioxd_pipewriter *pw, size_t n) { if (pw->failed || n > pw->cap) return nullptr; - if (pw->len + n > pw->cap && ioma_pipewriter_flush(pw) < 0) + if (pw->len + n > pw->cap && ioxd_pipewriter_flush(pw) < 0) return nullptr; - return ioma_pipewriter_at(pw); + return ioxd_pipewriter_at(pw); } -void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n) +void ioxd_pipewriter_advance(ioxd_pipewriter *pw, size_t n) { pw->len += n; } -char *ioma_pipewriter_front(ioma_pipewriter *pw, size_t n) +char *ioxd_pipewriter_front(ioxd_pipewriter *pw, size_t n) { if (n > pw->lead - pw->head) return nullptr; @@ -326,7 +326,7 @@ char *ioma_pipewriter_front(ioma_pipewriter *pw, size_t n) return pw->buf + pw->lead - pw->head; } -char *ioma_pipewriter_back(ioma_pipewriter *pw, size_t n) +char *ioxd_pipewriter_back(ioxd_pipewriter *pw, size_t n) { if (n > pw->slack - pw->tail) return nullptr; @@ -335,7 +335,7 @@ char *ioma_pipewriter_back(ioma_pipewriter *pw, size_t n) return at; } -int ioma_pipewriter_through(ioma_pipewriter *pw, const void *data, size_t n) +int ioxd_pipewriter_through(ioxd_pipewriter *pw, const void *data, size_t n) { if (pw->failed) return -1; @@ -346,13 +346,13 @@ int ioma_pipewriter_through(ioma_pipewriter *pw, const void *data, size_t n) return 0; } -int ioma_pipewriter_write(ioma_pipewriter *pw, const void *data, size_t n) +int ioxd_pipewriter_write(ioxd_pipewriter *pw, const void *data, size_t n) { if (pw->failed) return -1; if (n > pw->cap) /* larger than the slab: straight from the caller's memory */ - return ioma_pipewriter_flush(pw) < 0 ? -1 : ioma_pipewriter_through(pw, data, n); - void *at = ioma_pipewriter_reserve(pw, n); + return ioxd_pipewriter_flush(pw) < 0 ? -1 : ioxd_pipewriter_through(pw, data, n); + void *at = ioxd_pipewriter_reserve(pw, n); if (!at) return -1; memcpy(at, data, n); @@ -360,32 +360,32 @@ int ioma_pipewriter_write(ioma_pipewriter *pw, const void *data, size_t n) return 0; } -int ioma_pipewriter_send(ioma_pipewriter *pw, const void *data, size_t n) +int ioxd_pipewriter_send(ioxd_pipewriter *pw, const void *data, size_t n) { - return ioma_pipewriter_write(pw, data, n) < 0 ? -1 : ioma_pipewriter_flush(pw); + return ioxd_pipewriter_write(pw, data, n) < 0 ? -1 : ioxd_pipewriter_flush(pw); } /* ── the pipe ──────────────────────────────────────────────────────────────────────────── */ -void ioma__pipe_init(struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack) +void ioxd__pipe_init(struct ioxd_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack) { - ioma_pipereader_init(&p->in, conn, gather, gather_cap); - ioma_pipewriter_init(&p->out, conn, slab, lead, cap, slack); + ioxd_pipereader_init(&p->in, conn, gather, gather_cap); + ioxd_pipewriter_init(&p->out, conn, slab, lead, cap, slack); } -void ioma__pipe_close(struct ioma_pipe *p) +void ioxd__pipe_close(struct ioxd_pipe *p) { - ioma_pipereader_close(&p->in); + ioxd_pipereader_close(&p->in); } -int ioma_pipe_read (ioma_pipe *p, ioma_slice *live) { return ioma_pipereader_read(&p->in, live); } -void ioma_pipe_examine(ioma_pipe *p, size_t n) { ioma_pipereader_examine(&p->in, n); } -void ioma_pipe_drop (ioma_pipe *p, size_t n) { ioma_pipereader_drop(&p->in, n); } -const char *ioma_pipe_keep (ioma_pipe *p, size_t n) { return ioma_pipereader_keep(&p->in, n); } -void ioma_pipe_release(ioma_pipe *p) { ioma_pipereader_release(&p->in); } -int ioma_pipe_copy (ioma_pipe *p, void *dst, size_t n) { return ioma_pipereader_copy(&p->in, dst, n); } -void *ioma_pipe_reserve(ioma_pipe *p, size_t n) { return ioma_pipewriter_reserve(&p->out, n); } -void ioma_pipe_advance(ioma_pipe *p, size_t n) { ioma_pipewriter_advance(&p->out, n); } -int ioma_pipe_write (ioma_pipe *p, const void *data, size_t n) { return ioma_pipewriter_write(&p->out, data, n); } -int ioma_pipe_flush (ioma_pipe *p) { return ioma_pipewriter_flush(&p->out); } -int ioma_pipe_send (ioma_pipe *p, const void *data, size_t n) { return ioma_pipewriter_send(&p->out, data, n); } +int ioxd_pipe_read (ioxd_pipe *p, ioxd_slice *live) { return ioxd_pipereader_read(&p->in, live); } +void ioxd_pipe_examine(ioxd_pipe *p, size_t n) { ioxd_pipereader_examine(&p->in, n); } +void ioxd_pipe_drop (ioxd_pipe *p, size_t n) { ioxd_pipereader_drop(&p->in, n); } +const char *ioxd_pipe_keep (ioxd_pipe *p, size_t n) { return ioxd_pipereader_keep(&p->in, n); } +void ioxd_pipe_release(ioxd_pipe *p) { ioxd_pipereader_release(&p->in); } +int ioxd_pipe_copy (ioxd_pipe *p, void *dst, size_t n) { return ioxd_pipereader_copy(&p->in, dst, n); } +void *ioxd_pipe_reserve(ioxd_pipe *p, size_t n) { return ioxd_pipewriter_reserve(&p->out, n); } +void ioxd_pipe_advance(ioxd_pipe *p, size_t n) { ioxd_pipewriter_advance(&p->out, n); } +int ioxd_pipe_write (ioxd_pipe *p, const void *data, size_t n) { return ioxd_pipewriter_write(&p->out, data, n); } +int ioxd_pipe_flush (ioxd_pipe *p) { return ioxd_pipewriter_flush(&p->out); } +int ioxd_pipe_send (ioxd_pipe *p, const void *data, size_t n) { return ioxd_pipewriter_send(&p->out, data, n); } diff --git a/lib/io/pipe.h b/lib/io/pipe.h index 2e2fdb5..ae17dcf 100644 --- a/lib/io/pipe.h +++ b/lib/io/pipe.h @@ -2,11 +2,11 @@ * io/pipe.h - a connection as a pipe: a reader over the buffers the kernel filled and a writer * over a slab. Every call that must wait suspends the calling coroutine and the worker's loop * resumes it on the completion, so the same code drives any connection the I/O plane runs. The - * HTTP engine reads through the reader; ioma_run_pipes hands a pipe to a handler of your own. + * HTTP engine reads through the reader; ioxd_run_pipes hands a pipe to a handler of your own. */ #pragma once -#include "ioma.h" +#include "ioxd.h" #include "io/conn.h" /* The reader hands out received bytes as one contiguous span at a time: in place in the kernel's @@ -17,7 +17,7 @@ * bytes and the run in progress. */ // BUF_SIZE can be increased to keep entire requests in a single rx_item, avoiding buffering -typedef struct ioma_pipereader { +typedef struct ioxd_pipereader { conn_t *conn; char *buf; /* the gathering buffer, the consumer's */ size_t cap; @@ -34,25 +34,25 @@ typedef struct ioma_pipereader { size_t run_start, run_len; size_t examined; /* live bytes the consumer looked at without consuming */ bool eof; - int error; /* 0, or IOMA_PIPE_GONE / IOMA_PIPE_FULL, sticky */ -} ioma_pipereader; + int error; /* 0, or IOXD_PIPE_GONE / IOXD_PIPE_FULL, sticky */ +} ioxd_pipereader; -void ioma_pipereader_init (ioma_pipereader *pr, conn_t *conn, char *buf, size_t cap); -void ioma_pipereader_close (ioma_pipereader *pr); /* returns the buffers it holds */ -int ioma_pipereader_read (ioma_pipereader *pr, ioma_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ -void ioma_pipereader_examine (ioma_pipereader *pr, size_t n); /* looked at n live bytes: the next read waits for more */ -void ioma_pipereader_drop (ioma_pipereader *pr, size_t n); /* consume n live bytes */ -const char *ioma_pipereader_keep (ioma_pipereader *pr, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ -void ioma_pipereader_run_begin(ioma_pipereader *pr); /* freeze the run; the next keep starts another */ -ioma_slice ioma_pipereader_run (const ioma_pipereader *pr); /* the run in progress */ -void ioma_pipereader_release (ioma_pipereader *pr); /* forget every kept byte; live bytes stay */ -int ioma_pipereader_copy (ioma_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ +void ioxd_pipereader_init (ioxd_pipereader *pr, conn_t *conn, char *buf, size_t cap); +void ioxd_pipereader_close (ioxd_pipereader *pr); /* returns the buffers it holds */ +int ioxd_pipereader_read (ioxd_pipereader *pr, ioxd_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ +void ioxd_pipereader_examine (ioxd_pipereader *pr, size_t n); /* looked at n live bytes: the next read waits for more */ +void ioxd_pipereader_drop (ioxd_pipereader *pr, size_t n); /* consume n live bytes */ +const char *ioxd_pipereader_keep (ioxd_pipereader *pr, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ +void ioxd_pipereader_run_begin(ioxd_pipereader *pr); /* freeze the run; the next keep starts another */ +ioxd_slice ioxd_pipereader_run (const ioxd_pipereader *pr); /* the run in progress */ +void ioxd_pipereader_release (ioxd_pipereader *pr); /* forget every kept byte; live bytes stay */ +int ioxd_pipereader_copy (ioxd_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ /* The writer: a slab with a head and a tail. Data goes in at the tail (reserve/advance, or write); * a frame's front goes into the lead just before the pending data and its back into the slack just * after it, and one flush sends the whole span. The HTTP reply puts its head and a chunk's size * line in front and a chunk's CRLF behind; a raw pipe may never touch them. */ -typedef struct ioma_pipewriter { +typedef struct ioxd_pipewriter { conn_t *conn; char *buf; /* [lead][cap][slack] */ size_t lead, cap, slack; @@ -60,46 +60,46 @@ typedef struct ioma_pipewriter { size_t len; /* data bytes */ size_t tail; /* bytes of the slack in use: a frame's back */ bool failed; /* the peer is gone: every call fails from here on */ -} ioma_pipewriter; +} ioxd_pipewriter; -void ioma_pipewriter_init (ioma_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack); -void ioma_pipewriter_reset (ioma_pipewriter *pw); /* drop everything pending */ -void *ioma_pipewriter_reserve(ioma_pipewriter *pw, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ -void ioma_pipewriter_advance(ioma_pipewriter *pw, size_t n); -char *ioma_pipewriter_front (ioma_pipewriter *pw, size_t n); /* n bytes just before the pending span; nullptr when the lead has no room */ -char *ioma_pipewriter_back (ioma_pipewriter *pw, size_t n); /* n bytes just after it; nullptr when the slack has no room */ -int ioma_pipewriter_write (ioma_pipewriter *pw, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ -int ioma_pipewriter_through(ioma_pipewriter *pw, const void *data, size_t n); /* send now, ahead of the pending span, bypassing the slab */ -int ioma_pipewriter_flush (ioma_pipewriter *pw); /* send front, data and back; suspends */ -int ioma_pipewriter_send (ioma_pipewriter *pw, const void *data, size_t n); /* write, then flush */ +void ioxd_pipewriter_init (ioxd_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack); +void ioxd_pipewriter_reset (ioxd_pipewriter *pw); /* drop everything pending */ +void *ioxd_pipewriter_reserve(ioxd_pipewriter *pw, size_t n); /* n bytes at the tail, flushing first when they do not fit; nullptr on failure or n > cap */ +void ioxd_pipewriter_advance(ioxd_pipewriter *pw, size_t n); +char *ioxd_pipewriter_front (ioxd_pipewriter *pw, size_t n); /* n bytes just before the pending span; nullptr when the lead has no room */ +char *ioxd_pipewriter_back (ioxd_pipewriter *pw, size_t n); /* n bytes just after it; nullptr when the slack has no room */ +int ioxd_pipewriter_write (ioxd_pipewriter *pw, const void *data, size_t n); /* copy in; larger than the slab goes straight out */ +int ioxd_pipewriter_through(ioxd_pipewriter *pw, const void *data, size_t n); /* send now, ahead of the pending span, bypassing the slab */ +int ioxd_pipewriter_flush (ioxd_pipewriter *pw); /* send front, data and back; suspends */ +int ioxd_pipewriter_send (ioxd_pipewriter *pw, const void *data, size_t n); /* write, then flush */ /* Where the next byte goes, and how many fit before the slab is full. */ -static inline char *ioma_pipewriter_at(const ioma_pipewriter *pw) +static inline char *ioxd_pipewriter_at(const ioxd_pipewriter *pw) { return pw->buf + pw->lead + pw->len; } -static inline size_t ioma_pipewriter_room(const ioma_pipewriter *pw) +static inline size_t ioxd_pipewriter_room(const ioxd_pipewriter *pw) { return pw->cap - pw->len; } -/* The pair every handler receives, HTTP or raw (the public ioma_pipe). Its buffers live on the +/* The pair every handler receives, HTTP or raw (the public ioxd_pipe). Its buffers live on the * connection's coroutine stack. */ -#ifndef IOMA_PIPE_GATHER -#define IOMA_PIPE_GATHER 16384 /* the reader's gathering buffer: kept plus live bytes */ +#ifndef IOXD_PIPE_GATHER +#define IOXD_PIPE_GATHER 16384 /* the reader's gathering buffer: kept plus live bytes */ #endif -#ifndef IOMA_PIPE_LEAD -#define IOMA_PIPE_LEAD 512 /* in front of the slab: a frame's front */ +#ifndef IOXD_PIPE_LEAD +#define IOXD_PIPE_LEAD 512 /* in front of the slab: a frame's front */ #endif -#ifndef IOMA_PIPE_CAP -#define IOMA_PIPE_CAP 8192 /* the slab: bytes buffered before a flush */ +#ifndef IOXD_PIPE_CAP +#define IOXD_PIPE_CAP 8192 /* the slab: bytes buffered before a flush */ #endif -#ifndef IOMA_PIPE_SLACK -#define IOMA_PIPE_SLACK 8 /* behind the slab: a frame's back */ +#ifndef IOXD_PIPE_SLACK +#define IOXD_PIPE_SLACK 8 /* behind the slab: a frame's back */ #endif -struct ioma_pipe { - ioma_pipereader in; - ioma_pipewriter out; +struct ioxd_pipe { + ioxd_pipereader in; + ioxd_pipewriter out; }; -void ioma__pipe_init (struct ioma_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack); -void ioma__pipe_close(struct ioma_pipe *p); +void ioxd__pipe_init (struct ioxd_pipe *p, conn_t *conn, char *gather, size_t gather_cap, char *slab, size_t lead, size_t cap, size_t slack); +void ioxd__pipe_close(struct ioxd_pipe *p); diff --git a/lib/io/proactor.c b/lib/io/proactor.c index be14a57..5cb3ea8 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -19,7 +19,7 @@ /* ── submission ────────────────────────────────────────────────────────────────────────── */ /* Claim an SQE. If the SQ is full mid-batch, flush without waiting and retry. */ -struct io_uring_sqe *ioma__sqe(proactor_t *p) +struct io_uring_sqe *ioxd__sqe(proactor_t *p) { struct io_uring_sqe *sqe = uring_get_sqe(&p->ring); for (int i = 0; !sqe && i < 16; i++) { @@ -38,7 +38,7 @@ struct io_uring_sqe *ioma__sqe(proactor_t *p) /* Arm the multishot accept: one SQE, then a CQE per new connection. */ static void arm_accept(proactor_t *p) { - struct io_uring_sqe *sqe = ioma__sqe(p); + struct io_uring_sqe *sqe = ioxd__sqe(p); sqe->opcode = IORING_OP_ACCEPT; sqe->fd = p->listen_fd; sqe->ioprio = IORING_ACCEPT_MULTISHOT; @@ -52,9 +52,9 @@ static void on_accept(proactor_t *p, int result, unsigned flags) { trace("[w%d] accept result=%d more=%d\n", p->id, result, !!(flags & IORING_CQE_F_MORE)); if (result >= 0) { - conn_t *c = ioma__conn_new(p, result); /* TCP_NODELAY came with the listener */ - ioma__arm_recv(p, c); - proactor_spawn(p, ioma__conn_main, c); + conn_t *c = ioxd__conn_new(p, result); /* TCP_NODELAY came with the listener */ + ioxd__arm_recv(p, c); + proactor_spawn(p, ioxd__conn_main, c); p->accepted++; } else { fprintf(stderr, "[w%d] accept: %s\n", p->id, strerror(-result)); @@ -79,7 +79,7 @@ static void dispatch(proactor_t *p, struct io_uring_cqe *cqe) break; } case TAG_RECV: - ioma__on_recv(p, ptr, cqe->res, cqe->flags); + ioxd__on_recv(p, ptr, cqe->res, cqe->flags); break; case TAG_ACCEPT: on_accept(p, cqe->res, cqe->flags); @@ -123,7 +123,7 @@ static void rearm_starved(proactor_t *p) return; p->bufs.returned = false; for (unsigned i = 0; i < p->nstarved; i++) - ioma__arm_recv(p, p->starved[i]); /* keeps the ref it already holds */ + ioxd__arm_recv(p, p->starved[i]); /* keeps the ref it already holds */ p->nstarved = 0; } @@ -219,7 +219,7 @@ void proactor_run(proactor_t *p) unsigned slots = fixed_slots(); /* optional: sockets live in a file table */ if (slots) uring_register_files_sparse(&p->ring, slots); - ioma__bufring_init(&p->bufs, &p->ring, p->id); + ioxd__bufring_init(&p->bufs, &p->ring, p->id); p->listen_fd = listener_open(p->port); arm_accept(p); fprintf(stderr, "[w%d] listening on 0.0.0.0:%u (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", @@ -232,7 +232,7 @@ void proactor_run(proactor_t *p) while (!*p->stop) { run_ready(p); rearm_starved(p); - ioma__bufring_publish(&p->bufs); + ioxd__bufring_publish(&p->bufs); rc = uring_submit_wait(&p->ring, 1, &wait_at_most); /* one syscall per batch */ if (rc < 0 && rc != -ETIME && rc != -EINTR && rc != -EAGAIN && rc != -EBUSY) { @@ -252,10 +252,10 @@ void proactor_run(proactor_t *p) /* Sockets, then the ring (which cancels every in-flight op and drops its buffer references), * then the memory the kernel could still have referenced. */ close(p->listen_fd); - ioma__bufring_unregister(&p->bufs, &p->ring); + ioxd__bufring_unregister(&p->bufs, &p->ring); uring_exit(&p->ring); - ioma__bufring_unmap(&p->bufs); + ioxd__bufring_unmap(&p->bufs); free(p->starved); - ioma__conn_pool_drain(p); + ioxd__conn_pool_drain(p); coro_pool_drain(); } diff --git a/lib/io/proactor.h b/lib/io/proactor.h index fe8c968..efd48bf 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -31,8 +31,8 @@ #endif typedef struct proactor proactor_t; -struct ioma_pipe; -typedef void (*handler_fn)(struct ioma_pipe *pipe); /* a connection, as a pipe */ +struct ioxd_pipe; +typedef void (*handler_fn)(struct ioxd_pipe *pipe); /* a connection, as a pipe */ struct proactor { /* set by the creator */ @@ -66,4 +66,4 @@ void proactor_spawn(proactor_t *p, void (*fn)(void *), void *arg); /* Claim an SQE to stage an operation; flushes without waiting when the SQ is full. For the * plane's own files: every op goes through here so it rides the loop's next enter. */ -struct io_uring_sqe *ioma__sqe(proactor_t *p); +struct io_uring_sqe *ioxd__sqe(proactor_t *p); diff --git a/lib/json/json.c b/lib/json/json.c index 1634b8d..af311d0 100644 --- a/lib/json/json.c +++ b/lib/json/json.c @@ -1,9 +1,9 @@ /* - * json/json.c - the forward-only JSON writer of ioma.h. Every value goes straight to the sink: + * json/json.c - the forward-only JSON writer of ioxd.h. Every value goes straight to the sink: * a run of safe bytes at a time, an escape at a time, a number formatted into a small stack * buffer. The sink is the reply, a raw pipe, or a buffer; the writer never allocates. */ -#include "ioma.h" +#include "ioxd.h" #include #include @@ -14,27 +14,27 @@ #define RUN_MAX 1024 /* bytes asked of the sink at a time */ /* n bytes of the sink to write into, or nullptr; the caller then advances by what it wrote. */ -static char *reserve(ioma_json *j, size_t n) +static char *reserve(ioxd_json *j, size_t n) { switch (j->kind) { - case IOMA_JSON_TO_REPLY: return ioma_reserve(j->to.ctx, n); - case IOMA_JSON_TO_PIPE: return ioma_pipe_reserve(j->to.pipe, n); - case IOMA_JSON_TO_MEM: return *j->to.mem.len + n <= j->to.mem.cap ? j->to.mem.p + *j->to.mem.len : nullptr; + case IOXD_JSON_TO_REPLY: return ioxd_reserve(j->to.ctx, n); + case IOXD_JSON_TO_PIPE: return ioxd_pipe_reserve(j->to.pipe, n); + case IOXD_JSON_TO_MEM: return *j->to.mem.len + n <= j->to.mem.cap ? j->to.mem.p + *j->to.mem.len : nullptr; } return nullptr; } -static void advance(ioma_json *j, size_t n) +static void advance(ioxd_json *j, size_t n) { switch (j->kind) { - case IOMA_JSON_TO_REPLY: ioma_advance(j->to.ctx, n); break; - case IOMA_JSON_TO_PIPE: ioma_pipe_advance(j->to.pipe, n); break; - case IOMA_JSON_TO_MEM: *j->to.mem.len += n; break; + case IOXD_JSON_TO_REPLY: ioxd_advance(j->to.ctx, n); break; + case IOXD_JSON_TO_PIPE: ioxd_pipe_advance(j->to.pipe, n); break; + case IOXD_JSON_TO_MEM: *j->to.mem.len += n; break; } } /* Raw bytes to the sink, in runs the slab can take; false marks the writer failed. */ -static bool put(ioma_json *j, const char *p, size_t n) +static bool put(ioxd_json *j, const char *p, size_t n) { while (n) { size_t run = n < RUN_MAX ? n : RUN_MAX; @@ -51,7 +51,7 @@ static bool put(ioma_json *j, const char *p, size_t n) return true; } -static bool put_cstr(ioma_json *j, const char *s) +static bool put_cstr(ioxd_json *j, const char *s) { return put(j, s, strlen(s)); } @@ -63,7 +63,7 @@ static bool needs_escape(unsigned char c) } /* A string, quoted and escaped: safe runs are copied whole, escapes one at a time. */ -static bool put_string(ioma_json *j, const char *p, size_t n) +static bool put_string(ioxd_json *j, const char *p, size_t n) { static const char hex[] = "0123456789abcdef"; if (!put(j, "\"", 1)) @@ -106,7 +106,7 @@ static bool put_string(ioma_json *j, const char *p, size_t n) } /* Before a value: the comma its level owes, unless it follows a key. */ -static bool separator(ioma_json *j) +static bool separator(ioxd_json *j) { if (j->failed) return false; @@ -123,24 +123,24 @@ static bool separator(ioma_json *j) /* ── the sinks ─────────────────────────────────────────────────────────────────────────── */ -ioma_json ioma_json_reply(ioma_ctx *ctx) +ioxd_json ioxd_json_reply(ioxd_ctx *ctx) { - ioma_content_type(ctx, "application/json"); - ioma_json j = { .kind = IOMA_JSON_TO_REPLY }; + ioxd_content_type(ctx, "application/json"); + ioxd_json j = { .kind = IOXD_JSON_TO_REPLY }; j.to.ctx = ctx; return j; } -ioma_json ioma_json_pipe(struct ioma_pipe *pipe) +ioxd_json ioxd_json_pipe(struct ioxd_pipe *pipe) { - ioma_json j = { .kind = IOMA_JSON_TO_PIPE }; + ioxd_json j = { .kind = IOXD_JSON_TO_PIPE }; j.to.pipe = pipe; return j; } -ioma_json ioma_json_mem(char *buf, size_t cap, size_t *len) +ioxd_json ioxd_json_mem(char *buf, size_t cap, size_t *len) { - ioma_json j = { .kind = IOMA_JSON_TO_MEM }; + ioxd_json j = { .kind = IOXD_JSON_TO_MEM }; j.to.mem.p = buf; j.to.mem.cap = cap; j.to.mem.len = len; @@ -151,11 +151,11 @@ ioma_json ioma_json_mem(char *buf, size_t cap, size_t *len) /* ── the values ────────────────────────────────────────────────────────────────────────── */ /* Open a container: its own level starts empty. */ -static bool open_level(ioma_json *j, char bracket) +static bool open_level(ioxd_json *j, char bracket) { if (!separator(j)) return false; - if (j->depth == IOMA_JSON_DEPTH) { + if (j->depth == IOXD_JSON_DEPTH) { j->failed = true; return false; } @@ -169,19 +169,19 @@ static bool open_level(ioma_json *j, char bracket) return put(j, &bracket, 1); } -bool ioma_json_object(ioma_json *j) +bool ioxd_json_object(ioxd_json *j) { return open_level(j, '{'); } -bool ioma_json_array(ioma_json *j) +bool ioxd_json_array(ioxd_json *j) { return open_level(j, '['); } /* Close the innermost container. Which bracket is remembered by what was written: an object's * level is one that took keys - tracked as a bit too. */ -bool ioma_json_end(ioma_json *j) +bool ioxd_json_end(ioxd_json *j) { if (j->failed || j->depth == 0) return false; @@ -191,7 +191,7 @@ bool ioma_json_end(ioma_json *j) return put(j, object ? "}" : "]", 1); } -bool ioma_json_key(ioma_json *j, const char *name) +bool ioxd_json_key(ioxd_json *j, const char *name) { if (!separator(j)) return false; @@ -201,12 +201,12 @@ bool ioma_json_key(ioma_json *j, const char *name) return true; } -bool ioma_json_string(ioma_json *j, ioma_slice s) +bool ioxd_json_string(ioxd_json *j, ioxd_slice s) { return separator(j) && put_string(j, s.p, s.len); } -bool ioma_json_cstr(ioma_json *j, const char *s) +bool ioxd_json_cstr(ioxd_json *j, const char *s) { return separator(j) && put_string(j, s, strlen(s)); } @@ -222,14 +222,14 @@ static char *digits(char *tmp_end, uint64_t v) return p; } -bool ioma_json_uint(ioma_json *j, uint64_t v) +bool ioxd_json_uint(ioxd_json *j, uint64_t v) { char tmp[24]; char *p = digits(tmp + sizeof tmp, v); return separator(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); } -bool ioma_json_int(ioma_json *j, int64_t v) +bool ioxd_json_int(ioxd_json *j, int64_t v) { char tmp[24]; uint64_t magnitude = v < 0 ? (uint64_t)(-(v + 1)) + 1 : (uint64_t)v; /* INT64_MIN has no positive twin */ @@ -241,10 +241,10 @@ bool ioma_json_int(ioma_json *j, int64_t v) /* The shortest decimal that reads back as the same double: 15, 16 or 17 significant digits, the * first that round-trips. snprintf follows the locale's decimal point; JSON wants '.'. */ -bool ioma_json_double(ioma_json *j, double v) +bool ioxd_json_double(ioxd_json *j, double v) { if (!isfinite(v)) - return ioma_json_null(j); + return ioxd_json_null(j); char tmp[32]; int n = 0; for (int precision = 15; precision <= 17; precision++) { @@ -265,17 +265,17 @@ bool ioma_json_double(ioma_json *j, double v) return separator(j) && put(j, tmp, (size_t)n); } -bool ioma_json_bool(ioma_json *j, bool v) +bool ioxd_json_bool(ioxd_json *j, bool v) { return separator(j) && put_cstr(j, v ? "true" : "false"); } -bool ioma_json_null(ioma_json *j) +bool ioxd_json_null(ioxd_json *j) { return separator(j) && put_cstr(j, "null"); } -bool ioma_json_raw(ioma_json *j, ioma_slice json) +bool ioxd_json_raw(ioxd_json *j, ioxd_slice json) { return separator(j) && put(j, json.p, json.len); } diff --git a/libioma.a b/libioma.a new file mode 100644 index 0000000000000000000000000000000000000000..86d964560208748b6a13a6e39a0cc77ebfc95d2b GIT binary patch literal 1237342 zcmc$_cRbZ!{5bx)=Cx-T*(-aKjO>}crMfPzJ+Es-iR>gJil!ARN{UL#NEsnS%1TNl zBcmiL-}8E1>s_Dk@B15n{PcL8`+T1Bd_K=}o#*S^drti7SiGCpK57}h|NhBtLy7SA zmXA+fX|Fty#DyAypkok3UG;zKK`Bc^e?KHN;?O_Ory7XlfAf%q%R?Ivh2#?S|M!DV z@PYnM56$7z(Erzmw&pza|Ma0Bw1?n_(HsvkI-LFIVM;j<{l9!d@!kQR7(C9?JA{D4 zLqya&z?-lRZj4|MIuG~1yFI-9a3PqGAS^xvw?2l8*yQ%a5ilXa8v`MsuKt@tL&=2E|$9e}4$MCq2 zQ2+I@Bi=YacgQ=?AB(}bhI$}IAlCi23y&j&;sgGo3kr4h^A7R)t2Z=Y!zKR=_+x|C z``iKp0x$u%@a^a}HHnjB@&3SIx3G1hz<})-BEcWFX`L8$6vmr?^M|kq7=jDfFbwu^ z5Izv=MhL{ip$HGyLh+&N5`w&gaIkxEc+8dqwspc|#JRS0;v%sA-T}CO`rYw?>!xla z_Qm1;?F92J1D!vPBw>2j2PHxb;qu5;(#? zq#k~u8{viL+D3~H+or>M|3)%y>bBnRfe!>(`FF1?*3I{yPJ$OcFw}EBqqa?nNcx9* zTZCcSZDGS8_+L&z7SEOt%s;UMYh-)WF#nAgVE@ba7`OlU7Z8Nt{^OX<^|@(0<}XVy zf4La5Wz%*_uq+84MAf%3{Aa%Zc;7Y9{Rjr@=SO5gFgSfNp#cQ%e>wwj5d@5zS7^X` zJb(_HR)qL@yWudnV4|Q64CCg#y(5Hx#S=m>;ogMx$gR@_xc}QpzdEG(?cp^jy z#Dpp4zH12_*-mIq`KwUvqBl7r$VTk1wakCe)hS%o+nFmTDhHxZkoe`7` zq{j~z;JKkL0XTq251bSdxV{oSK`I7q)hHqwy0OYO0YC-nEHX1FI6;9RQkcy_43TTw z`d;tZs!c?SjoOXK!E6X3igm|%U_<@ZHN+tE;X$qT-l*G1{5FdP#@!oKID*@HC^q}y zIs>nY5GW)Z8-#HqL_k4ac%tJ#<_3r2LJ0rq2?+`e0M>315gi+X^tj{P0^M=Mtiiee z4_z4V5U?IG?pOkrXoU}OESM+AZ@nTRIIPgNVSiA(5f31Pfv!F{w{^3T4lEvz-Ojz~ zL}b(#w|xvG7kF=PleU#^2z4lk)3(w7Vq2+&&<2EVtRw{8o`*;W9vcopGJkI_x9u(e zCs0mhqt}Hx$lEQ@i$DlMvKTKNC_{~GGXStb^S|4vDk~}?Bzu&VWr+e^sE_NL8jzq+ zV8crMLqYqXEo`F~d~$8|Y9ZZPkOrgL+|)NG1colAaJNiXr|E z08C3grtr?|+1R)a|rRaJY#VxNf#52L76@|1P08&OER&EUuNMvpNNMV$6 z2goPtY?SKj1vn!-j2HqsJsAAjh$3deI6UhjL$scds0YK>UVXU_MyM|y46aQ^DK>my zOxA;;uaSXCml2_{Otsws+^4IOswdEAdw!X$xJ#q*Tfe}YA;%N4y7Ih$u%H8H%<9!n(_s>J!N*Ad52^($Q&|wUN{3mW`eYCArk`9h=Tvl?u6b529O;sx@bngBiEavO9uOpeba}b zXpsJVDc#Ob5XC%*`hdVS)Y2idtZLuqgMqkd+5cp}s9ZyeqEPCd?Rp{l0|nUu1Bf0_ z5E1%6C`Iv1mlh@03+p2KUtMIkbV1^X_y=~%KOR{!L^Fm)7^Ox<7$vL`XpK_0XJ?cb z+(~7Wx}N2!Y6)x6}n(gk`xlThJ>Y1%JuaETns44^imDcDGNT3 zTpOqo_18f}H!G)6N|U1#D3>6osF9k9_yMsj6*#XM{p0nM_4(qaK~%SuN|3ZP_1+AB=g-+EX^I_MHYo#(x zGZkV?nNL|sd4}k;UdsTiB9%>%eR359pBzG=;S}J58*aGS z_@h9R!yqNxpkA@bfe#8ag7K4)!|(KU0t!ZC#ZwUFP>>)b6lBB?6a~yqL9!)^M0}?+ z=t71`q;|n#iEu6l4}b;G)E8h5A|opnX0gRhzJtwdqo16e-F6e^ zWLMdQcWuo~&MQs=vS-~OqOQ&?nt+so5z&=`5$S{%4#Y@FX#$8zV3-okNd@3_go+bp zK|{=F5x)%z^ls`eFeO5c7DW&;h#oDN4k$PSJv<;GswFUvEOB83WP!y4A=0-ug~)6d zBD*O>q7P6YoRV8Yq=-Ub`4BysVi%YhAyGou5Kwsw+(X^FF}uoE@7^s?bqiG60@b%b zjV*BB7O1%eYHfkqTcFMssJjK~ZGrk*purYsxCI(*fyP^)2?9d&B<9l_mRnM7+Gve{ z5Hr~Udf*9SP@EALtRn}hi35x<3lE^#3Fjp2NqbX(A?|aa8U;NF=tu=e7Xh6RkOiI< zVrFy+0G&knSZX-H>xe5gJb;E6;l5}9ZpdfE6ab86a}swXjGS)%;HMBYJOnX51I=v! z2@+L8vQZ1oqYhRaaVB0$m}DK{Ll6{kgdYvtL&64rHA4%aVfD!v;2cFWz)8l)2EL?0 zXazKE3_AmyRa`_qQ#7n69|N34qQovcM3guK>>No3*aTUK2@pYynW&>c6*%vpEEK{B zv4U^T&>0jwAsQLTMj?~XBFK3Z8s=amdLtEpLWpUIIMF&39aww_;Ugj!5qV5R;C&`| zj}Z}~@P_Te8;J-bLe@k?SP|q25n)G=W+Fn|p+6<6%||py^aUz?LxXN28Bv2CB0|)l zmxvHGcu7Qv=JgQ~q6Ym$gs8zQB0|()fQS$^c>Ny@B4$xMpk^Y9ekGC-kvSql)L@>7 z5H(mJB18=qi3m}HZ$yNs!FM7;)L;pPhNmHF@B_6Aj)W*O=`v~;90W^<5l#(hK!oHg z2_#HO1{ZELBMHS<&fbVy5& zv?m*g|NXv$_>`2Rjw46x0O9asqf?}XuFvRCTvKLf#)&M-@ zNP^U9#A+uJBuR6X4M)aa(C4@k4h?7Ie!cV5+sRi$9ctun3(!;Mc z;<~5eLl81#u~PBVBT*tE0`xEkEfEoBXaoo&5fMQUb|SJHLHLM>C<82jxb&$+*gKV7uJ$EQT~1y zrh&y5h;ES=D8f#Kzkoqkk!(Z25(I>(4*;=Zhz999;S|Z;oF-i!o(3V#+~Uh2CM$#I7+$^W7UGE(ZqngpU^?Jw{61K3G&n1P2!e32LgU?_ z2x1r!&D;=9VVVs?-4F-B6X5va31E8fZS;Z&{iRKML7pv#2};3}Ay$cV!EX;VSfEk} zGt#L^yXh^hEzp+cEZ`E)1R~KmNS_W#F&5^z>nz8kA{>UY~^?UX9TSX zk)l=kX^Aqyawdn2S-^r~fN1#9Fhm0+Z6~0WMrm@udLb;kIgD9QfQk-?+3170=-E&- zG_dY8d-+LHP#iD~104_zo56@e5xJOHP^9!kI`X~zXqbqZWs8w?osk7*1aB{3EYJk@ z2do+_X~((%*ia(>PJTcu1BTcT>TSMa-|!V+XEbI>M)9Lz5ggJ$2ck9nv>WDdZcMfA z*ImSUV4e*HU}d>Bd_fJn4`xq4v?xfV==f26MpLh#wdR1goFq& zo;W)w(d;0l#Nd5_I1LIWmsnS3lL`!_gNGdK+LOR13WZu)po2f)mpym@zzY=mzy2dZ z@siNMKdch}kg|nrNstC8xBmJ@-elkvw*I98o`SfJ5E29>auAQli3i-^7>W4%zp;h2 zvAH3}THnyv##Y}Nqhn`apl@vh1qJ%~Dad1RVc>`c97_aa!0{h^O6BeDhlAFc?94aW zECG*&xwfgXtrHaD9f`w$BY5x~KZt+_(BE@df=Mtow%}K28-z+(5fBj%1ii3$cR%j{ zUvTz@^$dZ)sWa90~$OzzGi$#ElRVqrdH50^$u=1JDN_9{~e^*N9~6mmT1+ zW5J>1-|o>j*VX|Jg1v47`NKB{0)yZ)Cn)4dfExyn4e-RR+xj=>_B_FWLtK0S&JP2- z2gw2AA(DRxxYGe&>>%dAzy3D1aInH?8yLXh19=SINFY4G5|FP1$kp2u;|BHuKzGq{CDD#}vIihNR@d{Pz)d{Q9gP{1YS;YSDrtp}DM1t2Nn z!C46C!NSf0XX*igp&?SC0pZ>O?otFSI7NjA!LhBIuN1f!K>){Wfp{Pg5CY-r18#oU z5U-74@4x^s;O4OnhaI8>1|4n^Bp&$?WhX%mmBRU1ST7h+U$7A3x_klqK*mIB{ zr~!U(a$sDK5I}~6cm?7KeE;ziAcZ+Ly^Hvtn2E#~!a@~@vp|Ud;nT$RNUY!9*}S6z z76cMF;yiGI{wGmFf^cqsv;OBEj|VvOjabhe4{*^Y6#hX0Xc&g|gIwYJ8AwVK!Z6?j z73|VBG6J0MVf{n?N%i%5h_SQO)3()z02|EpcUmJAKpqOfW58Y)o(&hUuEC~!cz+7J zK^}_05ZSx^66d`R(z$H8I`af9zM5aS4bc3QUqwi5CH zcOJY$aPTb)a7zKg=)gAuHj@UacA)OS1rzpIA?_46hiA$oOVfvg*`af|D3G3#j{58N37 zmJPT>074Dh2^K10BioQF`Zp(%8tdsJ57I3N?;VJ|^^j@>;*4-@rU_D*HjM?r0~aok z#k+p84V*??h5$g83F1l+3Xqos@cjdHBl-Q`bl&!+-f##8gTvzk0x^DpZdd{+A&`f6 z1P+7{z7hu!^W&eO5MOi{@Mm%E|zp=gA)BsHB_TM$>yZ$m>k2AalBAWL1Ja#tV6}-N0)7L}Z#{cMIt#4y% zZLDi+Y+-H#{6-AiX7NTgDBc_E79YO8s{Wp6dkRC|0U+i5zyjQ03k<{IJ^TX0A(_w+ zyo`5%n_s9qP6oVELnHpv1<7~?`r~BWy#qZ1W%O_%zJ$Oa8Jj>iUmQUOzF6`fVj1v4 z#V9LEA!4M!t5n9-8`LXgl}dYoLIQ4lx&r{Tz$Ul{4z#ozgd{aGfFz#>cvpFQc;mKc zrQn@H0HFAfy4VnZsr6Snalp^pRmRiJ?O#3Q6gO<#e0Kn0@Fk`Y@EH^s;vIopX@W6W zh~J7n60d=w&xbZ5m|pJhFNq;EMTF(xdbf>;xxrp;8KMM{+AxeJe<+uXXf7 zhFNm9ygx_T{u4!V4duL_3Kn|v2=`2cIhZackqJu97TIViusqK)7b5tHg&eH2o{ zB`s>(7jV4hklK|R7ybg*)j!sETcbZ8TRQ4O_e6v&QjLX`H~r?VzD5I&9S$hnV*Y}( zIP&jq(SLkfRQa^7C%oSipL3FutU;eyg3s~wS*I_sK-Wvp3nc9&ZsuH@IlMvjn?C{yDy{Y=NM&O^GBF^#F`@>^plYk zj@Z3?%@WBUGyW`55FFj&RbRHiJrpS4~Dim1fsF8JTl?&zkp*Ro42H z_qJ^1qo)dN_b{=XWv`Unwew}2%fjz4imvX*<#tnevFYiXSe;ZU#`yW{CXpq7ZiT7} zp+RFR>b*&qxqTAPTwuwhj+0p-e0Yjdb04NkP_8+?4^k~RaLSw;ZQmcqTpjE->X_a) zf<`>FgJNa}wDZCtUB+}#?wE+%*m?8sq|9BWH0O?M)>$Q$F%9cPN%fv9T_eM2IFos2 z*zO`3lY^`wS^-GtU@(8r{Mxy+z|{+W0=O(OeaHy1f|4ll&2KI=S$bb>m_9NzXH{Y0 z8L8s=w%45D+@o)yiJwowr%jbTb``(-^>~ThjZm}He~L|bbVleJ^~t9wcU`yh zC0Gu>D?fe)YFNB2F2)Jp*hyd^>8@_Wd>(U`<;v)823204<$|`XH~SBlwwiG^moY+nDDY7XuCkR7v-iaZ zpPut+^DoYbiZF@pV#8C52whYidp>;kfYO~Jp1j_vuS@4xuTxMO>vmL%Ga8j9cQrKI zj*es;y3Q`xa`~8rmH4@Sx*ym0HD!*)tg1IwKXoNfKHZ(D_PAs>TPd31!!;@?X8ux> z;0ES~i-%@}*i^Od2V~Y)Heg(>FBV@>>hF417?WO>`AA;gM$oK4wgY8J!jHS&LCPFc zte#NZE2{57!eqiMA}K0vOh3yo%J!$qIMT3FjFTZk##U%%*Zy~mR`+*IF3i3OdK{P- zed^$GYUN`=eAH&GY?<*^Jqu3vG&5iSN>unWG&d(%S51SuPxs_rzNg`a7~mezdkobhNSUZ z%HJ%|*>k$`F=A~&8a%lqAJ2C3ocK*$RD^2pznXZAO{_P?srYA%VPK%tf!^|J_cI2P z-kkwe_e|yGA!SGfa=3ko(eYYh0NKH;O!tyk*RBdUal&2AW+ zD^R;T`i)Y)=n1(#leDY+m^{tbM|<>Ys%M(#4ms)z&^U*yrb`;^V|USzl?wJwTB0uJ zsy)`c(i^!W%g6PEl@t9zUk#x&`W7bN-QQD%Z#R!q$W*y{Lpu~mBsj*h_#-Bj8o6%^ zC;t)ftc*098!ghBY}xxsx}m++-S^t#V6K~#v<9TH7^TB=@#9%D#|#?B-J7%$-z}PU z5oB{#64EKz$N)RT1LnfCXMK-P#Z;Ba9dg&dpp!TfbV5MDU7vwDhEzClg3FbJiOR^` zK(Du?(vOncD*)vXP2jt%&dON3SXRl#IB-Aa$sPs2my3z<$}hf-k}z?&3vh`WcKcH| z%3o-2R1e~~%h++qaKbgQ`GKxqp-J6g&lG3&RZP+QMUQNZ?<%%n{6>LS+0204V~>N^ zctv_A+KZD;Qe4YrNlBKVaFpsv7rD<;=`UcN-i9-%<83R-Ik(*+tb$(GvU61r-Fe~hyKjWN0aj(`&?r?hDKo8K;;+Q)@9w$;R^4upb7$cV!%sO;=50rrUqX>-Cp_3c@?z z+{Djh75;ULDW(e6@h0Kdz0Pqg8a79UG53C-Hd9YaGz^Z5H$Fd+BAIMk{nd@}yGC4* zV=A@n$(f9O)O?q`^77liWghVqf1`LyJaiu&sug)HD}jrU@X<6Qlt+fjBO}QpBh4iv z%OfMtC8NkAqdZTBK2JtU?n5tJV3JXq>-Ei5zmwn$DHOs@WN3& zOA>={?~YNk_y*(0@jmHO=ej@bzZRM~tu*nc^q}{P*lM1esAcVeCU#G9gF8Bfw8~dJ z)b0Ls^IEs{zqm!O$bZ^VG_E33{m%8^v!8M&FmFQX)OUzH+^_yD`Od zDl^4P%dsT|F^_q^`Q8u%ztw|36mfra1l7p^+4J}rjP;6eUvJH|u_ZBdrYFf5%c~nJ zVo&p)|HwU&R@iKBfUPW2aeD4Pr~k9yj?2LXbiun4chw~87$-A&j#_~>CN#hM{yb|3 z$Pu!G4p(yDnYnY{qP>Rc2~SWHHH-YIuye)VNZ#CzAbBIFKi_w|EN@{=l{$%DGUKBo zx@__O_f@$JgsIeG=_@SJyG))Y2VL0Vfo@-gx5mMAwE9EuqQUk%=4aj_NCt#!=hcNC9kwR zB}j-}A?un*b&8$j3cAw%$!SdW>{k+pD(+bzXDyQUsyHL}S(Hhhc;!_kXL@_BLtbYac6Vw~ zn?bB))A@2j$->cHc}MPCTk>-8VL;vyiX@#Zkby|DNdu!8x4>gvc9o8^E0R}_ElI|x zM`!tFy}pmqT}&H%syyX4mpuSKBVPf}b87oYv`(?K=$Ge{d(3PJg1Y$^npO7~*(Jgm$2VH%^ zJLl1ro_*j(DMM>W`aP*e>pD?yeINpH+o#iN_m zvVzOIj+~G$_G{|*jblnd-%vF$mAvut+%2OP>hw240#xG%2Si+AvF*o$8_mRZ9%E0H zhOA9>4}Hn-elqrK?QuD?=ANObR4z-+huZhTiY&Vu^3)EJ^bayHOm&Li5^1dptL9ac z9-*tfWN^V?&zkQH+Ge6s;~cGizZ0&Yb2wk-6?v8B%*x%?r0^+YhU($F`41<&zMU|uG~atUq^iGs^fHMMUkuoIO;H>Z(ktSwKRd?L)Xv=bwwx(pdhwYnvj|7|}A2=gs3_EOA5DU7QmabL_Iw1UXXP6aLoaw`pzk|QZ7 zNAjB)DiMk?YUs66J(;XBXS7qx#WX@~#4@4g?w|TI$%>>lFT)eF^3o&EAHeC>JY`I@ ztGDFQ&P?Sy0g*_|wmwNYOWS-Q6_vkK!BlnCRLmO!|3e7cy>KKjcr~MwVOnHfa%RE2 z&gJ`yx*Y%GPo0LROIm3L^~IPpu8rs)xdbiCL_^CK#=n+id`5r$ppPX@zc|ua|LW$a z;Qo*_biU3Q`prZk>I$d&SB=mxmAvaYBcUIs)rZIY_g8kh?lw!mp%rHO(6u)7>V?o^ z%=aSRqdjZKKBvoFlKY+UE0&pQkeo@+=gK}2R)^Z(YO`*E z;*eE4Y++mfS|oJu=xoUc&*_*IE4nJD>sETo_{k?CnuYeazOhM{c9`UxSedljKWv`Q z?bA9{sW?md^v&fXw0knkmSvUuT+o9fSC&5w#jM>F5M)aWBmZ zxUQ6<`TP$^@rv^0lU!>YL=~{A?wZyq-|v1XEZP3Uz18~e_&{{4MxlaYQ@rBXSRqO! z;e_(o$lRb?j2-p+_rd%o0$+uEo%j`=?Bsh#h%;+e^PzdK!qatpPsSb1PV1k_0A_$Btu#gl?B_^0CI-%biRRs53mT^3GSOLu&UB?GG9{-RF#MY3LuL z_Sf{?AH8gDi1P7jFBN3_BEnDds7FZc^!xKi-c;`~{+!+M+WuYF!P`Hk#pk{)H1cM$ zx_+TMH?80xu}JY?RH$IpH|NZZPSyi|JDffKR=3+=#dAWobHN?~nvoM#1@;yP3{D(# zS)RoSRJUutwvYAswVTz@J^KCqZ#C7KwM@&ij|`RFZ^rA}4yz?nDo`&B-fXVTW%{7y z?jbn7r<{s}Y8U6@sQ!!tI7&x;rNXEimd$*#hjw96HFo^6&0!zyeOa@m4C3sA121rW ze&l1)(OlE+BdHKlT1{p0@xE>6-V)UZ<4fUR6Zog|tNZW9zOu*cmxwCur>bhOGkcpe ztRK01Q0moFUCf06%G@4f@{Cv-T8) zg*gvmPa9+gjYfI0?+teRgZoqzd-JB+AfsYj-Rer&aXO0K_*}u(##-;N>f7%%IX|nG zJy3kvLuI1USbHaynhevAC zgmgO@zE%3V=?B z%wJ6lLwVkH>6PC}&R=Bgb~0+&n;c5dM4+HnjSKq3n|~+$^djY}2fIIaunTO6?PFQC@u};-}%yYO|4$-q1q2yi!*c?uOHb&EA<@x3plUpjY>R0!-`MS#q?2DcU&V*W% zCPWk{L~8B-)xKl+9A`3R)>n~ur7bf~Y-J#>-7j!?BwUeqo_s?z^0)#CF-!;sqo)w48R)*MZmC<`wP zJEd-A?if^za#t^{lJ?XUdi}e_P`?kZab31~+a_3fG;M7zK2=TQWfHg28BT_-+&|uVkMA%!<`o=GX`o#a zFp(oS_4Cegj;ppS4U2kJHm^5)QAJDj$nELsTbWW^mPq|}y?rQOWQ8Rba+PCJx~-uM6=&XOa}$oQHuzm0B* zv}4rroX`bDd!{%12`GkFxfcgBMbcXM?Q9MBUNE|}y;c;YpuKt}`-tf8d{z3}oC4`j zxLf#mBTUc>D&_JA8b~>m>L4eacCVLP@~>F+C3emPzF69Xj`Eu6Z+CvR&b;a73H_v$ znxs$Jvghy}#n-p@{?Qu{N3n<Z!8v+pmiwK9=+RB74WCNq&;8q`*kcs@Yg}{;8(bxS7|H zTxP6M&=ItW%vqyDt0xr3Q!U1wZ%Q-Xjc#T#Ow}RbkNm(=t9QcwmxnKZ=hf#wo1#pf z?vDN7XRPS+YQgcHckf&QTdZDQG0j*0l-GFu50a`$`_RJFQ>d1Ey9!$7V=OHXbFqYs zc96t6lwl=B@@zZ|^z^JVguLk*6XHeDSC23^yvOE(eP@=I5MyRZne3CtsE^W?PxUwm zI?^^>*#?IgCuc0!_v>d_UB75cJ+oNk%=W8Ng>U{w*T`o(rmt74YOT10wSP5UJ^9;V zw}iVVyzE9D`K~p^sDf?k$$9IA=Ttl(lq^-EX(5u zb(;#5l4#~xW9fMZ?fe7lmG7eRD~6eYp^7QKl$FQXMG}dv7PC(dv}5yv&P7bIwrWFtyFAv&Qn*gKNmy2 zvvE!(YL87@7AF+v!Ih|m*7wB8ekiBrS>`Mm*MBe>-Mbvu`BTWuHy)R^G(zAATVb}6 zKhM;czkJ})soNeRqL=N}URT8)SKI0EG||oO4avKT11G3764fnkTN-J4hdCa;uk|`4 z(LJDkuu}FJO3pJdPTS$nZ2^)48FLSKBumw^T}PQI&kH|vzE7qvdbTKMOgF^X&A4s+ zPO3F+rpB7u_b^$Xx-y$ctF?Ca1GNWb!u>8%P9EpmpCYF6`lvC_kBtg@!?{vBcVRb1l=1$~Z)~k1DIA5pLb?gI)W0&bA3ha|P=!F|Shj!Agqh@nj z?jNlcSDULI1fP<(cp{Wj<`q;LO?u&hP!I*_gRx1bR(L5&w z1>LL8?kFQsC)Yck(0zH}gDmx3>yy3{W#a;c`JvZsv`%s&n>z)v5pKw%rrs$3wUt{8 zYcc;23;P^n;PlVeR}2r&U=yTbUoU7xIEm0Q1?@^vs_4_SWT*2IxVZo547p^O+$c{- z*dP49%&9{?FJgUDhOJ9jOQ2%tIwUXJlwaH$Q1Q+|E$XBCT5HkMk?>k^xaeEPhWajcHI;9xuj!-aD-@E&O1<6`CJi zef!|%%Obaff}!t&V>C~nI~{yG#lFyDH1f&5ezV1Em}l0``_0bwH*m=6 z&Nt_W61NB9?x{0V2=|lPje1}+m(7^!dq~q9pB}{=_O6ybs=fLoeM$Vcm;qlqx9Ods0kleuWKcVkmXnjyn{bbsnP-f5 zuaGw1KK$q=6TZ&LdEY>wdJ@0zky+gbKQ-UBU7`J{7T_!2aQM{xfRo-@NFFY?aOs!G z@l#SQL*Lh~>%}I#8Ad(0dLg4zS&+KwjS%Hdyz*O=}(ZyJS=Dp{Jv5&VkF;4PJJap{H`v z*(HN3wsd_r%$2brGIaUQzYmvu5tfqeV0uzLo!cxYS2f6S`YP0O^5^3|6Z`Y2wq;nw z1a_=R0hRj+s_T`OewKy&r4gh|l~#8vrn&0SqS*x(sC_lMD_VCd`Y|0pwI|ByMAwX! z?BdNglq~ZW`#y$JWZ;!qIJ{5q96lmL;;%AdzN4Gz*ZUhIUuXF68QKdfJ{*SoSBA}~ zJccgc{p}kk-8O2Z{rT0M{MxBrT?sZB=EJ91Y8ObVm4DGjgf6?xwYHeYU*}!4GJU3@ z=U8kwWQ1W{di*Egqqen)y!Dl3QOe}W=PF)jODT{={G9anE+{di+N842O0}>_45c0S zIM|OTlI~WZBbF-KDDbUKN$BwNPXjM-VJfRSZK=SahxIfQhP73W*?A-Gk{pL+p)4DRfmxAd zFB;smkHO@z4#$Ss^jp*uE$n^MeUInV!#qiX$sSs$#!plGPUrvf!g>#3YENHE6Q<6I zVZH7``zS0tc3N(sXc_gPMfLr|)STI0jBIgXDmhR|#E#Cl-4sxMrs$Idx7MUmjWMRH z(kc&q50E5}^8`knm=Ss?K&8Gi!Oq3I@8iRQ>Tl0=1P|mK4fds7HQO_7TL1jmF9G9Y zxxOhR2Dw#JuBij!9M}BnCX*K8xSmJL^%NcD-@S07_Ni+)Cd@#AE%JtV2$kJ*J7c}n zjaPdFC$A;%Yj#}o|M}!3m55UP!u#y(S+((dm8|<^ydq|(S&m9(DDIjpO_shYc$|g> z`;?63R(jVFMuF7{wYQVH_03t(&zI8s&n9dxGVgc4M!6R*TN|1zG*m0QD>E@r#}|H!tZ~+H>c-bv9NvAlO!dQJ(TWu$NED} z=_@W3)^^-mNgAMPvLsRbkvX@lvDSLWy#85>6OE|E;|~25sOQH)6ROi?>bz4HgS~?{ z>OTohww;{r642CNw9(l4LH}5?LjK){Uq`-FJ>VarPcvBR^HS{5P*SV8^CXX@DKvi~ zv7=zPt+8(;f;FOhq>GoF!Ou%sfuY3T@Q2OAOC{YIU3VY6iT1ji*&<@=tMe`Ft(J>R zRM1NoZ8NB+n)C9ISg}HIY1_MBDf1M3!`>hL_9-1a%@P0nC+!=dTos<-2X2EgK^i3; zH5uU`PMEf{EI9@-mZ_`>{SL)GT!%IAnH{q<7j=Kz<$gI?lzx)l`xDnm^GQu$FW-K! zQ)*(wQ(vQs7s#Zh?M1neaL73`Fa|kZT%!GoR8Htk`h*=Ve%O>noUR@&t2>nBVSDPD`m`#<~`tlc3L#>`+noNEsg6owFyG0Zb>}DL*b7pLAT1!)rZf28K$j!H5qak>0$?*2mYPt=6*+Vpr*(<;9{v%$>hu15KvUv>7p zw9hK4&|Gt2%Xk|4UguDK8f`fwuO>IcNk@3#im%+AkwtyYgX9*Ec7U23-3hz>e7g!k5CHG5%9WOyZXVzoZ#Ld~IIDF~#GDK3)JGm;pIlUJby4yuivMTM)0V-WES!_r_3^Ny9#Uu$+vIy4 z9h$3c0bNvuJG6R#@0C0%rP(zhdnBHbK0~SW$S2!dxJ7fuB>mrtYmDm6sY|{+lO#hn zggauGv)?WpW7B(X{!EwI=l8Us*CB;i(cMuyNCyBL*VZm`(e~uu z^L|*#OdA|cnR7h8_EM*h-lSCU7%DFQPy!8$fG8DvXYmKtr)T6smm)lAcvv%?8a~gP zUmIbuxz)^3wEO#qA%B%9bB)6!^u}UUF{|tN2zR(Ek7fxr@TvLCLjaB{Ztzx==?3UpXMaYv&MeBPrpVlQ6wX33h zP6l+cgARpcZ|KU-4Uq5T72tpC5yMI|G@spF|Mbs%^7w(N>fAFYlYC4sSJ5aTb?XuN zhybLjHBD!janVfm=rJX#l!yXJS%~k_hxZrTKiciMeOcBh;9TWJ`iixI$O8VTH~W5s z#J2OP-%yK(P7}VY7}kA>yhPsg%wLz2UvD;>q#de*IwAYQ!&k}k?2eR=cdMwaer7CX z#trQoJ-cw_V0%K%j(kB6!i`!x4x78Qla|qBCt~9kM6DSVR(|?ZRieIC75s`|iS-!s zs}wun=|?w)%2p`cl3ne(4Q=Y%!R)8$`yYqR9=wP z-W%Wj#ul|cv@DRdrcb@M*=-m+na%M2LxM~a&N@b$i?>>OiL9d8xuSn(d7*>>`+`?5 zOEI&*a>vDk5hr)l6=r)Byz-%@9lh^;?^4s!S&cAq`^a;pRj*VVWmYRCV(a)cqdAVI z{jOPQBJ~c=v-4@$z2lG!rhEuDP?ky`#-cI3v-UOjw?!G3FIPCLEz)XR`cNi5kZ^UH z!J!*gi+yGLIhE3q&P!fv$vPl;?Ot(-;uqe0*XzSZmPN04!n?lYTBT;h{l?b69(Zgq zanSEV(Y~kk3zBc~(!xf?WkEt3c{?BO4K*6M-o;t293=SLvG4Z%X{YK_*6DZK)9tU{ zW%NCLXHFk4C2;)cva{7(`tK#dm#(^ZDTko_cNK5m5VZAtvGT3F6D>RS z>0LkxNqM3obT+LgV;~kEpf|X);k3cc#IoBnjCodG#}vg*naZrC{BnG^pYla-O-;S3 zz$msAe`Lu)KfY!-m|k{@a@^yxSCos9Z(Cc}-mvC9nIAZr_V@~%LC-vSc2(l8uSg<2 zGq1udT5yQmt@F*zb5BP!Ub86L-90_S%qBRSn1A)*{yVh-I@SGQvo5DT^RQPxKC$Fl z|GSKP)iUy2rjcr7dHy4(nHThrFH4J^6FirJ-`lg_(72ZS%K0mtF2Xaq_|{lezc@a&7Se#^2_1BMWD*-Mg&S7%SZr zPf2&0EZIQS8b5eDM*fJ}V)N;?7LoH2YA;J|VwR~z$e(0P0Y%A}n!8ef zLw<@$_Cb6=Nj@z@Gr`i5{L&iBRfFe2Eu4jX)2vS1-PUExu;@gvBj63b5_+{!e z1!)yEq=#nvlS9(z-S;?|SGs-+Q#@P_O0F zu){hslaO`cJIaAjv3u=?6brtOrK;s>gznR-WL=zG2+Ix?Xy&poYrqwI-E`^I?cha< zOgAarE@-F19ix0lJ5{ak1-&v_J$27Q-noBjleoxk{AlgLYe&4GD}!!jx%VkWpZM5Q zKDSglp3OkGUJBm~3s3)G9QM$FX5V2Ns9~pC zaoM$Mc@+i;i?+q=(vkNMF9-`?2#?yaXTO)6G�Th^g=OIEg`yuBrK4OLn}RhSVh4 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

2`x5n+KSx6qXl|fJdgvUZ0wr3rz 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 z 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 ^dNP4f2lhl*ILhfn&@*cV4^9#a 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≺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 })@XSwH^kx@rM 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 s6Y|1i%^I0}mv&xDMXF^|Vy*<+!PX&&cDJKBv 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

0D4cFDt&AJjE0W@;<+P@7T2A{a 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 OLGBNp@ypMwSkX*Rx=-PjPr-(Hw~xX{l-1nJ~1d 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 z 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 z z${jj(*o#h8Oz5R;R}n9ts|iD?a}8A=u(sju<3L@K1XoK=FtT;b+lk zCJJ&4v;c8U^0F3TD75f{A-Az`bY+Pv3XK8u&76f2HH%8rEG}e8f&Q%3bcoSn;}~MH zS9QVVI?bLoJK)`()JCOfiw!;$!H3eJ4@}7qIS!uVrvC@ra)pbGJ%q>0go{FF=4IuR zmhT~|hCF1DsRPBJqZR1rDF(zAkZ)R=ZlZ?DLicL^k_|u8VQ~XNJ@})=&rtZC`>IfF zQ2mjES1Xrr_&grpB}scn5Yb8;zN*Bj)@^$2VVip;ooKxhCov=IF-Yhr51fuILv>rp zuP!jf7)7Cmja*<`0vLaPzX+eVIVas9G_ic_a0cXItgl zpgw8SvHff(;fUGMwZiPW`FhJ@Z8x<=QFOwkIAv(KJ~bQR5QR0C(|#!5C*p?C5SJX@jOp*CYg7<$MTaFaqUk`pNZHMq6+nS4T2_bTPcKGNKrG zd=U31jZqltuwNq{WsFg#FtA(KrO}>z%}Qwl6;HpA((n=5LyQA

001YndYjJ;~$ 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 literal 0 HcmV?d00001 diff --git a/playground/hello/main.c b/playground/hello/main.c index 2825a50..c489abd 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -1,49 +1,49 @@ /* - * playground/hello - a small libioma server: two routes, one worker per core. + * playground/hello - a small libioxd server: two routes, one worker per core. * - * make && ./ioma-hello + * make && ./ioxd-hello * curl http://127.0.0.1:8080/hello/diogo * curl -d 'knock' http://127.0.0.1:8080/repeat/25 * - * Against an installed libioma: cc main.c $(pkg-config --cflags --libs ioma) -o hello + * Against an installed libioxd: cc main.c $(pkg-config --cflags --libs ioxd) -o hello */ -#include +#include /* GET /hello/:name - the capture is the first route parameter; the reply goes into the slab. */ -static void hello(ioma_ctx *ctx) +static void hello(ioxd_ctx *ctx) { - ioma_slice name = ctx->req.route_params[0].value; - ioma_printf(ctx, "hello %.*s\n", (int)name.len, name.p); + ioxd_slice name = ctx->req.route_params[0].value; + ioxd_printf(ctx, "hello %.*s\n", (int)name.len, name.p); } /* POST /repeat/:times - reads the body, then streams it back that many times as numbered lines. - * Each write lands in the reply slab; ioma_flush every ten of them sends what is there, so the + * Each write lands in the reply slab; ioxd_flush every ten of them sends what is there, so the * client sees lines as they are produced instead of one reply at the end. The first flush sends * the head and the body streams chunked from then on. The slab also goes out by itself whenever * it fills, and whatever is left goes out when the handler returns. A write or a flush returns -1 * once the peer is gone. */ -static void repeat(ioma_ctx *ctx) +static void repeat(ioxd_ctx *ctx) { int64_t times; - if (!ioma_to_i64(ctx->req.route_params[0].value, ×) || times < 1) { + if (!ioxd_to_i64(ctx->req.route_params[0].value, ×) || times < 1) { ctx->res.status = 400; - ioma_text(ctx, "usage: POST a body to /repeat/\n"); + ioxd_text(ctx, "usage: POST a body to /repeat/\n"); return; } - ioma_slice body = ioma_body_all(ctx); /* the whole body; over 16 KB it is refused */ + ioxd_slice body = ioxd_body_all(ctx); /* the whole body; over 16 KB it is refused */ if (ctx->res.status != 200) return; /* 413: the engine sends it, nothing to add */ for (int64_t i = 1; i <= times; i++) { - if (ioma_printf(ctx, "%lld: %.*s\n", (long long)i, (int)body.len, body.p) < 0) + if (ioxd_printf(ctx, "%lld: %.*s\n", (long long)i, (int)body.len, body.p) < 0) return; - if (i % 10 == 0 && ioma_flush(ctx) < 0) + if (i % 10 == 0 && ioxd_flush(ctx) < 0) return; } } int main(void) { - IOMA_GET ("/hello/:name", hello); - IOMA_POST("/repeat/:times", repeat); - return ioma_run(0, 8080); + IOXD_GET ("/hello/:name", hello); + IOXD_POST("/repeat/:times", repeat); + return ioxd_run(0, 8080); } diff --git a/tests/ioma-pipe-server b/tests/ioma-pipe-server new file mode 100755 index 0000000000000000000000000000000000000000..61cbaa3555872c8fe98b43cd9261c004d185c420 GIT binary patch literal 155304 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

_T!UVAfoJg8UBD{?*FcXEd^nxo3^KIut_-Xf`Ws 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%0Dmr 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 A%K!iX literal 0 HcmV?d00001 diff --git a/tests/pipe-server.c b/tests/pipe-server.c index 53ecc08..8fa36ee 100644 --- a/tests/pipe-server.c +++ b/tests/pipe-server.c @@ -1,36 +1,36 @@ /* - * pipe-server.c - a line echo server on ioma_run_pipes: the pipe API without HTTP. Each line + * pipe-server.c - a line echo server on ioxd_run_pipes: the pipe API without HTTP. Each line * comes back as "echo: "; "quit" ends the connection; a line longer than the pipe's * buffer ends it too (the reader reports no room). `make check` runs tests/pipes.py against it. */ -#include +#include #include #include /* One connection: lines in, echoes out, until the peer leaves. */ -static void echo(ioma_pipe *pipe) +static void echo(ioxd_pipe *pipe) { for (;;) { - ioma_slice live = { NULL, 0 }; - if (ioma_pipe_read(pipe, &live) <= 0) /* the end, or no room for a longer line */ + ioxd_slice live = { NULL, 0 }; + if (ioxd_pipe_read(pipe, &live) <= 0) /* the end, or no room for a longer line */ return; const char *nl = memchr(live.p, '\n', live.len); if (!nl) { /* half a line: wait for the rest */ - ioma_pipe_examine(pipe, live.len); + ioxd_pipe_examine(pipe, live.len); continue; } size_t n = (size_t)(nl - live.p) + 1; if (n == 5 && memcmp(live.p, "quit\n", 5) == 0) return; - char *out = ioma_pipe_reserve(pipe, 6 + n); /* format straight into the slab */ + char *out = ioxd_pipe_reserve(pipe, 6 + n); /* format straight into the slab */ if (!out) return; memcpy(out, "echo: ", 6); /* NOLINT(bugprone-not-null-terminated-result): bytes, not a C string */ memcpy(out + 6, live.p, n); - ioma_pipe_advance(pipe, 6 + n); - ioma_pipe_drop(pipe, n); - if (ioma_pipe_flush(pipe) < 0) + ioxd_pipe_advance(pipe, 6 + n); + ioxd_pipe_drop(pipe, n); + if (ioxd_pipe_flush(pipe) < 0) return; } } @@ -38,5 +38,5 @@ static void echo(ioma_pipe *pipe) int main(int argc, char **argv) { int port = argc > 1 ? (int)strtol(argv[1], NULL, 10) : 8100; - return ioma_run_pipes(2, port, echo); + return ioxd_run_pipes(2, port, echo); } diff --git a/tests/server.c b/tests/server.c index 72c8052..6e07eaf 100644 --- a/tests/server.c +++ b/tests/server.c @@ -2,90 +2,90 @@ * tests/server.c - the server smoke.py and stress.py talk to: one route per feature of the * request/response model. `make check` builds it, runs both suites against it and stops it. */ -#include +#include #include /* GET / */ -static void home(ioma_ctx *ctx) +static void home(ioxd_ctx *ctx) { - ioma_text(ctx, "hello from ioma\n"); /* 200, text/plain: the defaults */ + ioxd_text(ctx, "hello from ioxd\n"); /* 200, text/plain: the defaults */ } /* GET /health */ -static void health(ioma_ctx *ctx) +static void health(ioxd_ctx *ctx) { - ioma_text(ctx, "ok"); + ioxd_text(ctx, "ok"); } /* GET /whoami?x=1&y=2 - everything the request carries, read straight from its fields and * arrays: the raw query, then each parameter split and decoded, then every header (names are - * lower-cased). ioma_printf formats straight into the reply buffer. */ -static void whoami(ioma_ctx *ctx) + * lower-cased). ioxd_printf formats straight into the reply buffer. */ +static void whoami(ioxd_ctx *ctx) { - ioma_request *r = &ctx->req; - ioma_printf(ctx, "method = %.*s\npath = %.*s\nquery = %.*s\nkeep-alive = %s\n", + ioxd_request *r = &ctx->req; + ioxd_printf(ctx, "method = %.*s\npath = %.*s\nquery = %.*s\nkeep-alive = %s\n", (int)r->method.len, r->method.p, (int)r->path.len, r->path.p, (int)r->query.len, r->query.p, r->keep_alive ? "yes" : "no"); for (size_t i = 0; i < r->n_params; i++) - ioma_printf(ctx, "param %.*s = %.*s\n", + ioxd_printf(ctx, "param %.*s = %.*s\n", (int)r->params[i].key.len, r->params[i].key.p, (int)r->params[i].value.len, r->params[i].value.p); for (size_t i = 0; i < r->n_headers; i++) - ioma_printf(ctx, "header %.*s: %.*s\n", + ioxd_printf(ctx, "header %.*s: %.*s\n", (int)r->headers[i].key.len, r->headers[i].key.p, (int)r->headers[i].value.len, r->headers[i].value.p); - ioma_header(ctx, "X-Powered-By", "ioma"); /* fine: nothing has gone out yet */ + ioxd_header(ctx, "X-Powered-By", "ioxd"); /* fine: nothing has gone out yet */ } /* GET /users/:id?fields=... - the :id capture is req.route_params[0]. A query parameter is found by * walking req.params: there are few, so the loop is the lookup. */ -static void user(ioma_ctx *ctx) +static void user(ioxd_ctx *ctx) { - ioma_slice id = ctx->req.route_params[0].value; - ioma_slice fields = { "", 0 }; + ioxd_slice id = ctx->req.route_params[0].value; + ioxd_slice fields = { "", 0 }; for (size_t i = 0; i < ctx->req.n_params; i++) - if (ioma_slice_eq(ctx->req.params[i].key, "fields")) + if (ioxd_slice_eq(ctx->req.params[i].key, "fields")) fields = ctx->req.params[i].value; - ioma_printf(ctx, "user %.*s fields=%.*s\n", (int)id.len, id.p, (int)fields.len, fields.p); + ioxd_printf(ctx, "user %.*s fields=%.*s\n", (int)id.len, id.p, (int)fields.len, fields.p); } -/* GET /users/:id/posts/:post - captures come in pattern order; ioma_to_i64 reads a whole number +/* GET /users/:id/posts/:post - captures come in pattern order; ioxd_to_i64 reads a whole number * or fails, so a non-numeric id is a 400 instead of a silent zero. */ -static void post(ioma_ctx *ctx) +static void post(ioxd_ctx *ctx) { int64_t user_id, post_id; - if (!ioma_to_i64(ctx->req.route_params[0].value, &user_id) || - !ioma_to_i64(ctx->req.route_params[1].value, &post_id)) { + if (!ioxd_to_i64(ctx->req.route_params[0].value, &user_id) || + !ioxd_to_i64(ctx->req.route_params[1].value, &post_id)) { ctx->res.status = 400; - ioma_text(ctx, "ids must be integers\n"); + ioxd_text(ctx, "ids must be integers\n"); return; } - ioma_printf(ctx, "post %lld of user %lld\n", (long long)post_id, (long long)user_id); + ioxd_printf(ctx, "post %lld of user %lld\n", (long long)post_id, (long long)user_id); } /* GET /convert?i=..&d=..&b=.. - the typed conversions; a value that does not parse is a 400. */ -static void convert(ioma_ctx *ctx) +static void convert(ioxd_ctx *ctx) { for (size_t k = 0; k < ctx->req.n_params; k++) { - ioma_kv p = ctx->req.params[k]; + ioxd_kv p = ctx->req.params[k]; int64_t i; double d; bool b; - if (ioma_slice_eq(p.key, "i") && ioma_to_i64(p.value, &i)) { - ioma_printf(ctx, "i=%lld\n", (long long)i); - } else if (ioma_slice_eq(p.key, "d") && ioma_to_double(p.value, &d)) { - ioma_printf(ctx, "d=%g\n", d); - } else if (ioma_slice_eq(p.key, "b") && ioma_to_bool(p.value, &b)) { - ioma_printf(ctx, "b=%s\n", b ? "true" : "false"); + if (ioxd_slice_eq(p.key, "i") && ioxd_to_i64(p.value, &i)) { + ioxd_printf(ctx, "i=%lld\n", (long long)i); + } else if (ioxd_slice_eq(p.key, "d") && ioxd_to_double(p.value, &d)) { + ioxd_printf(ctx, "d=%g\n", d); + } else if (ioxd_slice_eq(p.key, "b") && ioxd_to_bool(p.value, &b)) { + ioxd_printf(ctx, "b=%s\n", b ? "true" : "false"); } else { ctx->res.status = 400; - ioma_printf(ctx, "bad %.*s\n", (int)p.key.len, p.key.p); + ioxd_printf(ctx, "bad %.*s\n", (int)p.key.len, p.key.p); return; } } @@ -94,193 +94,193 @@ static void convert(ioma_ctx *ctx) /* POST /echo - the body read whole (Content-Length or chunked, decoded) and sent back with the * same content type. The reply's content type is a slice, so the request's header value is * assigned as is; no copy. */ -static void echo(ioma_ctx *ctx) +static void echo(ioxd_ctx *ctx) { - ioma_slice body = ioma_body_all(ctx); - ioma_content_type(ctx, "application/octet-stream"); + ioxd_slice body = ioxd_body_all(ctx); + ioxd_content_type(ctx, "application/octet-stream"); for (size_t i = 0; i < ctx->req.n_headers; i++) - if (ioma_slice_eq(ctx->req.headers[i].key, "content-type")) + if (ioxd_slice_eq(ctx->req.headers[i].key, "content-type")) ctx->res.content_type = ctx->req.headers[i].value; - ioma_write(ctx, body.p, body.len); + ioxd_write(ctx, body.p, body.len); } -/* POST /greet with a form body (name=...) - ioma_kv_parse splits and decodes it like a query +/* POST /greet with a form body (name=...) - ioxd_kv_parse splits and decodes it like a query * string. The decoded values only need to live while the handler runs, so a local arena will do: * the reply is copied into the sink as it is written. */ -static void greet(ioma_ctx *ctx) +static void greet(ioxd_ctx *ctx) { - ioma_slice body = ioma_body_all(ctx); - ioma_kv form[8]; + ioxd_slice body = ioxd_body_all(ctx); + ioxd_kv form[8]; char arena[512]; - size_t n = ioma_kv_parse(body.p, body.len, form, 8, arena, sizeof arena); + size_t n = ioxd_kv_parse(body.p, body.len, form, 8, arena, sizeof arena); - ioma_slice name = { "stranger", 8 }; + ioxd_slice name = { "stranger", 8 }; for (size_t i = 0; i < n; i++) - if (ioma_slice_eq(form[i].key, "name")) + if (ioxd_slice_eq(form[i].key, "name")) name = form[i].value; - ioma_printf(ctx, "hello %.*s\n", (int)name.len, name.p); + ioxd_printf(ctx, "hello %.*s\n", (int)name.len, name.p); } /* GET /stream?n=lines - a body far larger than the buffer. Nothing special to do: once the * buffer fills, the framework sends the head and streams the rest (chunked on HTTP/1.1), and * each write that reaches the wire just suspends this handler until the send completes. */ -static void stream(ioma_ctx *ctx) +static void stream(ioxd_ctx *ctx) { int64_t n = 1000; for (size_t i = 0; i < ctx->req.n_params; i++) - if (ioma_slice_eq(ctx->req.params[i].key, "n")) - ioma_to_i64(ctx->req.params[i].value, &n); + if (ioxd_slice_eq(ctx->req.params[i].key, "n")) + ioxd_to_i64(ctx->req.params[i].value, &n); for (int64_t i = 1; i <= n; i++) - ioma_printf(ctx, "line %lld of %lld\n", (long long)i, (long long)n); + ioxd_printf(ctx, "line %lld of %lld\n", (long long)i, (long long)n); } -/* POST /upload - a body of any size, streamed: each ioma_body_read_until hands over the next bytes +/* POST /upload - a body of any size, streamed: each ioxd_body_read_until hands over the next bytes * straight from the wire (suspending the handler while they arrive), nothing is buffered. A * handler that never asks for the body does not pay for it either: the framework drains it. */ -static void upload(ioma_ctx *ctx) +static void upload(ioxd_ctx *ctx) { char chunk[4096]; size_t total = 0; int n, reads = 0; - while ((n = ioma_body_read_until(ctx, chunk, sizeof chunk)) > 0) { + while ((n = ioxd_body_read_until(ctx, chunk, sizeof chunk)) > 0) { total += (size_t)n; reads++; } - ioma_printf(ctx, "%zu bytes in %d reads\n", total, reads); + ioxd_printf(ctx, "%zu bytes in %d reads\n", total, reads); } /* POST /chunks[?first=N] - the body chunk by chunk, exactly as the client framed it: each chunk's * length and bytes on a line, "end" after the last. With first=N, N bytes are streamed off first * and the chunk read then gives the rest of the chunk they came from. A chunk that does not fit * the buffer is a 413 (the engine answers it); a body that is not chunked is a 400. */ -static void chunks(ioma_ctx *ctx) +static void chunks(ioxd_ctx *ctx) { char buf[1024]; int64_t first = 0; for (size_t i = 0; i < ctx->req.n_params; i++) - if (ioma_slice_eq(ctx->req.params[i].key, "first")) - ioma_to_i64(ctx->req.params[i].value, &first); + if (ioxd_slice_eq(ctx->req.params[i].key, "first")) + ioxd_to_i64(ctx->req.params[i].value, &first); if (first > 0 && first <= (int64_t)sizeof buf) - ioma_printf(ctx, "first=%d\n", ioma_body_read_until(ctx, buf, (size_t)first)); + ioxd_printf(ctx, "first=%d\n", ioxd_body_read_until(ctx, buf, (size_t)first)); int n; - while ((n = ioma_body_read_next_chunk(ctx, buf, sizeof buf)) > 0) - ioma_printf(ctx, "%d:%.*s\n", n, n, buf); + while ((n = ioxd_body_read_next_chunk(ctx, buf, sizeof buf)) > 0) + ioxd_printf(ctx, "%d:%.*s\n", n, n, buf); if (n == 0) { - ioma_text(ctx, "end\n"); + ioxd_text(ctx, "end\n"); } else if (ctx->res.status == 200) { /* -1 without a status: not chunked */ ctx->res.status = 400; - ioma_text(ctx, "not chunked\n"); + ioxd_text(ctx, "not chunked\n"); } } /* GET /users/new - a static segment beside the :id capture; the static one wins for GET. */ -static void new_user_form(ioma_ctx *ctx) +static void new_user_form(ioxd_ctx *ctx) { - ioma_text(ctx, "new user form\n"); + ioxd_text(ctx, "new user form\n"); } /* POST /users/:id - and POST /users/new lands here, since the static segment has no POST. */ -static void update_user(ioma_ctx *ctx) +static void update_user(ioxd_ctx *ctx) { - ioma_slice id = ctx->req.route_params[0].value; - ioma_printf(ctx, "updated %.*s\n", (int)id.len, id.p); + ioxd_slice id = ctx->req.route_params[0].value; + ioxd_printf(ctx, "updated %.*s\n", (int)id.len, id.p); } /* GET /api/ping and GET /api/admin/stats - endpoints in groups; the prefixes come from the groups. */ -static void ping(ioma_ctx *ctx) +static void ping(ioxd_ctx *ctx) { - ioma_text(ctx, "pong\n"); + ioxd_text(ctx, "pong\n"); } -static void stats(ioma_ctx *ctx) +static void stats(ioxd_ctx *ctx) { - ioma_text(ctx, "stats\n"); + ioxd_text(ctx, "stats\n"); } /* Middleware on the /api group: every reply below it carries the header. */ -static void api_header(ioma_ctx *ctx, ioma_next *next) +static void api_header(ioxd_ctx *ctx, ioxd_next *next) { - ioma_header(ctx, "x-api", "v1"); - ioma_next_run(ctx, next); + ioxd_header(ctx, "x-api", "v1"); + ioxd_next_run(ctx, next); } /* Middleware on /api/admin: the token, or a 401 without running what is below. */ -static void require_token(ioma_ctx *ctx, ioma_next *next) +static void require_token(ioxd_ctx *ctx, ioxd_next *next) { for (size_t i = 0; i < ctx->req.n_headers; i++) { - if (ioma_slice_eq(ctx->req.headers[i].key, "x-token") && ioma_slice_eq(ctx->req.headers[i].value, "secret")) { - ioma_next_run(ctx, next); + if (ioxd_slice_eq(ctx->req.headers[i].key, "x-token") && ioxd_slice_eq(ctx->req.headers[i].value, "secret")) { + ioxd_next_run(ctx, next); return; } } ctx->res.status = 401; - ioma_text(ctx, "token required\n"); + ioxd_text(ctx, "token required\n"); } /* Middleware on one endpoint only. */ -static void endpoint_header(ioma_ctx *ctx, ioma_next *next) +static void endpoint_header(ioxd_ctx *ctx, ioxd_next *next) { - ioma_header(ctx, "x-endpoint", "stats"); - ioma_next_run(ctx, next); + ioxd_header(ctx, "x-endpoint", "stats"); + ioxd_next_run(ctx, next); } /* GET /json/:id - a small document, written as you go into the reply. */ -static void json_item(ioma_ctx *ctx) +static void json_item(ioxd_ctx *ctx) { int64_t id; - if (!ioma_to_i64(ctx->req.route_params[0].value, &id)) { + if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) { ctx->res.status = 400; - ioma_text(ctx, "id must be an integer\n"); + ioxd_text(ctx, "id must be an integer\n"); return; } - ioma_json j = ioma_json_reply(ctx); - ioma_json_object(&j); - ioma_json_key(&j, "id"); ioma_json_int(&j, id); - ioma_json_key(&j, "name"); ioma_json_cstr(&j, "Zo\xc3\xab \"Z\" O'Neil\n"); - ioma_json_key(&j, "ratio"); ioma_json_double(&j, 0.1); - ioma_json_key(&j, "ok"); ioma_json_bool(&j, true); - ioma_json_key(&j, "none"); ioma_json_null(&j); - ioma_json_key(&j, "tags"); ioma_json_array(&j); - ioma_json_cstr(&j, "a"); - ioma_json_cstr(&j, "b"); - ioma_json_end(&j); - ioma_json_end(&j); + ioxd_json j = ioxd_json_reply(ctx); + ioxd_json_object(&j); + ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); + ioxd_json_key(&j, "name"); ioxd_json_cstr(&j, "Zo\xc3\xab \"Z\" O'Neil\n"); + ioxd_json_key(&j, "ratio"); ioxd_json_double(&j, 0.1); + ioxd_json_key(&j, "ok"); ioxd_json_bool(&j, true); + ioxd_json_key(&j, "none"); ioxd_json_null(&j); + ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + ioxd_json_cstr(&j, "a"); + ioxd_json_cstr(&j, "b"); + ioxd_json_end(&j); + ioxd_json_end(&j); } /* GET /json/big?n=N - N objects in an array, far more than the slab holds: it streams, chunked. */ -static void json_big(ioma_ctx *ctx) +static void json_big(ioxd_ctx *ctx) { int64_t n = 2000; for (size_t i = 0; i < ctx->req.n_params; i++) - if (ioma_slice_eq(ctx->req.params[i].key, "n")) - ioma_to_i64(ctx->req.params[i].value, &n); - ioma_json j = ioma_json_reply(ctx); - ioma_json_array(&j); + if (ioxd_slice_eq(ctx->req.params[i].key, "n")) + ioxd_to_i64(ctx->req.params[i].value, &n); + ioxd_json j = ioxd_json_reply(ctx); + ioxd_json_array(&j); for (int64_t i = 0; i < n; i++) { - ioma_json_object(&j); - ioma_json_key(&j, "i"); ioma_json_int(&j, i); - ioma_json_key(&j, "sq"); ioma_json_int(&j, i * i); - ioma_json_end(&j); + ioxd_json_object(&j); + ioxd_json_key(&j, "i"); ioxd_json_int(&j, i); + ioxd_json_key(&j, "sq"); ioxd_json_int(&j, i * i); + ioxd_json_end(&j); } - ioma_json_end(&j); + ioxd_json_end(&j); } /* Middleware: stamps a Server header, then runs the rest of the chain. Setting headers before - * calling ioma_next_run means they land even on a reply that streams (afterwards the head may + * calling ioxd_next_run means they land even on a reply that streams (afterwards the head may * already be on the wire); c->status and the rest are there to inspect on the way back out. * One that wanted to block a request (auth, rate limit) would write its reply and return - * without calling ioma_next_run. */ -static void add_server(ioma_ctx *ctx, ioma_next *next) + * without calling ioxd_next_run. */ +static void add_server(ioxd_ctx *ctx, ioxd_next *next) { - ioma_header(ctx, "Server", "ioma"); - ioma_next_run(ctx, next); + ioxd_header(ctx, "Server", "ioxd"); + ioxd_next_run(ctx, next); } /* The fallback for anything unrouted, replacing the built-in text 404. */ -static void not_found(ioma_ctx *ctx) +static void not_found(ioxd_ctx *ctx) { ctx->res.status = 404; - ioma_content_type(ctx, "application/json"); - ioma_text(ctx, "{\"error\":\"not found\"}"); + ioxd_content_type(ctx, "application/json"); + ioxd_text(ctx, "{\"error\":\"not found\"}"); } /* An environment variable as a number, or the fallback when unset or not a whole number. */ @@ -297,37 +297,37 @@ static long env_number(const char *name, long fallback) int main(void) { - /* the routes as a script: outside any IOMA_GROUP block this is the root */ - IOMA_USE(add_server); /* root middleware: every request */ - IOMA_GET ("/", home); - IOMA_GET ("/health", health); - IOMA_GET ("/whoami", whoami); - IOMA_GET ("/users/:id", user); - IOMA_GET ("/users/new", new_user_form); /* static beside the capture: wins for GET */ - IOMA_POST("/users/:id", update_user); /* so POST /users/new falls through to :id */ - IOMA_GET ("/users/:id/posts/:post", post); - IOMA_GET ("/convert", convert); - IOMA_POST("/echo", echo); - IOMA_POST("/greet", greet); - IOMA_GET ("/stream", stream); - IOMA_POST("/upload", upload); - IOMA_POST("/chunks", chunks); - IOMA_GET ("/json/:id", json_item); - IOMA_GET ("/json/big", json_big); /* static beside the capture */ - IOMA_DEFAULT(not_found); + /* the routes as a script: outside any IOXD_GROUP block this is the root */ + IOXD_USE(add_server); /* root middleware: every request */ + IOXD_GET ("/", home); + IOXD_GET ("/health", health); + IOXD_GET ("/whoami", whoami); + IOXD_GET ("/users/:id", user); + IOXD_GET ("/users/new", new_user_form); /* static beside the capture: wins for GET */ + IOXD_POST("/users/:id", update_user); /* so POST /users/new falls through to :id */ + IOXD_GET ("/users/:id/posts/:post", post); + IOXD_GET ("/convert", convert); + IOXD_POST("/echo", echo); + IOXD_POST("/greet", greet); + IOXD_GET ("/stream", stream); + IOXD_POST("/upload", upload); + IOXD_POST("/chunks", chunks); + IOXD_GET ("/json/:id", json_item); + IOXD_GET ("/json/big", json_big); /* static beside the capture */ + IOXD_DEFAULT(not_found); - /* groups: /api with middleware of its own (IOMA_USE inside a block adds to that group; listing + /* groups: /api with middleware of its own (IOXD_USE inside a block adds to that group; listing * it after the prefix, as /admin does, is the same), /api/admin below it gated by a token, and * one endpoint with middleware for itself only, listed after its handler */ - IOMA_GROUP("/api") { - IOMA_USE(api_header); - IOMA_GET("/ping", ping); - IOMA_GROUP("/admin", require_token) { - IOMA_GET("/stats", stats, endpoint_header); + IOXD_GROUP("/api") { + IOXD_USE(api_header); + IOXD_GET("/ping", ping); + IOXD_GROUP("/admin", require_token) { + IOXD_GET("/stats", stats, endpoint_header); } } - int workers = (int)env_number("IOMA_WORKERS", 0); /* 0: one per core */ - int port = (int)env_number("IOMA_PORT", 8080); - return ioma_run(workers, port > 0 && port < 65536 ? port : 8080); + int workers = (int)env_number("IOXD_WORKERS", 0); /* 0: one per core */ + int port = (int)env_number("IOXD_PORT", 8080); + return ioxd_run(workers, port > 0 && port < 65536 ? port : 8080); } diff --git a/tests/smoke.py b/tests/smoke.py index 6c82f21..428377a 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Functional checks for the ioma HTTP layer: python3 tests/smoke.py [port]. +"""Functional checks for the ioxd HTTP layer: python3 tests/smoke.py [port]. Talks to tests/server.c (make check builds and runs it): GET /, /health, /whoami, /users/:id, POST /echo, ... """ @@ -67,9 +67,9 @@ def check(name, cond): results = [] st, hd, body = get("/") -results.append(check("GET / -> 200 'hello from ioma'", st == 200 and body == b"hello from ioma\n")) +results.append(check("GET / -> 200 'hello from ioxd'", st == 200 and body == b"hello from ioxd\n")) results.append(check("GET / content-type text/plain", hd.get("content-type") == "text/plain")) -results.append(check("Server header added by middleware", hd.get("server") == "ioma")) +results.append(check("Server header added by middleware", hd.get("server") == "ioxd")) st, hd, body = get("/health") results.append(check("GET /health -> 200 'ok'", st == 200 and body == b"ok")) @@ -77,7 +77,7 @@ def check(name, cond): st, hd, body = get("/whoami?x=1&y=2") results.append(check("GET /whoami -> 200", st == 200)) results.append(check(" parsed path/query in body", b"path = /whoami" in body and b"query = x=1&y=2" in body)) -results.append(check(" custom header X-Powered-By: ioma", hd.get("x-powered-by") == "ioma")) +results.append(check(" custom header X-Powered-By: ioxd", hd.get("x-powered-by") == "ioxd")) # route parameter + percent-decoded query parameter st, hd, body = get("/users/42?fields=a%20b+c&x=1") @@ -149,7 +149,7 @@ def check(name, cond): st1, _, b1 = read_response(s) st2, _, b2 = read_response(s) s.close() -results.append(check("pipelined two requests", st1 == 200 and b1 == b"ok" and st2 == 200 and b2 == b"hello from ioma\n")) +results.append(check("pipelined two requests", st1 == 200 and b1 == b"ok" and st2 == 200 and b2 == b"hello from ioxd\n")) # request split across writes with pauses s = connect() @@ -288,7 +288,7 @@ def raw_exchange(pieces, pause=0.03): s.send(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 100000\r\n\r\n" + b"z" * 100000) st, hd, body = read_response(s) s.close() -results.append(check("ioma_body on a 100 KB body -> 413", st == 413)) +results.append(check("ioxd_body on a 100 KB body -> 413", st == 413)) # an ignored body past the drain limit: the reply is served and says close s = connect() @@ -340,7 +340,7 @@ def dechunk(raw): # --- groups: prefixes chain, middleware wraps outer to inner, one endpoint's own middleware --- st, hd, body = get("/api/ping") results.append(check("GET /api/ping -> group prefix, group middleware, root middleware", - st == 200 and body == b"pong\n" and hd.get("x-api") == "v1" and hd.get("server") == "ioma")) + st == 200 and body == b"pong\n" and hd.get("x-api") == "v1" and hd.get("server") == "ioxd")) st, hd, body = get("/api/ping/") results.append(check("GET /api/ping/ -> trailing slash tolerated", st == 200 and body == b"pong\n")) st, hd, body = get("/api/admin/stats") diff --git a/tests/stress.py b/tests/stress.py index fc510a1..b076243 100644 --- a/tests/stress.py +++ b/tests/stress.py @@ -7,7 +7,7 @@ gcc -O2 -g -Wall -Iinclude -Ithird_party/picohttpparser -pthread \\ -DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4 \\ playground/hello/main.c lib/*/*.c lib/io/*.S \\ - third_party/picohttpparser/picohttpparser.c -o ioma-tiny + third_party/picohttpparser/picohttpparser.c -o ioxd-tiny At shutdown the server must report "0 still open" on every worker. """ @@ -18,7 +18,7 @@ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8080 REQ = b"GET /health HTTP/1.1\r\nHost: x\r\n\r\n" -OK = b"HTTP/1.1 200 OK\r\ncontent-type: text/plain\r\ncontent-length: 2\r\nserver: ioma\r\n\r\nok" +OK = b"HTTP/1.1 200 OK\r\ncontent-type: text/plain\r\ncontent-length: 2\r\nserver: ioxd\r\n\r\nok" def connect(timeout=5): diff --git a/tests/unit.c b/tests/unit.c index a9b4b94..572fac9 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -1,8 +1,8 @@ /* - * unit.c - the handler helpers of include/ioma.h checked without a server: comparisons, the + * unit.c - the handler helpers of include/ioxd.h checked without a server: comparisons, the * typed conversions and key/value parsing. `make check` runs it before the HTTP suites. */ -#include +#include #include #include @@ -22,22 +22,22 @@ static void check(const char *what, bool ok, int line) #define CHECK(cond) check(#cond, (cond), __LINE__) /* A slice over a C string. */ -static ioma_slice S(const char *cstr) +static ioxd_slice S(const char *cstr) { - return (ioma_slice){ cstr, strlen(cstr) }; + return (ioxd_slice){ cstr, strlen(cstr) }; } /* Each conversion: does text parse to want, and does a failure leave the output alone? */ -static bool i64_is(const char *text, int64_t want) { int64_t v = 7; return ioma_to_i64(S(text), &v) && v == want; } -static bool i64_fails(const char *text) { int64_t v = 7; return !ioma_to_i64(S(text), &v) && v == 7; } -static bool u64_is(const char *text, uint64_t want) { uint64_t v = 7; return ioma_to_u64(S(text), &v) && v == want; } -static bool u64_fails(const char *text) { uint64_t v = 7; return !ioma_to_u64(S(text), &v) && v == 7; } -static bool int_is(const char *text, int want) { int v = 7; return ioma_to_int(S(text), &v) && v == want; } -static bool int_fails(const char *text) { int v = 7; return !ioma_to_int(S(text), &v) && v == 7; } -static bool dbl_is(const char *text, double want) { double v = 7; return ioma_to_double(S(text), &v) && v == want; } -static bool dbl_fails(const char *text) { double v = 7; return !ioma_to_double(S(text), &v) && v == 7; } -static bool bool_is(const char *text, bool want) { bool v = !want; return ioma_to_bool(S(text), &v) && v == want; } -static bool bool_fails(const char *text) { bool v = true; return !ioma_to_bool(S(text), &v) && v; } +static bool i64_is(const char *text, int64_t want) { int64_t v = 7; return ioxd_to_i64(S(text), &v) && v == want; } +static bool i64_fails(const char *text) { int64_t v = 7; return !ioxd_to_i64(S(text), &v) && v == 7; } +static bool u64_is(const char *text, uint64_t want) { uint64_t v = 7; return ioxd_to_u64(S(text), &v) && v == want; } +static bool u64_fails(const char *text) { uint64_t v = 7; return !ioxd_to_u64(S(text), &v) && v == 7; } +static bool int_is(const char *text, int want) { int v = 7; return ioxd_to_int(S(text), &v) && v == want; } +static bool int_fails(const char *text) { int v = 7; return !ioxd_to_int(S(text), &v) && v == 7; } +static bool dbl_is(const char *text, double want) { double v = 7; return ioxd_to_double(S(text), &v) && v == want; } +static bool dbl_fails(const char *text) { double v = 7; return !ioxd_to_double(S(text), &v) && v == 7; } +static bool bool_is(const char *text, bool want) { bool v = !want; return ioxd_to_bool(S(text), &v) && v == want; } +static bool bool_fails(const char *text) { bool v = true; return !ioxd_to_bool(S(text), &v) && v; } static void test_integers(void) { @@ -132,99 +132,99 @@ static void test_bools(void) static void test_strings(void) { - CHECK(ioma_slice_eq(S("abc"), "abc")); - CHECK(!ioma_slice_eq(S("abc"), "ab")); - CHECK(!ioma_slice_eq(S("abc"), "abcd")); - CHECK(ioma_slice_eq(S(""), "")); - CHECK(ioma_slice_eq((ioma_slice){ nullptr, 0 }, "")); /* an absent slice is empty */ + CHECK(ioxd_slice_eq(S("abc"), "abc")); + CHECK(!ioxd_slice_eq(S("abc"), "ab")); + CHECK(!ioxd_slice_eq(S("abc"), "abcd")); + CHECK(ioxd_slice_eq(S(""), "")); + CHECK(ioxd_slice_eq((ioxd_slice){ nullptr, 0 }, "")); /* an absent slice is empty */ - CHECK(ioma_slice_eq_ci(S("Content-Type"), "content-type")); - CHECK(ioma_slice_eq_ci(S("GZIP"), "gzip")); - CHECK(!ioma_slice_eq_ci(S("gzip"), "gzi")); - CHECK(!ioma_slice_eq_ci(S("gzip"), "gzipx")); + CHECK(ioxd_slice_eq_ci(S("Content-Type"), "content-type")); + CHECK(ioxd_slice_eq_ci(S("GZIP"), "gzip")); + CHECK(!ioxd_slice_eq_ci(S("gzip"), "gzi")); + CHECK(!ioxd_slice_eq_ci(S("gzip"), "gzipx")); - CHECK(ioma_slice_starts_with(S("/api/users"), "/api/")); - CHECK(ioma_slice_starts_with(S("/api/users"), "")); - CHECK(!ioma_slice_starts_with(S("/api"), "/api/")); - CHECK(ioma_slice_ends_with(S("data.json"), ".json")); - CHECK(!ioma_slice_ends_with(S("json"), ".json")); + CHECK(ioxd_slice_starts_with(S("/api/users"), "/api/")); + CHECK(ioxd_slice_starts_with(S("/api/users"), "")); + CHECK(!ioxd_slice_starts_with(S("/api"), "/api/")); + CHECK(ioxd_slice_ends_with(S("data.json"), ".json")); + CHECK(!ioxd_slice_ends_with(S("json"), ".json")); - ioma_slice t = ioma_slice_trim(S(" a b \t\r\n")); + ioxd_slice t = ioxd_slice_trim(S(" a b \t\r\n")); CHECK(t.len == 3 && memcmp(t.p, "a b", 3) == 0); - CHECK(ioma_slice_trim(S(" \t ")).len == 0); - CHECK(ioma_slice_trim(S("")).len == 0); - CHECK(ioma_slice_trim(S("x")).len == 1); + CHECK(ioxd_slice_trim(S(" \t ")).len == 0); + CHECK(ioxd_slice_trim(S("")).len == 0); + CHECK(ioxd_slice_trim(S("x")).len == 1); char buf[4]; - CHECK(ioma_cstr(S("abc"), buf, sizeof buf) && strcmp(buf, "abc") == 0); - CHECK(!ioma_cstr(S("abcd"), buf, sizeof buf) && strcmp(buf, "abc") == 0); /* what fit, terminated */ - CHECK(ioma_cstr(S(""), buf, sizeof buf) && buf[0] == '\0'); + CHECK(ioxd_cstr(S("abc"), buf, sizeof buf) && strcmp(buf, "abc") == 0); + CHECK(!ioxd_cstr(S("abcd"), buf, sizeof buf) && strcmp(buf, "abc") == 0); /* what fit, terminated */ + CHECK(ioxd_cstr(S(""), buf, sizeof buf) && buf[0] == '\0'); buf[0] = 'x'; - CHECK(!ioma_cstr(S("a"), buf, 0) && buf[0] == 'x'); /* cap 0 writes nothing */ + CHECK(!ioxd_cstr(S("a"), buf, 0) && buf[0] == 'x'); /* cap 0 writes nothing */ } static void test_kv_parse(void) { - ioma_kv kv[8]; + ioxd_kv kv[8]; char arena[64]; - size_t n = ioma_kv_parse("a=1&b=hello+world&c=%41%zz&&d&e=", 32, kv, 8, arena, sizeof arena); + size_t n = ioxd_kv_parse("a=1&b=hello+world&c=%41%zz&&d&e=", 32, kv, 8, arena, sizeof arena); CHECK(n == 5); - CHECK(ioma_slice_eq(kv[0].key, "a") && ioma_slice_eq(kv[0].value, "1")); - CHECK(ioma_slice_eq(kv[1].key, "b") && ioma_slice_eq(kv[1].value, "hello world")); - CHECK(ioma_slice_eq(kv[2].key, "c") && ioma_slice_eq(kv[2].value, "A%zz")); /* a bad escape stays */ - CHECK(ioma_slice_eq(kv[3].key, "d") && kv[3].value.len == 0); - CHECK(ioma_slice_eq(kv[4].key, "e") && kv[4].value.len == 0); + CHECK(ioxd_slice_eq(kv[0].key, "a") && ioxd_slice_eq(kv[0].value, "1")); + CHECK(ioxd_slice_eq(kv[1].key, "b") && ioxd_slice_eq(kv[1].value, "hello world")); + CHECK(ioxd_slice_eq(kv[2].key, "c") && ioxd_slice_eq(kv[2].value, "A%zz")); /* a bad escape stays */ + CHECK(ioxd_slice_eq(kv[3].key, "d") && kv[3].value.len == 0); + CHECK(ioxd_slice_eq(kv[4].key, "e") && kv[4].value.len == 0); CHECK(kv[0].value.p != arena && kv[1].value.p >= arena); /* a view when undecoded, else in the arena */ - n = ioma_kv_parse("k%20ey=v&x=y", 12, kv, 8, arena, sizeof arena); - CHECK(n == 2 && ioma_slice_eq(kv[0].key, "k ey")); - n = ioma_kv_parse("a=1&b=x+y&c=3", 13, kv, 8, arena, 0); /* no arena: the pair needing it is skipped */ - CHECK(n == 2 && ioma_slice_eq(kv[1].key, "c")); - n = ioma_kv_parse("a=1&b=2&c=3", 11, kv, 1, arena, sizeof arena); + n = ioxd_kv_parse("k%20ey=v&x=y", 12, kv, 8, arena, sizeof arena); + CHECK(n == 2 && ioxd_slice_eq(kv[0].key, "k ey")); + n = ioxd_kv_parse("a=1&b=x+y&c=3", 13, kv, 8, arena, 0); /* no arena: the pair needing it is skipped */ + CHECK(n == 2 && ioxd_slice_eq(kv[1].key, "c")); + n = ioxd_kv_parse("a=1&b=2&c=3", 11, kv, 1, arena, sizeof arena); CHECK(n == 1); int v; - CHECK(ioma_kv_parse("page=12", 7, kv, 8, arena, sizeof arena) == 1 && ioma_to_int(kv[0].value, &v) && v == 12); + CHECK(ioxd_kv_parse("page=12", 7, kv, 8, arena, sizeof arena) == 1 && ioxd_to_int(kv[0].value, &v) && v == 12); } /* The JSON writer into memory: what a document looks like, byte for byte. */ -static bool json_is(const char *want, void (*write)(ioma_json *)) +static bool json_is(const char *want, void (*write)(ioxd_json *)) { char buf[512]; size_t len; - ioma_json j = ioma_json_mem(buf, sizeof buf, &len); + ioxd_json j = ioxd_json_mem(buf, sizeof buf, &len); write(&j); return !j.failed && len == strlen(want) && memcmp(buf, want, len) == 0; } -static void doc_nested(ioma_json *j) +static void doc_nested(ioxd_json *j) { - ioma_json_object(j); - ioma_json_key(j, "id"); ioma_json_int(j, 42); - ioma_json_key(j, "name"); ioma_json_cstr(j, "Zo\xc3\xab \"Z\" O'Neil\n\t\x01"); - ioma_json_key(j, "tags"); ioma_json_array(j); ioma_json_cstr(j, "a"); ioma_json_cstr(j, "b"); ioma_json_end(j); - ioma_json_key(j, "empty"); ioma_json_object(j); ioma_json_end(j); - ioma_json_key(j, "none"); ioma_json_null(j); - ioma_json_key(j, "ok"); ioma_json_bool(j, true); - ioma_json_key(j, "raw"); ioma_json_raw(j, S("[1,2]")); - ioma_json_end(j); + ioxd_json_object(j); + ioxd_json_key(j, "id"); ioxd_json_int(j, 42); + ioxd_json_key(j, "name"); ioxd_json_cstr(j, "Zo\xc3\xab \"Z\" O'Neil\n\t\x01"); + ioxd_json_key(j, "tags"); ioxd_json_array(j); ioxd_json_cstr(j, "a"); ioxd_json_cstr(j, "b"); ioxd_json_end(j); + ioxd_json_key(j, "empty"); ioxd_json_object(j); ioxd_json_end(j); + ioxd_json_key(j, "none"); ioxd_json_null(j); + ioxd_json_key(j, "ok"); ioxd_json_bool(j, true); + ioxd_json_key(j, "raw"); ioxd_json_raw(j, S("[1,2]")); + ioxd_json_end(j); } -static void doc_numbers(ioma_json *j) +static void doc_numbers(ioxd_json *j) { - ioma_json_array(j); - ioma_json_int(j, 0); ioma_json_int(j, -7); ioma_json_int(j, INT64_MIN); ioma_json_int(j, INT64_MAX); - ioma_json_uint(j, UINT64_MAX); - ioma_json_double(j, 0.1); ioma_json_double(j, 2.5); ioma_json_double(j, -0.0); ioma_json_double(j, 1e21); - ioma_json_double(j, 9007199254740993.0); ioma_json_double(j, 1.0 / 3.0); - ioma_json_double(j, INFINITY); ioma_json_double(j, NAN); - ioma_json_end(j); + ioxd_json_array(j); + ioxd_json_int(j, 0); ioxd_json_int(j, -7); ioxd_json_int(j, INT64_MIN); ioxd_json_int(j, INT64_MAX); + ioxd_json_uint(j, UINT64_MAX); + ioxd_json_double(j, 0.1); ioxd_json_double(j, 2.5); ioxd_json_double(j, -0.0); ioxd_json_double(j, 1e21); + ioxd_json_double(j, 9007199254740993.0); ioxd_json_double(j, 1.0 / 3.0); + ioxd_json_double(j, INFINITY); ioxd_json_double(j, NAN); + ioxd_json_end(j); } -static void doc_top_level(ioma_json *j) { ioma_json_cstr(j, "just a string"); } -static void doc_array_of_arrays(ioma_json *j) +static void doc_top_level(ioxd_json *j) { ioxd_json_cstr(j, "just a string"); } +static void doc_array_of_arrays(ioxd_json *j) { - ioma_json_array(j); - ioma_json_array(j); ioma_json_int(j, 1); ioma_json_end(j); - ioma_json_array(j); ioma_json_end(j); - ioma_json_end(j); + ioxd_json_array(j); + ioxd_json_array(j); ioxd_json_int(j, 1); ioxd_json_end(j); + ioxd_json_array(j); ioxd_json_end(j); + ioxd_json_end(j); } static void test_json(void) @@ -236,19 +236,19 @@ static void test_json(void) char small[8]; size_t len; - ioma_json j = ioma_json_mem(small, sizeof small, &len); - CHECK(ioma_json_object(&j) && ioma_json_key(&j, "k")); /* {"k": is 5 bytes */ - CHECK(!ioma_json_cstr(&j, "too long for what is left") && j.failed); - CHECK(!ioma_json_int(&j, 1)); /* failed stays failed */ + ioxd_json j = ioxd_json_mem(small, sizeof small, &len); + CHECK(ioxd_json_object(&j) && ioxd_json_key(&j, "k")); /* {"k": is 5 bytes */ + CHECK(!ioxd_json_cstr(&j, "too long for what is left") && j.failed); + CHECK(!ioxd_json_int(&j, 1)); /* failed stays failed */ char deep[512]; - j = ioma_json_mem(deep, sizeof deep, &len); + j = ioxd_json_mem(deep, sizeof deep, &len); bool ok = true; - for (int i = 0; i < IOMA_JSON_DEPTH; i++) - ok = ok && ioma_json_array(&j); - CHECK(ok && !ioma_json_array(&j)); /* one level too many */ - j = ioma_json_mem(deep, sizeof deep, &len); - CHECK(!ioma_json_end(&j)); /* nothing open */ + for (int i = 0; i < IOXD_JSON_DEPTH; i++) + ok = ok && ioxd_json_array(&j); + CHECK(ok && !ioxd_json_array(&j)); /* one level too many */ + j = ioxd_json_mem(deep, sizeof deep, &len); + CHECK(!ioxd_json_end(&j)); /* nothing open */ } int main(void) From 34e259f60b4aec3e2921bb2b0081508a0cf95706 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 22:55:38 +0100 Subject: [PATCH 19/49] Hello example: GET /users/:id, a JSON document written as you go Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- README.md | 2 +- playground/hello/main.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c60cad1..7d5fea1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Run `make` in the repo root. It produces `libioxd.a`, `libioxd.so` and the demo ## Run -`./ioxd-hello` is the smallest server: two routes, `GET /hello/:name` and a `POST /repeat/:times` +`./ioxd-hello` is the smallest server: three routes, `GET /hello/:name`, a `GET /users/:id` that writes JSON, and a `POST /repeat/:times` that reads the body and streams it back, one worker per core on port 8080. Ctrl-C stops it. A server exercising every feature of the request and response model is `tests/server.c`, the fixture the test suites run against. diff --git a/playground/hello/main.c b/playground/hello/main.c index c489abd..9a401df 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -1,8 +1,9 @@ /* - * playground/hello - a small libioxd server: two routes, one worker per core. + * playground/hello - a small libioxd server: three routes, one worker per core. * * make && ./ioxd-hello * curl http://127.0.0.1:8080/hello/diogo + * curl http://127.0.0.1:8080/users/42 * curl -d 'knock' http://127.0.0.1:8080/repeat/25 * * Against an installed libioxd: cc main.c $(pkg-config --cflags --libs ioxd) -o hello @@ -41,9 +42,39 @@ static void repeat(ioxd_ctx *ctx) } } +/* GET /users/:id - a JSON document, written as you go: each call puts its bytes straight into the + * reply, escaped, with the commas and nesting tracked for you; nothing is built up in memory + * first. ioxd_json_reply sets the content type. A document larger than the slab streams out + * chunked while the writer keeps going. */ +static void user(ioxd_ctx *ctx) +{ + int64_t id; + if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) { + ctx->res.status = 400; + ioxd_text(ctx, "the id must be an integer\n"); + return; + } + ioxd_json j = ioxd_json_reply(ctx); + ioxd_json_object(&j); + ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); + ioxd_json_key(&j, "name"); ioxd_json_cstr(&j, "Zo\xc3\xab \"Z\" O'Neil"); /* escaped on the way out */ + ioxd_json_key(&j, "active"); ioxd_json_bool(&j, id % 2 == 0); + ioxd_json_key(&j, "score"); ioxd_json_double(&j, 0.1 * (double)id); + ioxd_json_key(&j, "address"); ioxd_json_object(&j); + ioxd_json_key(&j, "city"); ioxd_json_cstr(&j, "Porto"); + ioxd_json_key(&j, "zip"); ioxd_json_null(&j); + ioxd_json_end(&j); + ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + ioxd_json_cstr(&j, "new"); + ioxd_json_cstr(&j, "c23"); + ioxd_json_end(&j); + ioxd_json_end(&j); +} + int main(void) { IOXD_GET ("/hello/:name", hello); + IOXD_GET ("/users/:id", user); IOXD_POST("/repeat/:times", repeat); return ioxd_run(0, 8080); } From 8c6cb532a0c3946c0ff447da248911dc25869744 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Tue, 8 Sep 2026 23:54:33 +0100 Subject: [PATCH 20/49] JSON: a struct described once, serialized with one call IOXD_JSON_STRUCT(name, FIELDS) expands a field list twice - into the struct's members and into a name_to_json function - so the two cannot drift. A line is the field's kind, its type (or the nested struct's name) and its name: VALUE picks the writer by C type through _Generic; OBJECT calls the nested struct's function; OPTIONAL is a pointer that comes out as null when NULL; ARRAY and OBJECTS loop over a count field. Plain text substitution: the generated function is the code one would write by hand, with no table and nothing at runtime. IOXD_JSON_WRITER makes only the function, for a struct declared elsewhere; IOXD_JSON_FIELD and IOXD_JSON_VALUE serve hand-written documents. A null char pointer serializes as null. The hello example's GET /users/:id fills a struct - nested address, optional billing, an array of tags, an array of order objects - and serializes it with one call; unit tests cover every kind, empty and null cases, and the field macro; a strict-C11 consumer compiles the macros without a warning. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 7 +++++ README.md | 3 ++- include/ioxd.h | 60 ++++++++++++++++++++++++++++++++++++++++- lib/json/json.c | 2 ++ playground/hello/main.c | 58 +++++++++++++++++++++++++-------------- tests/unit.c | 60 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 168 insertions(+), 22 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index d16038f..2a4414f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -294,6 +294,13 @@ whatever the locale says. Nesting and the commas it owes are two bits per level, deeper than `IOXD_JSON_DEPTH` fails cleanly. A reply larger than the slab streams out chunked while the writer keeps going, which is the whole point of writing as you go. +A struct can be described once and serialized with one call: `IOXD_JSON_STRUCT(user, USER_FIELDS)` +expands a field list twice, into the struct's members and into a `user_to_json` function, so the +two cannot drift. A line is the field's kind - `VALUE`, `OBJECT`, `OPTIONAL`, `ARRAY`, `OBJECTS` - its +type and its name; scalars pick their writer by C type through `_Generic`, nested structs call +their own function, arrays loop over a count field. It is text substitution all the way down: the +generated function is the code one would write by hand, with no table and nothing at runtime. + ## Tunables | name | default | what | diff --git a/README.md b/README.md index 7d5fea1..754f6cf 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,8 @@ is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port. Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with -the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills. The same registrations read as a script with the `IOXD_GET`, `IOXD_GROUP` and `IOXD_USE` macros, a group's block +the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills; a struct +described once with `IOXD_JSON_STRUCT` serializes with one call, nested objects and arrays included. The same registrations read as a script with the `IOXD_GET`, `IOXD_GROUP` and `IOXD_USE` macros, a group's block nesting the routes below it; the hello example and `tests/server.c` are written that way. `playground/hello/main.c` is a complete example. diff --git a/include/ioxd.h b/include/ioxd.h index ed453b3..40945ed 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -313,7 +313,7 @@ bool ioxd_json_array (ioxd_json *j); /* [ bool ioxd_json_end (ioxd_json *j); /* } or ], whichever is open */ bool ioxd_json_key (ioxd_json *j, const char *name); /* "name": */ bool ioxd_json_string(ioxd_json *j, ioxd_slice s); /* "...", escaped */ -bool ioxd_json_cstr (ioxd_json *j, const char *s); +bool ioxd_json_cstr (ioxd_json *j, const char *s); /* NULL is null */ bool ioxd_json_int (ioxd_json *j, int64_t v); bool ioxd_json_uint (ioxd_json *j, uint64_t v); bool ioxd_json_double(ioxd_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ @@ -321,6 +321,64 @@ bool ioxd_json_bool (ioxd_json *j, bool v); bool ioxd_json_null (ioxd_json *j); bool ioxd_json_raw (ioxd_json *j, ioxd_slice json); /* already JSON: copied as is */ +/* A value by its C type, and a key with one: the _Generic picks ioxd_json_int for the integer + * types, _uint for the unsigned ones, _double for float and double, _bool, _cstr for a char + * pointer, _string for a slice. */ +#define IOXD_JSON_VALUE(j, x) _Generic((x), \ + bool: ioxd_json_bool, \ + char: ioxd_json_int, signed char: ioxd_json_int, short: ioxd_json_int, \ + int: ioxd_json_int, long: ioxd_json_int, long long: ioxd_json_int, \ + unsigned char: ioxd_json_uint, unsigned short: ioxd_json_uint, unsigned: ioxd_json_uint, \ + unsigned long: ioxd_json_uint, unsigned long long: ioxd_json_uint, \ + float: ioxd_json_double, double: ioxd_json_double, \ + char *: ioxd_json_cstr, const char *: ioxd_json_cstr, \ + ioxd_slice: ioxd_json_string)((j), (x)) +#define IOXD_JSON_FIELD(j, name, x) (ioxd_json_key((j), (name)) && IOXD_JSON_VALUE((j), (x))) + +/* A struct described once, serialized with one call. The description is a list of fields, each + * line its kind, its C type (or, for a nested struct, that struct's name) and its name: + * + * #define USER_FIELDS(X) \ + * X(VALUE, int64_t, id) // a scalar, written by its type \ + * X(VALUE, const char *, name) \ + * X(OBJECT, address, address) // a nested struct, by value \ + * X(OPTIONAL, address, billing) // a pointer to one; null when NULL \ + * X(ARRAY, const char *, tags, n_tags) // scalars, and the count field \ + * X(OBJECTS, order, orders, n_orders) // nested structs, and the count + * IOXD_JSON_STRUCT(user, USER_FIELDS) // struct user, and user_to_json(ioxd_json *, const struct user *) + * + * IOXD_JSON_STRUCT defines the struct and the function; IOXD_JSON_WRITER only the function, for + * a struct declared elsewhere with the same fields. A nested struct's own IOXD_JSON_STRUCT comes + * first. Counts are size_t; arrays are pointers to their first element. */ +#define IOXD_JSON_STRUCT(name, FIELDS) \ + struct name { FIELDS(IOXD__JSON_MEMBER) }; \ + IOXD_JSON_WRITER(name, FIELDS) +#define IOXD_JSON_WRITER(name, FIELDS) \ + static inline bool name##_to_json(ioxd_json *j, const struct name *v) \ + { \ + ioxd_json_object(j); \ + FIELDS(IOXD__JSON_WRITE) \ + return ioxd_json_end(j); \ + } + +/* What each kind of line becomes: a member, and a piece of the writer. */ +#define IOXD__JSON_MEMBER(kind, ...) IOXD__JSON_MEMBER_##kind(__VA_ARGS__) +#define IOXD__JSON_MEMBER_VALUE(type, field) type field; +#define IOXD__JSON_MEMBER_OBJECT(sname, field) struct sname field; +#define IOXD__JSON_MEMBER_OPTIONAL(sname, field) const struct sname *field; +#define IOXD__JSON_MEMBER_ARRAY(type, field, count) type *field; size_t count; +#define IOXD__JSON_MEMBER_OBJECTS(sname, field, count) const struct sname *field; size_t count; +#define IOXD__JSON_WRITE(kind, ...) IOXD__JSON_WRITE_##kind(__VA_ARGS__) +#define IOXD__JSON_WRITE_VALUE(type, field) ioxd_json_key(j, #field); IOXD_JSON_VALUE(j, v->field); +#define IOXD__JSON_WRITE_OBJECT(sname, field) ioxd_json_key(j, #field); sname##_to_json(j, &v->field); +#define IOXD__JSON_WRITE_OPTIONAL(sname, field) ioxd_json_key(j, #field); if (v->field) sname##_to_json(j, v->field); else ioxd_json_null(j); +#define IOXD__JSON_WRITE_ARRAY(type, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { IOXD_JSON_VALUE(j, v->field[i_]); } \ + ioxd_json_end(j); +#define IOXD__JSON_WRITE_OBJECTS(sname, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { sname##_to_json(j, &v->field[i_]); } \ + ioxd_json_end(j); + /* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ /* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. diff --git a/lib/json/json.c b/lib/json/json.c index af311d0..cc2fa23 100644 --- a/lib/json/json.c +++ b/lib/json/json.c @@ -208,6 +208,8 @@ bool ioxd_json_string(ioxd_json *j, ioxd_slice s) bool ioxd_json_cstr(ioxd_json *j, const char *s) { + if (!s) + return ioxd_json_null(j); /* a null pointer is JSON null */ return separator(j) && put_string(j, s, strlen(s)); } diff --git a/playground/hello/main.c b/playground/hello/main.c index 9a401df..250174f 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -42,11 +42,33 @@ static void repeat(ioxd_ctx *ctx) } } -/* GET /users/:id - a JSON document, written as you go: each call puts its bytes straight into the - * reply, escaped, with the commas and nesting tracked for you; nothing is built up in memory - * first. ioxd_json_reply sets the content type. A document larger than the slab streams out - * chunked while the writer keeps going. */ -static void user(ioxd_ctx *ctx) +/* The shapes GET /users/:id replies with, described once: each list defines the struct and its + * *_to_json function. A line is the field's kind, its type (or the nested struct's name) and its + * name; ARRAY and OBJECTS lines add the field that holds the count. */ +#define ADDRESS_FIELDS(X) \ + X(VALUE, const char *, city) \ + X(VALUE, const char *, zip) /* NULL comes out as null */ +IOXD_JSON_STRUCT(address, ADDRESS_FIELDS) + +#define ORDER_FIELDS(X) \ + X(VALUE, int, number) \ + X(VALUE, double, total) +IOXD_JSON_STRUCT(order, ORDER_FIELDS) + +#define USER_FIELDS(X) \ + X(VALUE, int64_t, id) \ + X(VALUE, const char *, name) \ + X(VALUE, bool, active) \ + X(OBJECT, address, address) /* nested, by value */ \ + X(OPTIONAL, address, billing) /* a pointer: null when there is none */ \ + X(ARRAY, const char *, tags, n_tags) /* scalars, and the count field */ \ + X(OBJECTS, order, orders, n_orders) /* nested objects, and the count */ +IOXD_JSON_STRUCT(user, USER_FIELDS) + +/* GET /users/:id - fill the struct, serialize it with one call. The document goes straight into + * the reply, escaped, streamed chunked if it outgrows the slab; ioxd_json_reply sets the content + * type. */ +static void user_endpoint(ioxd_ctx *ctx) { int64_t id; if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) { @@ -54,27 +76,23 @@ static void user(ioxd_ctx *ctx) ioxd_text(ctx, "the id must be an integer\n"); return; } + const char *tags[] = { "new", "c23" }; + struct order orders[] = { { 1, 9.5 }, { 2, 0.25 } }; + struct user u = { + .id = id, .name = "Zo\xc3\xab \"Z\" O'Neil", .active = id % 2 == 0, + .address = { .city = "Porto", .zip = NULL }, + .billing = NULL, + .tags = tags, .n_tags = 2, + .orders = orders, .n_orders = id % 2 == 0 ? 2 : 0, + }; ioxd_json j = ioxd_json_reply(ctx); - ioxd_json_object(&j); - ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); - ioxd_json_key(&j, "name"); ioxd_json_cstr(&j, "Zo\xc3\xab \"Z\" O'Neil"); /* escaped on the way out */ - ioxd_json_key(&j, "active"); ioxd_json_bool(&j, id % 2 == 0); - ioxd_json_key(&j, "score"); ioxd_json_double(&j, 0.1 * (double)id); - ioxd_json_key(&j, "address"); ioxd_json_object(&j); - ioxd_json_key(&j, "city"); ioxd_json_cstr(&j, "Porto"); - ioxd_json_key(&j, "zip"); ioxd_json_null(&j); - ioxd_json_end(&j); - ioxd_json_key(&j, "tags"); ioxd_json_array(&j); - ioxd_json_cstr(&j, "new"); - ioxd_json_cstr(&j, "c23"); - ioxd_json_end(&j); - ioxd_json_end(&j); + user_to_json(&j, &u); } int main(void) { IOXD_GET ("/hello/:name", hello); - IOXD_GET ("/users/:id", user); + IOXD_GET ("/users/:id", user_endpoint); IOXD_POST("/repeat/:times", repeat); return ioxd_run(0, 8080); } diff --git a/tests/unit.c b/tests/unit.c index 572fac9..c2974c4 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -227,8 +227,68 @@ static void doc_array_of_arrays(ioxd_json *j) ioxd_json_end(j); } +/* Structs described once: every kind of field, nested twice, arrays of both scalars and objects. */ +#define ADDRESS_FIELDS(X) \ + X(VALUE, const char *, city) \ + X(VALUE, const char *, zip) +IOXD_JSON_STRUCT(address, ADDRESS_FIELDS) + +#define ORDER_FIELDS(X) \ + X(VALUE, int, number) \ + X(VALUE, double, total) \ + X(ARRAY, int, items, n_items) +IOXD_JSON_STRUCT(order, ORDER_FIELDS) + +#define USER_FIELDS(X) \ + X(VALUE, int64_t, id) \ + X(VALUE, const char *, name) \ + X(VALUE, bool, active) \ + X(VALUE, ioxd_slice, handle) \ + X(VALUE, unsigned, visits) \ + X(OBJECT, address, address) \ + X(OPTIONAL, address, billing) \ + X(ARRAY, const char *, tags, n_tags) \ + X(OBJECTS, order, orders, n_orders) +IOXD_JSON_STRUCT(user, USER_FIELDS) + +static void doc_struct(ioxd_json *j) +{ + const char *tags[] = { "new", "vip" }; + int items[] = { 7, 9 }; + struct order orders[] = { { 1, 9.5, items, 2 }, { 2, 0.25, items, 0 } }; + struct address billing = { "Lisboa", "1000-001" }; + struct user u = { + .id = 42, .name = "Zo\xc3\xab \"Z\"", .active = true, .handle = S("zoe"), .visits = 3, + .address = { "Porto", NULL }, .billing = &billing, + .tags = tags, .n_tags = 2, .orders = orders, .n_orders = 2, + }; + user_to_json(j, &u); +} +static void doc_struct_empty(ioxd_json *j) +{ + struct user u = { .id = 1, .name = NULL, .handle = S(""), .address = { NULL, NULL } }; + user_to_json(j, &u); +} +static void doc_field_macro(ioxd_json *j) +{ + ioxd_json_object(j); + IOXD_JSON_FIELD(j, "n", 5); + IOXD_JSON_FIELD(j, "x", 2.5); + IOXD_JSON_FIELD(j, "s", "str"); + IOXD_JSON_FIELD(j, "b", false); + IOXD_JSON_FIELD(j, "u", 7U); + IOXD_JSON_FIELD(j, "sl", S("slice")); + ioxd_json_end(j); +} + static void test_json(void) { + CHECK(json_is("{\"id\":42,\"name\":\"Zo\xc3\xab \\\"Z\\\"\",\"active\":true,\"handle\":\"zoe\",\"visits\":3," + "\"address\":{\"city\":\"Porto\",\"zip\":null},\"billing\":{\"city\":\"Lisboa\",\"zip\":\"1000-001\"}," + "\"tags\":[\"new\",\"vip\"],\"orders\":[{\"number\":1,\"total\":9.5,\"items\":[7,9]},{\"number\":2,\"total\":0.25,\"items\":[]}]}", doc_struct)); + CHECK(json_is("{\"id\":1,\"name\":null,\"active\":false,\"handle\":\"\",\"visits\":0,\"address\":{\"city\":null,\"zip\":null},\"billing\":null,\"tags\":[],\"orders\":[]}", doc_struct_empty)); + CHECK(json_is("{\"n\":5,\"x\":2.5,\"s\":\"str\",\"b\":false,\"u\":7,\"sl\":\"slice\"}", doc_field_macro)); + CHECK(json_is("{\"id\":42,\"name\":\"Zo\xc3\xab \\\"Z\\\" O'Neil\\n\\t\\u0001\",\"tags\":[\"a\",\"b\"],\"empty\":{},\"none\":null,\"ok\":true,\"raw\":[1,2]}", doc_nested)); CHECK(json_is("[0,-7,-9223372036854775808,9223372036854775807,18446744073709551615,0.1,2.5,-0,1e+21,9007199254740992,0.3333333333333333,null,null]", doc_numbers)); CHECK(json_is("\"just a string\"", doc_top_level)); From b5f84a8148f171bd64ad818feee10475551c939e Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 00:24:33 +0100 Subject: [PATCH 21/49] include/ioxd/: the public header split by concern, ioxd.h the umbrella slice.h (slices, conversions, key/value parsing), http.h (request, response, context, body, reply, ioxd_run), router.h (groups, endpoints, middleware, the script macros), json.h (the writer, structs described once) and pipe.h (a connection as a pipe). Each stands on its own under strict C11 and includes what it needs; ioxd.h includes them all. Installed as /include/ioxd.h plus /include/ioxd/*.h, so a consumer still writes #include with -I/include; pkg-config, the Makefile and CMake follow. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 3 +- CMakeLists.txt | 5 +- Makefile | 11 +- include/ioxd.h | 409 +----------------------------------------------- ioxd.pc.in | 2 +- 5 files changed, 19 insertions(+), 411 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 2a4414f..af7b508 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -14,7 +14,8 @@ process │ └─ pools: conn objects, coroutine stacks ``` -`include/ioxd.h` is the whole public API. Under `lib/` there are two planes, one concern per file: +`include/ioxd.h` is the whole public API, an umbrella over `include/ioxd/`: `slice.h`, `http.h`, +`router.h`, `json.h` and `pipe.h`, one per concern, each usable on its own. Under `lib/` there are two planes, one concern per file: `io/` is the I/O plane - `uring.c` (the ring), `coro.c` + `switch_x86_64.S` (coroutines), `bufring.c` (the buffer ring), `conn.c` (a connection and its awaits), `proactor.c` (the worker loop), with `proactor.h` as the interface the other plane uses - and `http/` is the HTTP plane - diff --git a/CMakeLists.txt b/CMakeLists.txt index 57ff007..20e1600 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ add_library(ioxd::ioxd ALIAS ioxd) target_include_directories(ioxd PUBLIC $ - $ + $ PRIVATE lib third_party/picohttpparser) @@ -117,7 +117,8 @@ endif() install(TARGETS ioxd EXPORT ioxdTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(FILES include/ioxd.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ioxd) +install(FILES include/ioxd.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY include/ioxd DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(EXPORT ioxdTargets NAMESPACE ioxd:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioxd diff --git a/Makefile b/Makefile index d0ce6e8..f98dd58 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # # make build libioxd.a, libioxd.so and the examples # make lib just the libraries -# make install install libs, headers (under /include/ioxd) and ioxd.pc +# make install install libs, ioxd.h and ioxd/*.h (under /include) and ioxd.pc # sudo make install PREFIX=/usr/local # # Downstream then builds with: cc app.c $(pkg-config --cflags --libs ioxd) -o app @@ -25,7 +25,7 @@ LTO := $(shell $(CC) -Werror -flto -ffat-lto-objects -x c -c /dev/null -o /d CFLAGS ?= -O3 -g $(LTO) WARN := -Wall -Wextra $(STD) CPP := -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser -HDRS := $(wildcard include/*.h lib/*/*.h) +HDRS := $(wildcard include/*.h include/ioxd/*.h lib/*/*.h) PTHREAD := -pthread VERSION := 0.1.0 @@ -33,7 +33,7 @@ SONAME := libioxd.so.0 PREFIX ?= /usr/local LIBDIR := $(PREFIX)/lib -INCDIR := $(PREFIX)/include/ioxd +INCDIR := $(PREFIX)/include PCDIR := $(LIBDIR)/pkgconfig UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run json/json @@ -111,18 +111,19 @@ ioxd.pc: ioxd.pc.in # --- install / uninstall --- install: lib ioxd.pc - install -d $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR) $(DESTDIR)$(PCDIR) + install -d $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR)/ioxd $(DESTDIR)$(PCDIR) install -m644 libioxd.a $(DESTDIR)$(LIBDIR)/ install -m755 libioxd.so $(DESTDIR)$(LIBDIR)/libioxd.so.$(VERSION) ln -sf libioxd.so.$(VERSION) $(DESTDIR)$(LIBDIR)/$(SONAME) ln -sf $(SONAME) $(DESTDIR)$(LIBDIR)/libioxd.so install -m644 include/ioxd.h $(DESTDIR)$(INCDIR)/ + install -m644 include/ioxd/*.h $(DESTDIR)$(INCDIR)/ioxd/ install -m644 ioxd.pc $(DESTDIR)$(PCDIR)/ @echo "installed ioxd $(VERSION) to $(PREFIX)" uninstall: rm -f $(DESTDIR)$(LIBDIR)/libioxd.a $(DESTDIR)$(LIBDIR)/libioxd.so* - rm -rf $(DESTDIR)$(INCDIR) + rm -rf $(DESTDIR)$(INCDIR)/ioxd $(DESTDIR)$(INCDIR)/ioxd.h rm -f $(DESTDIR)$(PCDIR)/ioxd.pc clean: diff --git a/include/ioxd.h b/include/ioxd.h index 40945ed..89867af 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -1,5 +1,6 @@ /* - * ioxd.h - the libioxd API: what you write endpoints against. The one header that is installed. + * ioxd.h - the libioxd API: what you write endpoints against. Include this one; it brings in the + * parts under ioxd/, one per concern, which are installed beside it. * * Every request gets a context: the request, the response, and a slot for your own data. The * context is passed to each middleware and to the handler, and any of them may read the request @@ -21,404 +22,8 @@ */ #pragma once -#include -#include -#include - -#ifndef IOXD_MAX_HEADERS -#define IOXD_MAX_HEADERS 64 /* request headers kept */ -#endif -#ifndef IOXD_MAX_PARAMS -#define IOXD_MAX_PARAMS 32 /* query parameters kept */ -#endif -#ifndef IOXD_MAX_ROUTE_PARAMS -#define IOXD_MAX_ROUTE_PARAMS 8 /* :name captures a route pattern may have */ -#endif -#ifndef IOXD_MAX_RESP_HEADERS -#define IOXD_MAX_RESP_HEADERS 16 /* headers a reply may add */ -#endif - -/* A slice: pointer + length, the C span. Not NUL-terminated. */ -typedef struct { const char *p; size_t len; } ioxd_slice; - -/* One key/value pair of slices: a header, a query parameter, a route parameter. */ -typedef struct { ioxd_slice key, value; } ioxd_kv; - -/* ── the request ───────────────────────────────────────────────────────────────────────── */ - -/* All the data of a request, as slices into the connection's read buffer (decoded parameters - * into a per-request arena), valid only until the handler returns. Read the arrays directly; - * header names are lower-cased, so compare them with lowercase literals. The body is not here - * until you ask for it: ioxd_body reads it whole, ioxd_body_read streams it. */ -typedef struct ioxd_request { - ioxd_slice method; /* "GET", "POST", ... */ - ioxd_slice target; /* raw request target: path plus any query */ - ioxd_slice path; /* the path, query stripped */ - ioxd_slice query; /* raw text after '?', undecoded */ - int minor_version; /* 0 or 1 for HTTP/1.0 or 1.1 */ - - ioxd_kv headers[IOXD_MAX_HEADERS]; /* names lower-cased, values as received */ - size_t n_headers; - ioxd_kv params[IOXD_MAX_PARAMS]; /* query parameters, percent-decoded */ - size_t n_params; - ioxd_kv route_params[IOXD_MAX_ROUTE_PARAMS]; /* the :name captures, in pattern order */ - size_t n_route_params; - - size_t content_length; /* what the head declared; 0 if nothing */ - bool chunked; /* the body is chunked: length unknown */ - ioxd_slice body; /* the whole body, once ioxd_body read it */ - bool keep_alive; /* computed from version + Connection */ -} ioxd_request; - -/* ── the response ──────────────────────────────────────────────────────────────────────── */ - -/* The reply being shaped, and the write slab. Body bytes wait in buf[0, len); a full slab is - * sent and emptied, and the head (status, content type, headers) goes out in front of the first - * send - after the chain when everything fit, earlier when the body streams - and is frozen from - * then on (head_sent). You may write into buf + len yourself and advance len, up to cap. */ -typedef struct ioxd_response { - int status; /* 200 by default */ - ioxd_slice content_type; /* "text/plain" by default; any slice */ - ioxd_kv headers[IOXD_MAX_RESP_HEADERS]; /* added with ioxd_header */ - size_t n_headers; - bool close; /* close the connection after this reply */ - bool head_sent; - size_t content_length; /* declared with ioxd_content_length */ - bool has_length; - - bool chunked, failed; /* private: how a stream is framed; peer gone */ -} ioxd_response; - -/* ── the context ───────────────────────────────────────────────────────────────────────── */ - -typedef struct ioxd_ctx { - ioxd_request req; - ioxd_response res; - void *user; /* free slot: middleware hands data to the handler */ - void *priv; /* the engine's own state */ -} ioxd_ctx; - -typedef void (*ioxd_handler)(ioxd_ctx *ctx); - -/* Middleware runs around the handler (the onion model): shape the context, call ioxd_next_run to - * run the rest of the chain and then the endpoint, then act on the result - or write a reply and - * return WITHOUT calling ioxd_next_run to short-circuit (auth failure, cache hit). */ -typedef struct ioxd_next ioxd_next; -typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next); -void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next); - -/* ── the body ──────────────────────────────────────────────────────────────────────────── */ - -/* The whole body, read into the request buffer once and returned as a slice (also req.body). It - * must fit the buffer (16 KB by default): otherwise the slice is empty and res.status is 413, - * which becomes the reply - a handler that streams its reply should check and stop. Not after - * one of the reads below. */ -ioxd_slice ioxd_body_all(ioxd_ctx *ctx); - -/* The next bytes of the body into dst, reading until n are there or the body ends. Returns the - * count (less than n only at the end), 0 once it is all consumed, -1 on error (the connection - * then closes after the reply). Any size of body, nothing kept in the engine. */ -int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n); - -/* The next chunk of a chunked body, exactly as the sender framed it, into dst: the rest of the - * current chunk when a read stopped inside one, else the next whole one. Returns its length, 0 at - * the last chunk, -1 on error - a chunk larger than cap is a 413 - or when the body is not - * chunked. */ -int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap); - -/* ── the reply ─────────────────────────────────────────────────────────────────────────── */ - -/* Body writes into the slab. When it fills, it is sent - head first - and the body streams from - * then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. - * Return 0, or -1 once the peer is gone (further writes are ignored). */ -int ioxd_write (ioxd_ctx *ctx, const void *data, size_t len); -/* Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr - * once the peer is gone or n exceeds the slab) and advance by what was written. */ -void *ioxd_reserve(ioxd_ctx *ctx, size_t n); -void ioxd_advance(ioxd_ctx *ctx, size_t n); -int ioxd_text (ioxd_ctx *ctx, const char *s); /* a C string */ -int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ - -/* Shape the head. Only before it is sent: ioxd_header returns false afterwards. */ -bool ioxd_header (ioxd_ctx *ctx, const char *name, const char *value); /* both stay valid until sent; the name is sent lower-cased */ -void ioxd_content_type (ioxd_ctx *ctx, const char *type); -void ioxd_content_length(ioxd_ctx *ctx, size_t n); /* stream a large body with a known length */ -int ioxd_flush (ioxd_ctx *ctx); /* send what is in the slab now (starts streaming) */ - -/* ── slices ────────────────────────────────────────────────────────────────────────────── */ - -/* Everything a request carries is a slice: bytes with a length, not NUL-terminated, valid until - * the handler returns. These compare and convert one without copying it. */ -bool ioxd_slice_eq (ioxd_slice s, const char *cstr); /* exact */ -bool ioxd_slice_eq_ci (ioxd_slice s, const char *cstr); /* ASCII case-insensitive */ -bool ioxd_slice_starts_with(ioxd_slice s, const char *prefix); -bool ioxd_slice_ends_with (ioxd_slice s, const char *suffix); -ioxd_slice ioxd_slice_trim (ioxd_slice s); /* no leading/trailing space, tab, CR, LF */ - -/* A NUL-terminated copy in buf, for whatever wants a C string. False when it did not fit: buf - * then holds what fit, still terminated (cap 0 writes nothing). */ -bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap); - -/* Conversions. The whole slice must be the value - nothing around it, nothing after it - and a - * number that does not fit the type fails. On failure *out is left alone and false comes back, - * so "0" and "not a number" cannot be confused. Integers: an optional '-' and decimal digits. - * Doubles: also a fraction and an exponent ("2.5", ".5", "1e-3"); never inf, nan or hex; too - * large fails, too small rounds towards zero. - * Booleans: true/false, 1/0, yes/no, on/off, any case. */ -bool ioxd_to_int (ioxd_slice s, int *out); -bool ioxd_to_i64 (ioxd_slice s, int64_t *out); -bool ioxd_to_u64 (ioxd_slice s, uint64_t *out); -bool ioxd_to_double(ioxd_slice s, double *out); -bool ioxd_to_bool (ioxd_slice s, bool *out); - -/* Parse "k=v&k2=v2" - a query string, a form body - into out, up to cap pairs. Keys and values - * that need it ('+', %XX) are decoded into arena and point there; the rest are views of s. - * Returns the pair count. A pair that does not fit the arena is skipped. */ -size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap); - -/* ── routing ───────────────────────────────────────────────────────────────────────────── */ - -/* Endpoints live in groups, and groups nest. A group is a path prefix plus middleware: an - * endpoint "/users" in a group "/api" under a group "/v1" answers at "/v1/api/users", wrapped by - * the middleware of every group above it, outermost first, then its own. NULL as the group is - * the root: no prefix, and the middleware given to ioxd_use. - * - * Register everything before ioxd_run, from the main thread. ioxd_run resolves it once: every - * endpoint's full path into a segment tree and its middleware into one flat chain, which the - * workers then share read-only. A request costs one walk down the tree - no scan, no regex - and - * one call through its chain. */ -typedef struct ioxd_group ioxd_group; -typedef struct ioxd_endpoint ioxd_endpoint; - -ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix); /* "/api"; "" for middleware only */ -void ioxd_group_use(ioxd_group *group, ioxd_mw mw); /* wraps everything below it */ - -/* An endpoint: method matched exactly; path matched by segment below the group's prefix, with - * :name captures ("/users/:id") landing in req.route_params. A static segment beats a capture at - * any depth, and a static path that lacks the method falls through to a capture route that has - * it. A trailing slash is tolerated. */ -ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn); -void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw); /* wraps this one only */ - -/* The verbs, for short: ioxd_get(api, "/users/:id", user). */ -static inline ioxd_endpoint *ioxd_get (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "GET", path, fn); } -static inline ioxd_endpoint *ioxd_post (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "POST", path, fn); } -static inline ioxd_endpoint *ioxd_put (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PUT", path, fn); } -static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PATCH", path, fn); } -static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "DELETE", path, fn); } - -/* Root middleware: every request, the fallbacks included. */ -void ioxd_use(ioxd_mw mw); -/* The fallback when no path matches (a built-in 404 by default). A path that matches without the - * method gets a built-in 405 with an allow header. */ -void ioxd_default(ioxd_handler fn); - -/* ── the same, as a script ─────────────────────────────────────────────────────────────── */ - -/* Registration as a block-structured script: a current group, which the block after IOXD_GROUP - * sets (the root outside any block), endpoints registered into it, with their own middleware - * listed after the handler, and IOXD_USE adding middleware to it - so a group's middleware is - * either listed after its prefix or added with IOXD_USE inside its block. Plain functions - * underneath, so everything is type-checked; a group's block runs exactly once (do not break out - * of it). - * - * IOXD_USE(log); - * IOXD_GET("/", home); - * IOXD_GROUP("/api", api_header) { - * IOXD_GET("/ping", ping); - * IOXD_GROUP("/admin", require_token) { - * IOXD_GET("/stats", stats, timing); - * } - * } - */ -#define IOXD_MAX_MW 16 /* middleware per group and per endpoint */ -struct ioxd_group_args { const char *prefix; ioxd_mw mws[IOXD_MAX_MW + 1]; }; /* +1: the ending null */ -struct ioxd_endpoint_args { const char *path; ioxd_handler fn; ioxd_mw mws[IOXD_MAX_MW + 1]; }; - -/* What the macros call: the current group's stack and an endpoint with a middleware list. */ -ioxd_group *ioxd__group_begin(struct ioxd_group_args args); -ioxd_group *ioxd__group_end(void); -ioxd_group *ioxd__group_current(void); -ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args); - -/* The argument lists become the structs above. An argument count picks the expansion, so the - * middleware list always has its own braces and no macro is ever invoked with an empty variadic - * part: clean under -Wall -Wextra -pedantic, in C11 and later. */ -#define IOXD__CAT2(a, b) a##b -#define IOXD__CAT(a, b) IOXD__CAT2(a, b) -#define IOXD__PICK(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, name, ...) name -#define IOXD__RW(path, fn, ...) (struct ioxd_endpoint_args){ (path), (fn), { __VA_ARGS__, NULL } } -#define IOXD__RB(path, fn) (struct ioxd_endpoint_args){ (path), (fn), { NULL } } -#define IOXD__ROUTE_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ - IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ - IOXD__RW, IOXD__RW, IOXD__RB, IOXD__RB, IOXD__RB)(__VA_ARGS__) -#define IOXD__GW(prefix, ...) (struct ioxd_group_args){ (prefix), { __VA_ARGS__, NULL } } -#define IOXD__GB(prefix) (struct ioxd_group_args){ (prefix), { NULL } } -#define IOXD__GROUP_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ - IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ - IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GB, IOXD__GB)(__VA_ARGS__) - -#define IOXD_GROUP(...) \ - for (ioxd_group *IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_begin(IOXD__GROUP_ARGS(__VA_ARGS__)); \ - IOXD__CAT(ioxd__block_, __LINE__); IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_end()) -#define IOXD_USE(mw) ioxd_group_use(ioxd__group_current(), (mw)) -#define IOXD_ROUTE(method, ...) ioxd__endpoint((method), IOXD__ROUTE_ARGS(__VA_ARGS__)) -#define IOXD_GET(...) IOXD_ROUTE("GET", __VA_ARGS__) -#define IOXD_POST(...) IOXD_ROUTE("POST", __VA_ARGS__) -#define IOXD_PUT(...) IOXD_ROUTE("PUT", __VA_ARGS__) -#define IOXD_PATCH(...) IOXD_ROUTE("PATCH", __VA_ARGS__) -#define IOXD_DELETE(...) IOXD_ROUTE("DELETE", __VA_ARGS__) -#define IOXD_DEFAULT(fn) ioxd_default(fn) - -/* ── JSON, written as you go ───────────────────────────────────────────────────────────── */ - -/* A forward-only JSON writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation. The - * bytes go straight into the reply - or a raw pipe, or a buffer - escaped as they are written, - * and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what - * it means: - * - * ioxd_json j = ioxd_json_reply(ctx); // content-type: application/json - * ioxd_json_object(&j); - * ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); - * ioxd_json_key(&j, "name"); ioxd_json_string(&j, name); - * ioxd_json_key(&j, "tags"); ioxd_json_array(&j); - * ioxd_json_cstr(&j, "new"); - * ioxd_json_end(&j); - * ioxd_json_end(&j); - * - * Strings are taken as UTF-8 and passed through; '"', '\' and control characters are escaped. - * Every call returns false once the sink is gone (the peer left; the buffer is full) or the - * nesting passed IOXD_JSON_DEPTH, and the rest is dropped, so checking the last call is enough. */ -#define IOXD_JSON_DEPTH 64 -typedef struct ioxd_json { - enum { IOXD_JSON_TO_REPLY, IOXD_JSON_TO_PIPE, IOXD_JSON_TO_MEM } kind; - union { - ioxd_ctx *ctx; - struct ioxd_pipe *pipe; - struct { char *p; size_t cap, *len; } mem; - } to; - uint64_t has_value; /* per level: a value is there, so a comma is due */ - uint64_t is_object; /* per level: it closes with '}' rather than ']' */ - unsigned depth; - bool after_key; /* the next value follows a key: no comma */ - bool failed; -} ioxd_json; - -ioxd_json ioxd_json_reply(ioxd_ctx *ctx); /* into the reply; sets its content type */ -ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe); /* into a raw pipe's slab */ -ioxd_json ioxd_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ - -bool ioxd_json_object(ioxd_json *j); /* { */ -bool ioxd_json_array (ioxd_json *j); /* [ */ -bool ioxd_json_end (ioxd_json *j); /* } or ], whichever is open */ -bool ioxd_json_key (ioxd_json *j, const char *name); /* "name": */ -bool ioxd_json_string(ioxd_json *j, ioxd_slice s); /* "...", escaped */ -bool ioxd_json_cstr (ioxd_json *j, const char *s); /* NULL is null */ -bool ioxd_json_int (ioxd_json *j, int64_t v); -bool ioxd_json_uint (ioxd_json *j, uint64_t v); -bool ioxd_json_double(ioxd_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ -bool ioxd_json_bool (ioxd_json *j, bool v); -bool ioxd_json_null (ioxd_json *j); -bool ioxd_json_raw (ioxd_json *j, ioxd_slice json); /* already JSON: copied as is */ - -/* A value by its C type, and a key with one: the _Generic picks ioxd_json_int for the integer - * types, _uint for the unsigned ones, _double for float and double, _bool, _cstr for a char - * pointer, _string for a slice. */ -#define IOXD_JSON_VALUE(j, x) _Generic((x), \ - bool: ioxd_json_bool, \ - char: ioxd_json_int, signed char: ioxd_json_int, short: ioxd_json_int, \ - int: ioxd_json_int, long: ioxd_json_int, long long: ioxd_json_int, \ - unsigned char: ioxd_json_uint, unsigned short: ioxd_json_uint, unsigned: ioxd_json_uint, \ - unsigned long: ioxd_json_uint, unsigned long long: ioxd_json_uint, \ - float: ioxd_json_double, double: ioxd_json_double, \ - char *: ioxd_json_cstr, const char *: ioxd_json_cstr, \ - ioxd_slice: ioxd_json_string)((j), (x)) -#define IOXD_JSON_FIELD(j, name, x) (ioxd_json_key((j), (name)) && IOXD_JSON_VALUE((j), (x))) - -/* A struct described once, serialized with one call. The description is a list of fields, each - * line its kind, its C type (or, for a nested struct, that struct's name) and its name: - * - * #define USER_FIELDS(X) \ - * X(VALUE, int64_t, id) // a scalar, written by its type \ - * X(VALUE, const char *, name) \ - * X(OBJECT, address, address) // a nested struct, by value \ - * X(OPTIONAL, address, billing) // a pointer to one; null when NULL \ - * X(ARRAY, const char *, tags, n_tags) // scalars, and the count field \ - * X(OBJECTS, order, orders, n_orders) // nested structs, and the count - * IOXD_JSON_STRUCT(user, USER_FIELDS) // struct user, and user_to_json(ioxd_json *, const struct user *) - * - * IOXD_JSON_STRUCT defines the struct and the function; IOXD_JSON_WRITER only the function, for - * a struct declared elsewhere with the same fields. A nested struct's own IOXD_JSON_STRUCT comes - * first. Counts are size_t; arrays are pointers to their first element. */ -#define IOXD_JSON_STRUCT(name, FIELDS) \ - struct name { FIELDS(IOXD__JSON_MEMBER) }; \ - IOXD_JSON_WRITER(name, FIELDS) -#define IOXD_JSON_WRITER(name, FIELDS) \ - static inline bool name##_to_json(ioxd_json *j, const struct name *v) \ - { \ - ioxd_json_object(j); \ - FIELDS(IOXD__JSON_WRITE) \ - return ioxd_json_end(j); \ - } - -/* What each kind of line becomes: a member, and a piece of the writer. */ -#define IOXD__JSON_MEMBER(kind, ...) IOXD__JSON_MEMBER_##kind(__VA_ARGS__) -#define IOXD__JSON_MEMBER_VALUE(type, field) type field; -#define IOXD__JSON_MEMBER_OBJECT(sname, field) struct sname field; -#define IOXD__JSON_MEMBER_OPTIONAL(sname, field) const struct sname *field; -#define IOXD__JSON_MEMBER_ARRAY(type, field, count) type *field; size_t count; -#define IOXD__JSON_MEMBER_OBJECTS(sname, field, count) const struct sname *field; size_t count; -#define IOXD__JSON_WRITE(kind, ...) IOXD__JSON_WRITE_##kind(__VA_ARGS__) -#define IOXD__JSON_WRITE_VALUE(type, field) ioxd_json_key(j, #field); IOXD_JSON_VALUE(j, v->field); -#define IOXD__JSON_WRITE_OBJECT(sname, field) ioxd_json_key(j, #field); sname##_to_json(j, &v->field); -#define IOXD__JSON_WRITE_OPTIONAL(sname, field) ioxd_json_key(j, #field); if (v->field) sname##_to_json(j, v->field); else ioxd_json_null(j); -#define IOXD__JSON_WRITE_ARRAY(type, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ - for (size_t i_ = 0; i_ < v->count; i_++) { IOXD_JSON_VALUE(j, v->field[i_]); } \ - ioxd_json_end(j); -#define IOXD__JSON_WRITE_OBJECTS(sname, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ - for (size_t i_ = 0; i_ < v->count; i_++) { sname##_to_json(j, &v->field[i_]); } \ - ioxd_json_end(j); - -/* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ - -/* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. - * Every call that must wait suspends the connection's coroutine, and the worker's loop resumes - * it on the completion, so a handler reads and writes in straight-line code. The HTTP engine is - * one such handler; ioxd_run_pipes runs one of yours on raw TCP connections instead. */ -typedef struct ioxd_pipe ioxd_pipe; -typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe); -int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn); /* like ioxd_run, without HTTP */ - -/* Reading. The live bytes are the ones received and not yet consumed, always handed out as one - * contiguous span - in place in the kernel's buffer when they lie within one. read returns them - * once some are unexamined, otherwise it waits for more; examine says how many were looked at - * without being consumed, so the next read waits for more rather than returning the same bytes; - * drop consumes; keep consumes but leaves the bytes where they are, contiguous with earlier kept - * bytes and valid until release; copy is the plain read into your own buffer. read and copy - * return 0 at the end of input, IOXD_PIPE_GONE on a dead peer, IOXD_PIPE_FULL when kept plus - * live bytes would exceed the pipe's buffer. */ -#define IOXD_PIPE_GONE (-1) -#define IOXD_PIPE_FULL (-2) -int ioxd_pipe_read (ioxd_pipe *pipe, ioxd_slice *live); -void ioxd_pipe_examine(ioxd_pipe *pipe, size_t n); -void ioxd_pipe_drop (ioxd_pipe *pipe, size_t n); -const char *ioxd_pipe_keep (ioxd_pipe *pipe, size_t n); -void ioxd_pipe_release(ioxd_pipe *pipe); -int ioxd_pipe_copy (ioxd_pipe *pipe, void *dst, size_t n); - -/* Writing: a slab, sent on flush. reserve n bytes to write into directly and advance by what was - * written, or write to copy in; send is write then flush. -1 once the peer is gone. */ -void *ioxd_pipe_reserve(ioxd_pipe *pipe, size_t n); -void ioxd_pipe_advance(ioxd_pipe *pipe, size_t n); -int ioxd_pipe_write (ioxd_pipe *pipe, const void *data, size_t n); -int ioxd_pipe_flush (ioxd_pipe *pipe); -int ioxd_pipe_send (ioxd_pipe *pipe, const void *data, size_t n); - -/* ── run ───────────────────────────────────────────────────────────────────────────────── */ - -/* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port`, and block until - * SIGINT/SIGTERM. Returns 0 on clean shutdown. */ -int ioxd_run(int workers, int port); - -/* The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted. */ -const char *ioxd_reason(int status); +#include "ioxd/slice.h" /* slices, conversions, key/value parsing */ +#include "ioxd/http.h" /* request, response, context, body, reply, ioxd_run */ +#include "ioxd/router.h" /* groups, endpoints, middleware; the script macros */ +#include "ioxd/json.h" /* JSON written as you go; structs described once */ +#include "ioxd/pipe.h" /* a connection as a pipe, for other protocols */ diff --git a/ioxd.pc.in b/ioxd.pc.in index ee1b1bc..1720194 100644 --- a/ioxd.pc.in +++ b/ioxd.pc.in @@ -1,7 +1,7 @@ prefix=@PREFIX@ exec_prefix=${prefix} libdir=${exec_prefix}/lib -includedir=${prefix}/include/ioxd +includedir=${prefix}/include Name: ioxd Description: HTTP/1.1 server framework on a thread-per-core io_uring runtime From f67772aec8adf59c57b4e62c94e90807175339bc Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 00:39:02 +0100 Subject: [PATCH 22/49] json.c and api.c include the parts they implement, not the umbrella Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- lib/http/api.c | 3 ++- lib/json/json.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/http/api.c b/lib/http/api.c index ba4de42..7209685 100644 --- a/lib/http/api.c +++ b/lib/http/api.c @@ -4,7 +4,8 @@ * Nothing here touches the runtime. */ #include "http/internal.h" -#include "ioxd.h" +#include "ioxd/http.h" +#include "ioxd/slice.h" #include #include diff --git a/lib/json/json.c b/lib/json/json.c index cc2fa23..c3843a0 100644 --- a/lib/json/json.c +++ b/lib/json/json.c @@ -3,7 +3,8 @@ * a run of safe bytes at a time, an escape at a time, a number formatted into a small stack * buffer. The sink is the reply, a raw pipe, or a buffer; the writer never allocates. */ -#include "ioxd.h" +#include "ioxd/json.h" +#include "ioxd/pipe.h" #include #include From a9819ae6a32dcaa75064ff9e38cbb3da21766db0 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 00:52:54 +0100 Subject: [PATCH 23/49] TLS.md, FILES.md: kernel TLS with an OpenSSL handshake, SNI and rotation; static files over the ring with a watched snapshot Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- FILES.md | 40 ++++++++++++++++++++++++++++++ TLS.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 FILES.md create mode 100644 TLS.md diff --git a/FILES.md b/FILES.md new file mode 100644 index 0000000..60256a9 --- /dev/null +++ b/FILES.md @@ -0,0 +1,40 @@ +# Static files over the ring (design, branch `streams`) + +The model is ioxide.file's: small, hot files served from a baked, immutable snapshot; large files +as positional ring reads or, better, spliced from the descriptor straight into the socket - no +thread pool either way, and with kernel TLS the splice is encrypted on its way through. + +## The snapshot + +`ioxd_files_new("/srv/www")` walks the root once and builds a table keyed by URL path. Files up to +a threshold (256 KB) get their whole response baked: status line, `content-type` from the +extension, `content-length`, `etag` (inode, size, mtime), `last-modified`, then the body, in one +block, so serving one is a lookup and one send with nothing formatted. Larger files keep an open +descriptor and their `statx`; serving one is the head from the snapshot and the body by +`IORING_OP_SPLICE` from the descriptor through a pipe pair into the socket, in slices the writer +paces, or by positional `IORING_OP_READ` into the reply slab where splice is not wanted. Conditional +requests (`if-none-match`, `if-modified-since`) answer 304 from the snapshot alone. Ranges and +precompressed `.gz`/`.br` siblings are second-round work. + +The router grows a tail capture, `/static/*path`, so a handler is one line: + + IOXD_GET("/static/*path", assets); /* ioxd_files_serve(ctx, files, ctx->req.route_params[0].value) */ + +## Knowing a file changed + +Watching the file itself misses the case that matters: an atomic replace is a `rename` over the +old name, a new inode, and the old watch dies with the old one. So the watch is on directories, +one per directory in the tree (inotify watches are cheap; an asset tree of a few hundred +directories is nothing), and the events that mean "the content under this name is different" are +`IN_CLOSE_WRITE` (a write in place finished), `IN_MOVED_TO` (the atomic replace landed), +`IN_CREATE` and `IN_DELETE`. The descriptor is read as an ordinary ring read by the same control +coroutine that watches certificates - it is one facility, `lib/io/watch.c`, with two clients. + +Events are debounced, then the changed entries are confirmed with `statx` against the snapshot +(inode, size, mtime), re-baked, and a new snapshot is published: an atomic pointer with a +reference count, so a request that is mid-send from a baked block keeps the old snapshot alive +until its send completes, and the old snapshot is freed when the last lease drops. That is +ioxide.file's lease-safe reload, driven by the watch instead of only by `Reload()`, which stays +for deployments that swap the tree whole. `fanotify` could watch a whole mount with one +descriptor but needs privileges; inotify per directory does not. The fallback for filesystems +without events is the same `statx` sweep on a timer. diff --git a/TLS.md b/TLS.md new file mode 100644 index 0000000..683bbdb --- /dev/null +++ b/TLS.md @@ -0,0 +1,74 @@ +# TLS: one way, in the kernel (design, branch `streams`) + +## The shape + +Kernel TLS handles the record layer of an ordinary socket - encrypt on send, decrypt on receive - +but not the handshake. So a TLS connection is a plain connection with a prologue: + +1. **Handshake in userspace, over the pipe.** OpenSSL runs a TLS 1.3 server handshake through + memory BIOs on the connection's coroutine: ciphertext from the pipe's reader goes into the read + BIO, `SSL_do_handshake`, the write BIO is drained into the pipe's writer and flushed, repeat on + `WANT_READ`. Handshake bytes ride the same ring as everything else and the handshake suspends + like any await. Nothing above the pipe knows it happened. +2. **Keys into the socket.** The keylog callback hands us the TLS 1.3 traffic secrets (server for + TX, client for RX); RFC 8446 HKDF-Expand-Label makes the key and the IV; `setsockopt(TCP_ULP, + "tls")` attaches the ULP and `setsockopt(SOL_TLS, TLS_TX / TLS_RX)` installs them. Secrets are + zeroed once programmed. This is ioxide.tls's handoff, in C. +3. **Both directions in the kernel from then on.** The pipe's multishot recv delivers plaintext into + the provided buffers; the writer's sends are encrypted by the kernel; `splice` from a file + descriptor is encrypted too, which is what makes zero-copy file serving over TLS possible. + The HTTP engine, the reader and the writer are untouched. + +"One way" means exactly this: TLS 1.3, one AEAD suite the kernel knows (TLS_AES_128_GCM_SHA256; +AES-256-GCM and ChaCha20-Poly1305 are one table entry each), no session tickets (a ticket would +advance the record sequence after the handshake and break the handoff), no 0-RTT, no client +certificates in the first cut. No userspace record path exists, so there is nothing to fall back +to: a client that cannot do this suite fails the handshake. + +**The receive handoff, precisely.** A TLS 1.3 client may send its first request in the same +segment as its Finished, so when the handshake completes the reader may hold ciphertext past it. +Kernel RX can only start at a record boundary in the socket's own queue, so before installing RX +the prologue feeds whatever the reader holds through OpenSSL - `SSL_read` - until it ends on a +record boundary (waiting for the tail of a split record if it has to), hands the plaintext it got +to the reader as if it had just arrived, and installs `TLS_RX` with the record sequence those +records consumed. A control record after the handoff - close_notify, or a KeyUpdate the kernel +cannot honour - surfaces as `-EIO` on the recv, which the connection treats as end of input. +Browsers do not send KeyUpdate; that is the accepted limit. + +## Certificates: files on disk, SNI, a default, rotation + +- **Layout.** A directory per listener: `

//cert.pem` (the chain) and `key.pem`, plus + `/default/` for no SNI or no match. Matching is exact hostname, then one wildcard level + (`*.example.com` as the directory name `_.example.com`). +- **SNI.** `SSL_CTX_set_client_hello_cb` reads the server-name extension, looks the host up, and + switches the connection's context with `SSL_set_SSL_CTX`. Unknown or absent: the default. +- **Rotation without a restart.** One control coroutine on worker 0 watches the directory tree + with inotify - `IN_CLOSE_WRITE` for a file rewritten in place, `IN_MOVED_TO` for the atomic + replace (`rename` over the old file; a watch on the file itself would be lost with the inode), + `IN_CREATE`/`IN_DELETE` for hosts added and removed - read off the inotify descriptor as an + ordinary ring read. Events are debounced (500 ms: editors and certbot touch a directory several + times), then each changed host is confirmed with `statx` (inode, size, mtime against what is + loaded), parsed, checked (the key matches the certificate, the chain parses, not yet expired), + and built into a new `SSL_CTX`. The new table is published with an atomic pointer and a + generation; every handshake takes a reference to the table it started with, so an in-flight + handshake finishes on the old certificate and the old table is freed when the last reference + drops. A `statx` sweep every 60 s is the safety net for filesystems where inotify is silent + (NFS, some bind mounts), and `ioxd_tls_reload()` / SIGHUP force it for deployments that prefer + to say when. A rejected file (bad key, mismatch) is logged and the old certificate stays. + +## Where it plugs in + +Listeners become explicit, one per port and per worker, so plain and TLS can coexist and more than +one port can be served (ioxide's multi-port): + + ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree, starts watching + ioxd_listen(8080, NULL); // plain + ioxd_listen(8443, tls); // TLS + ioxd_run(0); // workers over every listener + +Per connection, `conn_main` runs the prologue when its listener has a TLS context, then the same +handler as always. `ctx->req` gains the negotiated server name and the fact that the connection is +TLS, for handlers and redirects. The dependency is libssl at handshake time; the data path is the +kernel's. Test surface: the fixture on a self-signed default certificate plus one SNI host; the +smoke suite through Python's `ssl` module; a rotation test that rewrites `cert.pem` atomically and +checks the next handshake presents the new one. From 008d8558e98d91f67a17880f7518936418df0375 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 01:12:47 +0100 Subject: [PATCH 24/49] Listeners: ioxd_listen adds ports, plain or TLS, beside ioxd_run's Every worker opens its own SO_REUSEPORT socket on each port; an accept CQE carries its listener, and a connection remembers the port it came in on and the port's TLS store - the hook the TLS prologue will use. ioxd_listen(port, tls) before the run adds a listener, at most eight; ioxd_run's own port joins as a plain one, and 0 there means only the added ones. The fixture serves a second plain port and the smoke suite hits it. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 2 +- Makefile | 2 +- README.md | 3 ++- TLS.md | 5 ++--- lib/http/run.c | 28 ++++++++++++++++++++++++---- lib/io/conn.c | 3 ++- lib/io/conn.h | 4 +++- lib/io/proactor.c | 42 +++++++++++++++++++++++++----------------- lib/io/proactor.h | 17 +++++++++++++++-- tests/server.c | 4 +++- tests/smoke.py | 7 +++++++ 11 files changed, 85 insertions(+), 32 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index af7b508..e6abbf1 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -8,7 +8,7 @@ kernel does the I/O. There are no locks and nothing is shared between workers. process ├─ worker 0 (thread pinned to CPU 0) ├─ worker 1 (CPU 1) ... │ ├─ io_uring one ring, one syscall per batch - │ ├─ SO_REUSEPORT listener the kernel spreads connections across workers + │ ├─ SO_REUSEPORT listeners one per port; the kernel spreads connections across workers │ ├─ provided buffer ring where the kernel puts received bytes │ ├─ coroutine per connection runs serve(): parse → handler → reply │ └─ pools: conn objects, coroutine stacks diff --git a/Makefile b/Makefile index f98dd58..16d9825 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ $(PIPESRV): tests/pipe-server.c libioxd.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) CHECK_PORT ?= 8099 -PIPE_PORT ?= 8100 +PIPE_PORT ?= 8101 # the fixture takes CHECK_PORT and the one after check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ diff --git a/README.md b/README.md index 754f6cf..c44c10f 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ body into its slab with `ioxd_write`, `ioxd_text` or `ioxd_printf`; the framewor in front of it, in one send when it fits and streamed when it does not. Endpoints live in groups: a group is a path prefix plus middleware, groups nest, and `ioxd_get(api, "/users/:id", user)` under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware of every group above it; the root is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it all once into a segment tree and flat -chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port. +chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port; more ports, plain or TLS, come +from `ioxd_listen` before it. Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills; a struct diff --git a/TLS.md b/TLS.md index 683bbdb..cfae5c8 100644 --- a/TLS.md +++ b/TLS.md @@ -62,9 +62,8 @@ Listeners become explicit, one per port and per worker, so plain and TLS can coe one port can be served (ioxide's multi-port): ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree, starts watching - ioxd_listen(8080, NULL); // plain - ioxd_listen(8443, tls); // TLS - ioxd_run(0); // workers over every listener + ioxd_listen(8443, tls); // TLS, besides ioxd_run's plain port + ioxd_run(0, 8080); // workers over every listener Per connection, `conn_main` runs the prologue when its listener has a TLS context, then the same handler as always. `ctx->req` gains the negotiated server name and the fact that the connection is diff --git a/lib/http/run.c b/lib/http/run.c index 63ee773..d1851a8 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -60,12 +60,28 @@ static void raise_nofile(void) /* Start the workers (workers <= 0: one per available core) and block until a stop signal. */ /* Worker threads, one proactor each, serving `port` with `handler` on every connection until * SIGINT/SIGTERM. What ioxd_run and ioxd_run_pipes share. */ +/* The listeners added before the run; ioxd_run's own port joins them. */ +static struct listener g_listeners[IOXD_MAX_LISTENERS]; +static int g_n_listeners; + +int ioxd_listen(int port, ioxd_tls *tls) +{ + if (port < 1 || port > 65535 || g_n_listeners == IOXD_MAX_LISTENERS) { + fprintf(stderr, "ioxd_listen: port %d refused (1..65535, at most %d listeners)\n", port, IOXD_MAX_LISTENERS); + return -1; + } + g_listeners[g_n_listeners++] = (struct listener){ .port = (uint16_t)port, .tls = tls }; + return 0; +} + static int run_workers(int workers, int port, handler_fn handler) { if (workers <= 0) workers = cpu_count(); - if (port < 1 || port > 65535) { - fprintf(stderr, "ioxd_run: 1<=port<=65535 required\n"); + if (port != 0 && ioxd_listen(port, nullptr) < 0) + return 2; + if (g_n_listeners == 0) { + fprintf(stderr, "ioxd_run: nothing to listen on\n"); return 2; } @@ -90,15 +106,19 @@ static int run_workers(int workers, int port, handler_fn handler) for (int i = 0; i < workers; i++) { ws[i].id = i; ws[i].cpu = i; - ws[i].port = (uint16_t)port; ws[i].handler = handler; + ws[i].n_listeners = g_n_listeners; + memcpy(ws[i].listeners, g_listeners, sizeof g_listeners); ws[i].stop = &g_stop; if (pthread_create(&th[i], nullptr, worker_thread, &ws[i]) != 0) { perror("pthread_create"); return 1; } } - fprintf(stderr, "ioxd: %d workers on :%d\n", workers, port); + fprintf(stderr, "ioxd: %d workers on", workers); + for (int i = 0; i < g_n_listeners; i++) + fprintf(stderr, " :%u%s", g_listeners[i].port, g_listeners[i].tls ? "/tls" : ""); + fputc('\n', stderr); for (int i = 0; i < workers; i++) pthread_join(th[i], nullptr); diff --git a/lib/io/conn.c b/lib/io/conn.c index 6aa7247..c99a5ab 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -37,7 +37,7 @@ static void submit_cancel(proactor_t *p, uint64_t target_user_data) /* Take a conn_t from the pool (or calloc one) and reset it for a fresh fd. Two owners hold it: * the handler coroutine and the multishot recv, so refs starts at 2. */ -conn_t *ioxd__conn_new(proactor_t *p, int fd) +conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd) { conn_t *c = p->conn_free; if (c) { @@ -52,6 +52,7 @@ conn_t *ioxd__conn_new(proactor_t *p, int fd) } c->fd = fd; c->p = p; + c->listener = l; c->waiter = nullptr; c->rx_head = 0; c->rx_tail = 0; diff --git a/lib/io/conn.h b/lib/io/conn.h index 05afd47..f8b2bf2 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -21,6 +21,7 @@ typedef struct proactor proactor_t; typedef struct conn conn_t; +struct listener; /* io/proactor.h: the port it was accepted on */ /* A slice the kernel delivered into a provided buffer, waiting for the handler to read it. */ struct rx_item { @@ -38,6 +39,7 @@ enum recv_state { struct conn { int fd; /* the socket, or its file slot under fixed files */ proactor_t *p; + struct listener *listener; /* the port it came in on: plain or TLS */ coro_t *waiter; /* coroutine parked waiting for bytes, or nullptr */ struct rx_item rx[RX_QUEUE]; /* delivered while nobody was reading */ unsigned rx_head, rx_tail; @@ -56,7 +58,7 @@ int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, e int ioxd__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno (the reader's primitive) */ /* For the loop (proactor.c): a connection's life from accept to the pool. */ -conn_t *ioxd__conn_new(proactor_t *p, int fd); /* from the pool, or fresh */ +conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd); /* from the pool, or fresh */ void ioxd__conn_main(void *arg); /* the connection's coroutine body */ void ioxd__arm_recv(proactor_t *p, conn_t *c); /* one multishot recv */ void ioxd__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); /* a recv CQE */ diff --git a/lib/io/proactor.c b/lib/io/proactor.c index 5cb3ea8..4521a0f 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -36,31 +36,32 @@ struct io_uring_sqe *ioxd__sqe(proactor_t *p) /* ── accept ────────────────────────────────────────────────────────────────────────────── */ /* Arm the multishot accept: one SQE, then a CQE per new connection. */ -static void arm_accept(proactor_t *p) +static void arm_accept(struct listener *l) { - struct io_uring_sqe *sqe = ioxd__sqe(p); + struct io_uring_sqe *sqe = ioxd__sqe(l->p); sqe->opcode = IORING_OP_ACCEPT; - sqe->fd = p->listen_fd; + sqe->fd = l->fd; sqe->ioprio = IORING_ACCEPT_MULTISHOT; - sqe->user_data = UD(p, TAG_ACCEPT); - if (p->ring.fixed_files) + sqe->user_data = UD(l, TAG_ACCEPT); + if (l->p->ring.fixed_files) sqe->file_index = IORING_FILE_INDEX_ALLOC; /* land each socket in a free slot, not an fd */ } /* An accept CQE: wrap the new fd in a conn, arm its recv, spawn its handler coroutine. */ -static void on_accept(proactor_t *p, int result, unsigned flags) +static void on_accept(struct listener *l, int result, unsigned flags) { - trace("[w%d] accept result=%d more=%d\n", p->id, result, !!(flags & IORING_CQE_F_MORE)); + proactor_t *p = l->p; + trace("[w%d] accept :%u result=%d more=%d\n", p->id, l->port, result, !!(flags & IORING_CQE_F_MORE)); if (result >= 0) { - conn_t *c = ioxd__conn_new(p, result); /* TCP_NODELAY came with the listener */ + conn_t *c = ioxd__conn_new(p, l, result); /* TCP_NODELAY came with the listener */ ioxd__arm_recv(p, c); proactor_spawn(p, ioxd__conn_main, c); p->accepted++; } else { - fprintf(stderr, "[w%d] accept: %s\n", p->id, strerror(-result)); + fprintf(stderr, "[w%d] accept :%u: %s\n", p->id, l->port, strerror(-result)); } if (!(flags & IORING_CQE_F_MORE)) - arm_accept(p); + arm_accept(l); } /* ── completions ───────────────────────────────────────────────────────────────────────── */ @@ -82,7 +83,7 @@ static void dispatch(proactor_t *p, struct io_uring_cqe *cqe) ioxd__on_recv(p, ptr, cqe->res, cqe->flags); break; case TAG_ACCEPT: - on_accept(p, cqe->res, cqe->flags); + on_accept(ptr, cqe->res, cqe->flags); break; default: /* TAG_IGNORE: cancel acknowledgements */ break; @@ -129,7 +130,7 @@ static void rearm_starved(proactor_t *p) /* ── listener ──────────────────────────────────────────────────────────────────────────── */ -/* A SO_REUSEPORT listener on port, one per worker so the kernel spreads connections. TCP_NODELAY +/* A SO_REUSEPORT socket on port; every worker opens its own, so the kernel spreads connections. TCP_NODELAY * is set here because Linux accepted sockets inherit it: no setsockopt per accept. */ static int listener_open(uint16_t port) { @@ -220,10 +221,16 @@ void proactor_run(proactor_t *p) if (slots) uring_register_files_sparse(&p->ring, slots); ioxd__bufring_init(&p->bufs, &p->ring, p->id); - p->listen_fd = listener_open(p->port); - arm_accept(p); - fprintf(stderr, "[w%d] listening on 0.0.0.0:%u (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", - p->id, p->port, p->cpu, BUF_COUNT, BUF_SIZE, p->ring.sq_entries, + char ports[IOXD_MAX_LISTENERS * 12] = "", *at = ports; + for (int i = 0; i < p->n_listeners; i++) { + struct listener *l = &p->listeners[i]; + l->p = p; + l->fd = listener_open(l->port); + arm_accept(l); + at += snprintf(at, sizeof ports - (size_t)(at - ports), "%s:%u%s", i ? " " : "", l->port, l->tls ? "/tls" : ""); + } + fprintf(stderr, "[w%d] listening on %s (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", + p->id, ports, p->cpu, BUF_COUNT, BUF_SIZE, p->ring.sq_entries, p->ring.has_sq_array ? "" : ", no sqarray", p->ring.enter_flags ? ", registered ring" : "", p->ring.fixed_files ? ", fixed files" : ""); @@ -251,7 +258,8 @@ void proactor_run(proactor_t *p) /* Sockets, then the ring (which cancels every in-flight op and drops its buffer references), * then the memory the kernel could still have referenced. */ - close(p->listen_fd); + for (int i = 0; i < p->n_listeners; i++) + close(p->listeners[i].fd); ioxd__bufring_unregister(&p->bufs, &p->ring); uring_exit(&p->ring); ioxd__bufring_unmap(&p->bufs); diff --git a/lib/io/proactor.h b/lib/io/proactor.h index efd48bf..0e964a5 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -34,17 +34,30 @@ typedef struct proactor proactor_t; struct ioxd_pipe; typedef void (*handler_fn)(struct ioxd_pipe *pipe); /* a connection, as a pipe */ +#ifndef IOXD_MAX_LISTENERS +#define IOXD_MAX_LISTENERS 8 /* ports one server may serve */ +#endif + +/* A listening port. Every worker opens its own socket on it (SO_REUSEPORT), so the kernel spreads + * the port's connections across workers; an accept CQE carries the listener it came from. */ +struct listener { + proactor_t *p; + int fd; /* the socket, or its file slot under fixed files */ + uint16_t port; + void *tls; /* the port's certificate store, or nullptr: plain */ +}; + struct proactor { /* set by the creator */ int id; int cpu; /* pin the thread here; -1 = don't */ - uint16_t port; + struct listener listeners[IOXD_MAX_LISTENERS]; /* port and tls set by the creator */ + int n_listeners; handler_fn handler; volatile sig_atomic_t *stop; /* owned by the worker thread */ struct uring ring; - int listen_fd; struct bufring bufs; /* the provided buffers recvs deliver into */ conn_t **starved; /* connections parked on -ENOBUFS */ unsigned nstarved, cap_starved; diff --git a/tests/server.c b/tests/server.c index 6e07eaf..8d47e59 100644 --- a/tests/server.c +++ b/tests/server.c @@ -329,5 +329,7 @@ int main(void) int workers = (int)env_number("IOXD_WORKERS", 0); /* 0: one per core */ int port = (int)env_number("IOXD_PORT", 8080); - return ioxd_run(workers, port > 0 && port < 65536 ? port : 8080); + int p = port > 0 && port < 65536 ? port : 8080; + ioxd_listen(p + 1, NULL); /* a second plain port: the same routes */ + return ioxd_run(workers, p); } diff --git a/tests/smoke.py b/tests/smoke.py index 428377a..6ed1120 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -303,6 +303,13 @@ def raw_exchange(pieces, pause=0.03): st, hd, body = None, {}, b"" s.close() results.append(check("ignored 2 MB body -> reply served with Connection: close", st == 404 and hd.get("connection") == "close")) +# --- a second listener: the port after ours serves the same routes --- +s = socket.create_connection(("127.0.0.1", PORT + 1), timeout=5) +s.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +st, hd, body = read_response(s) +s.close() +results.append(check("GET /health on the second listener -> 200 ok", st == 200 and body == b"ok")) + # --- the JSON writer: a document written as you go, and one that streams --- st, hd, body = get("/json/42") results.append(check("GET /json/:id -> escaped document, application/json", From f31a6bc24d97dd7730b4b7793fb791a6b67d5a17 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 01:27:45 +0100 Subject: [PATCH 25/49] TLS: kernel TLS after an OpenSSL handshake over the pipe; SNI; a certificate store A TLS listener's connection runs a prologue before its handler: OpenSSL's TLS 1.3 handshake through memory BIOs, reading ciphertext from the pipe and flushing its flights through it; the keylog callback catches the traffic secrets; HKDF-Expand-Label makes key and IV; TCP_ULP "tls" and SOL_TLS TLS_TX / TLS_RX go in through the ring (SOCKET_URING_OP_SETSOCKOPT, so the registered file table needs no fd). From then on the kernel does every record and nothing above the pipe knows. The receive handoff is exact: the multishot recv is paused, whatever it already delivered is decrypted in userspace record by record - the tail of a split record fetched straight from the socket - the plaintext injected into the reader, TLS_RX installed at the sequence consumed, the recv resumed. One suite (TLS_AES_128_GCM_SHA256), no tickets, no 0-RTT; a client that cannot do that fails the handshake. The store loads //{cert,key}.pem per hostname, `default` for no SNI or no match, `_.example.com` for a wildcard; the ClientHello callback picks the context; ioxd_tls_reload swaps a reference-counted table under handshakes in flight. make TLS=0 builds without OpenSSL. Also: await_send no longer sets MSG_WAITALL - kernel TLS refuses it and the loop finishes short sends anyway. Tests: self-signed certificates from tests/mkcerts.sh, the fixture listening on a third port, and smoke checks through Python's ssl for the default certificate, SNI, an unknown name, a POST body over kernel RX, keep-alive, a 3000-object streamed reply over kernel TX, and a refused TLS 1.2 client. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .gitignore | 1 + ARCHITECTURE.md | 2 +- CMakeLists.txt | 11 ++ Makefile | 26 ++-- include/ioxd.h | 1 + ioxd.pc.in | 1 + lib/http/run.c | 27 +++- lib/io/conn.c | 86 ++++++++++++- lib/io/conn.h | 10 ++ lib/io/pipe.c | 35 ++++++ lib/io/pipe.h | 2 + lib/tls/handshake.c | 298 ++++++++++++++++++++++++++++++++++++++++++++ lib/tls/internal.h | 26 ++++ lib/tls/store.c | 254 +++++++++++++++++++++++++++++++++++++ lib/tls/tls.h | 12 ++ tests/mkcerts.sh | 11 ++ tests/server.c | 6 + tests/smoke.py | 83 ++++++++++-- 18 files changed, 866 insertions(+), 26 deletions(-) create mode 100644 lib/tls/handshake.c create mode 100644 lib/tls/internal.h create mode 100644 lib/tls/store.c create mode 100644 lib/tls/tls.h create mode 100644 tests/mkcerts.sh diff --git a/.gitignore b/.gitignore index d4e787c..620fb71 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ compile_commands.json tests/ioxd-test-server tests/ioxd-unit tests/ioxd-pipe-server +tests/certs/ diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index e6abbf1..ed3937f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -155,7 +155,7 @@ therefore never recycled while a completion for it is still coming. `ioxd__await_item` hands the next queued buffer over whole - the pipe's reader owns it from then until it returns it to the ring - and parks if the queue is empty. `await_send` stages a SEND SQE -(`MSG_WAITALL`, so the kernel finishes short sends itself) and parks until its CQE; the pipe's +(the loop around it finishes short sends; kernel TLS refuses `MSG_WAITALL`) and parks until its CQE; the pipe's writer is the only caller. Nothing above the pipe touches either. ### Shared nothing diff --git a/CMakeLists.txt b/CMakeLists.txt index 20e1600..a338687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,8 @@ add_library(ioxd lib/http/router.c lib/http/run.c lib/json/json.c + lib/tls/store.c + lib/tls/handshake.c third_party/picohttpparser/picohttpparser.c) add_library(ioxd::ioxd ALIAS ioxd) @@ -76,6 +78,15 @@ target_include_directories(ioxd lib third_party/picohttpparser) target_compile_definitions(ioxd PRIVATE _GNU_SOURCE) +# TLS: OpenSSL for the handshake only; the kernel does the records (TLS.md). +option(IOXD_TLS "TLS listeners (needs OpenSSL 3)" ON) +if(IOXD_TLS) + find_package(OpenSSL 3 REQUIRED) + target_compile_definitions(ioxd PRIVATE IOXD_TLS=1) + target_link_libraries(ioxd PUBLIC OpenSSL::SSL OpenSSL::Crypto) +else() + target_compile_definitions(ioxd PRIVATE IOXD_TLS=0) +endif() target_compile_options(ioxd PRIVATE -Wall -Wextra) # Fat LTO objects when supported: the archive stays plain-linkable, and consumers that link with # -flto get cross-file inlining (the demo below does). diff --git a/Makefile b/Makefile index 16d9825..706dd2e 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,15 @@ LTO := $(shell $(CC) -Werror -flto -ffat-lto-objects -x c -c /dev/null -o /d CFLAGS ?= -O3 -g $(LTO) WARN := -Wall -Wextra $(STD) CPP := -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser +# TLS: OpenSSL for the handshake only; the kernel does the records (TLS.md). make TLS=0 leaves it out. +TLS ?= 1 +ifeq ($(TLS),1) +CPP += -DIOXD_TLS=1 +LIBS := -lssl -lcrypto +else +CPP += -DIOXD_TLS=0 +LIBS := +endif HDRS := $(wildcard include/*.h include/ioxd/*.h lib/*/*.h) PTHREAD := -pthread @@ -36,7 +45,7 @@ LIBDIR := $(PREFIX)/lib INCDIR := $(PREFIX)/include PCDIR := $(LIBDIR)/pkgconfig -UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run json/json +UNITS := io/uring io/coro io/bufring io/conn io/proactor io/pipe http/engine http/api http/router http/run json/json tls/store tls/handshake OBJ := $(addprefix obj/,$(addsuffix .o,$(UNITS))) obj/io/switch_x86_64.o obj/picohttpparser.o PICOBJ := $(addprefix obj/pic/,$(addsuffix .o,$(UNITS))) obj/pic/io/switch_x86_64.o obj/pic/picohttpparser.o @@ -54,7 +63,7 @@ libioxd.a: $(OBJ) $(AR) rcs $@ $^ libioxd.so: $(PICOBJ) - $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(PTHREAD) + $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(PTHREAD) $(LIBS) # --- static objects (used by libioxd.a and the examples) --- obj/%.o: lib/%.c $(HDRS) @@ -82,21 +91,22 @@ obj/pic/picohttpparser.o: third_party/picohttpparser/picohttpparser.c examples: $(EXAMPLES) # Link the static archive directly so the example runs in-tree without installing the .so. ioxd-hello: playground/hello/main.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) # --- tests: the unit test, then the fixture server with both suites against it --- $(TESTSRV): tests/server.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) $(UNIT): tests/unit.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) $(PIPESRV): tests/pipe-server.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) CHECK_PORT ?= 8099 PIPE_PORT ?= 8101 # the fixture takes CHECK_PORT and the one after check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ - IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ + [ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null; \ + IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) IOXD_CERTS=tests/certs ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ python3 tests/smoke.py $(CHECK_PORT); s=$$?; python3 tests/stress.py $(CHECK_PORT); t=$$?; \ kill -INT $$pid; wait $$pid 2>/dev/null; \ @@ -107,7 +117,7 @@ check: $(TESTSRV) $(UNIT) $(PIPESRV) # --- pkg-config --- ioxd.pc: ioxd.pc.in - sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' $< > $@ + sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' -e 's|@LIBS@|$(LIBS)|g' $< > $@ # --- install / uninstall --- install: lib ioxd.pc diff --git a/include/ioxd.h b/include/ioxd.h index 89867af..d35867a 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -27,3 +27,4 @@ #include "ioxd/router.h" /* groups, endpoints, middleware; the script macros */ #include "ioxd/json.h" /* JSON written as you go; structs described once */ #include "ioxd/pipe.h" /* a connection as a pipe, for other protocols */ +#include "ioxd/tls.h" /* certificates, for a TLS listener */ diff --git a/ioxd.pc.in b/ioxd.pc.in index 1720194..0605779 100644 --- a/ioxd.pc.in +++ b/ioxd.pc.in @@ -8,4 +8,5 @@ Description: HTTP/1.1 server framework on a thread-per-core io_uring runtime Version: @VERSION@ URL: https://github.com/MDA2AV/libioxd Libs: -L${libdir} -lioxd -pthread +Libs.private: @LIBS@ Cflags: -I${includedir} -pthread diff --git a/lib/http/run.c b/lib/http/run.c index d1851a8..8862316 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -5,6 +5,7 @@ #include "http/router.h" #include "io/pipe.h" #include "io/proactor.h" +#include "tls/tls.h" #include #include @@ -127,13 +128,35 @@ static int run_workers(int workers, int port, handler_fn handler) return 0; } +/* A TLS listener's connection runs the handshake before its handler; a plain one goes straight in. */ +static int prologue(struct ioxd_pipe *pipe) +{ + struct listener *l = pipe->in.conn->listener; + return l->tls ? ioxd__tls_prologue(pipe, l->tls) : 0; +} + +static void serve_http(struct ioxd_pipe *pipe) +{ + if (prologue(pipe) == 0) + ioxd__serve(pipe); +} + int ioxd_run(int workers, int port) { ioxd__router_build(); /* the routes, resolved once, shared read-only */ - return run_workers(workers, port, ioxd__serve); + return run_workers(workers, port, serve_http); +} + +static ioxd_pipe_handler g_pipe_handler; + +static void serve_pipe(struct ioxd_pipe *pipe) +{ + if (prologue(pipe) == 0) + g_pipe_handler(pipe); } int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn) { - return run_workers(workers, port, fn); + g_pipe_handler = fn; + return run_workers(workers, port, serve_pipe); } diff --git a/lib/io/conn.c b/lib/io/conn.c index c99a5ab..c4d35e3 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -189,6 +189,12 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) if (result <= 0) { /* peer FIN (0), an error, or our own cancel */ if (has_buf) ioxd__bufring_return(&p->bufs, buf_id); + if (c->pausing && result == -ECANCELED) { /* our pause, not the end of input */ + c->pausing = false; + c->recv = RECV_PAUSED; + wake_reader(c); + return; + } if (!c->eof) { c->eof = true; c->err = result; @@ -221,7 +227,11 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) } if (!more) { /* the kernel ended the multishot: re-arm */ - if (!c->closed && !c->eof) { + if (c->pausing) { /* ended on its own while a pause was asked */ + c->pausing = false; + c->recv = RECV_PAUSED; + wake_reader(c); + } else if (!c->closed && !c->eof) { ioxd__arm_recv(p, c); } else { c->recv = RECV_DONE; @@ -257,8 +267,9 @@ static void conn_close(conn_t *c) if (c->recv == RECV_ARMED) { submit_cancel(p, UD(c, TAG_RECV)); - } else if (c->recv == RECV_STARVED) { - starved_remove(p, c); + } else if (c->recv == RECV_STARVED || c->recv == RECV_PAUSED) { + if (c->recv == RECV_STARVED) + starved_remove(p, c); c->recv = RECV_DONE; c->refs--; /* the recv side's reference; ours, dropped last, keeps c alive */ } @@ -305,6 +316,73 @@ int ioxd__await_item(conn_t *c, struct rx_item *out) /* Send all of buf: a SEND SQE per round, parked until its CQE. Returns len, or -errno. */ +int ioxd__recv_pause(conn_t *c) +{ + proactor_t *p = c->p; + if (c->recv == RECV_ARMED) { + c->pausing = true; + submit_cancel(p, UD(c, TAG_RECV)); + while (c->recv == RECV_ARMED) { /* data may still land meanwhile: fine, it is queued */ + c->waiter = coro_current(); + coro_yield(); + } + c->pausing = false; + } + if (c->recv == RECV_STARVED) { + starved_remove(p, c); + c->recv = RECV_PAUSED; + } + return c->recv == RECV_PAUSED ? 0 : -1; +} + +void ioxd__recv_resume(conn_t *c) +{ + if (c->recv == RECV_PAUSED) + ioxd__arm_recv(c->p, c); +} + +int ioxd__recv_exact(conn_t *c, void *dst, size_t n) +{ + uint8_t *at = dst; + size_t left = n; + while (left) { + op_t op; + struct io_uring_sqe *sqe = ioxd__sqe(c->p); + sqe->opcode = IORING_OP_RECV; + sqe->fd = c->fd; + sqe->flags = c->p->ring.fixed_files ? IOSQE_FIXED_FILE : 0; + sqe->addr = (uint64_t)(uintptr_t)at; + sqe->len = (uint32_t)left; + sqe->msg_flags = MSG_WAITALL; + int got = await_op(sqe, &op); + if (got < 0) + return got; + if (got == 0) + return -ECONNRESET; + at += got; + left -= (size_t)got; + } + return (int)n; +} + +int ioxd__setsockopt(conn_t *c, int level, int name, const void *val, size_t len) +{ + op_t op; + struct io_uring_sqe *sqe = ioxd__sqe(c->p); + sqe->opcode = IORING_OP_URING_CMD; + sqe->fd = c->fd; + sqe->flags = c->p->ring.fixed_files ? IOSQE_FIXED_FILE : 0; + sqe->cmd_op = SOCKET_URING_OP_SETSOCKOPT; + sqe->level = (uint32_t)level; + sqe->optname = (uint32_t)name; + sqe->optval = (uint64_t)(uintptr_t)val; + sqe->optlen = (uint32_t)len; + int rc = await_op(sqe, &op); + if ((rc == -EOPNOTSUPP || rc == -EINVAL) && !c->p->ring.fixed_files) /* a kernel without the command */ + rc = setsockopt(c->fd, level, name, val, (socklen_t)len) < 0 ? -errno : 0; + return rc; +} + int await_send(conn_t *c, const void *buf, size_t len) { const uint8_t *src = buf; @@ -317,7 +395,7 @@ int await_send(conn_t *c, const void *buf, size_t len) sqe->flags = c->p->ring.fixed_files ? IOSQE_FIXED_FILE : 0; sqe->addr = (uint64_t)(uintptr_t)src; sqe->len = left > UINT32_MAX ? UINT32_MAX : (uint32_t)left; - sqe->msg_flags = MSG_NOSIGNAL | MSG_WAITALL; /* no SIGPIPE; the kernel finishes short sends */ + sqe->msg_flags = MSG_NOSIGNAL; /* no SIGPIPE; the loop finishes short sends (kernel TLS refuses MSG_WAITALL) */ int n = await_op(sqe, &op); if (n < 0) return n; diff --git a/lib/io/conn.h b/lib/io/conn.h index f8b2bf2..7209531 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -33,6 +33,7 @@ struct rx_item { enum recv_state { RECV_ARMED, /* multishot recv in flight; the kernel may post CQEs */ RECV_STARVED, /* it ended on -ENOBUFS; re-armed once buffers return */ + RECV_PAUSED, /* stopped on purpose, its ref kept; resume re-arms */ RECV_DONE, /* it posted its terminal CQE */ }; @@ -44,6 +45,7 @@ struct conn { struct rx_item rx[RX_QUEUE]; /* delivered while nobody was reading */ unsigned rx_head, rx_tail; enum recv_state recv; + bool pausing; /* a cancel is in flight to pause the recv */ int refs; /* the handler coroutine + the armed/starved recv */ bool closed; /* the handler returned; fd closed */ bool eof; /* recv ended: peer FIN, error, or queue overflow */ @@ -57,6 +59,14 @@ struct conn { int await_send(conn_t *c, const void *buf, size_t len); /* len when all sent, else -errno */ int ioxd__await_item(conn_t *c, struct rx_item *out); /* the next received buffer, whole: 1, 0 at the end, <0 -errno (the reader's primitive) */ +/* For a protocol prologue (TLS): stop the multishot recv so nothing more leaves the socket, take + * what it already delivered, read exact byte counts straight from the socket, program the + * socket, then resume. All suspend like any await. */ +int ioxd__recv_pause (conn_t *c); /* 0 once stopped; -1 if the input already ended */ +void ioxd__recv_resume(conn_t *c); +int ioxd__recv_exact (conn_t *c, void *dst, size_t n); /* n bytes into dst, or <0 */ +int ioxd__setsockopt (conn_t *c, int level, int name, const void *val, size_t len); /* 0 or -errno; over the ring */ + /* For the loop (proactor.c): a connection's life from accept to the pool. */ conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd); /* from the pool, or fresh */ void ioxd__conn_main(void *arg); /* the connection's coroutine body */ diff --git a/lib/io/pipe.c b/lib/io/pipe.c index 936d944..67abe96 100644 --- a/lib/io/pipe.c +++ b/lib/io/pipe.c @@ -271,6 +271,41 @@ int ioxd_pipereader_copy(ioxd_pipereader *pr, void *dst, size_t n) } } +bool ioxd_pipereader_avail(ioxd_pipereader *pr, ioxd_slice *live) +{ + if (pr->error) + return false; + ioxd_slice l = live_span(pr); + if (l.len <= pr->examined) { /* all seen: take a delivered buffer, if one is queued */ + if (pr->conn->rx_head == pr->conn->rx_tail || more(pr) <= 0) + return false; + l = live_span(pr); + } + *live = l; + return true; +} + +bool ioxd_pipereader_inject(ioxd_pipereader *pr, const void *data, size_t n) +{ + if (!pr->live_in_buf) { + if (pr->has_cur && pr->cur_pos < pr->cur.len) { /* live bytes in place: they move first */ + if (!gather(pr)) + return false; + } else { + pr->buf_pos = pr->buf_end = pr->floor; + pr->live_in_buf = true; + } + } + if (pr->buf_end + n > pr->cap) { + compact(pr); + if (pr->buf_end + n > pr->cap) + return false; + } + memcpy(pr->buf + pr->buf_end, data, n); + pr->buf_end += n; + return true; +} + /* ── the writer ────────────────────────────────────────────────────────────────────────── */ void ioxd_pipewriter_init(ioxd_pipewriter *pw, conn_t *conn, char *buf, size_t lead, size_t cap, size_t slack) diff --git a/lib/io/pipe.h b/lib/io/pipe.h index ae17dcf..bc9bbb8 100644 --- a/lib/io/pipe.h +++ b/lib/io/pipe.h @@ -47,6 +47,8 @@ void ioxd_pipereader_run_begin(ioxd_pipereader *pr); / ioxd_slice ioxd_pipereader_run (const ioxd_pipereader *pr); /* the run in progress */ void ioxd_pipereader_release (ioxd_pipereader *pr); /* forget every kept byte; live bytes stay */ int ioxd_pipereader_copy (ioxd_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ +bool ioxd_pipereader_avail (ioxd_pipereader *pr, ioxd_slice *live); /* like read, but never waits: false when nothing unexamined was delivered */ +bool ioxd_pipereader_inject (ioxd_pipereader *pr, const void *data, size_t n); /* bytes that arrived by another route, appended to the live bytes; false: no room */ /* The writer: a slab with a head and a tail. Data goes in at the tail (reserve/advance, or write); * a frame's front goes into the lead just before the pending data and its back into the slack just diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c new file mode 100644 index 0000000..52a0f35 --- /dev/null +++ b/lib/tls/handshake.c @@ -0,0 +1,298 @@ +/* + * tls/handshake.c - the prologue of a TLS connection: an OpenSSL handshake over the pipe, the + * traffic secrets caught by the keylog callback, HKDF-Expand-Label into key and IV, and the keys + * into the socket, so the kernel does every record from then on. See TLS.md. + */ +#include "tls/tls.h" +#include "tls/internal.h" + +#include +#include +#include +#include + +#if IOXD_TLS + +#include +#include +#include +#include +#include +#include +#include + +#define SECRET_LEN 32U /* SHA-256 suite: the traffic secrets */ +#define RECORD_MAX (5 + 16384 + 256) /* header, plaintext, tag and padding */ +#define PLAIN_MAX 65536 /* what a client may send before we listen */ + +/* The secrets of one handshake, found through the SSL's ex_data. */ +struct secrets { + unsigned char tx[SECRET_LEN], rx[SECRET_LEN]; /* server and client application traffic secrets */ + bool have_tx, have_rx; +}; + +static int ex_index; +static pthread_once_t ex_once = PTHREAD_ONCE_INIT; +static void make_ex_index(void) +{ + ex_index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); +} + +/* The last OpenSSL error, as text. */ +static const char *ssl_error_text(void) +{ + static thread_local char text[256]; + ERR_error_string_n(ERR_get_error(), text, sizeof text); + return text; +} + +/* 64 hex characters into 32 bytes. */ +static bool unhex(const char *hex, unsigned char *out) +{ + for (size_t i = 0; i < SECRET_LEN; i++) { + int hi = ioxd__hexdigit(hex[2 * i]), lo = ioxd__hexdigit(hex[2 * i + 1]); + if (hi < 0 || lo < 0) + return false; + out[i] = (unsigned char)((unsigned)hi << 4 | (unsigned)lo); + } + return true; +} + +/* "SERVER_TRAFFIC_SECRET_0 " and its CLIENT twin: the two we need. */ +void ioxd__tls_keylog(const SSL *ssl, const char *line) +{ + struct secrets *s = SSL_get_ex_data(ssl, ex_index); + if (!s) + return; + const char *tag = nullptr; + unsigned char *into = nullptr; + bool *have = nullptr; + if (strncmp(line, "SERVER_TRAFFIC_SECRET_0 ", 24) == 0) { tag = line + 24; into = s->tx; have = &s->have_tx; } + if (strncmp(line, "CLIENT_TRAFFIC_SECRET_0 ", 24) == 0) { tag = line + 24; into = s->rx; have = &s->have_rx; } + if (!tag) + return; + const char *secret = strchr(tag, ' '); /* past the client random */ + if (secret && strlen(secret + 1) >= (size_t)2 * SECRET_LEN && unhex(secret + 1, into)) + *have = true; +} + +/* RFC 8446 HKDF-Expand-Label(secret, label, "", n). */ +static bool expand_label(const unsigned char *secret, const char *label, unsigned char *out, size_t n) +{ + unsigned char info[64]; + size_t label_len = 6 + strlen(label), at = 0; + info[at++] = (unsigned char)(n >> 8); + info[at++] = (unsigned char)n; + info[at++] = (unsigned char)label_len; + memcpy(info + at, "tls13 ", 6); + at += 6; + memcpy(info + at, label, strlen(label)); + at += strlen(label); + info[at++] = 0; /* empty context */ + EVP_PKEY_CTX *k = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr); + if (!k) + return false; + size_t len = n; + bool ok = EVP_PKEY_derive_init(k) == 1 + && EVP_PKEY_CTX_hkdf_mode(k, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) == 1 + && EVP_PKEY_CTX_set_hkdf_md(k, EVP_sha256()) == 1 + && EVP_PKEY_CTX_set1_hkdf_key(k, secret, SECRET_LEN) == 1 + && EVP_PKEY_CTX_add1_hkdf_info(k, info, (int)at) == 1 + && EVP_PKEY_derive(k, out, &len) == 1 && len == n; + EVP_PKEY_CTX_free(k); + return ok; +} + +/* One direction's keys into the socket, from its traffic secret and the record sequence. */ +static int install(conn_t *c, int direction, const unsigned char *secret, uint64_t seq) +{ + unsigned char key[16], iv[12]; + if (!expand_label(secret, "key", key, sizeof key) || !expand_label(secret, "iv", iv, sizeof iv)) + return -1; + struct tls12_crypto_info_aes_gcm_128 ci = {}; + ci.info.version = TLS_1_3_VERSION; + ci.info.cipher_type = TLS_CIPHER_AES_GCM_128; + memcpy(ci.key, key, sizeof key); + memcpy(ci.salt, iv, 4); /* the 12-byte nonce, as the kernel splits it */ + memcpy(ci.iv, iv + 4, 8); + for (unsigned i = 0; i < 8; i++) + ci.rec_seq[i] = (unsigned char)(seq >> (56U - 8U * i)); + int rc = ioxd__setsockopt(c, SOL_TLS, direction, &ci, sizeof ci); + explicit_bzero(&ci, sizeof ci); + explicit_bzero(key, sizeof key); + explicit_bzero(iv, sizeof iv); + return rc; +} + +/* Everything the write BIO holds, out through the pipe. */ +static int flush_outbound(struct ioxd_pipe *pipe, BIO *wbio) +{ + char buf[4096]; + int n; + while ((n = BIO_read(wbio, buf, sizeof buf)) > 0) + if (ioxd_pipewriter_write(&pipe->out, buf, (size_t)n) < 0) + return -1; + return ioxd_pipewriter_flush(&pipe->out); +} + +/* Whatever the pipe has, or the next thing it gets, into the read BIO. */ +static int feed_inbound(struct ioxd_pipe *pipe, BIO *rbio) +{ + ioxd_slice live = { nullptr, 0 }; + int rc = ioxd_pipereader_read(&pipe->in, &live); + if (rc <= 0) + return -1; + BIO_write(rbio, live.p, (int)live.len); + ioxd_pipereader_drop(&pipe->in, live.len); + return 0; +} + +/* The length of the TLS record at the front of live, header included. */ +static size_t record_len(ioxd_slice live) +{ + return 5 + ((size_t)(unsigned char)live.p[3] << 8 | (unsigned char)live.p[4]); +} + +/* After the handshake, before the kernel takes over receiving: the client may already have sent + * application data, part of it delivered to us, part still in the socket. Kernel RX starts at a + * record boundary in the socket, so with the multishot recv stopped this takes whole records + * from what was delivered - fetching the tail of a split one straight from the socket - through + * OpenSSL, keeping the plaintext aside. The count consumed is the RX record sequence. */ +static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, unsigned char *plain, size_t *plain_len) +{ + ioxd_pipereader *pr = &pipe->in; + conn_t *c = pr->conn; + unsigned char tail[RECORD_MAX]; + long records = 0; + for (;;) { + ioxd_slice live = { nullptr, 0 }; + if (!ioxd_pipereader_avail(pr, &live)) + break; /* nothing delivered is left: the socket is at a boundary */ + while (live.len < 5 || live.len < record_len(live)) { + size_t need = live.len < 5 ? 5 - live.len : record_len(live) - live.len; + if (live.len >= 5 && record_len(live) > RECORD_MAX) + return -1; + ioxd_pipereader_examine(pr, live.len); + if (ioxd_pipereader_avail(pr, &live)) + continue; /* the next delivered buffer joined it */ + if (ioxd__recv_exact(c, tail, need) < 0 || !ioxd_pipereader_inject(pr, tail, need)) + return -1; /* the rest was still in the socket */ + if (!ioxd_pipereader_avail(pr, &live)) + return -1; + } + size_t len = record_len(live); + if ((unsigned char)live.p[0] != 23) /* not application data: an alert; give up */ + return -1; + BIO_write(rbio, live.p, (int)len); + ioxd_pipereader_drop(pr, len); + records++; + int n; + while ((n = SSL_read(ssl, plain + *plain_len, (int)(PLAIN_MAX - *plain_len))) > 0) + *plain_len += (size_t)n; + if (SSL_get_error(ssl, n) != SSL_ERROR_WANT_READ) + return -1; /* close_notify, or a record we cannot take */ + } + return records; +} + +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) +{ + pthread_once(&ex_once, make_ex_index); + conn_t *c = pipe->in.conn; + struct table *t = ioxd__tls_acquire(tls); + struct secrets s = {}; + unsigned char *plain = nullptr; + const char *why = nullptr; /* set on every failure: logged once */ + int r; + + SSL *ssl = SSL_new(ioxd__tls_fallback(t)); + BIO *rbio = BIO_new(BIO_s_mem()); + BIO *wbio = BIO_new(BIO_s_mem()); + if (!ssl || !rbio || !wbio) { + why = "out of memory"; + goto out; + } + SSL_set_bio(ssl, rbio, wbio); /* the SSL owns both from here */ + SSL_set_accept_state(ssl); + SSL_set_ex_data(ssl, ex_index, &s); + + for (;;) { /* the handshake, as an ordinary await loop */ + int ret = SSL_do_handshake(ssl); + int err = ret == 1 ? SSL_ERROR_NONE : SSL_get_error(ssl, ret); + if (flush_outbound(pipe, wbio) < 0) { + why = "peer gone while sending the handshake"; + goto out; + } + if (ret == 1) + break; + if (err != SSL_ERROR_WANT_READ) { + why = ssl_error_text(); + goto out; + } + if (feed_inbound(pipe, rbio) < 0) { + why = "peer gone during the handshake"; + goto out; + } + } + if (!s.have_tx || !s.have_rx) { + why = "no traffic secrets from the keylog callback"; + goto out; + } + + if (ioxd__recv_pause(c) < 0) { /* nothing more leaves the socket meanwhile */ + why = "input ended after the handshake"; + goto out; + } + plain = malloc(PLAIN_MAX); + size_t plain_len = 0; + long records = plain ? drain_records(pipe, ssl, rbio, plain, &plain_len) : -1; + if (records < 0) { + why = "early application data could not be taken"; + goto out; + } + + r = ioxd__setsockopt(c, SOL_TCP, TCP_ULP, "tls", sizeof "tls"); + if (r < 0) { + why = r == -ENOENT ? "kernel TLS unavailable: is the tls module loaded?" : strerror(-r); + goto out; + } + r = install(c, TLS_TX, s.tx, 0); + if (r == 0) + r = install(c, TLS_RX, s.rx, (uint64_t)records); + if (r < 0) { + why = r == -1 ? "key derivation failed" : strerror(-r); + goto out; + } + if (plain_len && !ioxd_pipereader_inject(&pipe->in, plain, plain_len)) { + why = "early application data does not fit"; + goto out; + } + ioxd__recv_resume(c); +out: + if (why) + fprintf(stderr, "ioxd_tls: connection dropped: %s\n", why); + explicit_bzero(&s, sizeof s); + if (plain) { + explicit_bzero(plain, PLAIN_MAX); + free(plain); + } + if (ssl) { + SSL_free(ssl); + } else { + BIO_free(rbio); + BIO_free(wbio); + } + ioxd__tls_release(tls, t); + return why ? -1 : 0; +} + +#else /* built without TLS */ + +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) +{ + (void)pipe; + (void)tls; + return -1; +} + +#endif diff --git a/lib/tls/internal.h b/lib/tls/internal.h new file mode 100644 index 0000000..46bc765 --- /dev/null +++ b/lib/tls/internal.h @@ -0,0 +1,26 @@ +/* + * tls/internal.h - what the store and the handshake share: the table a handshake holds a + * reference to, and the keylog callback the store installs on every context. + */ +#pragma once + +#include "ioxd/tls.h" + +/* The value of a hex digit, or -1. */ +static inline int ioxd__hexdigit(char c) +{ + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + +#if IOXD_TLS +#include + +struct table; +struct table *ioxd__tls_acquire (ioxd_tls *tls); /* store.c: the table serving now, referenced */ +void ioxd__tls_release (ioxd_tls *tls, struct table *t); +SSL_CTX *ioxd__tls_fallback(const struct table *t); /* the context a handshake starts on */ +void ioxd__tls_keylog (const SSL *ssl, const char *line); /* handshake.c: catches the traffic secrets */ +#endif diff --git a/lib/tls/store.c b/lib/tls/store.c new file mode 100644 index 0000000..8fe54a8 --- /dev/null +++ b/lib/tls/store.c @@ -0,0 +1,254 @@ +/* + * tls/store.c - the certificate store: one SSL_CTX per host directory, pinned to what kernel TLS + * can carry (TLS 1.3, TLS_AES_128_GCM_SHA256, no tickets), chosen by SNI at the ClientHello. + * The table of hosts is reference-counted so a reload swaps it under handshakes in flight. + */ +#include "tls/tls.h" +#include "tls/internal.h" + +#include +#include +#include + +#if IOXD_TLS + +#include +#include +#include +#include +#include + +struct host { + char *name; + SSL_CTX *ctx; +}; + +struct table { + int refs; /* the store's own, plus one per handshake in flight */ + struct host *hosts; + int n; + SSL_CTX *fallback; /* `default`, or the first host */ +}; + +struct ioxd_tls { + char *dir; + struct table *table; + pthread_mutex_t lock; /* around the table pointer and its refs */ +}; + +/* The last OpenSSL error, as text. */ +static const char *ssl_error(void) +{ + static thread_local char text[256]; + ERR_error_string_n(ERR_get_error(), text, sizeof text); + return text; +} + +/* Exact hostname compare, ASCII case-insensitive. */ +static bool host_eq(const char *a, size_t alen, const char *b) +{ + if (strlen(b) != alen) + return false; + for (size_t i = 0; i < alen; i++) + if (((unsigned char)a[i] | 0x20U) != ((unsigned char)b[i] | 0x20U)) + return false; + return true; +} + +/* The context for a server name: exact, then the wildcard of its parent domain. */ +static SSL_CTX *lookup(const struct table *t, const char *name, size_t len) +{ + for (int i = 0; i < t->n; i++) + if (host_eq(name, len, t->hosts[i].name)) + return t->hosts[i].ctx; + const char *dot = memchr(name, '.', len); + if (dot) { /* a.example.com -> _.example.com */ + char wild[256]; + size_t rest = len - (size_t)(dot - name); + if (rest + 1 < sizeof wild) { + wild[0] = '_'; + memcpy(wild + 1, dot, rest); + for (int i = 0; i < t->n; i++) + if (host_eq(wild, rest + 1, t->hosts[i].name)) + return t->hosts[i].ctx; + } + } + return nullptr; +} + +/* The ClientHello: pick the certificate by the server name, when there is one we know. */ +static int on_client_hello(SSL *ssl, int *alert, void *arg) /* NOLINT(readability-non-const-parameter): OpenSSL's signature */ +{ + (void)alert; + const struct table *t = arg; + const unsigned char *ext; + size_t ext_len; + if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &ext, &ext_len) || ext_len < 5) + return SSL_CLIENT_HELLO_SUCCESS; /* no SNI: the default */ + size_t list_len = (size_t)ext[0] << 8 | ext[1]; /* ServerNameList: one host_name entry */ + size_t name_len = (size_t)ext[3] << 8 | ext[4]; + if (list_len + 2 > ext_len || ext[2] != 0 || name_len + 5 > ext_len) + return SSL_CLIENT_HELLO_SUCCESS; + SSL_CTX *ctx = lookup(t, (const char *)ext + 5, name_len); + if (ctx) + SSL_set_SSL_CTX(ssl, ctx); + return SSL_CLIENT_HELLO_SUCCESS; +} + +/* One host's context: pinned to what the kernel can carry, with the files it was given. */ +static SSL_CTX *context_for(const char *cert, const char *key) +{ + SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); + if (!ctx) + return nullptr; + bool ok = SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION) + && SSL_CTX_set_ciphersuites(ctx, "TLS_AES_128_GCM_SHA256") + && SSL_CTX_set_num_tickets(ctx, 0) == 1 + && SSL_CTX_use_certificate_chain_file(ctx, cert) == 1 + && SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) == 1 + && SSL_CTX_check_private_key(ctx) == 1; + if (!ok) { + SSL_CTX_free(ctx); + return nullptr; + } + SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION | SSL_OP_NO_TICKET); + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_keylog_callback(ctx, ioxd__tls_keylog); + return ctx; +} + +static void table_free(struct table *t) +{ + for (int i = 0; i < t->n; i++) { + SSL_CTX_free(t->hosts[i].ctx); + free(t->hosts[i].name); + } + free(t->hosts); + free(t); +} + +/* Every host directory under dir into a new table; a host that fails keeps its context from + * `old` when it had one there. NULL when no host loads. */ +static struct table *load(const char *dir, const struct table *old) +{ + DIR *d = opendir(dir); + if (!d) { + fprintf(stderr, "ioxd_tls: %s: %s\n", dir, strerror(errno)); + return nullptr; + } + struct table *t = calloc(1, sizeof *t); + t->refs = 1; + struct dirent *e; + while ((e = readdir(d))) { + if (e->d_name[0] == '.') + continue; + char cert[PATH_MAX], key[PATH_MAX]; + snprintf(cert, sizeof cert, "%s/%s/cert.pem", dir, e->d_name); + snprintf(key, sizeof key, "%s/%s/key.pem", dir, e->d_name); + struct stat st; + if (stat(cert, &st) != 0) + continue; /* not a host directory */ + SSL_CTX *ctx = context_for(cert, key); + if (!ctx) { + fprintf(stderr, "ioxd_tls: %s: %s\n", cert, ssl_error()); + if (old) { /* keep what was serving */ + for (int i = 0; i < old->n; i++) + if (strcmp(old->hosts[i].name, e->d_name) == 0) { + ctx = old->hosts[i].ctx; + SSL_CTX_up_ref(ctx); + } + } + if (!ctx) + continue; + } + struct host *grown = realloc(t->hosts, ((size_t)t->n + 1) * sizeof *grown); + if (!grown) { + perror("realloc"); + abort(); + } + t->hosts = grown; + t->hosts[t->n++] = (struct host){ strdup(e->d_name), ctx }; + if (strcmp(e->d_name, "default") == 0) + t->fallback = ctx; + } + closedir(d); + if (t->n == 0) { + fprintf(stderr, "ioxd_tls: %s: no /cert.pem + key.pem loaded\n", dir); + table_free(t); + return nullptr; + } + if (!t->fallback) { + t->fallback = t->hosts[0].ctx; + fprintf(stderr, "ioxd_tls: no `default` host; %s answers when SNI matches nothing\n", t->hosts[0].name); + } + for (int i = 0; i < t->n; i++) /* the ClientHello callback sees this table */ + SSL_CTX_set_client_hello_cb(t->hosts[i].ctx, on_client_hello, t); + return t; +} + +ioxd_tls *ioxd_tls_new(const char *dir) +{ + struct table *t = load(dir, nullptr); + if (!t) + return nullptr; + ioxd_tls *tls = calloc(1, sizeof *tls); + tls->dir = strdup(dir); + tls->table = t; + pthread_mutex_init(&tls->lock, nullptr); + fprintf(stderr, "ioxd_tls: %d host%s from %s\n", t->n, t->n == 1 ? "" : "s", dir); + return tls; +} + +/* A reference to the table serving now; released after the handshake. */ +struct table *ioxd__tls_acquire(ioxd_tls *tls) +{ + pthread_mutex_lock(&tls->lock); + struct table *t = tls->table; + t->refs++; + pthread_mutex_unlock(&tls->lock); + return t; +} + +void ioxd__tls_release(ioxd_tls *tls, struct table *t) +{ + pthread_mutex_lock(&tls->lock); + int left = --t->refs; + pthread_mutex_unlock(&tls->lock); + if (left == 0) + table_free(t); +} + +SSL_CTX *ioxd__tls_fallback(const struct table *t) +{ + return t->fallback; +} + +int ioxd_tls_reload(ioxd_tls *tls) +{ + struct table *fresh = load(tls->dir, tls->table); + if (!fresh) + return -1; + pthread_mutex_lock(&tls->lock); + struct table *old = tls->table; + tls->table = fresh; + pthread_mutex_unlock(&tls->lock); + ioxd__tls_release(tls, old); /* the store's own reference to the old table */ + fprintf(stderr, "ioxd_tls: reloaded %d host%s from %s\n", fresh->n, fresh->n == 1 ? "" : "s", tls->dir); + return 0; +} + +#else /* built without TLS */ + +ioxd_tls *ioxd_tls_new(const char *dir) +{ + fprintf(stderr, "ioxd_tls: %s: this build has no TLS (make TLS=1 with libssl-dev)\n", dir); + return nullptr; +} + +int ioxd_tls_reload(ioxd_tls *tls) +{ + (void)tls; + return -1; +} + +#endif diff --git a/lib/tls/tls.h b/lib/tls/tls.h new file mode 100644 index 0000000..909280d --- /dev/null +++ b/lib/tls/tls.h @@ -0,0 +1,12 @@ +/* + * tls/tls.h - what the runner needs from the TLS plane: the prologue a TLS connection runs before + * its handler. The store itself is the public ioxd/tls.h. + */ +#pragma once + +#include "ioxd/tls.h" +#include "io/pipe.h" + +/* The handshake over the pipe, then the keys into the socket. 0, or -1: the connection is not + * usable (the handshake failed, the peer left, kernel TLS is unavailable). */ +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls); diff --git a/tests/mkcerts.sh b/tests/mkcerts.sh new file mode 100644 index 0000000..7876783 --- /dev/null +++ b/tests/mkcerts.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Self-signed certificates for the test fixture: `default` (CN=localhost) and one SNI host. +set -e +dir=${1:-tests/certs} +for host in default sni.test; do + cn=localhost; [ "$host" = default ] || cn=$host + mkdir -p "$dir/$host" + openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -subj "/CN=$cn" -days 30 \ + -keyout "$dir/$host/key.pem" -out "$dir/$host/cert.pem" 2>/dev/null +done +echo "certificates in $dir" diff --git a/tests/server.c b/tests/server.c index 8d47e59..26a9a2c 100644 --- a/tests/server.c +++ b/tests/server.c @@ -331,5 +331,11 @@ int main(void) int port = (int)env_number("IOXD_PORT", 8080); int p = port > 0 && port < 65536 ? port : 8080; ioxd_listen(p + 1, NULL); /* a second plain port: the same routes */ + const char *certs = getenv("IOXD_CERTS"); /* and a TLS port, given a certificate directory */ + if (certs) { + ioxd_tls *tls = ioxd_tls_new(certs); + if (tls) + ioxd_listen(p + 2, tls); + } return ioxd_run(workers, p); } diff --git a/tests/smoke.py b/tests/smoke.py index 6ed1120..d7d5ff2 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -50,6 +50,18 @@ def read_response(s): return status, headers, body +def dechunk(raw): + """A chunked body, decoded.""" + out = b"" + while True: + line, _, raw = raw.partition(b"\r\n") + n = int(line.split(b";")[0], 16) + if n == 0: + return out + out += raw[:n] + raw = raw[n + 2:] + + def get(path, extra=b"", keep=False): s = connect() conn = "keep-alive" if keep else "close" @@ -303,6 +315,66 @@ def raw_exchange(pieces, pause=0.03): st, hd, body = None, {}, b"" s.close() results.append(check("ignored 2 MB body -> reply served with Connection: close", st == 404 and hd.get("connection") == "close")) +# --- TLS: the third port, kernel TLS after an OpenSSL handshake (tests/certs from mkcerts.sh) --- +import os, ssl +CERTS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "certs") +if os.path.exists(os.path.join(CERTS, "default", "cert.pem")): + def cert_der(host): + return ssl.PEM_cert_to_DER_cert(open(os.path.join(CERTS, host, "cert.pem")).read()) + + def tls_connect(server_hostname="localhost", max_version=None): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + if max_version: + ctx.maximum_version = max_version + raw = socket.create_connection(("127.0.0.1", PORT + 2), timeout=5) + return ctx.wrap_socket(raw, server_hostname=server_hostname) + + s = tls_connect() + s.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") + st, hd, body = read_response(s) + results.append(check("TLS: GET /health -> 200 ok over TLS 1.3 with the default certificate", + st == 200 and body == b"ok" and s.version() == "TLSv1.3" and s.getpeercert(True) == cert_der("default"))) + s.close() + s = tls_connect(server_hostname="sni.test") + results.append(check("TLS: SNI sni.test -> that host's certificate", s.getpeercert(True) == cert_der("sni.test"))) + s.close() + s = tls_connect(server_hostname="nobody.example") + results.append(check("TLS: unknown SNI -> the default certificate", s.getpeercert(True) == cert_der("default"))) + s.close() + s = tls_connect() + s.send(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 9\r\n\r\nhello tls") + st, hd, body = read_response(s) + results.append(check("TLS: POST /echo with a body -> echoed (kernel RX)", st == 200 and body == b"hello tls")) + s.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") + st, hd, body = read_response(s) + results.append(check("TLS: a second request on the same connection -> 200", st == 200 and body == b"ok")) + s.close() + s = tls_connect() + s.send(b"GET /json/big?n=3000 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") + raw = b"" + while True: + try: + piece = s.recv(65536) + except (socket.timeout, ssl.SSLError): + break + if not piece: + break + raw += piece + s.close() + head, _, rest = raw.partition(b"\r\n\r\n") + doc = __import__("json").loads(dechunk(rest)) + results.append(check("TLS: 3000 objects streamed chunked over kernel TX, valid JSON", len(doc) == 3000)) + try: + s = tls_connect(max_version=ssl.TLSVersion.TLSv1_2) + s.close() + results.append(check("TLS: a TLS 1.2 client is refused", False)) + except ssl.SSLError: + results.append(check("TLS: a TLS 1.2 client is refused", True)) +else: + print("skip TLS: no tests/certs (run tests/mkcerts.sh)") + # --- a second listener: the port after ours serves the same routes --- s = socket.create_connection(("127.0.0.1", PORT + 1), timeout=5) s.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") @@ -319,17 +391,6 @@ def raw_exchange(pieces, pause=0.03): results.append(check("GET /json/x -> 400 from the handler", st == 400)) -def dechunk(raw): - out = b"" - while True: - line, _, raw = raw.partition(b"\r\n") - n = int(line.split(b";")[0], 16) - if n == 0: - return out - out += raw[:n] - raw = raw[n + 2:] - - s = connect() s.send(b"GET /json/big?n=3000 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") raw = b"" From 99328ba413abab86baa3811818f3cc2a37fe54a7 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 01:32:01 +0100 Subject: [PATCH 26/49] Tests: the TLS handoff at the wire level, the buffers at their limits, a 1 MB upload over TLS tests/tls_early.py (tlslite-ng, skipped when it is not installed) holds the client's writes back to send the request in the same TCP write as its Finished - whole, and with the record cut in two with a pause, so the server must decrypt what the kernel already delivered and fetch the tail of a split record before kernel RX takes over - then two early requests with the second split, a close_notify, and a corrupted record. make check runs it with TLS_PYTHON. The limits, at their boundaries, as known and to be grown later: a 15 KB request head served and one over 16 KB a 431; a 16000-byte body read whole and 16400 a 413; the 16 reply headers (15 beside the middleware's) with the next refused and the reply still served; a 3 KB reply header served and a 5 KB one closing the connection; 32 of 40 query parameters kept; 70 request headers a 400. Over TLS: a 1 MB upload streamed through kernel RX in 256 reads. The raw exchange helper decodes chunked replies. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- Makefile | 6 +- tests/server.c | 45 +++++++++++++++ tests/smoke.py | 39 +++++++++++++ tests/tls_early.py | 139 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 tests/tls_early.py diff --git a/Makefile b/Makefile index 706dd2e..4a12767 100644 --- a/Makefile +++ b/Makefile @@ -102,18 +102,20 @@ $(PIPESRV): tests/pipe-server.c libioxd.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) CHECK_PORT ?= 8099 -PIPE_PORT ?= 8101 # the fixture takes CHECK_PORT and the one after +PIPE_PORT ?= 8102 # the fixture takes CHECK_PORT and the two after (plain, TLS) +TLS_PYTHON ?= python3 # a python with tlslite-ng, for tests/tls_early.py (skips itself otherwise) check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ [ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null; \ IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) IOXD_CERTS=tests/certs ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ python3 tests/smoke.py $(CHECK_PORT); s=$$?; python3 tests/stress.py $(CHECK_PORT); t=$$?; \ + $(TLS_PYTHON) tests/tls_early.py $$(($(CHECK_PORT) + 2)); e=$$?; \ kill -INT $$pid; wait $$pid 2>/dev/null; \ ./$(PIPESRV) $(PIPE_PORT) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(PIPE_PORT) " && break; sleep 0.1; done; \ python3 tests/pipes.py $(PIPE_PORT); u=$$?; \ - kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t | u)) + kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t | e | u)) # --- pkg-config --- ioxd.pc: ioxd.pc.in diff --git a/tests/server.c b/tests/server.c index 26a9a2c..8198f2c 100644 --- a/tests/server.c +++ b/tests/server.c @@ -5,6 +5,7 @@ #include #include +#include /* GET / */ static void home(ioxd_ctx *ctx) @@ -264,6 +265,47 @@ static void json_big(ioxd_ctx *ctx) ioxd_json_end(&j); } +/* GET /headers?n=N - adds N headers; reports how many the reply took (IOXD_MAX_RESP_HEADERS). */ +static void headers(ioxd_ctx *ctx) +{ + static const char *names[32] = { + "x-h00", "x-h01", "x-h02", "x-h03", "x-h04", "x-h05", "x-h06", "x-h07", "x-h08", "x-h09", "x-h10", + "x-h11", "x-h12", "x-h13", "x-h14", "x-h15", "x-h16", "x-h17", "x-h18", "x-h19", "x-h20", "x-h21", + "x-h22", "x-h23", "x-h24", "x-h25", "x-h26", "x-h27", "x-h28", "x-h29", "x-h30", "x-h31", + }; + int64_t n = 0; + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioxd_slice_eq(ctx->req.params[i].key, "n")) + ioxd_to_i64(ctx->req.params[i].value, &n); + int taken = 0; + for (int64_t i = 0; i < n && i < 32; i++) + taken += ioxd_header(ctx, names[i], "v"); + ioxd_printf(ctx, "%d\n", taken); +} + +/* GET /bighead?len=N - one header whose value is N bytes: past the reply head's capacity the + * reply cannot be built and the connection closes without one. */ +static void bighead(ioxd_ctx *ctx) +{ + static char value[8192]; + int64_t len = 0; + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioxd_slice_eq(ctx->req.params[i].key, "len")) + ioxd_to_i64(ctx->req.params[i].value, &len); + if (len < 0 || len >= (int64_t)sizeof value) + len = sizeof value - 1; + memset(value, 'v', (size_t)len); + value[len] = '\0'; + ioxd_header(ctx, "x-big", value); + ioxd_text(ctx, "ok\n"); +} + +/* GET /params?... - how many query parameters the request kept (IOXD_MAX_PARAMS). */ +static void params(ioxd_ctx *ctx) +{ + ioxd_printf(ctx, "%zu\n", ctx->req.n_params); +} + /* Middleware: stamps a Server header, then runs the rest of the chain. Setting headers before * calling ioxd_next_run means they land even on a reply that streams (afterwards the head may * already be on the wire); c->status and the rest are there to inspect on the way back out. @@ -314,6 +356,9 @@ int main(void) IOXD_POST("/chunks", chunks); IOXD_GET ("/json/:id", json_item); IOXD_GET ("/json/big", json_big); /* static beside the capture */ + IOXD_GET ("/headers", headers); + IOXD_GET ("/bighead", bighead); + IOXD_GET ("/params", params); IOXD_DEFAULT(not_found); /* groups: /api with middleware of its own (IOXD_USE inside a block adds to that group; listing diff --git a/tests/smoke.py b/tests/smoke.py index d7d5ff2..1f2971b 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -264,6 +264,9 @@ def raw_exchange(pieces, pause=0.03): while b"\r\n\r\n" in data: head, _, rest = data.partition(b"\r\n\r\n") status = int(head.split(b" ")[1]) + if b"transfer-encoding: chunked" in head.lower(): # a streamed reply: the last on the connection + out.append((status, dechunk(rest))) + break n = 0 for line in head.split(b"\r\n"): if line.lower().startswith(b"content-length:"): @@ -315,6 +318,36 @@ def raw_exchange(pieces, pause=0.03): st, hd, body = None, {}, b"" s.close() results.append(check("ignored 2 MB body -> reply served with Connection: close", st == 404 and hd.get("connection") == "close")) +# --- the limits, at their boundaries: known, and the buffers can grow later --- +# a request head must fit the 16 KB gathering buffer (IOXD_PIPE_GATHER): 431 past it +big = b"x" * 15000 +st, hd, body = get("/health", extra=b"x-pad: " + big + b"\r\n") +results.append(check("a 15 KB request head -> 200 (gathered across receives)", st == 200 and body == b"ok")) +rs = raw_exchange([b"GET /health HTTP/1.1\r\nHost: x\r\nx-pad: " + b"x" * 16400 + b"\r\n\r\n"]) +results.append(check("a request head over 16 KB -> 431", len(rs) == 1 and rs[0][0] == 431)) +# a whole-body read must fit the same buffer with the head: 413 past it (streaming reads have no limit) +rs = raw_exchange([b"POST /echo HTTP/1.1\r\nHost: x\r\nConnection: close\r\nContent-Length: 16000\r\n\r\n" + b"e" * 16000]) +results.append(check("a 16000-byte body read whole -> echoed", rs == [(200, b"e" * 16000)])) +rs = raw_exchange([b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 16400\r\n\r\n" + b"e" * 16400]) +results.append(check("a 16400-byte body read whole -> 413", len(rs) == 1 and rs[0][0] == 413)) +# the reply takes at most 16 headers (IOXD_MAX_RESP_HEADERS); the root middleware's server header +# is one of them, so the handler gets 15, and the 16th is refused while the reply still goes out +st, hd, body = get("/headers?n=15") +results.append(check("15 reply headers beside the middleware's -> all taken", st == 200 and body == b"15\n" and hd.get("x-h14") == "v")) +st, hd, body = get("/headers?n=16") +results.append(check("one more -> refused, the reply still served with 15", st == 200 and body == b"15\n" and hd.get("x-h15") is None)) +# the reply head must fit 4 KB (IOXD_HEAD_CAP): a 3 KB header value goes, a 5 KB one cannot be built +st, hd, body = get("/bighead?len=3000") +results.append(check("a 3 KB reply header -> served", st == 200 and len(hd.get("x-big", "")) == 3000)) +rs = raw_exchange([b"GET /bighead?len=5000 HTTP/1.1\r\nHost: x\r\n\r\n"]) +results.append(check("a 5 KB reply header -> the reply cannot be built; the connection closes", rs == [])) +# the request keeps 32 query parameters; the rest are dropped +st, hd, body = get("/params?" + "&".join(f"p{i}=1" for i in range(40))) +results.append(check("40 query parameters -> 32 kept", st == 200 and body == b"32\n")) +# more request headers than the table holds is a parse failure: 400 +rs = raw_exchange([b"GET /health HTTP/1.1\r\nHost: x\r\n" + b"".join(b"x-h%d: v\r\n" % i for i in range(70)) + b"\r\n"]) +results.append(check("70 request headers -> 400 (the table holds 64)", len(rs) == 1 and rs[0][0] == 400)) + # --- TLS: the third port, kernel TLS after an OpenSSL handshake (tests/certs from mkcerts.sh) --- import os, ssl CERTS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "certs") @@ -366,6 +399,12 @@ def tls_connect(server_hostname="localhost", max_version=None): head, _, rest = raw.partition(b"\r\n\r\n") doc = __import__("json").loads(dechunk(rest)) results.append(check("TLS: 3000 objects streamed chunked over kernel TX, valid JSON", len(doc) == 3000)) + s = tls_connect() + s.send(b"POST /upload HTTP/1.1\r\nHost: x\r\nConnection: close\r\nContent-Length: 1048576\r\n\r\n") + s.sendall(b"u" * 1048576) + st, hd, body = read_response(s) + results.append(check("TLS: a 1 MB upload streamed through kernel RX -> 256 reads", st == 200 and body == b"1048576 bytes in 256 reads\n")) + s.close() try: s = tls_connect(max_version=ssl.TLSVersion.TLSv1_2) s.close() diff --git a/tests/tls_early.py b/tests/tls_early.py new file mode 100644 index 0000000..a05201f --- /dev/null +++ b/tests/tls_early.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +"""The TLS handoff at the wire level, with tlslite-ng (pip install tlslite-ng): the request sent +in the same TCP write as the client's Finished, once whole and once with its record cut in two +with a pause, so the server has to decrypt what the kernel already delivered and fetch the rest +of a split record from the socket before kernel RX takes over; then a close_notify, and a +corrupted record. Skips itself when tlslite-ng is not installed.""" +import socket, sys, time + +PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8101 # the fixture's TLS port + +try: + from tlslite import TLSConnection, HandshakeSettings +except ImportError: + print("skip tls_early: tlslite-ng not installed (pip install tlslite-ng)") + sys.exit(0) + + +class Held: + """A socket whose writes can be held back and released in one or more pieces, so several + TLS records - or half of one - go out in a single TCP write, or with a pause inside.""" + def __init__(self, sock): + self.sock, self.buf, self.hold = sock, bytearray(), False + + def send(self, data): + if self.hold: + self.buf += data + return len(data) + return self.sock.send(data) + + def release(self, n=None): + n = len(self.buf) if n is None else n + self.sock.sendall(bytes(self.buf[:n])) + del self.buf[:n] + + def recv(self, n): + self.release() # anything held goes out before we wait + return self.sock.recv(n) + + def __getattr__(self, name): + return getattr(self.sock, name) + + +def settings(): + s = HandshakeSettings() + s.minVersion = (3, 4) + s.maxVersion = (3, 4) + s.cipherNames = ["aes128gcm"] + return s + + +def connect(): + raw = socket.create_connection(("127.0.0.1", PORT), timeout=5) + held = Held(raw) + held.hold = True # the ClientHello is released by the first recv + conn = TLSConnection(held) + conn.handshakeClientCert(settings=settings(), serverName="localhost") + return conn, held # the client's Finished is still held + + +def read_reply(conn): + data = b"" + while b"\r\n\r\n" not in data: + data += conn.read() + head, _, body = data.partition(b"\r\n\r\n") + n = int([l for l in head.split(b"\r\n") if l.lower().startswith(b"content-length:")][0].split(b":")[1]) + while len(body) < n: + body += conn.read() + return head.split(b"\r\n")[0], body + + +results = [] + + +def check(name, cond): + print(f"{'ok ' if cond else 'FAIL'} {name}") + results.append(cond) + + +REQ = b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n" + +# 1. the request rides in the same TCP write as the Finished +conn, held = connect() +conn.write(REQ) +held.release() +status, body = read_reply(conn) +check("request in the same write as Finished -> 200 ok", status == b"HTTP/1.1 200 OK" and body == b"ok") +conn.close() + +# 2. the same, with the request's record cut in half and a pause: the tail is still in the socket +# when the server pauses its recv, and it has to fetch it before handing RX to the kernel +conn, held = connect() +conn.write(REQ) +total = len(held.buf) +held.release(total - 10) +time.sleep(0.3) +held.release() +status, body = read_reply(conn) +check("record split with a pause after the Finished -> 200 ok", status == b"HTTP/1.1 200 OK" and body == b"ok") +conn.close() + +# 3. two requests: the first whole with the Finished, the second's record split, keep-alive on the first +conn, held = connect() +conn.write(b"GET /health HTTP/1.1\r\nHost: x\r\n\r\n") +conn.write(REQ) +total = len(held.buf) +held.release(total - 7) +time.sleep(0.3) +held.release() +s1, b1 = read_reply(conn) +s2, b2 = read_reply(conn) +check("two early requests, the second's record split -> both answered", b1 == b"ok" and b2 == b"ok") +conn.close() + +# 4. a plain exchange, then the client's close_notify: the server sees a control record and closes +conn, held = connect() +held.release() +conn.write(b"GET /health HTTP/1.1\r\nHost: x\r\n\r\n") +status, body = read_reply(conn) +conn.closeSocket = False # close() sends close_notify but leaves the socket to us +conn.close() +eof = held.sock.recv(1) == b"" +check("close_notify from the client -> the server closes the connection", body == b"ok" and eof) + +# 5. garbage after the handshake: the kernel cannot decrypt it and the server closes +conn, held = connect() +held.release() +held.sock.sendall(b"\x17\x03\x03\x00\x20" + bytes(range(32))) +held.sock.settimeout(3) +try: + eof = held.sock.recv(1) == b"" +except ConnectionResetError: + eof = True # closed with unread data: a reset, still a close +except socket.timeout: + eof = False +check("a corrupted record after the handshake -> the server closes", eof) + +failed = results.count(False) +print("all passed" if not failed else f"{failed} FAILED") +sys.exit(1 if failed else 0) From 1f00207699442b2c827925f967fa0a782993d877 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 01:38:14 +0100 Subject: [PATCH 27/49] TLS: close_notify on close; the default test certificate is RSA; tlsfuzzer as a make target A TLS connection now ends with a close_notify alert sent as a control record through the kernel (sendmsg with TLS_SET_RECORD_TYPE, over the ring), so clients see a clean close; the wire test checks it. The fixture's default certificate is RSA - what most clients and test suites assume - with sni.test on ECDSA so both key types serve. make check-tlsfuzzer runs the six tlsfuzzer TLS 1.3 scripts that apply to a one-suite, TLS 1.3-only server; TLS.md records what the rest probe and why they fail by design, and the one real limit: a control record from the peer ends the connection without an alert of ours. The prologue's split-record scratch moved off the coroutine stack. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- Makefile | 16 ++++++++++++++++ TLS.md | 15 +++++++++++++++ lib/http/run.c | 14 ++++++++++---- lib/io/conn.c | 13 +++++++++++++ lib/io/conn.h | 2 ++ lib/tls/handshake.c | 33 ++++++++++++++++++++++++++++----- lib/tls/tls.h | 4 ++++ tests/mkcerts.sh | 12 ++++++------ tests/tls_early.py | 5 +++-- 9 files changed, 97 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 4a12767..77e4fa2 100644 --- a/Makefile +++ b/Makefile @@ -104,6 +104,7 @@ $(PIPESRV): tests/pipe-server.c libioxd.a CHECK_PORT ?= 8099 PIPE_PORT ?= 8102 # the fixture takes CHECK_PORT and the two after (plain, TLS) TLS_PYTHON ?= python3 # a python with tlslite-ng, for tests/tls_early.py (skips itself otherwise) +TLSFUZZER ?= # a tlsfuzzer checkout, for `make check-tlsfuzzer` (TLS_PYTHON must have its requirements) check: $(TESTSRV) $(UNIT) $(PIPESRV) @./$(UNIT) || exit 1; \ [ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null; \ @@ -140,3 +141,18 @@ uninstall: clean: rm -rf obj libioxd.a libioxd.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioxd.pc + +# tlsfuzzer's TLS 1.3 conformance scripts that apply to a TLS 1.3-only, one-suite server; the +# fixture must be up on CHECK_PORT with IOXD_CERTS (as `make check` runs it). Expected to pass: +# the rest of the suite probes AES-256, TLS 1.2 fallback and alerts we do not send (TLS.md). +TLSFUZZER_SCRIPTS := conversation zero-length-data record-padding unrecognised-groups keyshare-omitted rsa-signatures +.PHONY: check-tlsfuzzer +check-tlsfuzzer: $(TESTSRV) + @[ -n "$(TLSFUZZER)" ] || { echo "set TLSFUZZER= (git clone https://github.com/tlsfuzzer/tlsfuzzer)"; exit 2; } + @[ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null + @IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) IOXD_CERTS=tests/certs ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ + for i in $$(seq 1 50); do ss -ltn | grep -q ":$$(($(CHECK_PORT) + 2)) " && break; sleep 0.1; done; \ + rc=0; for t in $(TLSFUZZER_SCRIPTS); do \ + (cd $(TLSFUZZER) && $(abspath $(TLS_PYTHON)) scripts/test-tls13-$$t.py -h 127.0.0.1 -p $$(($(CHECK_PORT) + 2)) >/dev/null 2>&1) \ + && echo "ok tlsfuzzer test-tls13-$$t" || { echo "FAIL tlsfuzzer test-tls13-$$t"; rc=1; }; \ + done; kill -INT $$pid; wait $$pid 2>/dev/null; exit $$rc diff --git a/TLS.md b/TLS.md index cfae5c8..a3a9ee2 100644 --- a/TLS.md +++ b/TLS.md @@ -1,5 +1,20 @@ # TLS: one way, in the kernel (design, branch `streams`) +**Status.** Built: `lib/tls/store.c` (the store, SNI, reload) and `lib/tls/handshake.c` (the prologue +and the handoff); `ioxd_listen(port, ioxd_tls_new(dir))`. Verified by the smoke suite through +Python's `ssl` (default certificate, SNI, an unknown name, a POST body and a 1 MB upload through +kernel RX, keep-alive, a 3000-object reply through kernel TX, a refused TLS 1.2 client), by +`tests/tls_early.py` with tlslite-ng at the wire level (the request in the same TCP write as the +client's Finished, whole and with its record cut in two with a pause; two early requests; a +close_notify; a corrupted record), by six of tlsfuzzer's TLS 1.3 scripts (`make check-tlsfuzzer`), and +by a testssl.sh scan (TLS 1.3 only, forward-secret AEAD only). Known limits, all deliberate for now: +one suite, TLS_AES_128_GCM_SHA256 - AES-256-GCM and ChaCha20-Poly1305 are one table entry each in +the store and one key-size case in the handoff; no tickets, no 0-RTT, no client certificates; the +server sends close_notify when it closes, but a control record from the peer after the handoff +(an alert, a KeyUpdate, an over-long record) ends the connection without an alert of ours, since +the plain recv only reports it as an error - seeing record types would mean recvmsg with control +data on the multishot recv. The rotation watcher is the next step (FILES.md shares it). + ## The shape Kernel TLS handles the record layer of an ordinary socket - encrypt on send, decrypt on receive - diff --git a/lib/http/run.c b/lib/http/run.c index 8862316..3a57f9d 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -137,8 +137,11 @@ static int prologue(struct ioxd_pipe *pipe) static void serve_http(struct ioxd_pipe *pipe) { - if (prologue(pipe) == 0) - ioxd__serve(pipe); + if (prologue(pipe) != 0) + return; + ioxd__serve(pipe); + if (pipe->in.conn->listener->tls) + ioxd__tls_close_notify(pipe); } int ioxd_run(int workers, int port) @@ -151,8 +154,11 @@ static ioxd_pipe_handler g_pipe_handler; static void serve_pipe(struct ioxd_pipe *pipe) { - if (prologue(pipe) == 0) - g_pipe_handler(pipe); + if (prologue(pipe) != 0) + return; + g_pipe_handler(pipe); + if (pipe->in.conn->listener->tls) + ioxd__tls_close_notify(pipe); } int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn) diff --git a/lib/io/conn.c b/lib/io/conn.c index c4d35e3..97c2493 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -383,6 +383,19 @@ int ioxd__setsockopt(conn_t *c, int level, int name, const void *val, size_t len return rc; } +int ioxd__sendmsg(conn_t *c, const struct msghdr *msg) +{ + op_t op; + struct io_uring_sqe *sqe = ioxd__sqe(c->p); + sqe->opcode = IORING_OP_SENDMSG; + sqe->fd = c->fd; + sqe->flags = c->p->ring.fixed_files ? IOSQE_FIXED_FILE : 0; + sqe->addr = (uint64_t)(uintptr_t)msg; + sqe->len = 1; + sqe->msg_flags = MSG_NOSIGNAL; + return await_op(sqe, &op); +} + int await_send(conn_t *c, const void *buf, size_t len) { const uint8_t *src = buf; diff --git a/lib/io/conn.h b/lib/io/conn.h index 7209531..0798a33 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -22,6 +22,7 @@ typedef struct proactor proactor_t; typedef struct conn conn_t; struct listener; /* io/proactor.h: the port it was accepted on */ +struct msghdr; /* , for ioxd__sendmsg */ /* A slice the kernel delivered into a provided buffer, waiting for the handler to read it. */ struct rx_item { @@ -66,6 +67,7 @@ int ioxd__recv_pause (conn_t *c); /* 0 once stopped; -1 void ioxd__recv_resume(conn_t *c); int ioxd__recv_exact (conn_t *c, void *dst, size_t n); /* n bytes into dst, or <0 */ int ioxd__setsockopt (conn_t *c, int level, int name, const void *val, size_t len); /* 0 or -errno; over the ring */ +int ioxd__sendmsg (conn_t *c, const struct msghdr *msg); /* one sendmsg, for a message with control data */ /* For the loop (proactor.c): a connection's life from accept to the pool. */ conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd); /* from the pool, or fresh */ diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index 52a0f35..12ca045 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -14,6 +14,7 @@ #if IOXD_TLS #include +#include #include #include #include @@ -160,9 +161,9 @@ static size_t record_len(ioxd_slice live) * OpenSSL, keeping the plaintext aside. The count consumed is the RX record sequence. */ static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, unsigned char *plain, size_t *plain_len) { - ioxd_pipereader *pr = &pipe->in; - conn_t *c = pr->conn; - unsigned char tail[RECORD_MAX]; + ioxd_pipereader *pr = &pipe->in; + conn_t *c = pr->conn; + unsigned char *tail = plain + PLAIN_MAX; /* scratch for a split record, past the plaintext */ long records = 0; for (;;) { ioxd_slice live = { nullptr, 0 }; @@ -243,7 +244,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) why = "input ended after the handshake"; goto out; } - plain = malloc(PLAIN_MAX); + plain = malloc(PLAIN_MAX + RECORD_MAX); /* plaintext, then room for a split record: off the coroutine's stack */ size_t plain_len = 0; long records = plain ? drain_records(pipe, ssl, rbio, plain, &plain_len) : -1; if (records < 0) { @@ -273,7 +274,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) fprintf(stderr, "ioxd_tls: connection dropped: %s\n", why); explicit_bzero(&s, sizeof s); if (plain) { - explicit_bzero(plain, PLAIN_MAX); + explicit_bzero(plain, PLAIN_MAX + RECORD_MAX); free(plain); } if (ssl) { @@ -286,6 +287,23 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) return why ? -1 : 0; } +void ioxd__tls_close_notify(struct ioxd_pipe *pipe) +{ + unsigned char alert[2] = { 1, 0 }; /* warning, close_notify */ + struct iovec iov = { alert, sizeof alert }; + union { + char buf[CMSG_SPACE(sizeof(unsigned char))]; + struct cmsghdr align; + } ctl = {}; + struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, .msg_control = ctl.buf, .msg_controllen = sizeof ctl.buf }; + struct cmsghdr *cm = CMSG_FIRSTHDR(&msg); + cm->cmsg_level = SOL_TLS; + cm->cmsg_type = TLS_SET_RECORD_TYPE; + cm->cmsg_len = CMSG_LEN(sizeof(unsigned char)); + *CMSG_DATA(cm) = 21; /* the alert record type */ + ioxd__sendmsg(pipe->in.conn, &msg); +} + #else /* built without TLS */ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) @@ -295,4 +313,9 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) return -1; } +void ioxd__tls_close_notify(struct ioxd_pipe *pipe) +{ + (void)pipe; +} + #endif diff --git a/lib/tls/tls.h b/lib/tls/tls.h index 909280d..943ca72 100644 --- a/lib/tls/tls.h +++ b/lib/tls/tls.h @@ -10,3 +10,7 @@ /* The handshake over the pipe, then the keys into the socket. 0, or -1: the connection is not * usable (the handshake failed, the peer left, kernel TLS is unavailable). */ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls); + +/* Tell the peer the connection is ending: a close_notify alert, sent as a TLS control record + * through the kernel. Best effort, for a connection whose prologue succeeded. */ +void ioxd__tls_close_notify(struct ioxd_pipe *pipe); diff --git a/tests/mkcerts.sh b/tests/mkcerts.sh index 7876783..5c86383 100644 --- a/tests/mkcerts.sh +++ b/tests/mkcerts.sh @@ -2,10 +2,10 @@ # Self-signed certificates for the test fixture: `default` (CN=localhost) and one SNI host. set -e dir=${1:-tests/certs} -for host in default sni.test; do - cn=localhost; [ "$host" = default ] || cn=$host - mkdir -p "$dir/$host" - openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -subj "/CN=$cn" -days 30 \ - -keyout "$dir/$host/key.pem" -out "$dir/$host/cert.pem" 2>/dev/null -done +# default: RSA (what most clients and test suites assume); sni.test: ECDSA, so both key types serve +mkdir -p "$dir/default" "$dir/sni.test" +openssl req -x509 -newkey rsa:2048 -nodes -subj "/CN=localhost" -days 30 \ + -keyout "$dir/default/key.pem" -out "$dir/default/cert.pem" 2>/dev/null +openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -subj "/CN=sni.test" -days 30 \ + -keyout "$dir/sni.test/key.pem" -out "$dir/sni.test/cert.pem" 2>/dev/null echo "certificates in $dir" diff --git a/tests/tls_early.py b/tests/tls_early.py index a05201f..607ff4d 100644 --- a/tests/tls_early.py +++ b/tests/tls_early.py @@ -118,8 +118,9 @@ def check(name, cond): status, body = read_reply(conn) conn.closeSocket = False # close() sends close_notify but leaves the socket to us conn.close() -eof = held.sock.recv(1) == b"" -check("close_notify from the client -> the server closes the connection", body == b"ok" and eof) +tail = held.sock.recv(64) # the server's own close_notify (one encrypted record), then EOF +eof = tail == b"" or (tail[0] == 0x17 and held.sock.recv(1) == b"") +check("close_notify from the client -> the server sends its own and closes", body == b"ok" and eof) # 5. garbage after the handshake: the kernel cannot decrypt it and the server closes conn, held = connect() From dff1cb8e95921a975e3d1e989684b02859fe054e Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:05:10 +0100 Subject: [PATCH 28/49] TLS: OpenSSL is fed one record at a time, so a request sent with the client's Finished is not lost The handshake loop wrote every delivered byte into the read BIO. When the client's Finished and its first application record arrived in one segment, the record vanished into OpenSSL: the drain found nothing, kernel RX was installed one sequence number behind, and the connection hung. Records are now assembled one at a time in the prologue's own scratch, during the handshake and during the drain alike, so what follows the Finished stays in the reader; a record cut by the pause is completed from the socket. The drain stops at a close_notify and refuses a post-handshake message it cannot follow; the early plaintext is bounded by what the reader can take. The early-data test held the client's Finished through send() while tlslite sends it through sendall(), so its three coalescing cases never coalesced; the wrapper holds both now and the cases fail on the old code. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- lib/io/pipe.c | 17 +++-- lib/io/pipe.h | 2 +- lib/tls/handshake.c | 153 ++++++++++++++++++++++++++++---------------- tests/tls_early.py | 6 ++ 4 files changed, 116 insertions(+), 62 deletions(-) diff --git a/lib/io/pipe.c b/lib/io/pipe.c index 67abe96..7a3647c 100644 --- a/lib/io/pipe.c +++ b/lib/io/pipe.c @@ -271,22 +271,27 @@ int ioxd_pipereader_copy(ioxd_pipereader *pr, void *dst, size_t n) } } -bool ioxd_pipereader_avail(ioxd_pipereader *pr, ioxd_slice *live) +int ioxd_pipereader_avail(ioxd_pipereader *pr, ioxd_slice *live) { if (pr->error) - return false; + return pr->error; ioxd_slice l = live_span(pr); - if (l.len <= pr->examined) { /* all seen: take a delivered buffer, if one is queued */ - if (pr->conn->rx_head == pr->conn->rx_tail || more(pr) <= 0) - return false; + while (l.len <= pr->examined) { /* all seen: take a delivered buffer, if one is queued */ + if (pr->conn->rx_head == pr->conn->rx_tail) + return 0; + int rc = more(pr); + if (rc <= 0) + return rc; l = live_span(pr); } *live = l; - return true; + return 1; } bool ioxd_pipereader_inject(ioxd_pipereader *pr, const void *data, size_t n) { + if (pr->error) + return false; if (!pr->live_in_buf) { if (pr->has_cur && pr->cur_pos < pr->cur.len) { /* live bytes in place: they move first */ if (!gather(pr)) diff --git a/lib/io/pipe.h b/lib/io/pipe.h index bc9bbb8..80bf60b 100644 --- a/lib/io/pipe.h +++ b/lib/io/pipe.h @@ -47,7 +47,7 @@ void ioxd_pipereader_run_begin(ioxd_pipereader *pr); / ioxd_slice ioxd_pipereader_run (const ioxd_pipereader *pr); /* the run in progress */ void ioxd_pipereader_release (ioxd_pipereader *pr); /* forget every kept byte; live bytes stay */ int ioxd_pipereader_copy (ioxd_pipereader *pr, void *dst, size_t n); /* up to n live bytes into dst, consumed; >0, 0 at the end, <0 error */ -bool ioxd_pipereader_avail (ioxd_pipereader *pr, ioxd_slice *live); /* like read, but never waits: false when nothing unexamined was delivered */ +int ioxd_pipereader_avail (ioxd_pipereader *pr, ioxd_slice *live); /* like read, but never waits: 0 when nothing unexamined was delivered; <0 error */ bool ioxd_pipereader_inject (ioxd_pipereader *pr, const void *data, size_t n); /* bytes that arrived by another route, appended to the live bytes; false: no room */ /* The writer: a slab with a head and a tail. Data goes in at the tail (reserve/advance, or write); diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index 12ca045..aca6ae9 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -24,7 +24,8 @@ #define SECRET_LEN 32U /* SHA-256 suite: the traffic secrets */ #define RECORD_MAX (5 + 16384 + 256) /* header, plaintext, tag and padding */ -#define PLAIN_MAX 65536 /* what a client may send before we listen */ +#define PLAIN_MAX IOXD_PIPE_GATHER /* early plaintext: what the reader can take */ +#define KDF_FAILED (-4096) /* install's own failure, apart from errnos */ /* The secrets of one handshake, found through the SSL's ex_data. */ struct secrets { @@ -109,7 +110,7 @@ static int install(conn_t *c, int direction, const unsigned char *secret, uint64 { unsigned char key[16], iv[12]; if (!expand_label(secret, "key", key, sizeof key) || !expand_label(secret, "iv", iv, sizeof iv)) - return -1; + return KDF_FAILED; struct tls12_crypto_info_aes_gcm_128 ci = {}; ci.info.version = TLS_1_3_VERSION; ci.info.cipher_type = TLS_CIPHER_AES_GCM_128; @@ -136,22 +137,56 @@ static int flush_outbound(struct ioxd_pipe *pipe, BIO *wbio) return ioxd_pipewriter_flush(&pipe->out); } -/* Whatever the pipe has, or the next thing it gets, into the read BIO. */ -static int feed_inbound(struct ioxd_pipe *pipe, BIO *rbio) +/* The length of the TLS record whose 5-byte header is at rec, header included. */ +static size_t record_len(const unsigned char *rec) { - ioxd_slice live = { nullptr, 0 }; - int rc = ioxd_pipereader_read(&pipe->in, &live); - if (rc <= 0) - return -1; - BIO_write(rbio, live.p, (int)live.len); - ioxd_pipereader_drop(&pipe->in, live.len); - return 0; + return 5 + ((size_t)rec[3] << 8 | rec[4]); +} + +/* One whole TLS record out of the reader into rec: 1 when taken, -1 on error. During the + * handshake it waits for delivery. While draining it never waits: 0 when nothing delivered is + * left, which means the socket is at a record boundary; the tail of a record cut by the pause is + * fetched straight from the socket instead. OpenSSL gets exactly one record per feed, so what a + * client sent after its Finished stays in the reader for the drain rather than vanishing into + * the read BIO. */ +static int take_record(struct ioxd_pipe *pipe, bool draining, unsigned char *rec, size_t *len) +{ + ioxd_pipereader *pr = &pipe->in; + size_t have = 0, need = 5; + while (have < need) { + ioxd_slice live = { nullptr, 0 }; + int rc = draining ? ioxd_pipereader_avail(pr, &live) : ioxd_pipereader_read(pr, &live); + if (rc < 0 || (rc == 0 && !draining)) + return -1; + if (rc == 0) { /* nothing more was delivered */ + if (have == 0) + return 0; + if (ioxd__recv_exact(pr->conn, rec + have, need - have) < 0) + return -1; /* the rest of a split record, from the socket */ + have = need; + } else { + size_t k = live.len < need - have ? live.len : need - have; + memcpy(rec + have, live.p, k); + ioxd_pipereader_drop(pr, k); + have += k; + } + if (have == 5 && need == 5) { + need = record_len(rec); + if (need > RECORD_MAX) + return -1; + } + } + *len = have; + return 1; } -/* The length of the TLS record at the front of live, header included. */ -static size_t record_len(ioxd_slice live) +/* The next record the client sent, into the read BIO. */ +static int feed_inbound(struct ioxd_pipe *pipe, BIO *rbio, unsigned char *rec) { - return 5 + ((size_t)(unsigned char)live.p[3] << 8 | (unsigned char)live.p[4]); + size_t len; + if (take_record(pipe, false, rec, &len) <= 0) + return -1; + return BIO_write(rbio, rec, (int)len) == (int)len ? 0 : -1; } /* After the handshake, before the kernel takes over receiving: the client may already have sent @@ -159,41 +194,54 @@ static size_t record_len(ioxd_slice live) * record boundary in the socket, so with the multishot recv stopped this takes whole records * from what was delivered - fetching the tail of a split one straight from the socket - through * OpenSSL, keeping the plaintext aside. The count consumed is the RX record sequence. */ -static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, unsigned char *plain, size_t *plain_len) +static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, BIO *wbio, unsigned char *plain, + size_t *plain_len, const char **why) { - ioxd_pipereader *pr = &pipe->in; - conn_t *c = pr->conn; - unsigned char *tail = plain + PLAIN_MAX; /* scratch for a split record, past the plaintext */ - long records = 0; + unsigned char *rec = plain + PLAIN_MAX; /* scratch for one record, past the plaintext */ + long records = 0; for (;;) { - ioxd_slice live = { nullptr, 0 }; - if (!ioxd_pipereader_avail(pr, &live)) - break; /* nothing delivered is left: the socket is at a boundary */ - while (live.len < 5 || live.len < record_len(live)) { - size_t need = live.len < 5 ? 5 - live.len : record_len(live) - live.len; - if (live.len >= 5 && record_len(live) > RECORD_MAX) - return -1; - ioxd_pipereader_examine(pr, live.len); - if (ioxd_pipereader_avail(pr, &live)) - continue; /* the next delivered buffer joined it */ - if (ioxd__recv_exact(c, tail, need) < 0 || !ioxd_pipereader_inject(pr, tail, need)) - return -1; /* the rest was still in the socket */ - if (!ioxd_pipereader_avail(pr, &live)) - return -1; + size_t len; + int rc = take_record(pipe, true, rec, &len); + if (rc < 0) { + *why = "early application data could not be taken"; + return -1; } - size_t len = record_len(live); - if ((unsigned char)live.p[0] != 23) /* not application data: an alert; give up */ + if (rc == 0) + return records; /* the socket is at a boundary */ + if (rec[0] != 23) { /* an alert, or a handshake message: nothing we can hand over */ + *why = "a record other than application data after the handshake"; return -1; - BIO_write(rbio, live.p, (int)len); - ioxd_pipereader_drop(pr, len); + } + if (*plain_len == PLAIN_MAX) { + *why = "more early application data than the reader can hold"; + return -1; + } + if (BIO_write(rbio, rec, (int)len) != (int)len) { + *why = "out of memory"; + return -1; + } records++; int n; - while ((n = SSL_read(ssl, plain + *plain_len, (int)(PLAIN_MAX - *plain_len))) > 0) + while (*plain_len < PLAIN_MAX && (n = SSL_read(ssl, plain + *plain_len, (int)(PLAIN_MAX - *plain_len))) > 0) *plain_len += (size_t)n; - if (SSL_get_error(ssl, n) != SSL_ERROR_WANT_READ) - return -1; /* close_notify, or a record we cannot take */ + if (*plain_len == PLAIN_MAX && SSL_pending(ssl) > 0) { + *why = "more early application data than the reader can hold"; + return -1; + } + if (*plain_len == PLAIN_MAX) + continue; + int err = SSL_get_error(ssl, n); + if (err == SSL_ERROR_ZERO_RETURN) /* close_notify: what came before it is still served */ + return records; + if (err != SSL_ERROR_WANT_READ) { + *why = "a record OpenSSL could not take after the handshake"; + return -1; + } + if (BIO_pending(wbio) > 0) { /* OpenSSL answered something: a KeyUpdate we cannot follow */ + *why = "a post-handshake message from the client (key update?)"; + return -1; + } } - return records; } int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) @@ -209,7 +257,10 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) SSL *ssl = SSL_new(ioxd__tls_fallback(t)); BIO *rbio = BIO_new(BIO_s_mem()); BIO *wbio = BIO_new(BIO_s_mem()); - if (!ssl || !rbio || !wbio) { + plain = malloc(PLAIN_MAX + RECORD_MAX); /* early plaintext, then one record: off the coroutine's stack */ + if (!ssl || !rbio || !wbio || !plain) { + BIO_free(rbio); /* not the SSL's yet */ + BIO_free(wbio); why = "out of memory"; goto out; } @@ -230,7 +281,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) why = ssl_error_text(); goto out; } - if (feed_inbound(pipe, rbio) < 0) { + if (feed_inbound(pipe, rbio, plain + PLAIN_MAX) < 0) { why = "peer gone during the handshake"; goto out; } @@ -244,13 +295,10 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) why = "input ended after the handshake"; goto out; } - plain = malloc(PLAIN_MAX + RECORD_MAX); /* plaintext, then room for a split record: off the coroutine's stack */ size_t plain_len = 0; - long records = plain ? drain_records(pipe, ssl, rbio, plain, &plain_len) : -1; - if (records < 0) { - why = "early application data could not be taken"; + long records = drain_records(pipe, ssl, rbio, wbio, plain, &plain_len, &why); + if (records < 0) goto out; - } r = ioxd__setsockopt(c, SOL_TCP, TCP_ULP, "tls", sizeof "tls"); if (r < 0) { @@ -261,7 +309,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) if (r == 0) r = install(c, TLS_RX, s.rx, (uint64_t)records); if (r < 0) { - why = r == -1 ? "key derivation failed" : strerror(-r); + why = r == KDF_FAILED ? "key derivation failed" : strerror(-r); goto out; } if (plain_len && !ioxd_pipereader_inject(&pipe->in, plain, plain_len)) { @@ -277,12 +325,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) explicit_bzero(plain, PLAIN_MAX + RECORD_MAX); free(plain); } - if (ssl) { - SSL_free(ssl); - } else { - BIO_free(rbio); - BIO_free(wbio); - } + SSL_free(ssl); /* and its BIOs */ ioxd__tls_release(tls, t); return why ? -1 : 0; } diff --git a/tests/tls_early.py b/tests/tls_early.py index 607ff4d..0ff49c4 100644 --- a/tests/tls_early.py +++ b/tests/tls_early.py @@ -27,6 +27,12 @@ def send(self, data): return len(data) return self.sock.send(data) + def sendall(self, data): # tlslite sends its Finished this way + if self.hold: + self.buf += data + return None + return self.sock.sendall(data) + def release(self, n=None): n = len(self.buf) if n is None else n self.sock.sendall(bytes(self.buf[:n])) From e2092fdbfde73d7a327280cfd6e985d312b257ee Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:22:38 +0100 Subject: [PATCH 29/49] TLS store: a published context is never rewritten; a certificate that cannot serve is refused A reload carries a host that failed to load forward by sharing its old SSL_CTX, and the loop after it then called SSL_CTX_set_client_hello_cb(ctx, on_client_hello, new_table) on every context of the new table - re-pointing, with no lock, a context worker threads are reading and that a handshake already in flight was created from. A client sitting on its ClientHello was answered out of a table it never started on, and out of freed memory once that table was dropped. The callback goes on in context_for now, once, with a NULL argument, and finds the table through the SSL's ex_data instead: the prologue calls ioxd__tls_bind right after SSL_new and holds a reference to that table for as long as the SSL lives. Nothing writes to a context after it is published. A loaded certificate is checked against the clock - X509_cmp_time on notBefore and notAfter - and one that is not valid yet or has run out is a load failure like any other, so the host keeps what was serving. `default` is required: without it ioxd_tls_new fails instead of promoting whatever readdir returned first, and a reload that loses it keeps the previous fallback by host name or is refused whole. ioxd_tls_reload holds a reload mutex over all of it and a reference to the table it reads, so it no longer walks a table it does not own and no longer races another reload. Smaller things: host_eq folds only A-Z, so CR no longer matches `-` and DEL `_`; one trailing root dot is dropped, so `sni.test.` finds sni.test; the SNI extension must be exactly the one host_name entry we read (name_len + 3 == list_len, list_len + 2 == ext_len); ssl_error reports ERR_peek_last_error, the outermost reason, and clears the queue behind it; calloc and strdup are checked; snprintf truncation, S_ISREG on both files, and a warning for a key.pem readable past its owner; errno.h and limits.h come in directly. ioxd_tls_free joins the public header, with the note that it is not for a store a listener still uses; the TLS=0 stubs keep up. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- include/ioxd/tls.h | 26 ++++++ lib/tls/handshake.c | 1 + lib/tls/internal.h | 3 +- lib/tls/store.c | 196 ++++++++++++++++++++++++++++++++++++-------- 4 files changed, 189 insertions(+), 37 deletions(-) create mode 100644 include/ioxd/tls.h diff --git a/include/ioxd/tls.h b/include/ioxd/tls.h new file mode 100644 index 0000000..ec27455 --- /dev/null +++ b/include/ioxd/tls.h @@ -0,0 +1,26 @@ +/* + * ioxd/tls.h - TLS 1.3, terminated in the kernel after an OpenSSL handshake (TLS.md): a store of + * certificates to listen with. + */ +#pragma once + +#include "ioxd/http.h" + +/* A store from a directory: //cert.pem (the chain) and key.pem for each hostname, + * `default` for no SNI or no match, `_.example.com` for *.example.com. `default` is required - + * without it nothing can answer a name we do not have. NULL, with the reason on stderr, when + * nothing loads or the build has no TLS. Then: ioxd_listen(port, store). */ +ioxd_tls *ioxd_tls_new(const char *dir); + +/* Read the directory again and switch to what it holds. A host that fails to load - unreadable, + * mismatched, not valid yet, expired - keeps its old certificate, and the host answering for + * unmatched SNI keeps answering. Safe while serving: handshakes in flight finish on the table + * they started with, and reloads serialise against each other. 0, or -1 when nothing could be + * loaded at all, in which case what was serving still is. */ +int ioxd_tls_reload(ioxd_tls *tls); + +/* Give the store back: its certificates and the store itself, once the last handshake holding a + * table of it has finished. Not while a listener still uses it - every TLS connection takes a + * reference through the store - so this is for a store that was never listened on, or for after + * ioxd_run has returned. NULL is a no-op. */ +void ioxd_tls_free(ioxd_tls *tls); diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index aca6ae9..b652cf1 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -267,6 +267,7 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) SSL_set_bio(ssl, rbio, wbio); /* the SSL owns both from here */ SSL_set_accept_state(ssl); SSL_set_ex_data(ssl, ex_index, &s); + ioxd__tls_bind(ssl, t); /* the table its ClientHello picks a host from */ for (;;) { /* the handshake, as an ordinary await loop */ int ret = SSL_do_handshake(ssl); diff --git a/lib/tls/internal.h b/lib/tls/internal.h index 46bc765..5aac404 100644 --- a/lib/tls/internal.h +++ b/lib/tls/internal.h @@ -1,6 +1,6 @@ /* * tls/internal.h - what the store and the handshake share: the table a handshake holds a - * reference to, and the keylog callback the store installs on every context. + * reference to and hangs on its SSL, and the keylog callback the store installs on every context. */ #pragma once @@ -22,5 +22,6 @@ struct table; struct table *ioxd__tls_acquire (ioxd_tls *tls); /* store.c: the table serving now, referenced */ void ioxd__tls_release (ioxd_tls *tls, struct table *t); SSL_CTX *ioxd__tls_fallback(const struct table *t); /* the context a handshake starts on */ +void ioxd__tls_bind (SSL *ssl, struct table *t); /* the table its ClientHello picks a host from */ void ioxd__tls_keylog (const SSL *ssl, const char *line); /* handshake.c: catches the traffic secrets */ #endif diff --git a/lib/tls/store.c b/lib/tls/store.c index 8fe54a8..6975a9c 100644 --- a/lib/tls/store.c +++ b/lib/tls/store.c @@ -2,6 +2,11 @@ * tls/store.c - the certificate store: one SSL_CTX per host directory, pinned to what kernel TLS * can carry (TLS 1.3, TLS_AES_128_GCM_SHA256, no tickets), chosen by SNI at the ClientHello. * The table of hosts is reference-counted so a reload swaps it under handshakes in flight. + * + * A published context is never written to again. A reload carries a host that failed to load + * forward by sharing its old context, so a context can belong to more than one table and cannot + * name one: the ClientHello callback is installed once, when the context is built, and finds the + * table through the SSL its handshake holds a reference for. */ #include "tls/tls.h" #include "tls/internal.h" @@ -13,8 +18,11 @@ #if IOXD_TLS #include +#include +#include #include #include +#include #include #include @@ -27,30 +35,56 @@ struct table { int refs; /* the store's own, plus one per handshake in flight */ struct host *hosts; int n; - SSL_CTX *fallback; /* `default`, or the first host */ + SSL_CTX *fallback; /* `default`: what answers when SNI matches nothing */ }; struct ioxd_tls { char *dir; struct table *table; pthread_mutex_t lock; /* around the table pointer and its refs */ + pthread_mutex_t reload; /* one reload at a time, over the whole of it */ }; -/* The last OpenSSL error, as text. */ +/* The table a handshake started on, hung on its SSL: where the ClientHello callback finds it. */ +static int table_ex; +static pthread_once_t table_ex_once = PTHREAD_ONCE_INIT; +static void make_table_ex(void) +{ + table_ex = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); +} + +/* The prologue's SSL, told which table it started on. It holds a reference to that table for as + * long as the SSL lives, so the ClientHello callback can read it back whenever the peer gets + * round to sending one. */ +void ioxd__tls_bind(SSL *ssl, struct table *t) +{ + pthread_once(&table_ex_once, make_table_ex); + SSL_set_ex_data(ssl, table_ex, t); +} + +/* The outermost OpenSSL error, as text; the rest of the queue goes with it, since one left behind + * is reported against the next call that fails. */ static const char *ssl_error(void) { static thread_local char text[256]; - ERR_error_string_n(ERR_get_error(), text, sizeof text); + ERR_error_string_n(ERR_peek_last_error(), text, sizeof text); + ERR_clear_error(); return text; } +/* ASCII lowercase, and nothing else: folding every byte would match CR to `-` and DEL to `_`. */ +static unsigned char fold(unsigned char c) +{ + return c >= 'A' && c <= 'Z' ? (unsigned char)(c | 0x20U) : c; +} + /* Exact hostname compare, ASCII case-insensitive. */ static bool host_eq(const char *a, size_t alen, const char *b) { if (strlen(b) != alen) return false; for (size_t i = 0; i < alen; i++) - if (((unsigned char)a[i] | 0x20U) != ((unsigned char)b[i] | 0x20U)) + if (fold((unsigned char)a[i]) != fold((unsigned char)b[i])) return false; return true; } @@ -58,6 +92,8 @@ static bool host_eq(const char *a, size_t alen, const char *b) /* The context for a server name: exact, then the wildcard of its parent domain. */ static SSL_CTX *lookup(const struct table *t, const char *name, size_t len) { + if (len > 1 && name[len - 1] == '.') /* the root dot: `sni.test.` is `sni.test` */ + len--; for (int i = 0; i < t->n; i++) if (host_eq(name, len, t->hosts[i].name)) return t->hosts[i].ctx; @@ -76,26 +112,31 @@ static SSL_CTX *lookup(const struct table *t, const char *name, size_t len) return nullptr; } -/* The ClientHello: pick the certificate by the server name, when there is one we know. */ +/* The ClientHello: pick the certificate by the server name, when there is one we know. The table + * comes from the SSL rather than from `arg`, which is always NULL - see the note at the top. */ static int on_client_hello(SSL *ssl, int *alert, void *arg) /* NOLINT(readability-non-const-parameter): OpenSSL's signature */ { (void)alert; - const struct table *t = arg; + (void)arg; + const struct table *t = SSL_get_ex_data(ssl, table_ex); const unsigned char *ext; size_t ext_len; + if (!t) + return SSL_CLIENT_HELLO_SUCCESS; if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &ext, &ext_len) || ext_len < 5) return SSL_CLIENT_HELLO_SUCCESS; /* no SNI: the default */ size_t list_len = (size_t)ext[0] << 8 | ext[1]; /* ServerNameList: one host_name entry */ size_t name_len = (size_t)ext[3] << 8 | ext[4]; - if (list_len + 2 > ext_len || ext[2] != 0 || name_len + 5 > ext_len) - return SSL_CLIENT_HELLO_SUCCESS; + if (ext[2] != 0 || name_len + 3 != list_len || list_len + 2 != ext_len) + return SSL_CLIENT_HELLO_SUCCESS; /* not the single entry we read: the default */ SSL_CTX *ctx = lookup(t, (const char *)ext + 5, name_len); if (ctx) SSL_set_SSL_CTX(ssl, ctx); return SSL_CLIENT_HELLO_SUCCESS; } -/* One host's context: pinned to what the kernel can carry, with the files it was given. */ +/* One host's context: pinned to what the kernel can carry, with the files it was given. The + * callbacks go on here, once: nothing writes to a context after it is published. */ static SSL_CTX *context_for(const char *cert, const char *key) { SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); @@ -114,9 +155,28 @@ static SSL_CTX *context_for(const char *cert, const char *key) SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION | SSL_OP_NO_TICKET); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_keylog_callback(ctx, ioxd__tls_keylog); + SSL_CTX_set_client_hello_cb(ctx, on_client_hello, nullptr); return ctx; } +/* Why the context's certificate cannot serve now, or NULL when it can: a certificate that is not + * valid yet or has run out is a load failure like any other, so the old one stays. */ +static const char *not_current(const SSL_CTX *ctx) +{ + const X509 *x = SSL_CTX_get0_certificate(ctx); + if (!x) + return "no certificate in the chain"; + int before = X509_cmp_time(X509_get0_notBefore(x), nullptr); + int after = X509_cmp_time(X509_get0_notAfter(x), nullptr); + if (before == 0 || after == 0) + return "a validity period that does not parse"; + if (before > 0) + return "not valid yet: notBefore is in the future"; + if (after < 0) + return "expired: notAfter has passed"; + return nullptr; +} + static void table_free(struct table *t) { for (int i = 0; i < t->n; i++) { @@ -127,8 +187,18 @@ static void table_free(struct table *t) free(t); } +/* The host whose context answers when SNI matches nothing. */ +static const char *fallback_name(const struct table *t) +{ + for (int i = 0; i < t->n; i++) + if (t->hosts[i].ctx == t->fallback) + return t->hosts[i].name; + return nullptr; +} + /* Every host directory under dir into a new table; a host that fails keeps its context from - * `old` when it had one there. NULL when no host loads. */ + * `old` when it had one there. NULL when no host loads, or when nothing can answer for SNI that + * matches nothing: `default` is required, and only a reload may carry the previous one over. */ static struct table *load(const char *dir, const struct table *old) { DIR *d = opendir(dir); @@ -137,37 +207,55 @@ static struct table *load(const char *dir, const struct table *old) return nullptr; } struct table *t = calloc(1, sizeof *t); + if (!t) { + perror("ioxd_tls"); + closedir(d); + return nullptr; + } t->refs = 1; struct dirent *e; while ((e = readdir(d))) { if (e->d_name[0] == '.') continue; char cert[PATH_MAX], key[PATH_MAX]; - snprintf(cert, sizeof cert, "%s/%s/cert.pem", dir, e->d_name); - snprintf(key, sizeof key, "%s/%s/key.pem", dir, e->d_name); - struct stat st; - if (stat(cert, &st) != 0) + int cn = snprintf(cert, sizeof cert, "%s/%s/cert.pem", dir, e->d_name); + int kn = snprintf(key, sizeof key, "%s/%s/key.pem", dir, e->d_name); + if (cn < 0 || (size_t)cn >= sizeof cert || kn < 0 || (size_t)kn >= sizeof key) { + fprintf(stderr, "ioxd_tls: %s: the path to its certificate does not fit\n", e->d_name); + continue; + } + struct stat cs, ks; + if (stat(cert, &cs) != 0 || !S_ISREG(cs.st_mode) || stat(key, &ks) != 0 || !S_ISREG(ks.st_mode)) continue; /* not a host directory */ - SSL_CTX *ctx = context_for(cert, key); + if (ks.st_mode & ((unsigned)S_IRGRP | (unsigned)S_IROTH)) /* once per host, on every load */ + fprintf(stderr, "ioxd_tls: %s: mode %03o, readable past its owner\n", key, + (unsigned)(ks.st_mode & 0777)); + SSL_CTX *ctx = context_for(cert, key); + const char *why = ctx ? not_current(ctx) : ssl_error(); + if (ctx && why) { /* it parsed, but it cannot serve now */ + SSL_CTX_free(ctx); + ctx = nullptr; + } if (!ctx) { - fprintf(stderr, "ioxd_tls: %s: %s\n", cert, ssl_error()); + fprintf(stderr, "ioxd_tls: %s: %s (%s)\n", e->d_name, why, cert); if (old) { /* keep what was serving */ for (int i = 0; i < old->n; i++) if (strcmp(old->hosts[i].name, e->d_name) == 0) { ctx = old->hosts[i].ctx; - SSL_CTX_up_ref(ctx); + SSL_CTX_up_ref(ctx); /* shared with the old table, written to by neither */ } } if (!ctx) continue; } struct host *grown = realloc(t->hosts, ((size_t)t->n + 1) * sizeof *grown); - if (!grown) { - perror("realloc"); + char *name = strdup(e->d_name); + if (!grown || !name) { + perror("ioxd_tls"); abort(); } t->hosts = grown; - t->hosts[t->n++] = (struct host){ strdup(e->d_name), ctx }; + t->hosts[t->n++] = (struct host){ name, ctx }; if (strcmp(e->d_name, "default") == 0) t->fallback = ctx; } @@ -177,12 +265,20 @@ static struct table *load(const char *dir, const struct table *old) table_free(t); return nullptr; } - if (!t->fallback) { - t->fallback = t->hosts[0].ctx; - fprintf(stderr, "ioxd_tls: no `default` host; %s answers when SNI matches nothing\n", t->hosts[0].name); + if (!t->fallback) { /* no `default`: on a reload the host that was + * answering keeps doing so, if it is still here */ + const char *prev = old ? fallback_name(old) : nullptr; + for (int i = 0; prev && !t->fallback && i < t->n; i++) + if (strcmp(t->hosts[i].name, prev) == 0) + t->fallback = t->hosts[i].ctx; + if (!t->fallback) { + fprintf(stderr, "ioxd_tls: %s: no `default` host (default/cert.pem + key.pem) to answer" + " when SNI matches nothing\n", dir); + table_free(t); + return nullptr; + } + fprintf(stderr, "ioxd_tls: no `default` host; %s still answers when SNI matches nothing\n", prev); } - for (int i = 0; i < t->n; i++) /* the ClientHello callback sees this table */ - SSL_CTX_set_client_hello_cb(t->hosts[i].ctx, on_client_hello, t); return t; } @@ -192,13 +288,33 @@ ioxd_tls *ioxd_tls_new(const char *dir) if (!t) return nullptr; ioxd_tls *tls = calloc(1, sizeof *tls); - tls->dir = strdup(dir); + char *own = strdup(dir); + if (!tls || !own) { + perror("ioxd_tls"); + table_free(t); + free(own); + free(tls); + return nullptr; + } + tls->dir = own; tls->table = t; pthread_mutex_init(&tls->lock, nullptr); + pthread_mutex_init(&tls->reload, nullptr); fprintf(stderr, "ioxd_tls: %d host%s from %s\n", t->n, t->n == 1 ? "" : "s", dir); return tls; } +void ioxd_tls_free(ioxd_tls *tls) +{ + if (!tls) + return; + ioxd__tls_release(tls, tls->table); /* the store's own reference; the last one frees */ + pthread_mutex_destroy(&tls->reload); + pthread_mutex_destroy(&tls->lock); + free(tls->dir); + free(tls); +} + /* A reference to the table serving now; released after the handshake. */ struct table *ioxd__tls_acquire(ioxd_tls *tls) { @@ -225,16 +341,19 @@ SSL_CTX *ioxd__tls_fallback(const struct table *t) int ioxd_tls_reload(ioxd_tls *tls) { - struct table *fresh = load(tls->dir, tls->table); - if (!fresh) - return -1; - pthread_mutex_lock(&tls->lock); - struct table *old = tls->table; - tls->table = fresh; - pthread_mutex_unlock(&tls->lock); - ioxd__tls_release(tls, old); /* the store's own reference to the old table */ - fprintf(stderr, "ioxd_tls: reloaded %d host%s from %s\n", fresh->n, fresh->n == 1 ? "" : "s", tls->dir); - return 0; + pthread_mutex_lock(&tls->reload); /* one at a time, so the table it reads stays put */ + struct table *old = ioxd__tls_acquire(tls); /* and cannot be freed while load() reads it */ + struct table *fresh = load(tls->dir, old); + if (fresh) { + pthread_mutex_lock(&tls->lock); + tls->table = fresh; + pthread_mutex_unlock(&tls->lock); + fprintf(stderr, "ioxd_tls: reloaded %d host%s from %s\n", fresh->n, fresh->n == 1 ? "" : "s", tls->dir); + ioxd__tls_release(tls, old); /* the store's own reference to the old table */ + } + ioxd__tls_release(tls, old); /* the one this reload took */ + pthread_mutex_unlock(&tls->reload); + return fresh ? 0 : -1; } #else /* built without TLS */ @@ -245,6 +364,11 @@ ioxd_tls *ioxd_tls_new(const char *dir) return nullptr; } +void ioxd_tls_free(ioxd_tls *tls) +{ + (void)tls; +} + int ioxd_tls_reload(ioxd_tls *tls) { (void)tls; From a2fd86d22795e4cac3c8ae1bcd4a393e5232d01e Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:27:17 +0100 Subject: [PATCH 30/49] HTTP: the framing a request declares is checked before a handler sees it; a reply's head follows the request and the status; copied headers Request side (RFC 9112): a Content-Length is digits and nothing else, two of them must agree, Transfer-Encoding must end in chunked and name no other coding (501 otherwise), the two framings never come together, a folded header line is refused, an HTTP/1.1 request carries exactly one Host, every Connection line counts with close winning, an absolute-form target is routed by its path, a chunk size line keeps to the grammar, trailers are bounded, and a query that does not fit its arrays is a 400 or 414 rather than a partial view. Each was a request-smuggling vector behind a proxy. Reply side: no body after HEAD or on a 1xx, 204 or 304, no framing header on a 1xx or 204, a status outside three digits goes out as 500, a declared Content-Length is held to (corrected when buffered whole, cut and closed when streamed), a body left unread past the drain limit closes, and an Expect: 100-continue gets its interim reply on the first body read - or a close when the handler never reads. ioxd_header and ioxd_content_type copy into a per-reply arena (the head was serialized after the handler's frame was gone) and refuse control bytes, non-token names and the engine's own headers. ioxd_content_type and ioxd_content_length return whether they applied. ioxd_run checks that the application's ioxd_ctx is the library's, since the limits that size it are compile-time constants. The pipe reader pins a kernel buffer whose kept run it moves, so a kept pointer stays valid until release; drop and keep are clamped to the live bytes, the writer's advance to the slab; a raw handler's unsent slab is flushed at close. ioxd_cstr refuses an embedded NUL, %00 stays literal. The public headers under include/ioxd/ were never committed: a bare "ioxd" in .gitignore matched the directory. tests/conformance.py drives all of it at the wire level; the fixture routes it needs follow with the test-suite merge. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .gitignore | 2 +- include/ioxd.h | 4 +- include/ioxd/http.h | 183 +++++++++++++++++++++ include/ioxd/json.h | 127 +++++++++++++++ include/ioxd/pipe.h | 47 ++++++ include/ioxd/router.h | 102 ++++++++++++ include/ioxd/slice.h | 51 ++++++ include/ioxd/tls.h | 17 ++ lib/http/api.c | 146 ++++++++++++++--- lib/http/engine.c | 370 +++++++++++++++++++++++++++++++++--------- lib/http/run.c | 10 +- lib/io/pipe.c | 29 +++- lib/io/pipe.h | 2 +- lib/tls/handshake.c | 7 +- libioma.a | Bin 1237342 -> 0 bytes tests/conformance.py | 255 +++++++++++++++++++++++++++++ tests/server.c | 2 +- tests/unit.c | 10 +- 18 files changed, 1243 insertions(+), 121 deletions(-) create mode 100644 include/ioxd/http.h create mode 100644 include/ioxd/json.h create mode 100644 include/ioxd/pipe.h create mode 100644 include/ioxd/router.h create mode 100644 include/ioxd/slice.h create mode 100644 include/ioxd/tls.h delete mode 100644 libioma.a create mode 100644 tests/conformance.py diff --git a/.gitignore b/.gitignore index 620fb71..99db9eb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ ioxd-hello ioxd.pc # old binaries -ioxd +/ioxd ioxd-tiny ioxd-trace stackful diff --git a/include/ioxd.h b/include/ioxd.h index d35867a..cf8af2d 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -13,10 +13,10 @@ * * static void user(ioxd_ctx *ctx) { * ioxd_slice id = ctx->req.route_params[0].value; // the :id of "/users/:id" - * ioxd_printf(c, "user %.*s\n", (int)id.len, id.p); + * ioxd_printf(ctx, "user %.*s\n", (int)id.len, id.p); * } * int main(void) { - * ioxd_route("GET", "/users/:id", user); + * IOXD_GET("/users/:id", user); // or ioxd_route(NULL, "GET", "/users/:id", user) * return ioxd_run(0, 8080); // one worker per core * } */ diff --git a/include/ioxd/http.h b/include/ioxd/http.h new file mode 100644 index 0000000..34a1a7e --- /dev/null +++ b/include/ioxd/http.h @@ -0,0 +1,183 @@ +/* + * ioxd/http.h - the request, the response, the context a handler receives, the body read on + * demand, the reply written as you go, and the run. + */ +#pragma once + +#include +#include +#include + +#include "ioxd/slice.h" + + +/* The limits that size a request and a reply. They are build-time constants of the LIBRARY: + * an application may not redefine them, since they lay out the context the library allocates - + * ioxd_run checks that the two sides agree and refuses to start otherwise. A request past a + * limit is answered 400 (more headers than fit, more query parameters than fit) or 414 (more + * decoded query than fits its arena); a reply past one is refused by the call that adds to it. */ +#ifndef IOXD_MAX_HEADERS +#define IOXD_MAX_HEADERS 64 /* request headers; more is a 400 */ +#endif +#ifndef IOXD_MAX_PARAMS +#define IOXD_MAX_PARAMS 32 /* query parameters; more is a 400 */ +#endif +#ifndef IOXD_MAX_ROUTE_PARAMS +#define IOXD_MAX_ROUTE_PARAMS 8 /* :name captures a route pattern may have */ +#endif +#ifndef IOXD_MAX_RESP_HEADERS +#define IOXD_MAX_RESP_HEADERS 16 /* headers a reply may add */ +#endif +#ifndef IOXD_RESP_HEAD_CAP +#define IOXD_RESP_HEAD_CAP 3072 /* bytes the added headers may serialize to */ +#endif + +/* ── the request ───────────────────────────────────────────────────────────────────────── */ + +/* All the data of a request, as slices into the connection's read buffer (decoded parameters + * into a per-request arena), valid only until the handler returns. Read the arrays directly; + * header names are lower-cased, so compare them with lowercase literals. The body is not here + * until you ask for it: ioxd_body_all reads it whole, ioxd_body_read_until streams it. + * The engine has already checked the framing (RFC 9112): a Content-Length that is not a plain + * number, conflicting duplicates, a Transfer-Encoding with anything but a final "chunked", + * both fields together, a folded header line, or an HTTP/1.1 request without exactly one Host + * never reach a handler - they are answered 400 (501 for a transfer coding we do not + * implement) and the connection closes. */ +typedef struct ioxd_request { + ioxd_slice method; /* "GET", "POST", ... */ + ioxd_slice target; /* raw request target: path plus any query */ + ioxd_slice path; /* the path, query stripped */ + ioxd_slice query; /* raw text after '?', undecoded */ + int minor_version; /* 0 or 1 for HTTP/1.0 or 1.1 */ + + ioxd_kv headers[IOXD_MAX_HEADERS]; /* names lower-cased, values as received */ + size_t n_headers; + ioxd_kv params[IOXD_MAX_PARAMS]; /* query parameters, percent-decoded */ + size_t n_params; + ioxd_kv route_params[IOXD_MAX_ROUTE_PARAMS]; /* the :name captures, in pattern order */ + size_t n_route_params; + + size_t content_length; /* what the head declared; 0 if nothing */ + bool chunked; /* the body is chunked: length unknown */ + ioxd_slice body; /* the whole body, once ioxd_body_all read it */ + bool keep_alive; /* computed from version + Connection */ + bool expect_continue; /* "Expect: 100-continue": the body waits for the interim reply the first body read sends */ +} ioxd_request; + +/* ── the response ──────────────────────────────────────────────────────────────────────── */ + +/* The reply being shaped. Body bytes wait in the connection's write slab (ioxd_write, + * ioxd_printf, ioxd_reserve); a full slab is sent and emptied, and the head (status, content + * type, headers) goes out in front of the first send - after the chain when everything fit, + * earlier when the body streams - and is frozen from then on (head_sent). + * What goes on the wire follows the request and the status, not only the handler: a reply to + * HEAD, a 1xx, 204 or 304 carries no body whatever was written (HEAD keeps the Content-Length + * the GET would have had; 1xx and 204 carry no framing header at all), a status outside + * 100-999 goes out as 500, and a declared Content-Length that the writes do not match is + * corrected when the reply was buffered whole and closes the connection when it streamed. */ +typedef struct ioxd_response { + int status; /* 200 by default */ + ioxd_slice content_type; /* "text/plain" by default; assign a slice that outlives the handler (a literal), or ioxd_content_type copies one */ + ioxd_kv headers[IOXD_MAX_RESP_HEADERS]; /* added with ioxd_header: copies, names lower-cased */ + size_t n_headers; + bool close; /* close the connection after this reply */ + bool head_sent; + size_t content_length; /* declared with ioxd_content_length */ + bool has_length; + + bool chunked, failed; /* private: how a stream is framed; peer gone */ + size_t body_sent; /* private: body bytes sent so far */ + size_t head_len; /* private: the added headers, serialized */ + char head[IOXD_RESP_HEAD_CAP]; +} ioxd_response; + +/* ── the context ───────────────────────────────────────────────────────────────────────── */ + +typedef struct ioxd_ctx { + ioxd_request req; + ioxd_response res; + void *user; /* free slot: middleware hands data to the handler */ + void *priv; /* the engine's own state */ +} ioxd_ctx; + +typedef void (*ioxd_handler)(ioxd_ctx *ctx); + +/* Middleware runs around the handler (the onion model): shape the context, call ioxd_next_run to + * run the rest of the chain and then the endpoint, then act on the result - or write a reply and + * return WITHOUT calling ioxd_next_run to short-circuit (auth failure, cache hit). */ +typedef struct ioxd_next ioxd_next; +typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next); +void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next); + +/* ── the body ──────────────────────────────────────────────────────────────────────────── */ + +/* The whole body, read into the request buffer once and returned as a slice (also req.body). It + * must fit the buffer (16 KB by default): otherwise the slice is empty and res.status is 413, + * which becomes the reply - a handler that streams its reply should check and stop. Not after + * one of the reads below. A malformed chunked body is a 400 the same way. + * With "Expect: 100-continue" the first of these reads answers "100 Continue" before waiting; + * a handler that never reads such a body gets its reply sent and the connection closed. */ +ioxd_slice ioxd_body_all(ioxd_ctx *ctx); + +/* The next bytes of the body into dst, reading until n are there or the body ends. Returns the + * count (less than n only at the end), 0 once it is all consumed (or for n == 0), -1 on error + * (the connection then closes after the reply). Any size of body, nothing kept in the engine. */ +int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n); + +/* The next chunk of a chunked body, exactly as the sender framed it, into dst: the rest of the + * current chunk when a read stopped inside one, else the next whole one. Returns its length, 0 at + * the last chunk, -1 on error - a chunk larger than cap is a 413 - or when the body is not + * chunked. */ +int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap); + +/* ── the reply ─────────────────────────────────────────────────────────────────────────── */ + +/* Body writes into the slab. When it fills, it is sent - head first - and the body streams from + * then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. + * Return 0, or -1 once the reply failed: the peer is gone, or a format could not be written + * (further writes are ignored either way). */ +int ioxd_write (ioxd_ctx *ctx, const void *data, size_t len); +/* Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr + * once the peer is gone or n exceeds the slab) and advance by what was written - never more + * than reserved; advance clamps to the room that was there. */ +void *ioxd_reserve(ioxd_ctx *ctx, size_t n); +void ioxd_advance(ioxd_ctx *ctx, size_t n); +int ioxd_text (ioxd_ctx *ctx, const char *s); /* a C string */ +#if defined(__GNUC__) || defined(__clang__) +int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ +#else +int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...); +#endif + +/* Shape the head, only before it is sent: each returns false afterwards. ioxd_header copies the + * name (sent lower-cased) and the value, so temporaries are fine; it also returns false for a + * name that is not an HTTP token, a value with a control byte (CR, LF, NUL: no response + * splitting), a header the engine owns (content-length, transfer-encoding, connection), when + * the table or its IOXD_RESP_HEAD_CAP bytes are full. "content-type" through it sets the + * content type. */ +bool ioxd_header (ioxd_ctx *ctx, const char *name, const char *value); +bool ioxd_content_type (ioxd_ctx *ctx, const char *type); /* copied */ +bool ioxd_content_length(ioxd_ctx *ctx, size_t n); /* stream a large body with a known length */ +int ioxd_flush (ioxd_ctx *ctx); /* send what is in the slab now (starts streaming) */ + +/* ── run ───────────────────────────────────────────────────────────────────────────────── */ + +/* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port` and on every + * listener added below, and block until SIGINT/SIGTERM. Returns 0 on clean shutdown, non-zero + * when a worker failed, when the port could not be bound, or when the limits above differ + * between this header and the library (the context would not match). May be called again + * after it returns. */ +int ioxd__run(int workers, int port, size_t ctx_size); +static inline int ioxd_run(int workers, int port) +{ + return ioxd__run(workers, port, sizeof(ioxd_ctx)); +} + +/* More ports: each ioxd_listen before the run adds one, plain when tls is NULL, TLS 1.3 terminated + * in the kernel otherwise (a certificate store from ioxd_tls_new; TLS.md). ioxd_run's own port + * joins them as a plain one; 0 there means only the listeners added. At most 8. -1 if refused. */ +typedef struct ioxd_tls ioxd_tls; +int ioxd_listen(int port, ioxd_tls *tls); + +/* The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted. */ +const char *ioxd_reason(int status); diff --git a/include/ioxd/json.h b/include/ioxd/json.h new file mode 100644 index 0000000..d549ef5 --- /dev/null +++ b/include/ioxd/json.h @@ -0,0 +1,127 @@ +/* + * ioxd/json.h - JSON written as you go, and a struct described once, serialized with one call. + */ +#pragma once + +#include +#include +#include + +#include "ioxd/http.h" + +struct ioxd_pipe; /* ioxd/pipe.h */ + +/* ── JSON, written as you go ───────────────────────────────────────────────────────────── */ + +/* A forward-only JSON writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation. The + * bytes go straight into the reply - or a raw pipe, or a buffer - escaped as they are written, + * and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what + * it means: + * + * ioxd_json j = ioxd_json_reply(ctx); // content-type: application/json + * ioxd_json_object(&j); + * ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); + * ioxd_json_key(&j, "name"); ioxd_json_string(&j, name); + * ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + * ioxd_json_cstr(&j, "new"); + * ioxd_json_end(&j); + * ioxd_json_end(&j); + * + * Strings are taken as UTF-8 and passed through; '"', '\' and control characters are escaped. + * Every call returns false once the sink is gone (the peer left; the buffer is full) or the + * nesting passed IOXD_JSON_DEPTH, and the rest is dropped, so checking the last call is enough. */ +#define IOXD_JSON_DEPTH 64 +typedef struct ioxd_json { + enum { + IOXD_JSON_TO_REPLY, + IOXD_JSON_TO_PIPE, + IOXD_JSON_TO_MEM, + } kind; + + union { + ioxd_ctx *ctx; + struct ioxd_pipe *pipe; + struct { char *p; size_t cap, *len; } mem; + } to; + + uint64_t has_value; /* per level: a value is there, so a comma is due */ + uint64_t is_object; /* per level: it closes with '}' rather than ']' */ + unsigned depth; + bool after_key; /* the next value follows a key: no comma */ + bool failed; +} ioxd_json; + +ioxd_json ioxd_json_reply(ioxd_ctx *ctx); /* into the reply; sets its content type */ +ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe); /* into a raw pipe's slab */ +ioxd_json ioxd_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ + +bool ioxd_json_object(ioxd_json *j); /* { */ +bool ioxd_json_array (ioxd_json *j); /* [ */ +bool ioxd_json_end (ioxd_json *j); /* } or ], whichever is open */ +bool ioxd_json_key (ioxd_json *j, const char *name); /* "name": */ +bool ioxd_json_string(ioxd_json *j, ioxd_slice s); /* "...", escaped */ +bool ioxd_json_cstr (ioxd_json *j, const char *s); /* NULL is null */ +bool ioxd_json_int (ioxd_json *j, int64_t v); +bool ioxd_json_uint (ioxd_json *j, uint64_t v); +bool ioxd_json_double(ioxd_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ +bool ioxd_json_bool (ioxd_json *j, bool v); +bool ioxd_json_null (ioxd_json *j); +bool ioxd_json_raw (ioxd_json *j, ioxd_slice json); /* already JSON: copied as is */ + +/* A value by its C type, and a key with one: the _Generic picks ioxd_json_int for the integer + * types, _uint for the unsigned ones, _double for float and double, _bool, _cstr for a char + * pointer, _string for a slice. */ +#define IOXD_JSON_VALUE(j, x) _Generic((x), \ + bool: ioxd_json_bool, \ + char: ioxd_json_int, signed char: ioxd_json_int, short: ioxd_json_int, \ + int: ioxd_json_int, long: ioxd_json_int, long long: ioxd_json_int, \ + unsigned char: ioxd_json_uint, unsigned short: ioxd_json_uint, unsigned: ioxd_json_uint, \ + unsigned long: ioxd_json_uint, unsigned long long: ioxd_json_uint, \ + float: ioxd_json_double, double: ioxd_json_double, \ + char *: ioxd_json_cstr, const char *: ioxd_json_cstr, \ + ioxd_slice: ioxd_json_string)((j), (x)) +#define IOXD_JSON_FIELD(j, name, x) (ioxd_json_key((j), (name)) && IOXD_JSON_VALUE((j), (x))) + +/* A struct described once, serialized with one call. The description is a list of fields, each + * line its kind, its C type (or, for a nested struct, that struct's name) and its name: + * + * #define USER_FIELDS(X) \ + * X(VALUE, int64_t, id) // a scalar, written by its type \ + * X(VALUE, const char *, name) \ + * X(OBJECT, address, address) // a nested struct, by value \ + * X(OPTIONAL, address, billing) // a pointer to one; null when NULL \ + * X(ARRAY, const char *, tags, n_tags) // scalars, and the count field \ + * X(OBJECTS, order, orders, n_orders) // nested structs, and the count + * IOXD_JSON_STRUCT(user, USER_FIELDS) // struct user, and user_to_json(ioxd_json *, const struct user *) + * + * IOXD_JSON_STRUCT defines the struct and the function; IOXD_JSON_WRITER only the function, for + * a struct declared elsewhere with the same fields. A nested struct's own IOXD_JSON_STRUCT comes + * first. Counts are size_t; arrays are pointers to their first element. */ +#define IOXD_JSON_STRUCT(name, FIELDS) \ + struct name { FIELDS(IOXD__JSON_MEMBER) }; \ + IOXD_JSON_WRITER(name, FIELDS) +#define IOXD_JSON_WRITER(name, FIELDS) \ + static inline bool name##_to_json(ioxd_json *j, const struct name *v) \ + { \ + ioxd_json_object(j); \ + FIELDS(IOXD__JSON_WRITE) \ + return ioxd_json_end(j); \ + } + +/* What each kind of line becomes: a member, and a piece of the writer. */ +#define IOXD__JSON_MEMBER(kind, ...) IOXD__JSON_MEMBER_##kind(__VA_ARGS__) +#define IOXD__JSON_MEMBER_VALUE(type, field) type field; +#define IOXD__JSON_MEMBER_OBJECT(sname, field) struct sname field; +#define IOXD__JSON_MEMBER_OPTIONAL(sname, field) const struct sname *field; +#define IOXD__JSON_MEMBER_ARRAY(type, field, count) type *field; size_t count; +#define IOXD__JSON_MEMBER_OBJECTS(sname, field, count) const struct sname *field; size_t count; +#define IOXD__JSON_WRITE(kind, ...) IOXD__JSON_WRITE_##kind(__VA_ARGS__) +#define IOXD__JSON_WRITE_VALUE(type, field) ioxd_json_key(j, #field); IOXD_JSON_VALUE(j, v->field); +#define IOXD__JSON_WRITE_OBJECT(sname, field) ioxd_json_key(j, #field); sname##_to_json(j, &v->field); +#define IOXD__JSON_WRITE_OPTIONAL(sname, field) ioxd_json_key(j, #field); if (v->field) sname##_to_json(j, v->field); else ioxd_json_null(j); +#define IOXD__JSON_WRITE_ARRAY(type, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { IOXD_JSON_VALUE(j, v->field[i_]); } \ + ioxd_json_end(j); +#define IOXD__JSON_WRITE_OBJECTS(sname, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { sname##_to_json(j, &v->field[i_]); } \ + ioxd_json_end(j); diff --git a/include/ioxd/pipe.h b/include/ioxd/pipe.h new file mode 100644 index 0000000..e6e5b5e --- /dev/null +++ b/include/ioxd/pipe.h @@ -0,0 +1,47 @@ +/* + * ioxd/pipe.h - a connection as a pipe: a reader over the bytes the kernel received and a + * writer over a slab, for handlers of protocols other than HTTP. + */ +#pragma once + +#include + +#include "ioxd/slice.h" + +/* ── pipes ─────────────────────────────────────────────────────────────────────────────── */ + +/* A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. + * Every call that must wait suspends the connection's coroutine, and the worker's loop resumes + * it on the completion, so a handler reads and writes in straight-line code. The HTTP engine is + * one such handler; ioxd_run_pipes runs one of yours on raw TCP connections instead. */ +typedef struct ioxd_pipe ioxd_pipe; +typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe); +int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn); /* like ioxd_run, without HTTP */ + +/* Reading. The live bytes are the ones received and not yet consumed, always handed out as one + * contiguous span - in place in the kernel's buffer when they lie within one. read returns 1 + * with them once some are unexamined, otherwise it waits for more; examine says how many were + * looked at without being consumed, so the next read waits for more rather than returning the + * same bytes; drop consumes (never more than is live); keep consumes but leaves the bytes where + * they are, contiguous with earlier kept bytes and valid until release - it returns where they + * are, or NULL when they would not fit the pipe's buffer (the pipe is then FULL) or n is more + * than is live; copy is the plain read into your own buffer. read and copy return 0 at the end + * of input, IOXD_PIPE_GONE on a dead peer, IOXD_PIPE_FULL when kept plus live bytes would + * exceed the pipe's buffer (16 KB). A handler that returns with bytes still in the writer's + * slab has them sent before the connection closes. */ +#define IOXD_PIPE_GONE (-1) +#define IOXD_PIPE_FULL (-2) +int ioxd_pipe_read (ioxd_pipe *pipe, ioxd_slice *live); +void ioxd_pipe_examine(ioxd_pipe *pipe, size_t n); +void ioxd_pipe_drop (ioxd_pipe *pipe, size_t n); +const char *ioxd_pipe_keep (ioxd_pipe *pipe, size_t n); +void ioxd_pipe_release(ioxd_pipe *pipe); +int ioxd_pipe_copy (ioxd_pipe *pipe, void *dst, size_t n); + +/* Writing: a slab, sent on flush. reserve n bytes to write into directly and advance by what was + * written, or write to copy in; send is write then flush. -1 once the peer is gone. */ +void *ioxd_pipe_reserve(ioxd_pipe *pipe, size_t n); +void ioxd_pipe_advance(ioxd_pipe *pipe, size_t n); +int ioxd_pipe_write (ioxd_pipe *pipe, const void *data, size_t n); +int ioxd_pipe_flush (ioxd_pipe *pipe); +int ioxd_pipe_send (ioxd_pipe *pipe, const void *data, size_t n); diff --git a/include/ioxd/router.h b/include/ioxd/router.h new file mode 100644 index 0000000..4e60c0f --- /dev/null +++ b/include/ioxd/router.h @@ -0,0 +1,102 @@ +/* + * ioxd/router.h - groups, endpoints and middleware, and the same as a script. + */ +#pragma once + +#include + +#include "ioxd/http.h" + +/* ── routing ───────────────────────────────────────────────────────────────────────────── */ + +/* Endpoints live in groups, and groups nest. A group is a path prefix plus middleware: an + * endpoint "/users" in a group "/api" under a group "/v1" answers at "/v1/api/users", wrapped by + * the middleware of every group above it, outermost first, then its own. NULL as the group is + * the root: no prefix, and the middleware given to ioxd_use. + * + * Register everything before ioxd_run, from the main thread. ioxd_run resolves it once: every + * endpoint's full path into a segment tree and its middleware into one flat chain, which the + * workers then share read-only. A request costs one walk down the tree - no scan, no regex - and + * one call through its chain. */ +typedef struct ioxd_group ioxd_group; +typedef struct ioxd_endpoint ioxd_endpoint; + +ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix); /* "/api"; "" for middleware only */ +void ioxd_group_use(ioxd_group *group, ioxd_mw mw); /* wraps everything below it */ + +/* An endpoint: method matched exactly; path matched by segment below the group's prefix, with + * :name captures ("/users/:id") landing in req.route_params. A static segment beats a capture at + * any depth, and a static path that lacks the method falls through to a capture route that has + * it. A trailing slash is tolerated. */ +ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn); +void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw); /* wraps this one only */ + +/* The verbs, for short: ioxd_get(api, "/users/:id", user). */ +static inline ioxd_endpoint *ioxd_get (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "GET", path, fn); } +static inline ioxd_endpoint *ioxd_post (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "POST", path, fn); } +static inline ioxd_endpoint *ioxd_put (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PUT", path, fn); } +static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PATCH", path, fn); } +static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "DELETE", path, fn); } + +/* Root middleware: every request, the fallbacks included. */ +void ioxd_use(ioxd_mw mw); +/* The fallback when no path matches (a built-in 404 by default). A path that matches without the + * method gets a built-in 405 with an allow header. */ +void ioxd_default(ioxd_handler fn); + +/* ── the same, as a script ─────────────────────────────────────────────────────────────── */ + +/* Registration as a block-structured script: a current group, which the block after IOXD_GROUP + * sets (the root outside any block), endpoints registered into it, with their own middleware + * listed after the handler, and IOXD_USE adding middleware to it - so a group's middleware is + * either listed after its prefix or added with IOXD_USE inside its block. Plain functions + * underneath, so everything is type-checked; a group's block runs exactly once (do not break out + * of it). + * + * IOXD_USE(log); + * IOXD_GET("/", home); + * IOXD_GROUP("/api", api_header) { + * IOXD_GET("/ping", ping); + * IOXD_GROUP("/admin", require_token) { + * IOXD_GET("/stats", stats, timing); + * } + * } + */ +#define IOXD_MAX_MW 16 /* middleware per group and per endpoint */ +struct ioxd_group_args { const char *prefix; ioxd_mw mws[IOXD_MAX_MW + 1]; }; /* +1: the ending null */ +struct ioxd_endpoint_args { const char *path; ioxd_handler fn; ioxd_mw mws[IOXD_MAX_MW + 1]; }; + +/* What the macros call: the current group's stack and an endpoint with a middleware list. */ +ioxd_group *ioxd__group_begin(struct ioxd_group_args args); +ioxd_group *ioxd__group_end(void); +ioxd_group *ioxd__group_current(void); +ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args); + +/* The argument lists become the structs above. An argument count picks the expansion, so the + * middleware list always has its own braces and no macro is ever invoked with an empty variadic + * part: clean under -Wall -Wextra -pedantic, in C11 and later. */ +#define IOXD__CAT2(a, b) a##b +#define IOXD__CAT(a, b) IOXD__CAT2(a, b) +#define IOXD__PICK(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, name, ...) name +#define IOXD__RW(path, fn, ...) (struct ioxd_endpoint_args){ (path), (fn), { __VA_ARGS__, NULL } } +#define IOXD__RB(path, fn) (struct ioxd_endpoint_args){ (path), (fn), { NULL } } +#define IOXD__ROUTE_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RB, IOXD__RB, IOXD__RB)(__VA_ARGS__) +#define IOXD__GW(prefix, ...) (struct ioxd_group_args){ (prefix), { __VA_ARGS__, NULL } } +#define IOXD__GB(prefix) (struct ioxd_group_args){ (prefix), { NULL } } +#define IOXD__GROUP_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GB, IOXD__GB)(__VA_ARGS__) + +#define IOXD_GROUP(...) \ + for (ioxd_group *IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_begin(IOXD__GROUP_ARGS(__VA_ARGS__)); \ + IOXD__CAT(ioxd__block_, __LINE__); IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_end()) +#define IOXD_USE(mw) ioxd_group_use(ioxd__group_current(), (mw)) +#define IOXD_ROUTE(method, ...) ioxd__endpoint((method), IOXD__ROUTE_ARGS(__VA_ARGS__)) +#define IOXD_GET(...) IOXD_ROUTE("GET", __VA_ARGS__) +#define IOXD_POST(...) IOXD_ROUTE("POST", __VA_ARGS__) +#define IOXD_PUT(...) IOXD_ROUTE("PUT", __VA_ARGS__) +#define IOXD_PATCH(...) IOXD_ROUTE("PATCH", __VA_ARGS__) +#define IOXD_DELETE(...) IOXD_ROUTE("DELETE", __VA_ARGS__) +#define IOXD_DEFAULT(fn) ioxd_default(fn) diff --git a/include/ioxd/slice.h b/include/ioxd/slice.h new file mode 100644 index 0000000..d718e3f --- /dev/null +++ b/include/ioxd/slice.h @@ -0,0 +1,51 @@ +/* + * ioxd/slice.h - a slice, bytes with a length, and a key/value pair of them: what every request + * carries. Compare and convert them without copying; parse a query string or a form body. + */ +#pragma once + +#include +#include +#include + +/* A slice: pointer + length, the C span. Not NUL-terminated. */ +typedef struct { const char *p; size_t len; } ioxd_slice; + +/* One key/value pair of slices: a header, a query parameter, a route parameter. */ +typedef struct { ioxd_slice key, value; } ioxd_kv; + +/* ── slices ────────────────────────────────────────────────────────────────────────────── */ + +/* Everything a request carries is a slice: bytes with a length, not NUL-terminated, valid until + * the handler returns. These compare and convert one without copying it. */ +bool ioxd_slice_eq (ioxd_slice s, const char *cstr); /* exact */ +bool ioxd_slice_eq_ci (ioxd_slice s, const char *cstr); /* ASCII case-insensitive */ +bool ioxd_slice_starts_with(ioxd_slice s, const char *prefix); +bool ioxd_slice_ends_with (ioxd_slice s, const char *suffix); +ioxd_slice ioxd_slice_trim (ioxd_slice s); /* no leading/trailing space, tab, CR, LF */ + +/* A NUL-terminated copy in buf, for whatever wants a C string. False when it did not fit: buf + * then holds what fit, still terminated (cap 0 writes nothing) - and false when the slice holds + * a NUL of its own, which would end the C string early ("secret.txt%00.png" is not a PNG). */ +bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap); + +/* Conversions. The whole slice must be the value - nothing around it, nothing after it - and a + * number that does not fit the type fails. On failure *out is left alone and false comes back, + * so "0" and "not a number" cannot be confused. Integers: an optional '-' and decimal digits. + * Doubles: also a fraction and an exponent ("2.5", ".5", "1e-3"); never inf, nan or hex; too + * large fails, too small rounds towards zero. + * Booleans: true/false, 1/0, yes/no, on/off, any case. */ +bool ioxd_to_int (ioxd_slice s, int *out); +bool ioxd_to_i64 (ioxd_slice s, int64_t *out); +bool ioxd_to_u64 (ioxd_slice s, uint64_t *out); +bool ioxd_to_double(ioxd_slice s, double *out); +bool ioxd_to_bool (ioxd_slice s, bool *out); + +/* Parse "k=v&k2=v2" - a query string, a form body - into out, up to cap pairs. Keys and values + * that need it ('+', %XX) are decoded into arena and point there; the rest are views of s. A + * malformed %XX and %00 stay as written. Returns the pair count; *truncated (may be NULL) is set + * when a pair was left out - past cap, or not fitting the arena - so the caller can refuse the + * request rather than act on part of it. Every pair is returned, duplicates included, in order: + * pick a policy (first or last) and keep to it. */ +size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap, + bool *truncated); diff --git a/include/ioxd/tls.h b/include/ioxd/tls.h new file mode 100644 index 0000000..8118b94 --- /dev/null +++ b/include/ioxd/tls.h @@ -0,0 +1,17 @@ +/* + * ioxd/tls.h - TLS 1.3, terminated in the kernel after an OpenSSL handshake (TLS.md): a store of + * certificates to listen with. + */ +#pragma once + +#include "ioxd/http.h" + +/* A store from a directory: //cert.pem (the chain) and key.pem for each hostname, + * `default` for no SNI or no match, `_.example.com` for *.example.com. NULL, with the reason on + * stderr, when nothing loads or the build has no TLS. Then: ioxd_listen(port, store). */ +ioxd_tls *ioxd_tls_new(const char *dir); + +/* Read the directory again and switch to what it holds. A host that fails to load keeps its old + * certificate. Safe while serving: handshakes in flight finish on the table they started with. + * 0, or -1 when nothing could be loaded at all. */ +int ioxd_tls_reload(ioxd_tls *tls); diff --git a/lib/http/api.c b/lib/http/api.c index 7209685..a7ed536 100644 --- a/lib/http/api.c +++ b/lib/http/api.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -74,7 +75,8 @@ ioxd_slice ioxd_slice_trim(ioxd_slice s) return s; } -/* A NUL-terminated copy of the slice in buf; false when it did not all fit. */ +/* A NUL-terminated copy of the slice in buf; false when it did not all fit, or when the slice + * holds a NUL itself - the copy would read as a shorter string to whatever takes it. */ bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap) { if (cap == 0) @@ -83,7 +85,7 @@ bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap) if (n) memcpy(buf, s.p, n); buf[n] = '\0'; - return n == s.len; + return n == s.len && memchr(buf, '\0', n) == nullptr; } /* ── conversions ───────────────────────────────────────────────────────────────────────── */ @@ -162,9 +164,11 @@ bool ioxd_to_double(ioxd_slice s, double *out) memcpy(text, s.p, s.len); text[s.len] = '\0'; pthread_once(&c_locale_once, make_c_locale); + if (!c_locale) + return false; /* no "C" locale: never the process one, which may read "2.5" as 2 */ char *end; errno = 0; - double v = c_locale ? strtod_l(text, &end, c_locale) : strtod(text, &end); + double v = strtod_l(text, &end, c_locale); if (end != text + s.len || (errno == ERANGE && (v == HUGE_VAL || v == -HUGE_VAL))) return false; *out = v; @@ -191,7 +195,8 @@ bool ioxd_to_bool(ioxd_slice s, bool *out) /* ── key/value parsing ─────────────────────────────────────────────────────────────────── */ -/* Percent-decode [s, s+n) into dst ('+' becomes a space, a malformed %XX is kept as is). +/* Percent-decode [s, s+n) into dst ('+' becomes a space; a malformed %XX, and %00 - a NUL + * would end the value early for every C string function - are kept as they are). * Never longer than the input; returns the decoded length. */ static size_t decode(const char *src, size_t len, char *dst) { @@ -201,7 +206,7 @@ static size_t decode(const char *src, size_t len, char *dst) dst[out++] = ' '; } else if (src[i] == '%' && i + 2 < len) { int hi = ioxd__hexval((unsigned char)src[i + 1]), lo = ioxd__hexval((unsigned char)src[i + 2]); - if (hi >= 0 && lo >= 0) { + if (hi >= 0 && lo >= 0 && !(hi == 0 && lo == 0)) { dst[out++] = (char)(hi * 16 + lo); i += 2; } else { @@ -226,12 +231,19 @@ static bool decode_into(ioxd_slice *slice, char *arena, size_t arena_cap, size_t return true; } -/* "k=v&k2=v2" into pairs; see http.h. One pass per pair finds '=' and '&' and notes whether - * either side needs decoding, so the common undecoded pair is a view and costs a short scan. */ -size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap) +/* "k=v&k2=v2" into pairs; see slice.h. One pass per pair finds '=' and '&' and notes whether + * either side needs decoding, so the common undecoded pair is a view and costs a short scan. + * *truncated (may be NULL) says whether a pair was left out: past cap, or not fitting the arena. */ +size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap, + bool *truncated) { size_t used = 0, count = 0, start = 0; - while (start < len && count < cap) { + bool lost = false; + while (start < len) { + if (count == cap) { + lost = true; + break; + } size_t end = start, eq_at = len; bool key_needs_decode = false, value_needs_decode = false; for (; end < len && text[end] != '&'; end++) { @@ -249,45 +261,137 @@ size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, cha size_t mark = used; bool ok = (!key_needs_decode || decode_into(&key, arena, arena_cap, &used)) && (!value_needs_decode || decode_into(&value, arena, arena_cap, &used)); - if (ok) + if (ok) { out[count++] = (ioxd_kv){ key, value }; - else + } else { used = mark; /* skip the pair, give its arena back */ + lost = true; + } } start = end + 1; } + if (truncated) + *truncated = lost; return count; } /* ── shaping the reply ─────────────────────────────────────────────────────────────────── */ -/* Add a header to the reply. false once the head is on the wire, or when the table is full. */ +/* An HTTP token character (RFC 9110): what a field name is made of. */ +static bool is_tchar(unsigned char c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') + || (c != 0 && strchr("!#$%&'*+-.^_`|~", c) != nullptr); +} + +/* A field value may hold anything but a control byte: no CR or LF (they would end the line + * and start another: response splitting), no NUL, no other C0 byte except a tab, no DEL. */ +static bool valid_field_value(const char *v, size_t n) +{ + for (size_t i = 0; i < n; i++) { + unsigned char c = (unsigned char)v[i]; + if ((c < 0x20 && c != '\t') || c == 0x7f) + return false; + } + return true; +} + +/* The bytes of the head arena a copied content type takes: it sits at the far end, so the + * serialized lines can grow from the front without it in their way. */ +static size_t content_type_reserved(const ioxd_response *res) +{ + uintptr_t p = (uintptr_t)res->content_type.p, lo = (uintptr_t)res->head, hi = lo + sizeof res->head; + return p >= lo && p < hi ? res->content_type.len : 0; +} + +/* n bytes appended to the reply's head arena, or nullptr when they do not fit. */ +static char *head_room(ioxd_response *res, size_t n) +{ + if (n > sizeof res->head - content_type_reserved(res) - res->head_len) + return nullptr; + char *at = res->head + res->head_len; + res->head_len += n; + return at; +} + +/* Bytes into the arena at *at, which moves past them: a line is assembled from its parts. */ +static void put_bytes(char **at, const void *src, size_t n) +{ + memcpy(*at, src, n); + *at += n; +} + +/* Add a header to the reply: copied into the head arena as its serialized line, the name + * lower-cased, and remembered in headers[] as slices into that line. False once the head is on + * the wire, when the table or the arena is full, when the name is not a token or the value has + * a control byte, and for the headers the engine writes itself - "content-type" is taken as + * ioxd_content_type would. */ bool ioxd_header(ioxd_ctx *ctx, const char *name, const char *value) { ioxd_response *res = &ctx->res; - if (res->head_sent || res->n_headers == IOXD_MAX_RESP_HEADERS) + if (!name || !value) + return false; + size_t name_len = strlen(name), value_len = strlen(value); + if (res->head_sent || res->n_headers == IOXD_MAX_RESP_HEADERS || name_len == 0) + return false; + for (size_t i = 0; i < name_len; i++) + if (!is_tchar((unsigned char)name[i])) + return false; + if (!valid_field_value(value, value_len)) + return false; + if (name_len == 12 && strncasecmp(name, "content-type", 12) == 0) + return ioxd_content_type(ctx, value); + if ((name_len == 14 && strncasecmp(name, "content-length", 14) == 0) + || (name_len == 17 && strncasecmp(name, "transfer-encoding", 17) == 0) + || (name_len == 10 && strncasecmp(name, "connection", 10) == 0)) return false; - res->headers[res->n_headers++] = (ioxd_kv){ { name, strlen(name) }, { value, strlen(value) } }; + char *line = head_room(res, name_len + 2 + value_len + 2); + if (!line) + return false; + char *at = line; + for (size_t i = 0; i < name_len; i++) + *at++ = (char)lower((unsigned char)name[i]); + put_bytes(&at, ": ", 2); + put_bytes(&at, value, value_len); + put_bytes(&at, "\r\n", 2); + res->headers[res->n_headers++] = (ioxd_kv){ { line, name_len }, { line + name_len + 2, value_len } }; return true; } -/* Set the content type from a C string (a slice can be assigned to res.content_type directly). */ -void ioxd_content_type(ioxd_ctx *ctx, const char *type) +/* Set the content type from a C string: a copy in the head arena (a slice that outlives the + * handler can be assigned to res.content_type directly). False once the head is sent, or for a + * value with a control byte, or when the arena is full. */ +bool ioxd_content_type(ioxd_ctx *ctx, const char *type) { - ctx->res.content_type = (ioxd_slice){ type, strlen(type) }; + ioxd_response *res = &ctx->res; + if (!type || res->head_sent) + return false; + size_t n = strlen(type); + if (!valid_field_value(type, n)) + return false; + if (n > sizeof res->head - res->head_len) + return false; + char *copy = res->head + sizeof res->head - n, *at = copy; /* at the far end, past the lines */ + put_bytes(&at, type, n); + res->content_type = (ioxd_slice){ copy, n }; + return true; } -/* Declare the body length, so a body larger than the slab streams with Content-Length. */ -void ioxd_content_length(ioxd_ctx *ctx, size_t n) +/* Declare the body length, so a body larger than the slab streams with Content-Length. False + * once the head is sent. */ +bool ioxd_content_length(ioxd_ctx *ctx, size_t n) { + if (ctx->res.head_sent) + return false; ctx->res.content_length = n; ctx->res.has_length = true; + return true; } -/* Write a C string. */ +/* Write a C string (NULL writes nothing). */ int ioxd_text(ioxd_ctx *ctx, const char *s) { - return ioxd_write(ctx, s, strlen(s)); + return s ? ioxd_write(ctx, s, strlen(s)) : 0; } /* The reason phrase for a status code; "Unknown" if unlisted. */ diff --git a/lib/http/engine.c b/lib/http/engine.c index f3da6a9..644e221 100644 --- a/lib/http/engine.c +++ b/lib/http/engine.c @@ -11,6 +11,7 @@ #include "io/pipe.h" #include "picohttpparser.h" +#include #include #include #include @@ -27,6 +28,9 @@ #ifndef IOXD_DRAIN_MAX #define IOXD_DRAIN_MAX (1024UL * 1024) /* unread body discarded after a handler before we close instead */ #endif +#ifndef IOXD_TRAILER_MAX +#define IOXD_TRAILER_MAX 4096 /* bytes of chunked trailers taken before the body is a 400 */ +#endif /* serve() hands req.headers to picohttpparser as its header array: a kv (two slices) must lay * out exactly like a phr_header (name, name_len, value, value_len). */ @@ -44,6 +48,9 @@ struct serve_state { bool body_whole; /* ioxd_body_all kept it */ int body_err; /* 0, a status to answer (400, 413), or -1: peer gone */ size_t chunk_left; /* data bytes of the current chunk still to deliver */ + bool head_only; /* a HEAD request: the reply's body stays unsent */ + bool no_body; /* decided with the head: HEAD, 1xx, 204, 304 */ + bool continue_sent; /* the 100 Continue an Expect asked for went out */ }; #define STATE(ctx) ((struct serve_state *)(ctx)->priv) #define READER(ctx) (&STATE(ctx)->pipe->in) @@ -68,37 +75,60 @@ static bool eq_ci(const char *a, size_t an, const char *b, size_t bn) return true; } -/* Parse a decimal size; stops at the first non-digit. */ -static size_t parse_size(const char *s, size_t n) +/* A Content-Length value: decimal digits and nothing else, into *out; false for anything else, + * including a number too large for size_t. Anything looser lets one request smuggle another + * behind a proxy that reads the value differently. */ +static bool parse_length(const char *s, size_t n, size_t *out) { + if (n == 0) + return false; size_t v = 0; for (size_t i = 0; i < n; i++) { - if (s[i] < '0' || s[i] > '9') break; - v = v * 10 + (size_t)(s[i] - '0'); + unsigned d = (unsigned char)s[i] - (unsigned)'0'; /* wraps huge for a non-digit */ + if (d > 9 || v > (SIZE_MAX - d) / 10) + return false; + v = v * 10 + d; } - return v; + *out = v; + return true; +} + +/* The comma-separated tokens of a list header value, one per call from *at, blanks trimmed; + * false once the list is done. */ +static bool next_token(const char *value, size_t len, size_t *at, ioxd_slice *tok) +{ + while (*at < len && (value[*at] == ' ' || value[*at] == ',' || value[*at] == '\t')) (*at)++; + if (*at >= len) + return false; + size_t start = *at; + while (*at < len && value[*at] != ',') (*at)++; + size_t end = *at; /* trim trailing blanks */ + while (end > start && (value[end - 1] == ' ' || value[end - 1] == '\t')) end--; + *tok = (ioxd_slice){ value + start, end - start }; + return true; } /* Is `tok` one of the comma-separated tokens in the header value [s, s+n)? Case-insensitive. */ static bool token_present_ci(const char *value, size_t len, const char *tok) { - size_t tok_len = strlen(tok); - size_t at = 0; - while (at < len) { - while (at < len && (value[at] == ' ' || value[at] == ',' || value[at] == '\t')) at++; - size_t start = at; - while (at < len && value[at] != ',') at++; - size_t end = at; /* trim trailing blanks */ - while (end > start && (value[end - 1] == ' ' || value[end - 1] == '\t')) end--; - if (eq_ci(value + start, end - start, tok, tok_len)) return true; - at++; - } + size_t tok_len = strlen(tok), at = 0; + ioxd_slice t; + while (next_token(value, len, &at, &t)) + if (eq_ci(t.p, t.len, tok, tok_len)) + return true; return false; } -/* The three headers the engine itself needs; p == nullptr when absent. */ +/* What the engine picks from the request headers as it lower-cases their names: the framing + * fields, Host, Connection and Expect - and whether they make a request it must refuse. */ struct picked_headers { - ioxd_slice content_length, transfer_enc, connection; + ioxd_slice content_length; + unsigned n_content_length, n_transfer_enc, n_host; + bool te_last_chunked; /* the last transfer coding named is chunked */ + bool te_other; /* a coding other than that final chunked was named */ + bool close, keep_alive; /* over every Connection line */ + bool expect_continue; + int refuse; /* 0, or the status to answer: 400, 417 */ }; /* Lower-case ASCII in place, eight bytes per step. The bytes must all be below 0x80 - true for @@ -119,25 +149,72 @@ static inline void lower_inplace(char *s, size_t n) if ((unsigned)(s[i] - 'A') < 26U) s[i] += 'a' - 'A'; } +/* One Transfer-Encoding line into the picked state: its codings join the list the earlier + * lines made, so a chunked that was last is last no more. */ +static void pick_transfer_encoding(struct picked_headers *picked, ioxd_slice value) +{ + picked->n_transfer_enc++; + if (picked->te_last_chunked) + picked->te_other = true; + picked->te_last_chunked = false; + size_t at = 0; + ioxd_slice tok; + bool any = false; + while (next_token(value.p, value.len, &at, &tok)) { + any = true; + size_t peek = at; + ioxd_slice more; + bool last = !next_token(value.p, value.len, &peek, &more); + if (last && eq_ci(tok.p, tok.len, "chunked", 7)) + picked->te_last_chunked = true; + else + picked->te_other = true; + } + if (!any) + picked->refuse = 400; /* an empty list */ +} + /* One pass over the request headers: lower-case each name in place (the buffer is ours), so * handlers and this switch compare with plain memcmp. The switch on the name length rejects - * nearly every header before a byte is compared. */ + * nearly every header before a byte is compared. A folded continuation line (obs-fold) comes + * from the parser with no name: it must not be interpreted, so the request is refused. */ static struct picked_headers pick_headers(ioxd_request *req) { - struct picked_headers picked = { { nullptr, 0 }, { nullptr, 0 }, { nullptr, 0 } }; + struct picked_headers picked = {}; for (size_t i = 0; i < req->n_headers; i++) { ioxd_kv *hdr = &req->headers[i]; char *name = (char *)hdr->key.p; + if (!name) { + picked.refuse = 400; + continue; + } lower_inplace(name, hdr->key.len); switch (hdr->key.len) { - case 14: - if (memcmp(name, "content-length", 14) == 0) picked.content_length = hdr->value; + case 4: + if (memcmp(name, "host", 4) == 0) picked.n_host++; break; - case 17: - if (memcmp(name, "transfer-encoding", 17) == 0) picked.transfer_enc = hdr->value; + case 6: + if (memcmp(name, "expect", 6) == 0) { + if (eq_ci(hdr->value.p, hdr->value.len, "100-continue", 12)) picked.expect_continue = true; + else picked.refuse = 417; + } break; case 10: - if (memcmp(name, "connection", 10) == 0) picked.connection = hdr->value; + if (memcmp(name, "connection", 10) == 0) { + if (token_present_ci(hdr->value.p, hdr->value.len, "close")) picked.close = true; + if (token_present_ci(hdr->value.p, hdr->value.len, "keep-alive")) picked.keep_alive = true; + } + break; + case 14: + if (memcmp(name, "content-length", 14) == 0) { + if (picked.n_content_length++ && !(hdr->value.len == picked.content_length.len + && memcmp(hdr->value.p, picked.content_length.p, hdr->value.len) == 0)) + picked.refuse = 400; /* two that disagree */ + picked.content_length = hdr->value; + } + break; + case 17: + if (memcmp(name, "transfer-encoding", 17) == 0) pick_transfer_encoding(&picked, hdr->value); break; default: break; @@ -146,15 +223,12 @@ static struct picked_headers pick_headers(ioxd_request *req) return picked; } -/* HTTP/1.1 keeps alive unless "close"; HTTP/1.0 only with "keep-alive". */ -static bool keep_alive_from(int minor_version, ioxd_slice connection) +/* HTTP/1.1 keeps alive unless a Connection line says "close"; HTTP/1.0 only with "keep-alive". */ +static bool keep_alive_from(int minor_version, const struct picked_headers *picked) { - bool keep = minor_version >= 1; - if (connection.p) { - if (token_present_ci(connection.p, connection.len, "close")) keep = false; - else if (token_present_ci(connection.p, connection.len, "keep-alive")) keep = true; - } - return keep; + if (picked->close) + return false; + return minor_version >= 1 || picked->keep_alive; } /* ── the reply: head serialization and the write slab ──────────────────────────────────── */ @@ -213,6 +287,10 @@ static void send_status(ioxd_pipewriter *pw, int code) char head[128]; int len = snprintf(head, sizeof head, "HTTP/1.1 %d %s\r\ncontent-length: 0\r\nconnection: close\r\n\r\n", code, ioxd_reason(code)); + if (len < 0) + return; + if ((size_t)len >= sizeof head) + len = (int)sizeof head - 1; ioxd_pipewriter_reset(pw); /* whatever the handler had buffered is moot */ ioxd_pipewriter_send(pw, head, (size_t)len); } @@ -222,30 +300,39 @@ enum framing { FRAME_LENGTH, FRAME_CHUNKED, FRAME_UNTIL_CLOSE, + FRAME_NONE, /* a reply that cannot have one: 1xx, 204, a 304 with no length */ }; +/* The status as it goes on the wire: three digits, or a 500 for a handler's mistake. */ +static int wire_status(int status) +{ + return status >= 100 && status <= 999 ? status : 500; +} + /* Serialize the head into dst by memcpy of precomposed pieces plus the integer writer - no * snprintf. Every field name goes out lower-cased: the engine's own are lowercase literals, a - * handler's are folded as they are copied. Returns the length, or -1 if it does not fit. */ + * handler's were folded as ioxd_header copied them, so they are one memcpy of the arena. + * Returns the length, or -1 if it does not fit. */ static int build_head(const ioxd_ctx *ctx, char *dst, size_t cap, enum framing framing, size_t body_len) { const ioxd_response *res = &ctx->res; char *p = dst; char *end = dst + cap; + int status = wire_status(res->status); #define NEED(n) do { if ((size_t)(end - p) < (size_t)(n)) return -1; } while (0) #define PUT(src, n) do { NEED(n); memcpy(p, (src), (size_t)(n)); p += (n); } while (0) #define PUTC(lit) PUT((lit), sizeof(lit) - 1) - struct cslice line = status_line(res->status); + struct cslice line = status_line(status); if (line.p) { PUT(line.p, line.len); } else { PUTC("HTTP/1.1 "); NEED(3); - p += put_uint(p, (size_t)res->status); + p += put_uint(p, (size_t)status); PUTC(" "); - const char *reason = ioxd_reason(res->status); + const char *reason = ioxd_reason(status); PUT(reason, strlen(reason)); PUTC("\r\n"); } @@ -272,14 +359,7 @@ static int build_head(const ioxd_ctx *ctx, char *dst, size_t cap, enum framing f else if (ctx->req.minor_version == 0) PUTC("connection: keep-alive\r\n"); - for (size_t i = 0; i < res->n_headers; i++) { /* names go out lower-cased */ - NEED(res->headers[i].key.len); - for (size_t j = 0; j < res->headers[i].key.len; j++) - *p++ = (char)lower_ascii((unsigned char)res->headers[i].key.p[j]); - PUTC(": "); - PUT(res->headers[i].value.p, res->headers[i].value.len); - PUTC("\r\n"); - } + PUT(res->head, res->head_len); /* the handler's lines, serialized as added */ PUTC("\r\n"); #undef PUTC @@ -308,19 +388,31 @@ static int fail(ioxd_response *res) /* Send the slab, with the head in front of it the first time. That first time decides the * framing: a final flush with the head unsent means the whole body is here (Content-Length, one * send); an early flush means the body outgrew the slab, so it streams - with the declared length - * if the handler gave one, else chunked on HTTP/1.1, else until close on HTTP/1.0. */ + * if the handler gave one, else chunked on HTTP/1.1, else until close on HTTP/1.0. It also + * settles what the request and the status dictate: no body at all after HEAD, a 1xx, 204 or + * 304 (RFC 9112 6.3), no framing header on a 1xx or 204, and "connection: close" when the + * body still on the wire is more than will be drained. A declared length is held to: a whole + * buffered reply gets the real one, a stream never exceeds it, and one that falls short closes. */ static int flush(ioxd_ctx *ctx, bool final) { - ioxd_response *res = &ctx->res; - ioxd_pipewriter *pw = WRITER(ctx); + ioxd_response *res = &ctx->res; + ioxd_pipewriter *pw = WRITER(ctx); + struct serve_state *state = STATE(ctx); if (res->failed) return -1; char head[IOXD_HEAD_CAP]; int head_len = 0; if (!res->head_sent) { /* the first send: decide the framing */ + int status = wire_status(res->status); + bool bodyless = status < 200 || status == 204 || status == 304; enum framing framing = FRAME_LENGTH; - size_t body_len = res->has_length ? res->content_length : pw->len; - if (!res->has_length && !final) { + size_t body_len = res->has_length && !final ? res->content_length : pw->len; + state->no_body = state->head_only || bodyless; + if (res->has_length && final) + res->content_length = pw->len; /* buffered whole: the length is what was written */ + if (bodyless) { + framing = status == 304 && res->has_length ? FRAME_LENGTH : FRAME_NONE; + } else if (!res->has_length && !final) { if (ctx->req.minor_version >= 1) { framing = FRAME_CHUNKED; res->chunked = true; @@ -329,11 +421,33 @@ static int flush(ioxd_ctx *ctx, bool final) res->close = true; } } + if (!state->body_done && !state->body_err) { /* a body left unread: more than the drain takes means close */ + size_t left = ctx->req.chunked ? SIZE_MAX : ctx->req.content_length - state->body_read; + if (left > IOXD_DRAIN_MAX || (ctx->req.expect_continue && !state->continue_sent)) + res->close = true; /* an expecting client may never send it at all */ + } head_len = build_head(ctx, head, sizeof head, framing, body_len); - if (head_len < 0) + if (head_len < 0) { + send_status(pw, 500); return fail(res); + } res->head_sent = true; } + if (state->no_body) { /* the head alone; what was written as a body stays here */ + ioxd_pipewriter_reset(pw); + if (head_len && ioxd_pipewriter_through(pw, head, (size_t)head_len) < 0) + return fail(res); + return 0; + } + bool over = false; + if (res->has_length) { /* never a byte past the declared length */ + size_t left = res->content_length - res->body_sent; + if (pw->len > left) { + pw->len = left; + over = true; + } + } + res->body_sent += pw->len; if (res->chunked && pw->len) { /* the slab's bytes as one chunk: size in front, CRLF behind */ char size_line[16]; int digits = put_hex(size_line, pw->len); @@ -362,20 +476,24 @@ static int flush(ioxd_ctx *ctx, bool final) } if (ioxd_pipewriter_flush(pw) < 0) return fail(res); + if (over) + return fail(res); /* the handler wrote past its own length: nothing more goes */ return 0; } /* After the chain: send what is left - the whole reply if nothing went out yet - and close a - * chunked stream. */ + * chunked stream. A streamed reply that fell short of its declared length closes the + * connection, so the client sees it was cut. */ static int finish(ioxd_ctx *ctx) { ioxd_response *res = &ctx->res; ioxd_pipewriter *pw = WRITER(ctx); if (res->failed) return -1; - if (!res->head_sent || pw->len) /* nothing sent yet, or bytes still in the slab */ - return flush(ctx, true); - if (res->chunked) { /* streamed and drained: just the terminator */ + if (!res->head_sent || pw->len) { /* nothing sent yet, or bytes still in the slab */ + if (flush(ctx, true) < 0) + return -1; + } else if (res->chunked) { /* streamed and drained: just the terminator */ char *back = ioxd_pipewriter_back(pw, 5); if (!back) return fail(res); @@ -383,6 +501,8 @@ static int finish(ioxd_ctx *ctx) if (ioxd_pipewriter_flush(pw) < 0) return fail(res); } + if (res->has_length && !STATE(ctx)->no_body && res->body_sent != res->content_length) + res->close = true; return 0; } @@ -415,7 +535,7 @@ static int write_formatted_heap(ioxd_ctx *ctx, const char *fmt, va_list ap, size { char *tmp = malloc(len + 1); if (!tmp) - return -1; + return fail(&ctx->res); /* the reply cannot be completed as promised */ vsnprintf(tmp, len + 1, fmt, ap); int rc = ioxd_write(ctx, tmp, len); free(tmp); @@ -487,6 +607,22 @@ static void body_fail(ioxd_ctx *ctx, int status) ctx->res.status = status; } +/* Before the first read of the body: a client that sent "Expect: 100-continue" is waiting for + * the interim reply before it sends a byte (RFC 9110 10.1.1), so it goes out now, ahead of + * anything the handler has buffered. False when the peer is gone. */ +static bool body_begin(ioxd_ctx *ctx) +{ + struct serve_state *state = STATE(ctx); + if (!ctx->req.expect_continue || state->continue_sent || ctx->res.head_sent) + return true; + state->continue_sent = true; + if (ioxd_pipewriter_through(WRITER(ctx), "HTTP/1.1 100 Continue\r\n\r\n", 25) < 0) { + state->body_err = -1; + return false; + } + return true; +} + /* The live bytes with something unexamined, or more of them; a failure recorded: no room is a * 413, the peer gone or the input ending inside the body is -1. */ static bool body_bytes(ioxd_ctx *ctx, ioxd_slice *live) @@ -516,14 +652,21 @@ static long body_line(ioxd_ctx *ctx, ioxd_slice *live) } } -/* After the last chunk: trailer lines up to an empty one, then the body is done. */ +/* After the last chunk: trailer lines up to an empty one, then the body is done. They are + * dropped unread, and bounded, so a peer cannot hold the connection with an endless trailer. */ static bool chunk_trailers(ioxd_ctx *ctx) { - ioxd_slice live = { nullptr, 0 }; + ioxd_slice live = { nullptr, 0 }; + size_t taken = 0; for (;;) { long len = body_line(ctx, &live); if (len < 0) return false; + taken += (size_t)len + 2; + if (taken > IOXD_TRAILER_MAX) { + body_fail(ctx, 400); + return false; + } ioxd_pipereader_drop(READER(ctx), (size_t)len + 2); if (len == 0) break; @@ -533,13 +676,18 @@ static bool chunk_trailers(ioxd_ctx *ctx) } /* The next chunk's size line - hex digits, an optional extension, CRLF - into chunk_left. The - * last chunk (size 0) also takes its trailers and ends the body. */ + * last chunk (size 0) also takes its trailers and ends the body. The line is held to the + * grammar (RFC 9112 7.1): digits, then either the CRLF or blanks and a ';' with something after + * it; a size line the reader cannot hold is malformed, not too large. */ static bool chunk_header(ioxd_ctx *ctx) { ioxd_slice live = { nullptr, 0 }; long len = body_line(ctx, &live); - if (len < 0) + if (len < 0) { + if (STATE(ctx)->body_err == 413) + body_fail(ctx, 400); return false; + } size_t size = 0, i = 0; for (; i < (size_t)len; i++) { int digit = ioxd__hexval((unsigned char)live.p[i]); @@ -551,7 +699,9 @@ static bool chunk_header(ioxd_ctx *ctx) } size = (size << 4) | (size_t)digit; } - bool ended = i == (size_t)len || live.p[i] == ';' || live.p[i] == ' ' || live.p[i] == '\t'; + size_t j = i; + while (j < (size_t)len && (live.p[j] == ' ' || live.p[j] == '\t')) j++; + bool ended = (j == (size_t)len && j == i) || (j + 1 < (size_t)len && live.p[j] == ';'); if (i == 0 || !ended) { body_fail(ctx, 400); return false; @@ -598,6 +748,8 @@ ioxd_slice ioxd_body_all(ioxd_ctx *ctx) return req->body; if (state->body_read || state->body_err) /* already streaming, or failed */ return none; + if (!state->body_done && !body_begin(ctx)) + return none; if (req->chunked) { while (!state->body_done) { @@ -675,7 +827,7 @@ static int chunk_data(ioxd_ctx *ctx, struct serve_state *state, char *dst, size_ state->chunk_left -= (size_t)got; state->body_read += (size_t)got; if (state->chunk_left == 0 && !chunk_end(ctx)) - return -1; + return got; /* what was copied still counts; the next call fails */ return got; } @@ -683,8 +835,14 @@ static int chunk_data(ioxd_ctx *ctx, struct serve_state *state, char *dst, size_ int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n) { struct serve_state *state = STATE(ctx); - if (state->body_err || n == 0) + if (state->body_err) return -1; + if (n == 0 || state->body_done) + return 0; + if (!body_begin(ctx)) + return -1; + if (n > INT_MAX) + n = INT_MAX; /* the count comes back as an int */ char *out = dst; size_t got = 0; while (got < n && !state->body_done) { @@ -711,13 +869,15 @@ int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap) return -1; if (state->body_done) return 0; + if (!body_begin(ctx)) + return -1; if (state->chunk_left == 0) { if (!chunk_header(ctx)) return -1; if (state->body_done) return 0; } - if (state->chunk_left > cap) { /* the chunk does not fit dst */ + if (state->chunk_left > cap || cap > INT_MAX) { /* the chunk does not fit dst */ body_fail(ctx, 413); return -1; } @@ -781,7 +941,10 @@ static long read_head(ioxd_ctx *ctx) (struct phr_header *)req->headers, &req->n_headers, already); if (parsed >= 0) { - ioxd_pipereader_keep(pr, (size_t)parsed); /* the head stays put, where it was parsed */ + if (!ioxd_pipereader_keep(pr, (size_t)parsed)) { /* the head stays put, where it was parsed */ + send_status(WRITER(ctx), 431); + return -1; + } ioxd_pipereader_run_begin(pr); /* the body's kept bytes are a run of their own */ return parsed; } @@ -794,29 +957,64 @@ static long read_head(ioxd_ctx *ctx) } } -/* The rest of the request from its head: path and query, the query split into params, the - * headers lower-cased and the three the engine needs picked out. The body stays on the wire; - * body_start is where it begins. */ -static void fill_request(ioxd_request *req, char *params_arena, size_t arena_cap) +/* Does the slice begin with this literal, ignoring ASCII case? */ +static bool starts_ci(ioxd_slice s, const char *lit) { - const char *qmark = memchr(req->target.p, '?', req->target.len); + size_t n = strlen(lit); + return s.len >= n && eq_ci(s.p, n, lit, n); +} + +/* The rest of the request from its head: path and query (an absolute-form target loses its + * scheme and authority first), the query split into params, the headers lower-cased and the + * ones the engine needs picked out, and the framing settled. The body stays on the wire. + * Returns 0, or the status the request must be refused with. */ +static int fill_request(ioxd_request *req, char *params_arena, size_t arena_cap) +{ + ioxd_slice target = req->target; + if (starts_ci(target, "http://") || starts_ci(target, "https://")) { /* absolute-form: RFC 9112 3.2.2 */ + size_t skip = target.p[4] == ':' ? 7 : 8; + const char *slash = memchr(target.p + skip, '/', target.len - skip); + target = slash ? (ioxd_slice){ slash, (size_t)(target.p + target.len - slash) } : (ioxd_slice){ "/", 1 }; + } + const char *qmark = memchr(target.p, '?', target.len); if (qmark) { - req->path = (ioxd_slice){ req->target.p, (size_t)(qmark - req->target.p) }; - req->query = (ioxd_slice){ qmark + 1, req->target.len - req->path.len - 1 }; + req->path = (ioxd_slice){ target.p, (size_t)(qmark - target.p) }; + req->query = (ioxd_slice){ qmark + 1, target.len - req->path.len - 1 }; } else { - req->path = req->target; - req->query = (ioxd_slice){ req->target.p + req->target.len, 0 }; + req->path = target; + req->query = (ioxd_slice){ target.p + target.len, 0 }; } + bool truncated = false; req->n_params = req->query.len - ? ioxd_kv_parse(req->query.p, req->query.len, req->params, IOXD_MAX_PARAMS, params_arena, arena_cap) + ? ioxd_kv_parse(req->query.p, req->query.len, req->params, IOXD_MAX_PARAMS, params_arena, arena_cap, &truncated) : 0; req->n_route_params = 0; /* the router fills these */ + req->body = (ioxd_slice){ nullptr, 0 }; /* on demand: ioxd_body_all fills it */ struct picked_headers picked = pick_headers(req); - req->chunked = picked.transfer_enc.p && token_present_ci(picked.transfer_enc.p, picked.transfer_enc.len, "chunked"); - req->content_length = picked.content_length.p ? parse_size(picked.content_length.p, picked.content_length.len) : 0; - req->keep_alive = keep_alive_from(req->minor_version, picked.connection); - req->body = (ioxd_slice){ nullptr, 0 }; /* on demand: ioxd_body_all fills it */ + req->chunked = false; + req->content_length = 0; + req->keep_alive = keep_alive_from(req->minor_version, &picked); + req->expect_continue = picked.expect_continue; + if (picked.refuse) + return picked.refuse; + if (truncated) /* part of the query would be missing: never act on part */ + return req->n_params == IOXD_MAX_PARAMS ? 400 : 414; + if (req->minor_version >= 1 ? picked.n_host != 1 : picked.n_host > 1) + return 400; /* RFC 9112 3.2: exactly one Host on HTTP/1.1 */ + if (picked.n_transfer_enc) { + if (picked.n_content_length) + return 400; /* both framings: RFC 9112 6.1 */ + if (picked.te_other) + return 501; /* a transfer coding we do not implement */ + if (!picked.te_last_chunked) + return 400; /* chunked, but not as the last coding */ + req->chunked = true; + } else if (picked.n_content_length) { + if (!parse_length(picked.content_length.p, picked.content_length.len, &req->content_length)) + return 400; + } + return 0; } /* The engine's bookkeeping for reading the body on demand: where it starts, what already @@ -840,6 +1038,8 @@ static void init_response(ioxd_response *res, ioxd_pipewriter *pw) res->has_length = false; res->chunked = false; res->failed = false; + res->body_sent = 0; + res->head_len = 0; ioxd_pipewriter_reset(pw); } @@ -859,10 +1059,15 @@ void ioxd__serve(struct ioxd_pipe *pipe) long head_len = read_head(&ctx); if (head_len < 0) return; - fill_request(&ctx.req, params, sizeof params); + int refused = fill_request(&ctx.req, params, sizeof params); init_body_state(&state, pipe, &ctx.req); init_response(&ctx.res, &pipe->out); ctx.user = nullptr; + if (refused) { /* the framing cannot be trusted: answer, close */ + send_status(&pipe->out, refused); + return; + } + state.head_only = ctx.req.method.len == 4 && memcmp(ctx.req.method.p, "HEAD", 4) == 0; ioxd__dispatch(&ctx); /* middleware chain + endpoint */ @@ -871,7 +1076,10 @@ void ioxd__serve(struct ioxd_pipe *pipe) send_status(&pipe->out, state.body_err); return; } - drain_body(&ctx); /* what the handler left unread */ + if (ctx.req.expect_continue && !state.continue_sent && !state.body_done) + ctx.res.close = true; /* never asked for: the client may not send it, so no drain */ + else + drain_body(&ctx); /* what the handler left unread */ if (state.body_err) return; if (finish(&ctx) < 0) /* sends; suspends meanwhile */ diff --git a/lib/http/run.c b/lib/http/run.c index 3a57f9d..fccac40 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -144,8 +144,16 @@ static void serve_http(struct ioxd_pipe *pipe) ioxd__tls_close_notify(pipe); } -int ioxd_run(int workers, int port) +/* ioxd_run, through the header's inline: the caller's sizeof(ioxd_ctx) must be ours, or the + * limits that size it (IOXD_MAX_HEADERS and friends) were redefined on one side and every + * handler would read the context at the wrong offsets. */ +int ioxd__run(int workers, int port, size_t ctx_size) { + if (ctx_size != sizeof(ioxd_ctx)) { + fprintf(stderr, "ioxd_run: the application's ioxd_ctx is %zu bytes, the library's %zu: " + "IOXD_MAX_* limits redefined on one side\n", ctx_size, sizeof(ioxd_ctx)); + return 1; + } ioxd__router_build(); /* the routes, resolved once, shared read-only */ return run_workers(workers, port, serve_http); } diff --git a/lib/io/pipe.c b/lib/io/pipe.c index 7a3647c..a59e44f 100644 --- a/lib/io/pipe.c +++ b/lib/io/pipe.c @@ -49,7 +49,10 @@ static void compact(ioxd_pipereader *pr) } } -/* Move the current buffer's run and live bytes into buf, so what follows can join them. */ +/* Move the current buffer's run and live bytes into buf, so what follows can join them. A run + * that was kept in place has pointers out to it, so its buffer stays pinned rather than going + * back to the ring - unless another buffer is pinned already (the HTTP engine's head), in which + * case the run just moves and ioxd_pipereader_run is where to find it. */ static bool gather(ioxd_pipereader *pr) { size_t live = pr->has_cur ? pr->cur.len - pr->cur_pos : 0; @@ -60,6 +63,11 @@ static bool gather(ioxd_pipereader *pr) memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->run_start, run); pr->run_start = pr->floor; pr->floor += run; + if (!pr->has_pinned) { + pr->pinned = pr->cur; + pr->has_pinned = true; + pr->cur_is_pinned = true; + } } pr->run_in_cur = false; if (live) @@ -136,12 +144,15 @@ void ioxd_pipereader_examine(ioxd_pipereader *pr, size_t n) pr->examined = n; } -/* Forget n live bytes of the current place. */ +/* Forget n live bytes of the current place; never more than there are. */ static void consume(ioxd_pipereader *pr, size_t n) { + size_t have = live_span(pr).len; + if (n > have) + n = have; if (pr->live_in_buf) { pr->buf_pos += n; - if (pr->buf_pos == pr->buf_end) { + if (pr->buf_pos >= pr->buf_end) { pr->buf_pos = pr->buf_end = pr->floor; pr->live_in_buf = false; } @@ -160,6 +171,11 @@ void ioxd_pipereader_drop(ioxd_pipereader *pr, size_t n) const char *ioxd_pipereader_keep(ioxd_pipereader *pr, size_t n) { const char *kept; + ioxd_slice live = live_span(pr); + if (n > live.len) + return nullptr; /* more than is live: the caller's mistake */ + if (n == 0) + return live.p; if (pr->live_in_buf) { if (pr->run_len == 0) { /* a run starts where the live bytes are */ pr->run_in_cur = false; @@ -187,6 +203,7 @@ const char *ioxd_pipereader_keep(ioxd_pipereader *pr, size_t n) memcpy(pr->buf + pr->floor, (const char *)pr->cur.ptr + pr->cur_pos, n); kept = pr->buf + pr->floor; pr->floor += n; + pr->buf_pos = pr->buf_end = pr->floor; /* buf's (empty) live region moves up with it */ } else { return nullptr; /* nothing live: the caller's mistake */ } @@ -293,7 +310,7 @@ bool ioxd_pipereader_inject(ioxd_pipereader *pr, const void *data, size_t n) if (pr->error) return false; if (!pr->live_in_buf) { - if (pr->has_cur && pr->cur_pos < pr->cur.len) { /* live bytes in place: they move first */ + if (pr->has_cur) { /* live bytes, or a run, in place: they move first */ if (!gather(pr)) return false; } else { @@ -355,7 +372,8 @@ void *ioxd_pipewriter_reserve(ioxd_pipewriter *pw, size_t n) void ioxd_pipewriter_advance(ioxd_pipewriter *pw, size_t n) { - pw->len += n; + size_t room = ioxd_pipewriter_room(pw); + pw->len += n < room ? n : room; /* never past the slab, whatever was claimed */ } char *ioxd_pipewriter_front(ioxd_pipewriter *pw, size_t n) @@ -415,6 +433,7 @@ void ioxd__pipe_init(struct ioxd_pipe *p, conn_t *conn, char *gather, size_t gat void ioxd__pipe_close(struct ioxd_pipe *p) { + ioxd_pipewriter_flush(&p->out); /* what a handler left in the slab still goes */ ioxd_pipereader_close(&p->in); } diff --git a/lib/io/pipe.h b/lib/io/pipe.h index 80bf60b..85e08c3 100644 --- a/lib/io/pipe.h +++ b/lib/io/pipe.h @@ -42,7 +42,7 @@ void ioxd_pipereader_close (ioxd_pipereader *pr); / int ioxd_pipereader_read (ioxd_pipereader *pr, ioxd_slice *live); /* 1: live bytes with something unexamined; waits for more otherwise; 0 at the end of input; <0 error */ void ioxd_pipereader_examine (ioxd_pipereader *pr, size_t n); /* looked at n live bytes: the next read waits for more */ void ioxd_pipereader_drop (ioxd_pipereader *pr, size_t n); /* consume n live bytes */ -const char *ioxd_pipereader_keep (ioxd_pipereader *pr, size_t n); /* consume n live bytes, kept: contiguous with the run; nullptr when there is no room */ +const char *ioxd_pipereader_keep (ioxd_pipereader *pr, size_t n); /* consume n live bytes but keep them, contiguous with the run; where they are, or nullptr: no room (FULL), or n past the live bytes */ void ioxd_pipereader_run_begin(ioxd_pipereader *pr); /* freeze the run; the next keep starts another */ ioxd_slice ioxd_pipereader_run (const ioxd_pipereader *pr); /* the run in progress */ void ioxd_pipereader_release (ioxd_pipereader *pr); /* forget every kept byte; live bytes stay */ diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index aca6ae9..39c8a97 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -40,11 +40,12 @@ static void make_ex_index(void) ex_index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); } -/* The last OpenSSL error, as text. */ +/* The outermost OpenSSL error, as text; the queue is cleared, so nothing stale is read later. */ static const char *ssl_error_text(void) { static thread_local char text[256]; - ERR_error_string_n(ERR_get_error(), text, sizeof text); + ERR_error_string_n(ERR_peek_last_error(), text, sizeof text); + ERR_clear_error(); return text; } @@ -221,7 +222,7 @@ static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, BIO *wbio return -1; } records++; - int n; + int n = -1; while (*plain_len < PLAIN_MAX && (n = SSL_read(ssl, plain + *plain_len, (int)(PLAIN_MAX - *plain_len))) > 0) *plain_len += (size_t)n; if (*plain_len == PLAIN_MAX && SSL_pending(ssl) > 0) { diff --git a/libioma.a b/libioma.a deleted file mode 100644 index 86d964560208748b6a13a6e39a0cc77ebfc95d2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1237342 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�Th^g=OIEg`yuBrK4OLn}RhSVh4 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

2`x5n+KSx6qXl|fJdgvUZ0wr3rz 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 z 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 ^dNP4f2lhl*ILhfn&@*cV4^9#a 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≺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 })@XSwH^kx@rM z?*|Ft7H5fTLvOOw&~7~q$YU>&4uk(y`fUwQKB@BTjnrw>|95mVF|7g`|4&)$e}}3V zhqiX&U6q@>^MBJ$f;W9`#-YFih(Y?j>K?dmH@(siNRpq9B;3M3Q7FJ-S&B8_5}Fwi zdJT$kW^dp}((Ys{t+a(G#NiAFE2kdj$M~K}t1%UHEX8ri2vogaI(82LOnKDohR*%w zn%y`cXEhja_+DMyCtP9?0S;>`WnK@XsqG=iX?1DzI+Ic0hgu6g(bwJ_cwQsQ2RY^fuSJnD0i#^7L2J=5hziUos6j@h%`0(tdUvEsO~;!92wr|$t!)x#`@SxPGl#33;k1$0~i_OT@D!z(L0bP@KX zcR`BIH8AG9u_Yo4fqt7aCXi&G<5CBJPB8?dL$g4S#9o$^^}AkhMPs_a$#-A0mmsbp zI*Rq0-S?Yx?%DuI0gqL<>oe1{&oIrd`ZGui;URD|zeo}&KZemZgMJ1p<>hHeA9Eu} z7tdZ|@5F`mE6AU``i~loL=lK~(H~)=jD(q6L}vhi_j2h&z{Ni1m_`gE^b=YjlUj=( zJ|aFslH;1XH5Ph=^YqErBXH1}vDc+XQy}QBHQ+43T|~!}wpw&JX?U%}L;czntHCru zk6OJN^i2Ijq#RIHzZGy%Uu`2ZF2TOm{PTPgbT0RZ63OyGND3|VO)DrlF!jS)fI#yK zPX7c#n9A*kwAI*Bpi5W%7TX|UIAUcvy678in3oP-5k7*?J(;IV$7?T0LuserodQA) z`DBiW)tpC%yRNhH>3zuEOL-vShJ`d;#Xy^`GoX#CZw9Ym@@_VQOFzilA#~kmMvfqt znMb347y}wg4&HUH`(Bzq=VQa;+RT2(=`i`I80#xLSA(q;<}P#$+DIePOAnhHfbe;c zoset#zckhL0$7o!T_XYs&er{|cZENbY>59Z>6rueKP0wDwBY9Ixn}oN#{fOapVG}P zbfd|31`o&27qYEr{}@MJ$XhynwT_&hF}mnK2#j6`TxeJI^}3pDoB_m1btMiS5xKk{Ual zJ}f<^xY%_^xUSWYA%SkUXhMujKIbT9_Sdb1pkDo-91dGpn`kUWv@MP!d3nQv zWh_=tK>F`GW=5>Bq;{>QX!spE_IBx4A#7sVPe45%V0Wy3xd^0KuECU7E5`pG_++P; zW;1RCFdKQD?w(bX4iC9 zm|`ZmJv$vt)R(LomoI!@ue#Svb_SB1I0?4b>!{?N%g$V~nIHAxp%y(V!~u`0hcwfI8Vq(vczUCnywr8uIm0Kv!5PKlkqZ$Le7poT#QSfFqg7DeFP~v z&av-svhPH)?{K#7_%`;P*51DMyp}cd(z8JX@=9V+gQspJFg=k(UgSZ7!=tZd?&n995jq{yAWR5nUPJeLiSU>3MM_G5y-GdmQnfT}%IR5F z91^TpD2e!dI%e+eEAbRoKcLW4%4Q6hz5}x-Mt>d8kMP6TM-3H7FldjNNQ)|OB!JOujs@oQ0&`%Y88_J+yV{(-m0}2< zOqpgpZkLdKE5*|#{jKxUq50h=dB>$pkG!O({wf}%@EMc!JcY8|w*hb1jBO5{XhavF zQlD?etucp>5TN0DLz5X-WcEB=sxz|HB8(NO#=_t+lOag~7Jw?jhffy74A;iSIC1_H6+e-UvW ziTFoY|C@*)i9p(s+CHI;@CM$gVjDqrLPCKxXCuuTEj30w@xw;Le&mOE9plC`QJ0RL zhB+7=hLS1iSdiY~peTsP$+X`15l}c^ap^ao--PM7i`;7zKZTCU7fo}_u2amgbdJQD zYmxv$20VrXOPLgf#?mlLMy~x0@GZ|=`tiCtD7$DH*xR& zrdSoX+Ymkj_#U}1nJa}z5@bI_^R4C)57TGQb#I>gC`II}5otO}H?YC^L+M5njNd-p z*aPMmy>ualI6R=^lW6B4B|@K$mv%bHKd{S3{(;RG=O2@T^N+P1<{vGzMAG8cHvc#* z(kTzobdTz*%O` zGtIabn%;kw!#ag~4&P3^zGtO)gwbiZ7x-pR1YE>=1YG}WE3(`1mgV46R2xD^(cO~+0oBkiMfR%E;{#_%U+7Ll)_9R3_#}wuDQtUvDHM9u}7pY z`Z1kNgUQHYM;}K^GzA_4^J`xEQre}c<`87~c&y9Ia~$Y**Pn!UAv^ z7X)_n2QQ*sU4;IMxf+S#n-}Ced)7e9y)OOr3lJjW=-2^ogkWCMqA5-w#38_Kc);fL z{NN%!-=GIcNJwr|)p=m>gh7WjaFFM){i7X=zH6m0fmi=q2LgS_0{yK6fj%@L(39;2 z;s;kQ{S#V(!Ae9!4if1!0&{V$fQLU2;e2*s5AVRKel5hK6(0&>ZrcwbAt5dOVfsBQ zk(feos?huMX? zAy(Aa)+vj9zPi$~>Z+x_(#rbUB}#c?eQ8w#=+)GK_QJZ-+RDlXpI>S4*VAv*l-JhO z1PCpwukwRqS;f+_nsS?8X<5Cmrc7B-TXA0Lg7f_NWu>}B^`(%d!3WvSZS>){nONq< zOO?i&hN^{Nlw4KgS89CA{Yqt3O4zr1u2slgx1%7_a~s?_@`L9fw|=H+~Eq@GN! zw82-u)TdNd*Vfi6)wRn=u!i!gDrHGkO>KSYQeS;TRc(zjWBj-|rDJAH9ej3Y*)%#RT&EnQgCSYEoc zthBlc9?^)-3Q+<1(o%FSuRE`_e9>Z58fxn5!MT#FZ51i6tvj!sZG`-#V_|pnuON@B ztoQj)CKZMa1rHi~$nIaH)YR5c3;p0W`|PqswbeeQqQ0z(WiU1)Aqlebn@RaZMM&YJT`Li(lT*HsORK(4G_!7n@cYD(+iD83qhX?d0KFNjzM z<1ADrPMe)PZb(-0;GyY5(le9OmiQZMd<6@AHNN_)a#YLe%NG?a&mERFY-n=Y!sN8+ zS;=V){)z(F6TQ+ZtNpe3tSs}Vp_Ep;;7`7Ce*++84d>OAFT&8)Ha4U+)-0>4sYvse zEvWWUBSx)!aavt{tsmI6^&kjD5Vso2tIHY|+0B?nXeh6g>I&5Jm$LoD_*azq%XkLl z!q^0AY#)H?8!`8M3#)3#6D!1wXM4l$6K0H=I=*!Fv{{p)Eu5Is{s=&Vz^*G5NBU+ zYeYZ1sBz&UAyH{XRRbnc`63YtDnx{xIcv;}If$`{_x0zAiN*BT-W9cta65Jnjwh@x z1--Ir((OFhsC+T|1I@XbvL!yYGK6I*VhO;65ke?VmgDF4n7gA?X=9BaJe^=wYKO^Ef7wE?qqVK7rmngSmZtr6zSXhw) zA}Z%%-B`>4j+A5!YltAfa0bUdPHf^eiZU~9Mh_5M#`MvmDI@DRlPum zbX=e&@;!f5WtFc&v{ls(K>>33>X93xs7xF;E-!h&>;(uDjaHhFHnfqeLoOOJG(B@@ z`ruQn2L8)CUVICRzCwl6g1%b3o4!~jzUYr%@kE&}^?dww-Q`}jTX=}O3179E0$6u$ zv3|jFY^3)pZER%1mHKIs$!m?%A_uH73nMeNaiNg|#ziKNiA(^-*hu%pFx^lEY@7|l zZ^F`FC8)OO?Tlzc8yC!5}pY>6 zxqy#}8~{Av3oc{uLpsW6{M(IxbXCyzz0h_w(Y%UiUTL7uT60ol<{H;&k>_Z2p-g3r zL}h#!|Kg`%eYK2#ns7{{cdZ6()*%{Y^d zTA|svb|XACOgje+6WTS537Z5Sk61inNQd9&aXUzz){Yd$e*?N3)?{cUc9NCJ0cjDiUl5zqTcQ{UC!t__&K%WS7c-O{~F~F@1wIGwjv zQmYM;ba;`vhVt#N9X0CCpI-=W)fN7VWH1mlo&U;jJ22p(?SYJMdsm>DFg1y<{cE>` zp$C3UI?#dP{A-;-un(aa(b-}7B*zF~bi+SY!OzE9m;IZveNZR-CJVsxAF#m|+zxE^ z&y7-dU7|yE`_jcvdD~Uzt}7#*vRu%WQF7HO>&iH%EEjZ+95O_db!9?(ARxLju^k*g zEQ>3*9egxHa+UHnE#octIc?yD7QDUay?f`YXd*ug7f!^rM8t^7S@x%%B2?m&oU6@D=fIZ zCfLo*7QBn)pEmqPE)3`O&4$ta7Ovzfp>6QD0G^Bkytdba08kundp!<7NAMRqfq&Qu z{8%S&lCLBB(Vf8QmykQc&+Y_1p%eI-oxm4#0zbbK_%(pXAP#uDKtWu#|K8jQ{(Tny z>lQw*zv%a5C-|>+0)M*`_`4Q;FMdOiE<0j=V!@LwxL-6YM=f}(1-IAYUoH4<3(o5? z`b1#e>&X78oxq0yPWGvzK#I%$Mc|@N@XxXEcUZ|EudnELz6F212a{2FtweEcCv-M; z0>7^l_^wXiuXO_dpcD8Hoxo|0@5pYkoxlSbd%N>GasHW}8GPgv*c_%$8JDTxBZoeQ z(MK+Q3?9s%L+EoT7a40f6&aXKr7UjY53UbkRQ&inVKK$QOmfIDN5XX9f~?BQoWZ%+ zdGIlP&?oZxeYjpS8*-HJfw?mUGdL`tC(+e5uEzkaF+!qI)fzm zS)IUJBsvr#Z94aLf*((WaS>nqM6rY4-GaB}n`AA~ZQ<)JIMJb4ZS%dl6a1wvAmJi> z3c)u11s1$5{TDic$5<(RTl{66z<;#h#1}uf?eJZ1rS?SUR0)2Q1gG4}mb0I=fDwMW z1iwpy%lNNKaGCyR5Y?}@g_P$CHQm+o-M)CV^P6H z_`~qe)@!K*m+{w0aGCE`2`=;fhXj}DACcg)z9ZvE8X=EN{{{&z%X3VE%k*_CuWW12 z76~r<|J@Qi7yNBI9HgL$i|Ekq*M`Sf0hi#ktFhr(5?sa~Bf)bd{HYQ=UxM$I;4+;< z5?q$^$4=lnIXAAhcBrD@Yr$nZ52avg!DTy_N^lu}wFDo7ezqM#tUQE2><_suH)0FtZtM?vHG#Ve{3vklXLEty5cnSg|I7Mj@g1s|)4I5u*y=nue_0kCTV!hf3T&!0Qfs6Hu7r3~; zY!>!+aeOdS+?1~<8p1mNfWxWGjahmpY=pyw%=xJhAJh2)!(kzBu2MJ*12X5az{Let zim^|wp8)4Wysz>F`B@$)wqQBPgTe7e%H~4*%3O>sA<9P~p8@A>tq9)&Ivok`Yp#Iq zgztm2mT)cD_a^*5s8@f&!+{SbJPGQnC;R~TIfd}j&@LMZpALLC;Ul0CjuO5I;&YMk zxzLVx2;T_)+rf5hmkXd%kMM<1uRjRi0lFOtZv^eACHyhOA%*afU_X>_cZkDZgzLf2 z8HBUnA(ofLgtIp-$jb)8tARgxgu5u_(ka3(fcy*Cd@T4gh43%XUh@gZIIkfbp1FiC2mLFAJ41XP5WWI*EWuy&GX&~emhjU`H;@7euMXp(hVb%SkS*;9 zuL$~`2_FOfN=vv-k d{s{O2!mj~eNBAM|a}VKdfS(}zE$Cb$yf^sCUd<>k7`J7> zZ3#C3{knwXb&3{*TSI)h5$*^2QG^cy`#8eWp`VWN{(*AEZ3(Ymp+EP) ze<#R?9LGIR!qLx$gyV6j3E|bik2Zu`Lb(xy9|!w*!tuOf0O7+R4kHQQ4ddY?!e>J} zt|WXHq_+|t1##O;_+v;PCmesI>LTI&puV>WS3$d*!FG)Q1n|EU;hDfI5Pl2dR-N!p z5T8K8{eXuMJ`VirK==*V-=hgP2K&B*4?nt`{ z$9V`x2*>^U0^u&8^Mdd%;QuGW4S|=1>*^SvQxJc=o{zjQ^tVuAkNTYmM?e20JPq1w zBHzj{u=mZ!a+tlO!yk`|1;ru95sat99Ul$@Y9L#G-!8E!dpYT2NRC* z2`4-V^hXfB9rlaugrm+`!Y4o+-V^>0_){6~BVfHyrwie0KqsAWv|mIxj{A9pqy1gN zuYf;a2=55x+NqV6qkh&Uyeh;klyGdX=puMB;gg~N4MtSuE%d8>grog6 z!twjmYr<yOI!SRrAC{}WU8w|Lg;`c;P!jHlJ z9zi(Hd5Z0a|!PS`^9F$t)ZWsB%IH`ZK+ zA@U2r>%b@4Lvt0*P)FVg>@>vQ7t&#bRJCVV`k(+EEf>4AjjL3$|RA0VAgcvDF032zDMv4pRK^d!RhylK8nS3U~c7j|2i z7yiB7UBMo9C)plOVPpk34VO6|k}t#l0*7&#!;mK1V>!G(aE^9(pOhB|LxyZ$MgFh& z1BW=7_z0YrtA}yVk8r$y8caA|ml69F*J%R#Z)ak^iSHb2=^_7D{NeU^ov;_-t6>L7 zBzzyF#eTwd=7YW1PdLZ>6r+evf2eN`;duXa2H|g@0T&To1KMjp;dq{KlJNO(UU8N1 zJc!Q&!tws;8^ZB=A09t>f8h0f4LW!|7&#t~_`H0+AjkWsy$J6P?U+V*X^8VM!WV!& zpRX_KH-h-gA{_4*Iip+xD6m2+hsK2c;ArE%NOgr9Q;{C zxE=HpK3`w7$2jjH9OI1l8?nAe!Ov^Nem&IpG2s}u_k?>xJdHsQ^)a4&9>3@(-jBik z5A87yjfuS}^v`(0u|5L{UkYhG;i$8a@Z+F=nsB^-`k3%Ah|fF14}lKOTgG~6p}i_Y zdm=xrghdJ^9Ip#^BD^cl$d+ir8-RWs;duWvjc}bJBh4iI5%3L!frs;QV>7nIKH?N-T?IfAbdHbaX&*HPl!(fvB&$Tsf14ld%RAM zIuoIv|3mC?yk1E-#`zrKc>nYk;duY_IpH16}Gq#o(=ugi|{R= zTbJ;*z%_)oSLCJkgoi@A^d!6)_>)BVNU+EI)#!gP>|axf{Sfef8Q~cJ?Sz{_`VisR zF1HECc^97vw*r66p#9O$yAX#8gj++ssuPamUOmFm&sK!v{nPe@V|(-@JOKPmBK#55 zXAt3dUV-P2Sg$z{=V`sR$^srud|J03eynj)H@GlUz288P%KB0uS0glI8EEnSvL+tVXsg7_Ls81&0c>Enp zIL?>&oA5dihh>E0_1jZ~_=D%6sAB^4^?-ha z`~Ywb;dq^V5aGkXeiq?4?`H$y%b*{!*DuNomfHvXEJOG(=ns_%$9ZERgo8U$9N~EX zbR6N{;Ll>hUx7cn2rmce%Y@_o)Bgzfg#KwF+#j@MW#aj_BjE|)k1yeP|CGIULtc0> zTnGDQB;mawZkdF)!1f{>uWM}~9Pgjvb4*w+Ubi_9_WWxAKSjmoVV@Em+~3~`oZlkA z@Al&TQ_kTwqEsN*^ZL55Kfb7i`;7cM{St_CWr1`1%FzGn5bh28NfUwda$VUUUqT44 zpkS#DaI9}rcs?Oqu;>140e|8J&h`C4Cz)_B;AsLEb%qF>>%@ZnFv5EPA452PKOaZ< zaIl|F_&4CQ2!9KFjlj8|*Py;z1Wd@FRpb0)7@aPxAg|=%MKU zE7)^?K7l{a1kU~G0XnY;?+*MU;dq|>mGD@wH-HOLe7_LOEeo9bS&`TmgY)&;0_T4A z1O2*$MV_FTU@)a#B&Xe4qiV$bp5-h;9O@D=o}F^*TL&%CkWpQIu{AY=i9FmZUg#vfn%I&JF`OA@?5az{+tK< z4+7`@Q~~~laChLwaAJewMm^x>ga-gGA#kzWG6Lu2>cHNfaJ-)7DsZmz0qkoCoa^|( z`K=$}HGnq&j`5k|%rdbhM6l=j?qJ_Z;9P$a@NmL&fNKfg2|SMQt-wD+`bEp=NAZ{3hn!!z`4#B_Q#j60_QreZZejt@yfFW{T~Yc`vJ$} z>`-WzrUK`ZFCjk734ac}E#Y{5rX%5>z`h6Jc%31da3lC0ng|^IpNR1n?D^_s@PCxR zx&Kz6^B3VIfKMSD=LO9m+#c-b07rjLf4~T&Ek@KP0>@@Q;M!^~A4)=YYM5FprCy;B!Z6f%9^6!QO^&yw2tT9OLHi$}+LV zU9ji+4{k_3c4_ zrNFuV3D8+f_z~dS2)_k<7vcW`KS=m{;71963H%)4HQ~C=CBmx%|5xB*z3vN~*DDR| z9}}Jg`~`4~TMLL=aencLEy&H>m2@S-=YqWta2#)IL7amG&i%=Oa+?r726zj?rvYz6 z_!Qt>310*}g7ANU#}a-9cs$`JfcF(Rk2BV5pul;(@cEV@gxm0duw^9SLBPil-T?S` z;28g-5a(5d4}o#!7~#`_Ul8=U|M>i&IM0*&-x|t&EZB37*Oy-iT-13laBklpbUqWF z0^A5DC-Ee=pAFoM@M*xUfnyw|d$3GwsY2{efV~&t$AH%+I;%k^NU-Pi!t=(~0_T2S z0-g4RUjW{f=r02O{)FcO&mp{1C0;8@T1j}R$_n3H1V0O$yTSdu4gQGpU^%}D{3fw~ z4*V|RkAdeCjxVtMNcb19H-HIe*j}#Sza?;P#^c-r#s_0rm*x{b z*j(ALns6`hb35T6BONFF82B&0G>sYY?7Y6`pkGNdfi_wz>34|fsn5Bvn-sld+=9tZq3;Y)$vCwwOG zCj#g3#QNq7ocnnX>^~BI3wW`zO1&}uC!yV41kQCng1sBz{{gQea6WDfhByZboa>Z? z`x6Zbw*npl9OLf*@8@bO*mM0H(2o*0*LMb;UW7XUPbR!Ja2?^*fe$9U7w}BNqkxYP zxaj9Nfpb5Xfc+%G=K-G%9OF<6;;@16PQXtRz6$u|BKTY2yxqA!d!XD8gzo~bf{Dmz zkN3UU4>!sS@ z^NDb@cYtzmzc2y&T7*xAavK82`r`YadkXeE&UpVXhVb(cw>|_la~*sU*FeI* zfR3Kzzmx}^eFEqD zcwG2b;9NfgbZ!wo1o&g%*e+e6z41MPynT7OUQn(fJTQg*c{J#l5a+9OHxYeWwUqY?noZ z=fVDh$4`vsa`1nnV9)Ej82B#WSg)=y9vu?wdECD7lQ_0q5;)h{13K3T-v<01;n#pa zBK!jI=K>eYeJ5~UZa&z5BK$RQLm2cHgM}UI6;vfMb6+#tUJK8Qh1#@xd3$wG%kk$M+^U5MC0>bq9|6 zw?N;!2(BSI-k=joxEJvDgx3MynQ)vB5e*#u!RPQ31$*w|6mGzlAp+<14FmmQgyZ~) zF@)oLAI1^h8+4`%oR_;C%AF^0UhZhHUqtu_;H!aSy-xE?Y}r}_KTmZ22A#`<&j5a# z@I}Dy6TSfW3&Pg`e?#~x;O~K>|98NDOJ}(nh1Zz_q5sq(9Ph)mBs>(ZUv~zM{do_> zIZoib$Zg{fpdMF zZ;?kh&d)ds9OFC?;&WcG=j9r~{(ev3T)#NnFMmY11@PB|zA+R2JOlPO7p^yL7wmca21C2-CcGi= zpjsA1pUv1`vb>`^jNMv zlxq*y@3CA*=s)hj(H?(~Oe5HH=?}E+hWgGWyfpBwgf{{HFX63$=M%mFcmZ(UUc9NcLH}37{d{akoR4Kg zcnJ9K2ps)K{Yrv8*FOUKwFS=iua2Nom+fhIfVZMd^zC{f$t~$Gw{2Fo5JxIpZnqM!jE70e#jOcEWsA!2jRHZ z894fhzbpEuV9(<}4eB+N@EqXT0_Ww>#`t@S}ux1b&k6FyJ=`9}D~r;n~0+3Y_=nme8M{37nha`NMmG^Z4upozH~h zd+y9DGb6U(e)kdVixZCXmP!N1_H708TJZODC~rjUM}s}i6XE6Zdf|Ho!%4ZuV2{72 zgMO-j#}RvP;0c7|Jg0QR>wx`0!u^2{1&;Mv0DL;(Sg-kl4zCx!?`XZidAkII&St_J z0pCgV6M$bK9Nz<&FX-?lTxH1qv875C<&(#ab9~>UKjCf76uZX2vA+0w;#$F;``;V< zi6cA|c%s00xfc|9X@J1FjtQKP4JP~v=u9Vk64=iod?@gF0_Wx4g>u&sj?eS%6gc8U)4w8cuHO*G+v|i^1Aa%~T<55XQowV8bDgI zaPBAmKDaI6@u1@f9OG;V_oFKb_B;;TK;KW`Tt5?Z>JUB@cw@rH0&hn6U%*=tj`L31 z5&k#WcL$FCTY>+vf<5>D2>9Pm;N1V^pz|l;IDaLZ@cm#vitwGla|AAy`;WkRx%a_- z0pYiSuLO?unhW*HBlaJ`{s7_mz|RmJd~W=jV9))$0`YkwaPDV0n6L1Ha691d33mnl znQ)xHV&th5#QQDRuL<^Mg!=$52^{0_8RFnj1g}kW>Vr;Q!UKT^6RrWSA-pN@)`YhK z-kxy$J<%?}(SLKepF5Or4RC!Cd?C>fhjNz^-UawN!efAMB0L)SZo&ru-%B{o2RZ~C z>lFe1-w-%Ib?d?Y`0`fZe5k!qT*i{h3qIKg=Z}GxCEObHYY_e)jN5@l@Q%Q-zhy(c zx)MGNcr@W-fyWY#^Pl<>J`e2E2>%E8K;RfRe4c%Rz3gu299Oto3A-n_F&mp`I@cD$t0bc?f z>xJ*PKSuZvsMm!e_-mq{4*L0o<9xesglB-gfzOZaI0U!_;gf)?37-Jm7C6>xBKYqn zaNe&rD#b|+1kU?aF4%V>`tw0QobXw|wM54dzK0GW_IY4GjBuRiH-_kx0i7vD@Kr?T zKIpF_{5J5NLhdJl%dqPP{t^()nyBqAiir~$G<9JdY{AoeB1MrT7djRiBxI6G@ z!fOJLCEN#i0&uMF3Gn|f!tp%-Q;XoMiGDrMUr%^l;5!I!27C|UO@JRJybJK-gm(gd z1~}HMw5ify?+EV$T&k&TM|3$N4Zux&m4eXzDDYy0vFqGJCv_uu|Y$r##H3TuZnu@J#~eI(VHtSKwTyIoR(fyb2J9aY-V69sfr~m{1&ih2sB4LEn}k>?eB!&g+ZwPWBP*;-=^vC;IC_|6&pR4bkxg zop*#+1^$KTtO9*IKc#%!PlrN(a1l7K7w$*Z1kURf0Q%m9*8&~@9OL`|%55yz^L{cK z%55ufuHPJVIufn{-h=QCz@rIo13VEp`h)M89ZmRI@N+rg(@HR>*pf$h6|lcX_$Xcp zwtNK6VFl z{%)WJbR-<#@I6H}2@i$wp#kCe9^FvFcf)?CBOG;x5#ATtWe(x^yMeic<9m{C1IPHw z2TvC7FM>VqhfdI5Qaz zxjw#6>=EHRq1@MmUjm*__$lDu2sf>)_+!vO`NZ}$1a2yD(N8OZb3dDby)EHEz{>*1 zIJ}2A_!2(KLGhyn;oiVI3HschScqGcz_~vWP;M{6y8%xo9Oq@~2=4{y>WvY~WwFrKbaD4CO-6HrS!tp%hSrOd0p;A8Y&)k1}zRbJ`j^FQj9L(8Y zEB42ia~!aR@|kdc!S&Vb&%=savG1)#@byJ-I};@z)p0F?dl$jI;QKxGa|-NdsQ(J$ zh3|nu{tb8nv_ID|V}Csq_auCO3-T!7H;S;gc2o?|J_YO}2=4)WB;gx@o0eBrPzUcT zwICdI@I4i1j~w4GfqbqaE1e-aS->I8@;r0izPLa$7anJkSAZ2BPktz^0cm%_+d#Ss z;eSFJrbWo*a-BKAQ4jSO1IO<@$X5Y}uNQ?nhk@6JPqaS+X$|2wARR{dLr7yiQ0Eo! zj>P^0q{9g}Nadr@&l1362rmV^58?PdC7JMwV4p^~FYtkc*8@J3aQwZVY{FZE zy`Jzcz{e6E1$+|W@xZ4Oj@LP76Fv&;mjUNV7@B3`SXSA99G_EuNO-QDV&|-U$Qq&! z#*;Jthx6+96MK9=j2ZZa_V_&r}@$< z3v#S)C&Kakb|>NZ{wXs!zd#-Q{V&NYbwGkHvM2l0r6`}VxR#=gkMz=M`|BjH=ty0p z85Uh%r52xToIE-@xa^7`49$euk@wCTUd8XuRa{drdA%g;CP zED?oUWjB&jl49cGwO&zvkv$`8`uoJx2#E31)&OPMBrYoEmz$F#BT`c$e`%7)Oa7Hb z?}X%-w8W^?U)dz5rD&s)5>s`*GKyo~BqT+rXn*N5tJg0?bV+@*i4n;u+Ei_#E+Q(< zt9FfFSjQ*z)26V7OpcF?(t6dd`3uwJxTro6vD(OJZAz+FZQoy5_R(sSBO>GD(zOvW zDM<-lwQK#tI8_&^OG}NAV_e(+SBBceXx9GR+N*ZJFARI8#l=U_ZK_wmuX>tn zC%1CIuOc25o0ixoLYETB_G{M90)7>F#a8K(UID*~y<*8akXOKO11>un86WQz@T-u= z#Pw%w$VW-9fM11NDOs`mZNTNCQ`jyRk(Q{7i}&*J{#E4VHu|0=k&W9Ca&au5&o6pQ zGz)HG1kcC}f7N8NCp^5&?pJNb#^Csf6m8!$EgRl^ynoeXvd6ZQ`5cWi4Evz%+isX&ok|YHW>b{{PL-zYl?C23sv$uzW2#3R`ITK8*jY{!1$= z_1{`f$;j)^ztYqCw_@yP<(F!tWGJ8e&wZ!NswBesG+A687Bm+rG zm5Ru}xV@5pCti1(vf#MVWH(G6p?>Wl#;2Zke9F0{1c1Fe*^NL z|4saOd_XfpENVS`p(oWx+d|VzMdaTO`L#p<$|}rn%>4UV`A$iS3I1*$W}x}Ki^#uT zr{ov_*ENgE&*vfito*8jlpODW6Tgu~T(l=1_9lb>HF{h9w+ z!q>|w}KW?M>>lcx~*>fdF zzu(k9rilEzUn%)p{wDv}BJvl1tK@(CoBHP!kze&u$v>ZM7Z+Opk45BP@J-3J<2U|S zVB^Ej;@{msp^m>9KbjYj|4+C;I_5X~e_9dwO{|sj5C7))^G^}^PueN@NB?I3Iax&h zPWDRvbH9oIyCU*eby4!eW!}OjRA^yR;?JP~%lJ;&_Yuf{2yb}6Mw-8N5&2C!DVB$S z)Bc@{$bYJE25&6x!D;9bb zgiq{_n13bYC*4Gv3;C@{ek+pR2>DAAo(uV@J*M$9nB_xXM2XXozeGck{;%y`Rz4qM zh?#V{p;Dvqa6^cH{|RJ&SbsdN;iuU@EC0qEg+BRB|Gy0NXEHx5hZidOt*iWi|EH{T zMfl%iv*N!MGz|Bj-?F9tKQE&ED<_rmy?-qJf69MUMES{Em4Y!pFF)uf<$o!nd~Em=T**8X$BfB2BEU+}(0<2M7!$9nRz`JyUN zN{ac-_g{XR$t`LAUgk>tCJ~1*iJy+lp`YddR7}Z__lLPpe8GJ9=??jot>6E9SU|`5 zj^s7WhuDwhXH6(kYs~MAhVY5;L)-$&r};Hd{&X__()=L|{H*;t?NAi`!C~J2{$PKY zANOCrnU>9cyH!G=8N70AX~F(@SEBj(=^b&A5jGE^w37dK-@o|y__O@u;RYlAj;<`q z{?YhHCdYXtRd+62ybITyot1Uvzn`zKyv5(&+s98{>rrfIlhCFHs_%*_ss8`y^K!=r zf46DKfz*)g524b3>hhm7Sg-EwrG1G0Lx}#2M*qI8&sm=%Ps=b9wsQr#=>mgB1)CRW0=}hI)ac&?sW%&0X>w9j znyfrkVAZr6Tb)^MG)cLx(I4*G?Yn+xP8)-efKRDAny7cTvr@7D;Z_DgIbBW%<@7n7 z@!34Reo)p?X9oVs_-x#73fq1*DC;T-j*EuNT zLpgP$lj_aBb%S$S>xu1hZz2Ho0X(dwc)9(7@3K~4#?&{6$ObawQngVWa zr`cVoq+W0_)r|E}W|ekTqu;C1e-OI|)UUnI^R|2+(hNVMD;J_a&8oOdb|m0rY8lP& zYiW)_2aW6`z9Z=$vChu@*5q_9@OjQQ>h5av-!%HGq54B|O+)m#PfveuW#0cn^k-RD zW0h>mHh86vTGQv=d=^1Gx!hKYrHV<-*k2nXG4oY-c+KUxu~~(Vz3V=5scqfv0Yu zMs<ru1egpUZ`|;cJT0qWbIYS-S=?lM zhI}k2I2c^bidCW>%d8xCkzxS$x z8P)B0T!vw}3>g1AZZ%@rLKPo_I)v!I@g@n&>E+yBljF%H`LM=@06UGoovWE9V4r&U z6h_(Zt(i~=@n3pR2QX%GlCXKGN%4?F#FsKgSO8>a2CVt@JP0&eg={IXgaA zf$=8LO+7g;uqr#Yo8{>&H39kRY;GE)KcUIm$6EHf&XGmN$RW^OXB${A?KHE{sDoKw zkvFE@)dXBk?W75~5u(2lmg8U>s&4u&r1C`uQqwd!e-wn}wDVPkv5~#<>xS6{X-Q48 zpR0!-W(9=mKWN4bay1LnA7)Li(&XJT)~G&&>g_`H$!v#d#r8FgohGL(bKyy9aW-bS zh6Ef^5A$T9XCZ9JvI{X}an_%D{0G}MJ}k%9!RH7okrk(#5X!o<2Rne6XjuH5H37k{ zRw>IhV}e~-G4De4H$(NouKvw)Y*}d9xq3gkna{fyL!qoqy+g;a%$hMQV~GA>SdOK{ zozHH}N)g&DR3Gl@+&ss~TozXk3*ip(0yO%Qq54a_-8@?4RAW_o@+d==XMoE)hw;HA zFGQ91_|-Rdrsq@exFXBT+h4tTB^Bq|tv4$@*%g3k}I>qSELu zgy`Rf^!C0W7b6^+#fOv*0A2K9_P*eXBLcO|A#ndzT{W+vkIL0b<-%nTd#>S z+OAQZu3vDA=hNiK<7H-nCo|Kv8rrcC9AV1328GGvJn5ZTz&j->DS25x-@6a&SZrXt zQ?}7`W`P$k=TT+>ck(AXzsXPa{$Hmv3-Xy?>g-_NJux)zW#q$9X2IK^yFDK3U!GmV zHN$@nPKDO#asDU}VfDu}N0`GLo&#t&Dg+b4ASD zK(@2$%#o42ZmyCqxR@J!7d5C>wmdVC3o!7s=LI;Lm7K^v4CnBSN)9W&F54K|+wj@a z^16||Ek9o>YgOeI`>;uts+8v|l1;oeQL5tM##YTF!$s_)~HC zIpM4%0_23ZlBi?Nb#f|Jmw9QG#8iCPD+}q z$Z1p75^Npg*UZp^<(5O@Z_x56+oIH{m0UeYw3f?NdW&%zYi?yHyV_QE)y_apw38ij zRub*ygo~2sAe(t8iH`CXZza)LPWV8g9QU$@f#UI1wk~_DhSuw1SeGH$)zj+kmDuGF z8#b*?im<89uvDJSoRo}v*zjzlln6!I@ZOiJmc8pKCk~@nlp%lg$dIcT^6tehOt5o9 z6MM727?DF@Qobx-hlGpcVwQ+iwp1vwf+dobL`6B#UrD&D*Rm}cQgQx*N&Y9-z)~`t z$JU*B8HPRhKYoq1_$~G?_q&bUp-n2g9B0Uo{~($SOzmvBjk%Fr3v;C>!JaD{nAIxJ zd!ixVQt}%!b&>bUzskH}>+)(&nKNwFmKjOLBTTq)17>SdlR*=n!Gs4u*%0?%ZF;8@28`V*|{*sfbEDwx2m95F6kt9#evQrI2 z3p_D0sl45|kZe&>H3uz9sw!{`xv-L|nzy)(9sg&hGT~kP78;tV910E1RGzn( ziJZwy)qtklG1c+ zy&ktwMMWmF^$^a%z8!BdSntWXG5eDqS$s zmv~x*ue$xsiZzIem7bU6|`m=VBi@7e>O)})=%6j|ct}>cws8Um+ zB=db0Zm~^D4EK3)4OMh1i{ZWiu5G~Mc|g{%G>DT9$|IVkL2R6KR30e};*+GK4diZx zjkH>B>oalzlKJZLykw`~Sc`MX*n)%&F{v?z=B(B{s9XGEJ9PB}1;Jh{eldPV7QE4@SHo z7GH%^$&hE3TRvRwNkh3Q+b_Z^-C`S5Y|jbzabs(&U{?q^h%`)L6+S5BIFIK z#8ZmLb!CrV@hz;U*0q;+DkYPzT%dC?wu#l-*PUlls^DAe7F%b9_=$yh%J!|m-qYi| zy=QH(uP)lV$o6Bv-bFs2QuJMXz`kPPZs86+R}Qm%={BtVMLZ{S+P(@;L1Wp|$HLR%AKi5r^A zhM?%r{bNOx_+Es$t7KtO-@>p2^S<;CTP(a(4a%ZvrLrM5Dkf)X!A85{DwUEd;lj$O z&P3I+->h(B#c}qQA6~e%m#WYwR47?n-ekl4VpYQmFb!K;USL^XVkz0*@6x4hn5KoX zlGVkEo0KWc$%^OYC^_u_D|xZ}vNkFU3&?HGbC(m%Tuds-rP^Do+)CJ37&_TIS+NrU z2Z$1DL`T*J%-iy^{}@*me<#^53nj8#*V%@JGq5Z>-Qj~!1uyBxX!0!;OG%a3hpXJo z78pD?3l-1r?p4?v+^CWqOSwQ^6(%`_{TZ`MK1;_ zCj$$4H;`@E;ZV5&Dc^-u{>cY8HmI_pscN4M^5T^pxV` z65@0cdtQS*^1&X2&?QN-PfAASOwXjGcqt(+F)1Y?ojpqwmy{@_uw$$?0;(4gp-o9i zOp+bc@vX|kDY4rA>5=ggJn5!Dc9xXP9^TVR$+}qishA}8T$J?vIX5XLJ}FYiE6c(Y zmBgOjVe5*Yx}>yZ_P_)SOJXl)`CpMi=!=C#rZR65BYyBUGDVvhSs2b#w#FWG(MinJ zG_91Ds*Q$7L>JaSIw`GZyjDrdP06fMB=%$=dv-}mjT^{XkA3uF^-k3J`LaYpWFKur z6f~F=(TK+{A|eep3oEz7u>Fnd{Rm02M*)u_xmZ+`QOPi=oiHl;%$dstqdj0+VJpFu~ zJ$pHOwyf#Qo<)hS$DTo9xjbXoQ;_U`Or*|}t$8N(?5&N`r7{wkIv_DBHYF)BDJ|7A zEwNu*VzeiF%r#!iH_8vQc(O-Wbj&&_g$Xi4CJq~-;v-XIaWm@?Y(rFxke1|UW1&N{ z;K>govWl`t)>!=I?!!;;zc+PZH;1RAScp^lD29E~c|T-)Un4qSy%s|Wxva@UcsI{l_Fzw?D0~ql%P$BN=TLp zyOP{%BNDY*w%da^uRV`w3JeT<$iYEE4tpX#d|KGSmC=T^-w%5f4+nd~jOFEzxJhxT z5vj@S;np8^UDnxUU*%^qB{>v@8gjp7PtYo3U<7+SI0_ntRYMn>6fNP7Aj$h=1pn>> z!t*KJ1*09|z@RkNT=^7ShxSjT<=MuacuOePliApTncy zd8qz-(Ma2PmiExLN51|+re!DF8D6ilI#;q)sVZAap)O{YMt_#>5^UxYlpUYw8d9OI zkK`-Wl=^jT7T9~WW$kG*<_viFz`%1Xl=P2uE91_E=d02UL+jM< zHoN=HX`?m94L4d;E}fU&$iS!7XwL~{El19BSdx{t&!&08lhLIsRLsjeaNyOek4Ag` zJJ8?1`+}GgH*fX`)@P*F$ko)adSEy4K$SZ8@7@2LUededfuN7wTii6cxbH~Di&;kw zupgrjYri(>dU&b8@l`83_ZT)I{)I*5YFkF_XliLR`NsM6-Znklvr1h}zH-px3e%GG4uX^sOEq1Pf z&7q2x`VzyOE-#w=d{~6E^S`o3?EU|+-*A0zw-Jjz?OxTq^WLll<9k_~k7}0N|Jj5Q z@%?w7SRN8*ukD(({8oO)ZkJjHzuRysBC%lu=Zs<2b)rn0)EMqPw_?JhcPA6VJ~|E= z`}JyENX7lNQa$>AuxPSzLzz~g9&3zBuFn{A+xx-A3ijIqhV7}CG}TLGskw9H;IwLH z4yPS6DjnEuX70Y#!>C<(kC{zttxulySK#E!eLuNAvs?VIY4_;P0k5l-$RA#Je5;;8 zQ!{7WpWdU)^}9E!*(4cGZFszxw~-uzGiJprNbiysgshz&R%ck;k(EnlS{s(?F>2lU z@gYWw(?U&`o)3-j$dC8Gy07V|O`7=4?n~96D-8!ksc)Mu`)D@5($k=d z+edEPH7QgzRGKJFmbMsOS{$+X`s&m3s=nP9GPusQ89U!Z)joM~$eunClZRM;xc{_j zw^4J)j~_H=UEk;0BlZEoO-om_@p7nCtBTLsS?5#TmwCL--nuN|eB)L5F)gp%y!6zd z(bk%C_MA(+aI*i+zJu0;xf|;T27TSM(Q(1{i2vfR_F0v`Wy{_}U7jBOw$q^G4&NJ3 z9qO;JadMv<(IPHo%e92p@fL@|9?vNkYH^BvSlMNqXtL;Ho!qKd+N{bCS=Byc+4Cy1 zQdS-gXg$g0AEVmi8g)t8m(k6^zH`d5h*UTCiBr2z3J98&-sxQTHCu;FYME1B<=3rc z%b^!{9%-qbyQz(Bg=3jO7dg+1>ee*Ck zYIi)kXXcnQ^L@_FKQLyuW|GT^v`NkU9nUoDmvyvj(3{}fJ&(7t+Y{_^%+UOB|y zv$b{b=yAMDUBB`%b^KbKDtolN|LoD1qDwRz?JmvnYI$YMpTp*Cw8?wp>ifLTuGT)A zpRet3E%a=Ti3IrD$J`@ zJS?tYf~r);@ujLJBg|UoXxfY)7VV#GFvGga3e%F#Z>t?D>EiC@8`Nd|#71#fEp>Gx z^pWc{AND)%o!}F+pvR<6HFwN7uxP-z>+|N!^0RpPWQ+f0mpfCh4E#`W^u{q^HQcsJ zJCkSU-U|q?(Kk8RM>XVL)i>)p7=J!{%{OV;=0p3QReI9iY|uR^@Uc2@#pgbmrT^${ z;%-y*&DnM{v)g2kTD|Yl2-Wb&6C=FWHJ>v4Ki3#}yZk~Cmfz389 zeS13loI&LU4#z!C4W46Weti5~_4G=OHDT-KZ)tX?+VU{h6pPq5J`Ex)u2^63GrhFH zaI#Ur{7c1R>}TkX?mlB^u`4jYZtYh7hM|@xu09?&%_KkfQeOSmrlzy&yM(;$G9#!{ zHSRs3(&J&_J*?)B zN;o!fuE(Eo4!N)LN`Ex1qiHoQYF?4rF!+heZSQN*K*@Q%Iea-%j0leABdJ!O+;+*O$k3XkYJ1^2z6mDos9=dpKt3 zQ6zI%_r|#Kc{4k*Y{*Y|pp7IjZ;v!>5j~AC0YF$KZ^?%DJ&e!Uvpf@kdOF z9$HtIDk&-ZLh{HOfgVT(oK9%(hG3_g~zrghl!N?Mg0}oE_SEmhQUrO#H~ig>&b+4!_-Mm`jxQzN%z~ zVc6*XW&y!I3!UAxQ_ep!jgz*HdY1K~@1+AXcHX~iUOCS6evR>;pYA)~%Y9IDuLsY* zE_HHxU|#cjU1N(ydp})0HMYj^cNS}E?HcWy?>xWmp*u?!zFO|m^}}M5M8mK>Y4d7T zxp1K7@j>m)yWP}YyIWAVuR~VF&n4!*jcWQnGOtvPa_zSj9~zrtS-qQQKu6ExzE?-z zGdbDo^yP--zm2WG*vP7&PQ^n<28D*rEoHgQb?d>3s~7oJ@^5?k{HvGqTAiwLG+!m3 zgEaf9l2Z1Uu$$W?M^*RHv@ZoCJGOsTP;hl}{E5SUW729=$@IJ>wJaZSZ(Q9Q{!v}S zC%Ad-PdjYc@pksptmbRGZQl{3oV=`6)hZ_SRC{|R$DOmw-CnZ9fq=GqZhX7s^K8@m zf_@D)N3{=0soOaJ^?|{)-gb>_ANy^`^}|zZ7`L2sWZulJZp$b7wmcu)zGS}+)%JGX z9KHFaw)BxXh7XUPIC1QO)_#_Gg0Ft$)9ey|T%Gsgzl?FaP1iYeSY0!ANS5=7GQKb7 z@4GSJ+b&JezVzB1PuFbY)<0x)`TmEiBxmgSVALb9QnzU9iXN+zZao<^YESUn_gHh_oAg;%1~*hc2K0o3|}5r{kzbOIz29Zo1re@xk%K%GJ1|veGP! zF70|?uPXNKz11t)z39HNTCn}J#h!l_Yi87I;Sz^SuLF-;R;nz`{A+9I-%|$nYg^}z zQ>%BYnocRcynFN9qlq;R&9*)5=3rLh>70TyljB^+?Oqsibxg(G4-fWIoAs-H&HJ^z ze{7p38I8|xt9O0>z|isA%Cc)~Y*ArcJ*}n1^U|B$dgbo;Y0C#+`|e9@oyxv^`l-w- zYm@P_n-@&=%}#n`a-#25qkoG3H9zfSWWiMXy;j3E>1tHleZ}DZsSBg563<2%xlJAK zsco)`lzOlq$J?=Deddd6?<>FPnqhHk_m%X_QpbJOadp=nqm zGWCoPT3%WCAbi?w`xalOALx1b#lYi-6Z*%qNbePainY1=DilD^TEZcF0R zZ#TXEZp?Gr&tWRx2CKhaZqaXz^;d^!W5c`Dn%(u2V?@t4($x#&@5W8@bG2IY)$e%q z_05jPYA;2%icdLtcj3K__A>{iW_gv`c-Gcw*zDM*!}SZUx4Lh9z4pj%z4uo+SAVo= zUil7N55Fkp&`h=5u+t#d<^f@wx>g(D*xtHieg9%t)4Rov25YOHeXQZo zT;-s-xM5-Qa|?Z3D^9Hyzaw0;_*yrkjwRL2=B{qmV(!~bBQxUmIUZT|HSF-yxo_aly;AEAF_zF#+Jb*VM^Z#MOJ*}QMpH~$UynvHhbGwQ^>)}EJN*bY-K z^=bBe@{VmTcU5Tti@utUnV91DwekQ*=|~0Vbz|SeJ=y13+sA8kE018QN{OwX;$Gd> z{ySny7dC|N8t%Q~QM~H$W=GOpYM2>j58LrDu5QOs1F|PLZmvU(Pln98ILf!tsDCRPZ<1C>o2Az6d%KnMe_ZUw zvajh+!<#y_d8_TPa?13(>@J+m3CFAB+I$XLt=09^+bnIrvdOxOGoy?j9J%!0(Mj8{ zO|FzSq-p&+eYXzFo?q-(o2u4%-9JX`{C8#k!7~dUCNCLK^+?~yM-#@q4WDUa={DLv z*|7POhh{FvMqW5KtNUL&?oYWF`Jhk3Z68h?xMJSr&Ybxzjs|*`3OhYv?}zRlY14g| zEL+#H&#p_A&$TVNXv^#_E0&F}w6yMn&08*?>@jX%L8-ADo9~!DJ-FYazjMqkS|?2z z+~&U)Pp*d~q_(*<>%8ywNdq5r+j4y57oWuk9iP>2+56nW-JWR!+DvlK-+F$>`L|66 zOS)o{XRhm_9dxA48BI+`)6Y9vJpX6L*F$5{Pd2W7XHq@q|62Ds@iD5*zQ->4PxNlB z0+&UEG>Dmf^YnpagYnacEjk(!<=yhd?k`^|46$1?tX}J|ZXYg&E`>NqBSEtRI82)#+3V+m{IC{^8DH|v4TAbrqY@5@Leh1yAJ)5`pNXHt(9{PWo z|K{G-UNh@Vd+|aaZC*8QMZ&G&wr4iIT6-=-n=pCPsx^H_zI(aeu}jZqC5D>Bg{|(f zx%Zv}n-&LeyZmCCRfP=~uimPfyWHd7CkBDh@4CG-k1Mn9^z=>;e^A3ljmi(QALbNu-0)7NM>bDhtG>m) zQhhc1Xq2yc^;P%5Jmpn>#)sFpo?dY;wx|76{n5?b5I&^M5NWvyq)7em&58WNwsrc;&2 zJFYjK*n8fsmjTyCeww&5dvCtf+PsWc#;oJ|jXBpM>o@wE*Vnma=aRD$zOIg&aHY+& zDwg%8m3V!l{A@?x*5{sAYvujqgIXR3)~gm-NmJ+cZTjl8yJIzN;;aiZ2L8LmDDhCj z?AZ2x3!gRF_Uz+_m=9}enbd9K_1E=r9~wEejY%jOxN&bq`;h!Qo%_DM+py!DD~5L2 z&%zdlR_-QsmAXkzBgQ;i{mA8Nx5?_{kvG+&MykA=%U|7`Ir&(Pf@p`iEzL?b-4UT5 zyY+a*^S;_IC-&#%Sk_)QquI%Q^Kwi+kGimM*#3Cmb1#NG(%URJ@^5JRr2#filasbQ z?`c15u)XSAOdIX)%}1l^o*3-@_R#c;J=sCSd$8KrI!hXJU0wID(k9g^yuOmO*FG*QWRbc$bp9~D>iM8%;CUzrfH(yj^|Rg z$>jgofeqe*252n_mfE|s;Tac7(BT^&Tc!x>s%3^24}F?Mp!4Nur{yrG zd(r>SQ=pX3m6z~J)t63HO0Xb>uB_Szn&tLTVL;S$Zj1KfiaT!p32DzON}vTvMP(UqpW1kvH)^XkzSaMXB@XybTM8o^4Fg3P_xN55XNaMwT=nNBuE| z84V3{^E@Rrq6w^m7*4%_O&cuziQ1xD#fpX=x)}ozQ{s$S4W7e@h18;3=8BdL3v`X{ zB!lN-=!6wr4KnEPADueh<9kA+6wvqXI95wSxAH%m6O9=tt2F&!j=&QOg)=)RvUfG=xtCOp|_?f7XKhr`3yL7 z7`j$OjjEQZW|OpVG-VT5PWo;SzhbfFBbbH%wLi{=0LRSsE00+4zg`kx93{Trum z;4*=GcxAk1+Tb4mV7mLGsHh8;4^GP|B96`V>}TUJLv4c4LqHr<5;VSKmNQv=X^6Nn zjdk)?&|ty5^Sg6z(Ip==~07?QTc=AnFdP*yCt1tquV7EwQsA617}^c0Pihe=gcx2kI?n0xbZ zOreqJvu`7BLdsMJIunoF`50a8YD#5$OF^C>B?t5RF;uXRO(Ac&IRx?2$AZ?lw*$wg zxk#r}<@6*qj{DYnV*@9yhk-7simAjbjtXfx#_!7=JWj$2;)lKSY+SXf-==AFTv&;s zM^mPSk(xmo3fMNCz<|*8mrj&I=$|$V9pG!rp;fXviGduocSVNbpS&#N$U<4G?vUVR zB|8YFl9e3xeN$W|7JsbY^jm4sdF*PqKoT#k5Cy*n7@o3zwPcaz_RE@AyM6V~_48Op-lu$eOw|~Kh;a%H zyqPi)lcncO4A`ASjK}}CPu;-ysR?7Nrf5Py!Pgv0Z+`1LokC}EkasD~cc&A)51mLn z!dX%8OY>*X(Xf$L*YH3~R|d&c2@|c`p6D?kA2a!V^GLd8 zMcqG-GrLbo{sYULo!fF|=QAuxnZ@xzO5Gmbk?u2^LTuLNiLC zW+h`G0he6-Pa@tmlr4G@=nlEMvpGd3Tg0TX>^!#&Qqh0(kd*n6i!=a7NYK zIXir5Q>S71<9ZkBLAY}NrVZ(W-Uf*I2+Z|1yYNg^2?EfL!3#~XDn6?N|93oiKxh&J z(%$Fg6R_0y`cFA0i1fW70v&o7aMGdX{>^e0y#tnyunRj73>Hv0zZkT>C!L_AKP%W~ z0Kv{^Bl6S3uKvSD5E&ZrFJN(lAfbN;1O>1M&<5xP5IAsacCy>IZ<+A>ikH}vkFmX@ zqD@vD_e>C2*ApHWUqi`RGd@IhM=m5&#qAl@GEMn8$5F4xeG^d&!tHUNt6EvX@{tSq zqQRD!%B)~*_Q=8*9!j^Zs69IP4NG?_`rzZCoFFo@6_*)8KezKXZ0F90VqFzm3C?ctIFG@MPd1@#PLKm;6! zdd9a%c{0WqYif2E>0Z8sx`Kvw*t%9hntXd)&F9p4{MZ0{TP-9} zfrMHk(mVtDvWT7OhY_7!U3t>QsQ3wqk>)vTMhA=i7+XW%yjIzb^7j5Bzp_2KZGh!%v(GlINNP#jNTiV=?3lP@Thi+01b$eH@3v=6YRRz#76E1hGV$-2Trf#+_X`np zzJ%{GfK9$!l;I@BR0cOOm?DW3auTedFi{SKqEca#gh#0GWy@aA1}nunCFSg)d=(iE zSXub}SoX`OHJD?)NPvs!DuHUiZgw5NP-0nlX_4?Q@i`fWB9#S7HvB4?E61DNAYCX1 zxHb;V;Gc4vp~lD2hB$=JTB7stc)LMquZ&JIJ| zPAQywb7(+m;8KzFF7f}q`6cjU3;>n&Z~1yOHNH?_fC!4rs zEd|cS*rjwM%Ng`+kv*-^*0)kO|0RlyuMn%Q|*UNAa>LjRXE+A z%OijhrcSE#oJ-0&=!#Cg`NZxiwo5D;ZQDPXt@0Kbj>!e|=A9+6H5{sxaS7qd=~8#u z>m4q2jDgZjx_xD$SZ`gcF1MmMJ2IJ_%Iz<@k@~!JKP^PLM^qIpr5x1YKpkkXr52 zLNjU;GWkmpPA9i8yY(n=oXDdhV!3XW2*myONlcv2;tZMi zf{CCC|Iz~wJOUc2fvCO9HUYagQ06jQX|PDU)sP56+&)s#Z@y;BFj*U%CcL}TGgZg; zxJlYRp84jc^Y3~om7-wY8Mf|nb8+B!S*Q>?W*2#=hU4;h^PseEt1*w0RCZ4cPTbT= zrMed0I9hoMi+AjnQ|j7u8hF#b3nL4BQ#xwdyd67^(n+D3c*uqwPkQz=SoNq{c1^!U zvmSiR@biSaHQ6Uwc&uAr4kNV#SQGjwC=EJ(?cVz~4 z-|U7)I%W=%d9tiVK3T}+M}kbG!$=hmC^s-!Ea%qf3&cpr_l??$YeYuX@Bxy}CIly! z4FgS>|El{!Cs+-|$60!&e;8*@Y!Xh+WBtwDe?iNcDHxnJ^e@Aa+WfH633QBZo0qm7 z34swmyUAMfbb!oNTNeBuOWUC!X#jZA8OUQZq#!0`3)4N85xBvpEzFRA%(+?Q*6tE@y$|rq!zanz$3se zU>^|gR%7L=={rYuljOM(`LrSmpF++twSJ5##X`!<&RwnSYU;bKEzQkO>n>e{Wj(71 zsf;gvnD@xCQkCFjNj9m$ZcU}Et&`8?K0i+?th#AqifBS<7@0jRcqi*8FtDLz3PrqlPwl_B zC{u50o{n-p*eLUN06W|I+lI?EP{29vSRW7Ls~Y#lwp!;?fy>ygm3ZJD7pTqo+7Uk( zWbfCtx}yaGo%`ZDIv+kiTRI1wDwiGoV&~oU&O2^Mp&!T5brxM9&8z_8HiK`=s!Feu zVRg$YO>V1WXr;4Lvtn|<{^5u9{8iTX-W2EAr+jSkRd1yaw`luV6PT+1mTIk9HBU0Z z+hnX0D&c$ig`H+nHGPk=zoOY(tljl;L1&lRK_*O(t%clk8tS%8=dMt@gYisL(GG8( z&Td^&w!>ZXt8Ee+I<#=TH-KfnB-J{hVxpLKLT!^F&4)p31did9H+C8PdQrhq8iukI%+>Rfo-jRZRDA)l#Hg(3wuMY^-6G8sMJ zKj4b@kpKr%#)DDN1I{SF>A?uzr9Q(~NmXEQQoaLY!u$WA3Xy{5X(B-{nOjHv|*GDYhEwoZTFLNTY_XK3{s$sqIx-e|VcrV^j%(W6DiAN)wW7A|*uOl8WcS zg271}8u?I7L{q6~5kB(42V+Imx9^ayl0CCKXNPh~veFYm;URZK#-g==)c?YIg6JH3er-`f+lP72(xr&;(09#(M)XmW?A15baev<8coezeI*rS z{r$g_a19I+4d7|!C)>ZM%0~uWuRkJ5M_{)gKiA8MnbbN}=nai%*)RB)C9!}^hEU`A zcd1M|1r((i7y~>MEW<9AoAkR{_#VPqV)39*i9zi=IT^WXFbbK%0g zk-E?h2F4I!)}EM)9y@h=Rs8HqWP`BuVsz%o<3DOOb|_mc!vM#>x zCmdsq{4p-HnBVvaEq9sHD@S*Hm%(ri9;-@k-ihM6oJ~#6O&uvgJwZKo z6BnY)ehiSgOUtOnaU0-DM&Rs~IF4YOFw*=uCa59_GYf zTxs_kG#J*bn@o*p+PsHQo>lrXsAQVC>W+t5lW?|4pu)>bqMs>uf`_`0+uUIq?PBHkGTv5UPPo`j2KL5FFv+onHhglD1aPte&@|*h1(-3y zdYKK6f$ig0X`lZR;Q~CvV}<jUYPJ;< zNNBdA4c+jCmM$?mgUtN~p6R%xr2NnS(#9+M=9Mo`N#Rw=sD{2~ZyQd{ z2R>Rm=rpJE?HS1Ci-N$9Na! zg`48G_AaR|tlfuRC8n92*^#bg7oj>!ArAtJ@ZY@J!UR2nY#|Ol16IT{{y#5@m`;U} zq@B}UW^Wk2AWs{)DhM=4e)C$>IO`9&(w=+@^r;Oscd z>5NLk4`*D;ay}}9c&#g}Tpm}Oh&y(ea?gFc`gMzp$C@tINlt3y^K$OXzhyp%g-@<( zhU=(F32|AYBhw~H{}fQ5{I&7We@?vveILt?($OXJ{>ya7rEma;q}}Bz-PR)sS)SNW z*X#%`Q%>m#ASG(t6jNV)9DAB`H6(whXy`u1&PUfO& zt67>0E6eXE;NoDZsUe2`To2wmLWUM=l;%4b|J3^$pi+V8K9sApd-bk)cj4G6F76DE z72I+>$w{_S-)fXK<2wnT9$g3eVgLzaajaN#`{cvg(XxYM5s>?|Zr6+0#do~(%`0(n zMn@}i+|AjV*l#IspP9G6it)#l-7FFkOlEky4EUFy(k_e*Cl)|&e?|wU&?55tzeY3}WyL~J8Rltue>4=?EX&d!g z+y~oJKYZ=m*{H|fQPz_sac9*Vw^`(bo&SpS@sSbwT6#h<1v>)UotzJ^4feF1>BbJ2 zEPwG&!n`D--heA?DJg6z#&(^XcW2^phl~mqxWbzpAoU+W^&c3~4c18f;-6UaCg;2< z8g*Q5&y4LVcSYyCIYw)9i}EXXh3C8}7|nIq5{bp%XpfHtt+yMJY&oKFR}Fv3Zh6DB z3HQ6a&gOl(Vg0367IFZdqkuec(-f2LBQ-J!@}0t}h|6_>BgU4FGwfs*W*86HL>hjE zMK1L7fqON^+hgs{uBYy8pmdd-Ys<}`Uf2ZYUHQf4;a|A+Q@(P``U%(irM$*z(eu(S@KVHv10v>N#kDSiqDQz{>RCe2EIz-cVdbvxfc;uk1=_( zp>A%v`5{4{r7pX0r)690BYl0Evqa{{$pPC<_4&ibb}@D#>wAR6!_1E(gp>J(7L}bx z%jmpMth2;?|Ke>A#f40wvt%>Xykj-Nzp=jR1C$&BwnntKt``wXEoF*!{+B!H=mIbM zMlUx0FY&ia9D;{kc+~r?w}BeF8Yovy@MyT3FG0oDyJK11v;Gj4^|>Z`Esjj-=lQd# z!<5au8n@c<3sg^f%9v1vjPSq(W!JELEyg@UYB`)16_Fx_<*q_y273CJO3CHP%4-ZY z9py7v8|~;CbS;|Z0>;il^#!K#C|YJl3{{ry<^sAxJf3G9iuYL8dg#<1N1UB#Tp<-vV3dTCPjbq8W{*a<(gT=5m#c4AIcc%v;xL`kGfo*7N~VtHlmUE(RwFFx^v@{qWx4b^T6R zo+kb5DC{bGklhhN4mqi9m=?B?;i;or?3&)POQ;(_ta z?PTszutIqKVJeTF5n+^Doc`_GWbWUW%f-&2J@&2W! zHr<9If=caX;WpH`L^%J3!5l|a2|F-AA=5zcBAci(hXM0WXh&j(5jH>}JZr@5xl(|5 z(Z;1fe}wW3H~&xYGySy;umLV_YZ8RQDy-iQ)42nON36m2#H;ZamMcTQZbq{(Xl==M|#SE_NuXNL&rG+l~5?suwNE3H_-YfpL`jNPAlt9;RmIU`@Yur z1dg@7SNsLV51u|^(HLfS)G|sP2ROYQOwQo)*p!v~(nx&i$KlwLviT{E3V1{1Kc-dW zWWPRpC`>M+OWH&q{`@@}lem-1hr9PU$APMyBxTlk2yTS3M=AhE+Z-FeNzQQAChv+j zr>EJHVy7k@t}P&pt$tqwJ*J=E-?+16#_P=c zfH*_)mdId?`$ge1cf-_x?LHG~42L6$$mK(qF#}oPCuUa*k7k=sRxrryk!MXQ%=teV z#0Q+g26$Fw%Jk!?@}UipbDwf>A)EpKvz1?n;e%3Yx>Ix4>2YbCnHp~sb`%4zJm3+D zBYs4I5Dg(7-%0!>5q1Vn$ZL*lXp2MpW|7>Z4j1;%5{v{O4X@qW4{C!^qx5pwj4=3h zunz((!jm$#-N1VG@w?moib}7@ROv*8~C$5*w~ zsxzKtPT7&y@LZB8icFFUoe#n(mT=fhc+c^l6$?xIK3-28-dUx2d1dEw3T#67zZkn% zCL=d!pJd}6h-UdJ0x*-(@`rDEOXL`WTq{d(|x{)^! zgZ(*@Ox|`ohC8T|S538_u{9o#7&Z!j4KXxUPu@1<)mHKtJ0gMn^BGJtg7V8|BAsPF zXy|8I6&HWnbK|_%AbHou^-ZEb%D#OlVMca#94?!Ye{iFV8Xgt7o{f79aC#}dO|bhU znhKE*Pt>}e`5e{D7S+Gx!@r-rhc6Pr`0*ln|I!u;zYo_CyPZ@uC!RKHaXU=t&}OwO zQnIZn(UqdEV?<{Yw{9p@#x55L)d0a0OF*Y0_$GJdQaa)Z`18J=r(3AJ`cS-Ahedl1 zsUqY_e9$-807Iu3`tM4}@n2FO9iG-H!5UFn6^ybGpP~8Ya$)Ho*{-r6Vl_{7mRV} zBnlDhhFJ&fL7qdKYZ>6X8m`X!;lM$kF4VE^_;rhwcH$Ts{Y5f061N8_EOKd83z zEJODCr|QP700i|Xd-^*Kld1y-V-2e6fDqNnEzm?^`exb`B8%hYuY-yfXKh=0rq@ez zibR`%b^<#WAIHlWGi&^cfHf+$k8c#JcWrdkh(Qt;naHoV)jZ#&7iOonJQ6DlpBJs? z!l*@~#?i!Dbu?MR&jCL!gRU4h9HlE=FkPhcKP)hhiFo;f{xUWhtpfIGvSUL*a=m$) zOA`o!fs1KYJvTNs^o*((cXy^3X)JdV06XLW(s80#HRe(pgY~KVdpZwG9zqx)t0g8K(ZDI@F zzSW=SCudxRqc#J7@ZF$fQzaAsDVb@yTPQ`k|FW(0YW97@l2@hnzty^G6bncNQH-sU zJ6C}X=;1-hAklvm*WS+gs9o&%`j_pu z<>iE|&H1}vJ<@K#Mgr}n_%2#c0JjKxxv?6jg*2|utJX9x1x?@k3C-Ld}i zHdQ{%f$B_xc%;v_T_MkAx7Q(dmDul7R8pf#+xH*xnUsX8U7YOVaCzBC7uj(EkYc<3 zOR(SPFR)tNwhkBOcRYg^)$n;26R)+go-@6PPPK%(R*1;FKI^w^Gg^Jt!j5jOsgnEY zLLn~!cqMWf=#{rDjuMkUgtNWJoE(vm-{9Yu-Nozbm(vFJ@He$g;*Xxn@(g8XGKqJ? ztjg)0;CqLX9*r*QHZ#yV!e&*Xa57icWbKx{uo!Lo2~?6g1DB0CZM@Kx43llmGC2kI zj&%Euvub?%dg~@K(B7`2s$0DB`>S?Mm5MuGUm}j)H%8e@b7)KOGIqFq`pfc#S_8oyCbuBXY8+-Qu!+jt13Fgt}hEFPS4W6vwK0C>&6!g++UXP z@=3!no&?}_Q@|*69V3e7-?e)5zuX-=wEX_;`PMO^D1+NyZU7^pb=0&~5eh=JsXO!P z3Yz7-dD8Cw!nuAHv|w5wleag=8R?MKwzCn)yZA(%4JNr9O&%?|5SW!0$ zk1y2u%qJj^PBc+V$anrh$L4Y!p+5A$*#p&lNv6bNI9Mkk#DYsNNkiB|_pd{@tR?j=%X{#BLm3eHsrc${ z9l-3NpUswUP&62d4`BiCMKGAJd6M$Mv*o5Vkf~xY3o((A#j^0w3E+thY)+`bEgI4( zgDlYJVs>9tsNzDy>VV+SbZeFcc6_A^xJMI%Glq!JlXWiFT(geuo^HQ@Py4V5(?pNp~64N*JRGCx!J$Q#tx5E=XGAOb3BOE^&p+-ed^T5n>_IAU!<5=4bOX+@os+ z8)q{u=7V*qVDX!3y&}3z`Ttbi5V#{IV3j6bt{;V#aGW&DW6KzlTojm~n|M`ls`|df z!!p&bn0U)ZQ20IYZM!zQb2iavSDtwnE^j*Bl^v(|i4FZst9ql2b9izT%ke++H~`=d z@C9IwFQqwCVckoaqyp!MAj&t;Y*l`X`7ON4tXse%z5A z(!K!>D;()P9}y`HEKkY1n+l7as_w2RH-S=PN;^p8TN+AS2{ybP1!QI z{9k3=(b-Qci&rmr-5>T#+YkplZEvL+56`_^Z9D??zxE|PotDd!Cq;J+NQ|pL%#FSK zlpZ6x&%6X*+ngSMdT*NNSj8?KDbVbcLOQ4;M&hW|2xzLNMvbbt z?mPFriUVz8Gd9F_syQi*xVY4nTA)yKHo-S8Sc;?=<-xjvqP+ZCRn1~Z{h1T2PUE$n zVL*aVT(6c;sZ;8wO?c!FMY^8~uBVGF%1#d)bzxvH*8In^^sFSXA|ATC37F|zU=b#* zSvMj9m1T16@D^(~d1oUr85KkBeO>U77@@2;G6K*-2+3O&w`_T{v5=H+(p*Hk_JVN2 zt&3?@sjaCs7PhEAnl~Y_5XCb?q!gQGCLuV{pjfqayDI8c*37sG6-zUO+vY=%zhgK9zv$4YM8+110xDi$oD0pEt3c;!Rdk?)@Sp+1AX`piJ*$8|gq z(Ph%^Xe5Ncj=ZrvlYIq(O5|4ZS%a%F9P>XbIlV9IOybXmsM$2)&1~aG^@8BG|{$QweYe? zo;Ow{iJ4|@O@E89=qnoZW{4iGQR%djQ$=@jQ6SF-ek5RBY6p&7nT_$(>4 z`|Kue6>`DlZ@WOhOonA43%RCZ zzbHXvl7V67XL+#YI!>6OT{hH!B-uKGf`zb?e4c)pg#!eglU?sAV6#+&<=>++>lw(q z#E$B$3q8#ie#Y*y)XBfi zw^my#uLRJvO%Dd47`PAltJ{v5`J9LBLFke)7!T*3<(Hb)rHE3(Uiz!nGa1T56aD$C zH+nT5Penh}T^Mdq3cI8Ifcfs$djUJ}crWOq*S}o33B6tMU3k2x)((vN54T`BoG4?m zGmpG?WaP0A1BxF7oXOW7l=yPJP?N?lyCd|r#<1E{qWRBU@r}1eu(%sW5FZbSkX-wi zok&NoJKObR{sk<9qVe0>4S&ywm6?m?lk21~JV&k1rj3p4Pu%e&?A*{UDfo3#^TC0$)An9QoTuIbN7 zlcx&NWCt-E;~9s@FQ3c{`1#Mka<~C2dldMM(PP!wbp?8Nz};shW<^?l+9IRR8C3+? zb_(%rHKK`z^1kCklP!S`tOeZ?$-PDO;jeLRzL13-vp$;c>{l z9P5S#FT|2OacbMHKM)&_*aa_5C7;)2|4hGr+SR(c50k1zFv&{a`YCx>vLG!119&;! zz1Vfe9^Gzlj&O*){Vnehn$D7MQ$OMS^}UsYxdo5e&I#vO|2f7Y4B1CZm+SNj@1DuM zpkisgz^2>3xpT4akM*#I^B}{(wkcuXI;+&(y1)A6pH_y)4|{H7%Gv%!FBd|0wWsn( zKazv?3_FKk{9)^3;uidN7P@f8GL*@CG*YJLzs~vc@H0)Ao3)mXov%yso=_wXFm+}t zs;OXK!j>-dt1uNYs#h?nM8m4oc#Nxf!;T${d1~TjE9vR1S2VOzmom*J-vkycL^Y15 zeH-;?^RzW;R)3djtuEJR4t5l7RNAQZtUg?*^C_IkWBaiK=G&|doxS3=CqENze@NbXpf$#{kP;#WG)W$zt9qBo3xx&o>r{`U zkab(6${cOy6G*8FKN?*}{FvTQuv6MPCGxG~uk=Mn=Tt5Lb|y`p2I$~8Mm%nuK#(kD!=NS@KsX|t` zRqM_Z#zK?+`7Vhv6OySbCm<)wK9TpQztGGGn@ud1*RsZlKu#-EwlCmbB=aI141DUU zXd7Vn?(@w)iFKl*e#RF83&AZnr8vPb54W+92&Ix;#8HJDW`QZWLRI0FkRg+Wo9YE? zk2~jZ>y+S?dy_u3`iTRS28ZcC-egjR5};8~%yg8)L+_PX(a|b{RhXls&?q5>8yb(g zlrf0UuFqcij2>-9-^Q5ZGxX#8fod~LEx|ILtzTh2tnC_b5X>W@MJG2zZT!SNvL(nI z^L2iv!)!8GGFNfXERP6vP3}T70;DMzi;3XvL9opOGFpu=_V7rMj1S%V%HCRqAUSAR z6m%yNNoWOhpLkZ_MVYiPGR_@wexo(<$9!D|L+5stc$mQUMY{P5{mG$yqJ*%VKGOzM z@T6dH3$BtnAnt%~(9;$|Im1t^*2oRToh5;OPifr+cUlbuhd)lK(uX42s@T{*2(oVF z&JBMO^M0lY&Jq`YZ>zs0n2}|IMCM8W@NFy+0mHfD4jaQO54TTrBK&20ND>xyVdKdt zrIO-?&;t9j$dXb{iNFt2`eDCoZdt%?vO2HIVzW~Q<7_>=Ja=m|rj`>1wu0v;U3vxK zBQ4Iqo1nNMbykQtaXg?zGSy#1(h&ysSzJ=2a8p&;q2*$oMfpVSnbM!K#L>tJJ>QOD z3(nQAmX+h-r;}gkjF0rF9UgAKNGTNNMdN-_8`vA&tb<6?E=C-qEnphbcjyB!Z~R#o z38~{O&08ZkZ3-a%)Q>d)^s*Nlh}T*z)`zXF&_7$)YA`oW`x1V^{ZF!M0l%;St>wwG z^~rn_3JaLGjVO-K~dUsdD?7sxm)HwMFkK@!kue(2Ejaz>*F?+s=(F+?XM;Trs zZz_QqgVR8j%$c6rq}bgEQD%?lss#YN0Y3pF#l*Zc{YvJnHtw5i_k{Aysd)uj#6}W! zjLx3`&x^mDN3>TQM-`5z5;|_TlnW4Z2w0-sc8sp8BYtIvvw3qKb{=MMDv<|=89<2) zO7w3jFz&|XNZ8zyIE2zPnTcPD<}<6m>Brs?;BrqO>ecO^AmECe{VdVhyIB;35cAM1V{ zGx}yxPWH%JJWo_&&J_w#m5)pb#c5Fs@X@4Rjzj>-3#FN}l5>2(*{+sVW@4yvH81OJ z=43%*bzPvIh#_r4^)ur1QcQ4soXW9foS-Ndnu0Z~RyOU+*g=-Zh;^1)u!rBscPGrO zZ?+Y@?X}~VT(k+@5>0UOxJ-Egd7?5FmMM9_p_h5~c-@$0Fyraku_rV$_EO!q5=h#+XC+mQSoSTsIFoICLr z&hQduXF?F62V)Un@*Ewz1~6BwBn9&3V}MRFqnz7F+=tt4t%h^eHe*wS+f>t@qWlE& zSEV4>8I*OV%dt-JxdRkCqsvn~tJtx31=oL$C|`$i>%>!>bC7vWi<;eWnBIiuc_A8k z$*F3A0PfoJo7Su>Iu%wpgjl($#AyZ_Sx7=8glvra9(ZEr5fo}Lrv*o8zt9qa(|#SL zAkagp)aYLSGDPWDzDk9|a$JRAXD{bhN!Ut~e!`UbxbaL`i!yBmP{hDSX5}t8)TY_DNg_pzd`v}X zViDB;h`s~}g9nVRD2o78ISJQW=8jP?2OK%9%`qSwwyW()iuZ%^BW=v1VZ^_sQn60r zS}^*OX`>#q*{sI``Ka~Pm&R2i$sEc4g;Mwcd;k#u)k5^Ps~N<4*;tT4{<>hTaztxv zd~pDZxIm3(dLb#1QTVrJHxT2(Kn&}umXc<9e-%V!0t)$p0pk(yEKc&b_gdp?6#ib7 z@2h+y)q1j(mqW+7Rm$)9kcN1jjQm!6? zUVxvT&9!=U!^j3EvzikYab4Sb@UOt0UBdr8=TbeZV1JhLb^tekA27OZWGE!& zw~h3t$G6#%c>*%AfneIxOB~w&li-W`^`~9fyTjhPq4G-QacP^Q>Bms7R99Ci<40|N z?`K(fNdLhg<~m}6X=}rKfABT`dL~@XIop6h>sk!NY}pr3nx$8u$L!?^9K_hc0N;RN zc(1&8b%!WZhvX9iUgCL)_A!((3tCa_Z( zBa{ygbWGILYzd9}4`v$a1RiuO2QPX~7H*gbgXysh&$lZVdmF|WM7RM{@uv(TCVJV{{9JwD5Fli_KfmxMr9Uv}jUD?R9YR4qWg)IHU-aAn+CQ^(( z9-UqE{La>j{GMV#qk8#XC&D=tX2Y!vgXb+h#Y z+$Otbhd1pz@m)=bEUcVnXS2*dZp(4HT{^O_*Vg}6Z>;&AHbL@hSk&T$Ld*f%0#?f* z+A}nOcRrCN9vnc^YK^UZy7=v#{<=1X?Fq{xQqS-7Sugm|z5$kHr{Mcn(nzyxlT1aZ zq@opEHJMRuh01ljtQNm2IV(q0_pRSt)@~}lt4k|Qu%xB$`>h!C5Os&ghcpbegz9X(|vKBIS zaq~E_=fiGVa&$*2g)}@g8K=J{YMMMQ*X;_aAf$ETrDHI_KHm3>BCz8L4Oup^ncVak z2VIKLnCh_HfUvh%ye7KO+TmDnLc!ns)4ONJ#aIfz@X#;sAULT;H^A%^svA>QGiW5E zl+6#4iv?n%6cTPYsKN;sY!w*HFv?gHBX6o%S!HS!4@nD?s_zp}GE47SR2Fm&|KQas z9Fh_%jZ|Za(7dzL zf#T!Y1aAe6EWCGY_?MS`KocQSvwlcx>)G5njI2#<_>A-pJC=utbap%TX$rg#Qpps* z*Fn>WKiN(crDD)oY>(2Zzt9ijkIgRRTm+~&|mnoNek@;V=!|r(nE@gbr4xRrfA)SyBQ-V~?R{ zpAc7y1NP)%9d_7aJY-{!v0NWNOG-fAcq=;P*F^^1TQgDdE&=|eAmMoHR9s-2P>OHC zcH(=}s~|&=_3I?}w&eFHjcQ)51&IB3py{g| zccw#wOCNKgTodtz(f%%$x+Okc;}fQhzjL3io$hK_sDn6$cN?rcm!XzL6{$ROyR!tX zhw*q}y#t6{BjGv>Jl3z6b!TBDTYh(-MpoXOOix+8{9FT0QV6J+)4%KUqg2J}`72{l zAvHu(11p6{Z7<5%)SD;7QI~B z)uiyMNMk; zl>+{(HFoISar1SSZwcHZ2q6e~BnsG?Rd>vT8~(d0K0nP%x)t_&Ak|l~T2K$C^4oIo zWI3seL=HwqBnAbo>>pN>pT)9^V5s#J_8IOL$!^f#sMGjl4)8R8;U!y(DjhUNBts#` zUz*^^I+LWcmc#6b5*nj;sHdCq5*Gg-ckdk*#nLp6&g||iyX2gaC{Z$qNR%85fT&}oO9mq_r1@3?)~Go zk2~E})s?!sx_6nLQK-AqaWZ8|Z+h>O0;xo^n46Y0InVqbf6yrvGoBPL|1fZ?;+JP` zm+c#Ij3$D;hsQwkWAgCM8yw!(VryV2`~Kdu+hre|_U;L=82YWTblbQ1Ca3u}aHHwN z*V(%&Qx_i3!}|8WOKX}zDccb>Dzf|ivCOZcD?n)-7+iUD&32moi2#?hxFtfqB|U{EpLBD@1UDV`na2h892^fTC8yO=xxW} ztVcv$4koZlCQ4}z7=de2)-%!wd?UVo&6*$Y^82dr)$ry<0;fyhRKS|8XRKtbXrw^Z zay=s{@rtI+dPaQgRUEU;$X>Gsk2Y?`O`7n__$B-zegVg*@a$ow|J%bwg*Z>_WIsfc zhTb$lF~kUX0B|ry$7bcxargsv@4d2*a<(F9pQm&slE6-pN<02t>8;!Q|EBbm|59mM zbV$g5uQe53ia;^I=pp_Q@F3oQ(|U<6K0^?DBp2u;oR=^7zTQ+;#!129LcsHlN8)@s zcRKHT>fw6jhsgKhmDE!aGgi>n#DB$Qp7j019C#fH7tBeM_7~Tac7OKrulDZe3vL!r zX2H9EXJKDLw{)NM%Uxe}Q(GZ`iK_cC(q5O-y%I<5 z3jNDP_8MK{nG|K)k+{gS(3`MK&Anyb`5~qSPQO`X{46}U{os~^>kmCY8@2jP+G`b~ z`1()Ri}XF$Gru3n6X-r?E!R}hzQp2nRzbQX&%tQ(OBq9^J71L;Yee)`-k5N^Y&gv3 z>h)B7=VWECndi*CYUk2=qQ9j}t74_>GWSnrxNs&}n&Fly}+ zVbzSl&$$IzR@ZvwNnJTmb?QOV&%<(Zvsd(;m^^s1U3!Y?;`2HdzY0tq3$Jk!4=URv zwwkhL&|~>W*W<@lXqBjcJfG{7ZlT;Iw# zJ4<3-z6_giG-R_6`9P+V*a7SWc7EH1jc?92+vQj4PH-KnbQSekSEb__;PIxgK#&pL zzhl&OW>CFom0Yz1uRvf;Q|XT7F&9ie;J0?X#&_z!i>||?Z#338$$AMSPp9)5+)G%l z>K*^meMU_ap+7H6s4}$XtZTZ>vJh9j)A-K=`%2AzUD2qSf2Zxijf}QR59|5oSEYD1 zFTJ`kUp;2_%mi0vfUbAX^g^Y6L4)AbS0+~r#HuXMK3uc3CRMn3^|?sJGiHx_=9!x< zEs+}9C1*P5w0dQG^f}K`{d3DEFCDJbTh`X&HMG_2=eFOL7B->>PCFGB&!3a=Ir)Rl zuVBCLzdi*2l6ZMu?TeOm(T;?$^NRYtTZ?3d51i+HP&3*`JG9)#(ldOD-Bl;L8Aorlh&vJ)z4FD@r+aoSX-;hkurxopEBM*!TTh>F z%8}H#*-Tw;x$xPJ1`U^IQ+90M9&&zbcvNJIoLx=aZL7Lh+ZUBp{+OheVlCtsUTWtQ zbErQxDRR+Td$$PFP5y!>-JZRjw@IMJBmo{w>tjuma#mP8=~-KS+E0t5k8gS?_Cu?i z@=`B24oG~qD^M9MD`ze%7L_#n~m98&)+ah>9?j{nqc! z6Jj=rh^*UvH}k03DOK%{s~>-U{Aoce|1z7_^B<wjB?%fec(!AUMj*={Rt+J&y@z^%2t!D3jUw@Z(F9~~G(dSvMaoIMM z7*N`?Yw5~eS)qKJ;5gqU}|H(n6^A2RK-Xo=~vs=94z0fPV z-FZ{zRrg&yYLA^=IpNy%rls>5d(V9sJ-zEo?&nJr9>kX9%$a>{a=GhS)zqWh35ua^VlGBlki%)+n@_*ewZ9|Cc-0QP#{rIk)_{y5`$EXiQu(h&>(JKxp zCTWUmpwRH#I~bM*uRmEM$clanN!Ture@Y1j~xohx7ENz-in%(cqSepGMEX|=AOLM%6r8zZWY0g)$G?)8W zn(Iw0&5er5I#8*Uue<+J#`lWKQfbudzstYj_+C1dE>D*`wsl=QhF8+5Jn{}y215>K zuEnX$wLDb53BAuR4Pkf>FO^SWEgzMi=%!Nzh*CkSpg;f>?sI7}cm^G+Bg3~hQ1NaasyMBpdo2^s2!Yz6 z;j27&cL-HNeoI}}Mhf0T2jP;^@-*CmDy_yEmLP0eb*yxEj$wyr*x6r zf`sYJ;w5errcob``JVf$`%LnlrvajZX85`H{=?!T3cQ*I(cMqY`B%-I`7lQ2ng0aI zoUK|OwrwVUpZyy2Y7BJ+Z*4MremnHjNaA&c5g&eAJw;XVb)8?#zB>i`0bH^`OeTJ2{j{(2(?u3hT!-I)==Lau-snWk~^!)gO;N@owzFBo| z*!GdOxFPkG^U))-FH?0ob85n69=i*OFUi;Lp4fX!Ltu-dfT;Dar%WOgCn;7g zoiVFkr0&&Bd<#vV@FMz)9G}jfIYZmdUB>f$&%4vlcXzyLI=OK$bvLk0=o%Sxu5c;McDr8i=G(S-XQ4@?;akrp6FKl=49{Bm^ni_#>t1VI=}ErziCz- z9ud`Lyy78^NE|bY0ukSskMBS*A|8~Jb?PeQL6%PrO#Q^-koy|?(m!Kbsg&)naBQ?O80{_Og1MsJ1gOAaSMZSJ+hLLLuRq(96&5f~RzK8v3CxOSNju~OoY zpFX~BL2&!+`jNSYQkPaH9(>Hay)tp((uuY;w3rni_ch6VnREXpwfEthqw^D;*S`>c zu;S`qgPzp&Ew-k0^QI_VI1(cL=*?mME2l!FGnBg1cz!Nmw)*~xocLo!EAKD)(fGga z&Pu)W{p(lb=XaBAjKBKcxSMFB`1Q&4yKy$xe*X9p|Lksr&HkU8zQjMd8)TFA^X=#O zcAhlVuGgiy!skD&zi3ouZ9AluCe(;a$zobRB=+ek;c4&i#=j<|Ni_Od9lK;f_e-@H zZLhw#boHnX-<^Xq6h;r_AODpy(yngf2M-)6s(u+N=JTrY!%4>8gQZE;sj7!hB#cJN z%=*cH`L0RG!dGVv(pCq`#7m{Nm}c0{T-P)DM&epyz_PD3{1>oIrB?6l23}W}mKRqB zkJgCAzdGwGwU)WMa8zHi*~!x2$C=l!%Nu{E*;tgV-P01Cl&bz=_+zN}k4?kI*`==U zhj~()8}AB@ny)JrdLNIarhb*Va#t#K!mq;jN0ZY|f7j{sd;Lqh=V(OQjPJ{y_+9z+ z?en||X|KL5d*m1WW6r?QnQ3!Aw3lAA>pDsueMA3k{(fG;MZKRASN)38tUk2wz4++& z^k2N66luR5-~S%HnE5;N_vc@3-A6@6b?{#|FZucXitak9mlpZ;clyPBKTLlf`l<6< z|HrJ+(xKnaf2;q#_Uo^oXB*S%e#?nVN=p9HoSxctT|XnoCvryP7VH7PPhjAgTbQL| z-v*rt6Q4x-PW-eXMN%ZANTBYdyRqe!%N@1MiX(h38>S7vdBf}Y27mA*FJMh`X4b2N z_VXQQKWf^N&o9&8@?gu*v4vu_BlUGw`uQ@KJqG4JiFqDZLrWowUY=P{n7g8}u0M9m zf_=^2!6y$+dUTV}P2tPBecAuG*QnW8<&~`G51QWz%w3wU%rh_J*_~siUKcj4 z`Se6~`AtVYJ&nX;uTv=DC4}qqcF`!EitgiG*`7hok%7nLMHb!o5d7Zm^-$57^T{bE zyb4zou29(^Y&bl8?pAsAf&=xhGxlorU5zZ)e!?p(Dx`2W(Q{<|jKMEYwHLphs7o!Z z3=KFjW75deHwz65@SJ^#OP}r&e!N+0jEljs&)VjmyI(m!=HlJVgzzt_ zldMuyXKYS+Gxuul9RJyeP4rz<&ZRt8-p_FMt6c7SLqw!gj&I_=hlL{3qWD)f1aF;m zKX=B7TYKV}DlI9Cdp#Jxzeg3NEse3NZCqs(7pG{I_p9)?(9t`s4QCmNi%;z?ocHM{ zRg8kHaNOS%@n+FET{C>fNwuH)>`%IK76uZG1l>?M6XE+5Lde(gzNLc{#FTI-g5 z+Y*lqi~7I+u+-~$u$X5`;>T4bx0U${THF(&A9yshyY`%nC_ikyc!one^vihju=3M~ zda3YN=k2ZUyb@l2E<*Gxf4FGX;;9b6tDLv3eO*B7oAtX1>mS8~4O#_JM|KG2-VeRe z*7b49(5rBxH?QjE^~Xo+?(K;c_5CnqUD)A_eW`;D_Hu5MY%O*;M%E|ozj5ATM)6AX z+W6V+*N5CrFWj?xW%TfgjzbAEI~NRX@!`3%vT!hwBG6d(vhBR3#m%R0>%1qGjJU zxe6zyoe87N+wVdvxPR;Jkf1=$lAI$uTK;&bxu9&XSi;PX?Q6Gx9Ne&=N+;~DGh|+=#I>v-8N={rrho|Jxh0rq5kzB)t6G68qVXdlrtIF}X^N zq<)wYo2T)hOHK91o>gXQxqMHUHZN>?1MR-Noc8FY)nK5lWY78G{9PqCYTw%Z^?a7F zz|RZ)?-r-Ds5Ml%N58)R>}3H|0wMb8zJoey_~Ox ze}vT(#jTlZ%x}JPftz`I-yC+?BQ>biUI-~D^yPDYH1R4;EWs+{Ns z3N!eTMS}iGLSxn*SLdRYbKRB&Og*tvuj5k{ZT{K`<&M>!yla$HLf|2;6;2a;G-UE! z2!o&Z$}1d(;7u))-7exo!{-WIwi->S#r+x&0j3_mpREw?CIKdOnA{=wcFBx+V+WC^tKMx zwpCN&>nhGoiDJzPh!>2Kq4zJY1#&}?<; z)AG`ecalk8=2|RM($ZQ#;8!Y8r5LT0H9K$VM*M2$vb*0O^T{mTy}oz)&}TZ|vXkNx zBZIkJ9S7X!{df=WeAv~nvS7{S4{?~C>7nMXl3ax$i!VzeVn=os4yWJmjyitj_>xDv zbG@JX4M{B3*;8B`De1w7j&E~x|7oOE;*^8u6V1fP?E)h zoiR)A)*Pw-&{LTCUA1zNi-W`Nb%k*S`x+aP@AgSWuFEJe+I7=XR9tK7u-x3lIaUvo z7c|6281AU9Qso}bN>C>wIxzPubPkP+*lrC9HS%Bwo5xz7-9#eoNLRRLpiX! z{y?Usibe5&2t4#EY5Guzr;vb&V*g({YfGHU(yL~j^pdEkG}|z9pvtuBb?`n$`Kv9O zn;mr;c4!wF#~9RXX0#H+v%)WF@0C(>`gW@5U|Zi_y#ZD6Y7uLFHRX8!Pu5Fkd!{Gt zYwpy@^^!0XQ%~tDYF2)-OEg8O+$A}+vDTt`N4nkffXb-{c$a)XHEV~*cf*HCcNI-U zheWSPIAf)?-}mp(bbh|J*zy6N&bKd-d-fjC7&v>X<&8-69*L6VfTqr=4bx-mhwl#r z4^`Jroc5w3>9EnOP44UDl5})@Hax6Ja_gb@x3)g};@fyCOYpLC<3;V4?k?*UPmT`MIi}7U*u$GIBsZ($5tDbp zKt|#I&=21>gx8*(9?2W5Yqeo(TkyfN+H+4&-~QNQz$HD;qa_Y^z`bk<| zP4^o|{MIKPZ69ghL10=S;*Tr)D3^7iVm=U+~H+84Cm#E%pct33=ev82@>Co~JYA z-Q=1~jay1lE4SMvE^F&LW39c1w>TZ&|H5GQDJ}fCdb4KWq;$g^vHbWSWnPxD%eFYF zcscO%nHo-VEZQljCK5jVUcmkAD-^nj8RlaykhMeYW0-3GDf8|w@f-(!)22@*^4`KGjelf2`tWLrzweA8xmiR>nR+t%yCjvc}|I@baOW{Q4&5!U3Y z5*ruwO?~b3?0{^3H{scb!zCkP!nRFz7MI*`t)RHL1HqkE@S)9rjed7P4>R3X{c+t}4M^cG9ui z^o*~m&`n%b`5b~oHPmx%HEP;7#bl`Dt$RfiGI!XeCQ@XQYH(-Cl6*_q9H|Y)lZ~zx z74KA?X}H1!PA5{b)Mnli$SU3`F<# zgW}==@21{ghDl2k$!lDP@aE?eU7N~XpP#Y}QO6ynWkhFob;XIfty!~PD9Dy_fS>2( zjOkgsg0}6;v>YW*9a|>KI>PRmO$TqvG!YEWbu`@oSP)4pe$gs)4 z_s1HseEIuofl>2mGYwzU`tCJnH)$QQZ8~l)Yk!P?Yd^1%13&0{eCMs>my{ZB7+b2lmTDN$fxz+5$hRp>_d>kf3M&&xnO9ss}QqPe;Ql=EUp()T!Bz(4NrutS# zwOI9iF8SLmCG(x-iX@ABvI38<&)!t-S)`RQrMLBZ*M7tQKSiti>{o?Swdn~Mam3Qsms zFp=MA`emPbj-$AA-jxS2F3W9~+p2HYPPlHKDqX&=q~dtUS}{vutIAfptnTSEH{ZJV z80RT^aLL|Fokt@lA;-1(mauQ`)naLxU9u{MFyc#hYE7__&buZr;3_XC+e2tqc8U8Q zJK#EDv*iBd`24_pHOXiPwcuV+?-Q|Ltt0w5w+O&PWce>o@?v@yy z5&ZrV>+_Dw)OW7aRBkD5UnJ_*H)s6_?S_)}6t$e&JR_c$6bT2aZ&~WWvf5=QFYp_> zP~txwUAMMWu|)Cd*@V2-3yO&u*3&j>ewcQB(f)xJgG{TP6{{q|C*^GV?x-K_ls#J@ z%4CS=MpS=JcfYR4<>t-ZpIg%}nLX;6Dcm1HAGvo*j7p+&F{;54{!qBY=xuRZDnRVvrr{8`8&+rI7d<*N%<%j^v_aDMS^6NB%Za<%XT zgM~4%6?Um6jBj(Vy4bGeX_X&&GtiQIwdS2rPR^vkibxw?TCn}^=|Mlc)XOjMXDu^u zPJ4fX;GY=fts8m0V~5CKMYv7M`n^@}yG~r{Ib#1gI5}PBmZzegS^e79*afXr-Ib#2 zXdAzWJ=waYJZR1)+N5O5&ViQqcDD^2t}NNI;h~6iaYF5!Eg9v0iEBKUcl7Oe%)3LZ zZtBqr%k1iY+niRtnMQ}=FW00C@2ps;8NG0=&CG(e8;WN=Xn(ZXLRG#{%8`f8hEVthxRKwGotL5tm*4|y~t4t>&Gm=WM}WnXRX+zOY-n+~$uySFknZ;6vp z7WbZVg;%TRJ8yyi@gstdWM!{RU%$afUEGO!AmGF#%jc!;>iG??7tM0~nvugdD5aDU zCjL|{+pb(~T^X(Z<`JC&{ItfZRIQb2ao*Du64NPj0|W@OZ)?xk?)H$3?u{e1sS2(g zs2;X^5Su(j&2?YNUJ+T>Z3(Ipwze)FMhXMxq!q;)+cev9B=^bKsZN|$spjgoE}Y*S zbCnsG62AYmG2g-RbyLn3ikvlGmAg;>_MzKfwfxN+e%^2%xS=Y%_rmmT#%qKXUu2BjS$c1qP^)uY3De{7PVW(g&y3ffO*5#D^QH|v^ONm}pBRuj z!%?c4Ukb0c4)YYwf3!qQb8p1QRe7Bi67lMhf@!Cpd^TSbwu!Pgueq7eDIic!dHG00 z*0R@o_3;$Fmi@x59mg*Y8=zAyVYCPZ}3go_n@B5%$<)T;+8Ln zFD_TtoKO?vA@*ob5F60k3_#55d z<8`Fxg5`*>)ibH-MvqJ>YeoOEu>EoKo=cyMp!Z&yyiWbGlP40sSqm8U?`_!8KmVb< zEWSJcgJ^Ds#gx^7adR%Wlv?!V(yvr^n)o)gcpC8)&RelGW6BTzsh>6nHhVPs2wlEx zWc|TtIN-v8hp(fQ@83#XI=HLO_^qYzmw3$}S7@vHL3-?mzr}7BU;p8}K*n zQvI#HP9pm1(~9uj9u*%xH?3FmUim~d!RXMNV#m=DZ=-uRO0xS+8E5#yl-j$4-EQPx z%2b&;vushhNT2rfHXWhro?`xuTQAOW4qan*aSLVrt0&VQ@4H>O;_8k~Zy5Ori>b5D z&s_GR$X@j&#p~rVM_$|4gVUHz^wUZ1^+$u-)=exZh9R-f*8$$Hjhg?ykZZHn6x@NB8^1BnjXO>dO0Z&yi5Ki9SR*iub~_JH2+Q&9nH zWMb-%9d>ZhEp*vetNVK1Yt6W&rxK(?y2=CUUiZzawfgpJddkchaz__BPVD1}=;_|- zF0Sp79)4rD>}+q_qPLGsm9<1HzrQw-IBJw3@Z+F&{F-#Bm%>XQJr--RS>>E_=~9Th zW7kU4^LPP#DQ3>H&fPP3`{(_YmsU2WyIlIQV`qI;*J4G>?TJgyKixD%TP5rBz<1uA zhpPPDL;comp0sJ;)!>zF0ZWg*Q{2lW9HVX@vu)NkQxBdon@)TKaeZVnHIpo?R)zaFHvc4`YKASGx z^UIB>iZ4F($^^T=JO0|+P6k7%$dE=t?+`{(vZLdNmla=%6n|H{|dO%l;-nG%T(Xu zp>pKCQ_hy&LXqkjdo4Q;Kc3m6P@}4Q@4Z2^p>l)2yZg4F%rKrA{3X1nQ;drk>r73w zo1HdxJPmz&$H!yR@J{E*_dEsVmvWqyDwpym7K{1Pj|%NrbI#}R7wz(v*E&gVheuW2 zx6mB?)kTHZ*zPMCh`MbOJMlt#LH*22Uju?ZnkU?_B9i5d^zxP&uM$kzcyVn*)SKyi z0;!AoUSG%_G>bD?Z#l!Rgzn`l#OtuhZRce#wae09Lx*1;-S3%q?C$0Gk*p;@K3xts zIOzL$^;hlAH3t3XE3Df_XRf@uFoy_?#n&$0>f9N*|B$8Bw6jWg4#hK0AOEp2l(ANC zb8z((yfC*mLu27+fx5WSXXkH~uewXLy0?BVpZ@#KL0Z6*s#%)%*95i*uNW3Ty*I>} zb~W`hebOwqW#`Uz_}D+>Gpgm?NDN`wkLudbT1qdmdAwlZnbEGBZ_D`h+1iID=$~HU z!gF+WJXX2v%6qjrBebBT{sx^LbMC8u(n@~Z(d?gPLphX-8D-fFea`DG9Ox4FoH1l7 zy7ApE?+c@`decoVFELu=wj^2EX+fodkHc0O|7qc$wtf#XD(+LR5he0AUR_;idq?Al z<dV91TTgec`+T)3#z&ygsC-&;!oWov=i(1F zO4^c*>QVt}8*b0LKhpoewK#PGe^Vk+*S+^qZT~L)_p%XV=w)4UzU?_TC7nLzP$19eh>bg%9_d#s@p%w@_oFz zy9PIUesV)W(Hj+|X_wV@$^5u1FUNb`ZF*JIa9O+_uAyI)_WHv#hwnQMYt^;A85ug_ z{AR;Un`;i=Rictowl6qZChojF{@(S>{;-OIYU<-J-y8MPWvCuEKHqrX@>uOVbEwxe zx-j;{G`CjmHG0KN_(NaIvXvw86{kNY6sBJDbNuP>P$?e7|T zU00qx#5j zn9}F(Sk;&szomM&{VKXb*s8-N}QiCC^s;>82C zq35dw4*%%W-FG%eRkr{8>F1vL8oxKVIG+erwr*`%UFmF=s3=-;#dzbR(2lL|dOyo1 z*~kdq>>9{3etT3TwcP4!WL2+JwolBb+W6O>ukPP`@zBM0Lgmpq?~lfOe`5B=PjJ5Wm^# zkf1BOLZ!Z`zFqk{)LpAsFSXsaG$O*-x^uTt#>-E_cbfQmbYy=QyeZPRJtsCnb@~VQ z9}3ye^7p&U>ZzE7^=RU^O9Vc*H%3}rlG7^A7D{OO64lqed!=RU{NSvji_sU2H(Q@y z_h!}OugpHr54*C|uD$K+ZR@i6RTSL$>(aSFp$D4r^Xq@YX^MH|yVBz$!UKchz3%V_ z@3C?TZkHH`L@#~kDp$ti$=AEb`z3`ZgmDpJa4X_CE>ZAS_`lO!8&3nTFOTGA(ZWFo z!kf*x5%)L#`l`bw6`+e?Q*jHTGfavH5E)+Jv!7W>k z-YyS!9CDRk93*;ueegIF=oGel0;Azo@KFhV=#}SOT`|7D6GQ~VLpjH}SeQeS5S%>D z90?90F4#XF?)>B`a)62oPGY@3p7UOGgx3TFxH%y@h#R_O4C)7FLxWwGLDkQXe4D)= z;*}7N#Qed>L6!YtdcWwXK(Oo&E(NM&d?m$&Cyc{v01OWIV*D5XG;~9vqIIKVf}qSVsLx{HYdtIF(E8E zE<6PgPSJ4z;X&|}M3SD>b4Dj$0lar{owH7ad1(ca4mR2#y3Dp&vp*rcnZAmivcC zAcuis%c7!_qA=Etx&|2Bw~KE0C2ux1#L&IRWazT(P;w#Xkdjk)a70i%mjaxS{Qu|m zJ>1NO%KP7gQgAmL+_R2aa_B<=eQ=jBfj=!KgFp>l^npK;ng$mp1MX$QFnJmg4%tuG zg#?jQOks2r9mZraXTk%Op$Ma-&!mxcCXVi_risG z1U}e3gi)QOr^<+0|Ul_WxE3z#w>xv;1vi*R)@ zBO7oI017dMY$&lB=48Ww)tD-R{AJ5(Sc)KKE~L|}M3A~J46OwGc<_@L zxL+PHKCH$x65}I4V(iJr5>~@OWD1alu^Nt~0x_(H6Ny=($%Y}jA&ay$qOdd`fI6wM5PS6IQ{4eXj$W(KVlyg? zcN}a~{KRYkj7^Ax{6H)bL*24j9`YC43y4M`Qo8`Mah<~~kopA(sfY^|jh7<)$NK1U zj1qv5E}&14L3MURS>X&c!dMs;!E?}vVKr3AMl!3RF4PE^HJHF*xS;=}1^gKGIMkJp z3~CJem<1mKD2iME(2xO5*HZ2P5OoH8kN_TOaYVzUkybESk;I<4Bmu*80*XW`8WB-J z_)sS2y~6%x2v>ILF81{6m)Vm%!(2n2GvJ)r1_2^~2FBk{bOMNqFy1Vw~& zq&FRbSa`nWLZ6_q2jM>>R0Y&9>H+u=ML zC*6;#sAR(=Km{*}2095;oro(S@nePTric^Vz)5T@Uh)>Y2?Zu3V~V&8aw4Y)#RG)Q zY8;3Gr-D?z3;(t7Ih1$|bL7D7!9ajfEATm5xHnw9F-#UArP)eC;InD*5+%sPmPoD| zl8Vo#Z|ahZIfV@i;HD!-qL2TdAjyA%l(|9th$|&HDhL}8=7y6D2NeDRdLzs|LL}82 zZEny+#Ly3Pqy&ax??lnsJXT0yWS`HX+$6>8mXl8HWW^5^je`^X$F7iR4%JY3$+|#7n-3EKkBEq7J(=`wI%p$?|ISDTaf9+tMgU}`jw9ppTRA(C z;w7sDkV7%%kqO*$fR!YUXdo=7n4|A3$0pp zUa^w`JAqXD0l>98;e+gF)(o-TFRlgxkcFeAhJY`0&=ll279kD) zwTB?9BL)wI8c&W*VPn`kkICF>lc=)-q{^B|WlkYg*Fmat%9sh$LAn3R1bOH%UZ?-o zgmKGD5U@i_3C!6^9OXF63uhjq$t&;;uxN0}O&%2!PKP=xb_&PEPU=|f=nJu8r%>si zu~Vpnu$%(R8HVlPH31McuQAmeW&KKiG%=}pwW+WS@8d_iE>0mc`C=F&N;p{7j4$zGpvNTK`natb*?>Zf0f@#72n22*h{}6Wahz^o4h|Zz#yox8 znBN%V^h}sF=IN|2rW`oAsYsuQHocr;v>eM6sE5{M)Q3|@=fm@&`nh15!(0t=gl&E! zF|%!XVRg}wAeR^xgUORbIh@!(x+U>yT5`cOowyp)JfNYukPAX`Hwy#ERBldgY^K_X zl{R9bjk;>1t~!XCQ;cKT4V^e{=t>TB6&IA##|~BEP;4rLCHjzT<4EV}lTM4%LQqpg zlR!o*Sxppd1^`)IPF680awThQBF2qPAnFPQFVO(uD3?e4%h*I{BP^#FavRS9Vhh+c zW)%N__NgXv45y6q?LXb>#isk;yVVT2)%ZWVlZxCz#=}C^mLnVJ^)w8<+6{5<>u{#=X&CZK-FFUtieWF-jEXId1D=$eothY4uN9V$Noc%SoCjCvnRE zn492hmM2P1@I{Pc(KLQ;jpNvC@RF@;i>7IC<5@1YV7d4pkm$pX%R&z28+HtujPsD^ z7(a7Z1CfVJ)VcYwzBrheqA}tW@W$kE-Z0=`(DEb)d{8!oZ)jtQtB;j=3G~Wd6}10F zU*A|$LU)`xGuWK)60~|Fb#yiVsgADM-_+6n&*~gxs{P0n;>G}Fr!yZ>kVoRLsLS$r>CsA!8y8U}z$0C4JJum*7Irli8NN)R;^yyTH2`%ka~zN=gz+geT*WYqCV)`| zrz#UHH2M*YfDQoRbb#M-=mdsHc}P+=_bHGh;4cP1IbIx74ddgp=A%L!@Je!_Vb^;Z@~e5J;^gDOZItGhHC z%wq6&yJW<0K0Y=VCgLK?O|DGWkm2@%oCrQqP>heND5r?P!r&2kwm%`=E5M+E852mu zIKuz~rbz0_#~KJELrDxAZwcREmC^Q9MGqVAcZ5-uz%<~ZMg|ApIOk48LxI?+lkO!2 zjaO5H8^LkACV?4pVou8yqe!PhpM!Kf(Xh>^V>TQSZ|b3ox> zDH8<`b(pFwVxbHX;)vXufyk7EPq5lQGaBDo0(+XQGj7@(R<{+*TNL2H%Ria2bQ+$ISe zwn^TSWLa=a@&UmA=+i2(9kJRjc|{UmNV~$K^Dd>4bl!iX^JLM@<h=4O{7(VnwJYfJXTney-3N_ zyzDd%D=!u+5=2V(8tZ~8&@EFG_n~Eqg5KWj-eqIGeK@@VgnEN2K4W7`+Ug5^u7ff= zSp>N6m-M8eU4fhB*7Nyy(Z>^(HRiX7QXo4mTHYV3#-G&WWSHBVlBpKP*sG0nJTO+=F&g^tmXp z3SRi4LVGUyQj~|R8p_k&imnj@^g8ja;w&`jN!mKGS~2-}OqG+l*5C=;4IPM25c)q- zuysWjob5W=RHD26baIPEZm7`=?G603GL;KBcMhE4sc~tgG~X!Pix!nc)>mcW(8$7n;bij{zLi3a zgNcA7pg4rDKB&N5UR+#2oc}8L$ig>J;Ie@Nonk3}I-wr4Yj_`y&!>IDGbs3c1i@&% z2(*BPgy5W?W&m7@pFxyo@OqpY4{Fxq*KnR>EEZEy#c6%`CqSa!CjiW<-NSo<56P3{ zTPAo`kUl4$;SJGoRSRY+nP8_NDBme~Nd$hIOv7jd z(6jXkUafMDRr{)|U~; zgZ2x7SmR2|6wVe#+%^f13bVM~5q>7j;`Ty#NSMtHc$e|r=i?Z2pYIDls?P-jiUfC) zMnavG!ukO6E&J3k~_SeM%Qiv$5sB)CVA1h6!#7w8ng{b{cS0O`+W zLwg7;kZwJES^S`O5C1o~kn;plkZ6dJk9<4$;j)9joSzyC)b0E|&?ZA|jKeqJfTj$} zv%u#aKMj5x2N&{x=f@WU6kt%B%Mskl+|0`{^)2u4Sp668T8;}yQd%qX2@{Nb!Yty0 zapz=lkkQ8c#^iAL#?0j_e z3tr!k$h=50zGSQbXZ)6B7|65M5?UG0IUbIg8H`K@yH2tI7Yt4{S%!Pg`em-NVgoGTpq}0xjfr>{siNn9$uUtu3-{BiVJ71`ZgdZ6#oz zww2gMupG0EIDh~Lh~q2(*@yOn_KSuR2W=lgrUtgMxwN7&`9-v{G5KY*i)0<8hs(5w zoI1DsTv|1fUroC}1OHtBGM4 zp!7heF*daKl&@p*zfyjZb#OcFC*?bp4#H9W7d4BSIkd`|H=xCmyOx>DgtU>%EM(GR zFh!JlXoms+Ck-LKWEwh!x{-Mb5&SI;onhQ!ApLJK;Q4>vAmT8h1$Eg7wo0^i#%l(c z{u+^ak!0i25c)BYm3O&UAGqai>~C{yM(j&EOhV2VPnv-_&B2N0k&e@H@m#PYWGSr( zwgt5H6x1rkOL1BiegLP{zzR=$4+}mQVFGjn?cZ{Fb#oxz|s$G1v{y%NBW1zJO=7`WXi)<62m5Ce^!N_d{ z0DA>#{jhhSbqaL}(RzgXg=qakABAYy!i~ag!p<=oE+E=Zz-}U2nARwq0o>5efn6;V zeIZ86hOdN>X+@uk!q$I86xzAs7;N`D#b~)CszUs*IJslRe(|#gVH*qzj^p121<(bh zNB9pFMYvJxKNkwFND&f6c=(lz?7|KKG7iWODngK3MDl}#k;HU__}jV?!0f)EG214-W0MjRnTsf_?f&!IGuVi^&^NR=xn$861at%5+Q8m128K>iVptuRZ`N+C8Ur=^N5LXq4^Ma zjS|ZNiUh9Ds_7EA6`jhf_lKPi8YbKVu>)?t;AAm^q04eUeLm>n<3=a}KMI|qA<6=S zQ+&Z9oRFkb6F>)Xf*%?)k!&~gv4=257b=W2qHy~sMLoffSRxAHxdd*kq^AT?V8Jp& zkG}AadW7<!2p|O=g)I{~t}A37mxUz&@6%AcDqx#?564G-&ZGW|jomvShW~K&LU+ zjdvnvOhj=)88M?Xke~2e2$>qvBTN`DQDM3d{T7?R2jR&Nm=dD&T!NTS65^rsJ}#3P znJ^MZ2sH?MG$JV62p9_FWYorCgw%i&OijWefMMFwpOSEQ&_j|?)h3Yg6d1e` zGL3*Uc?}6wBu0lFp43RvnRH8*Cesm)t#TMkWi)?DIsZ>oMr_Hkpi1M!WU?hj@HdcJ z(dH1iZ3Y;Tl0o1mFd)?A5HUi48qCQQ5I}UQ8sjj_G%+BEB2fSpgxItpRH@N=W2RCC z_7J?(L?xERIxKVb#>~xS8A=x?1b^y*Y1aQQTZwF~Cnmv#HCKIEbzQJ?8#^9Z-o<^v z2k_T};?s7Murk?(o+% zGz2&?0bNlT`V#g?DF89)Hz4EU1ivNWjIeviL_{HD2eP@a0ECvP9z{b~d12pJG5htLTGAG)LiJQUWrsa7m7YpP0sA`DAH z0Z|+ViskH3cPE`i>eNJ-0hW?T7@`a00T*=5U^O2Rc!3X{YdM8^$AHy}&afJ{axzgI z4T2GbxEPABjW{eH4C?1pA9kp0LmEJWQKN1~3k-EQ)siz2K_th|dH*4clUd_$SsV=f zXP)O|abyCTYSdhirV37=)2RcgWa3AQHbKusY3dPsAtCn&>^*=mo%$j5I!hz!Rv24h zXtP=Qa2W~RQDUX$|4#zg#?L2>_aQ{UDeR@oNXq}7~Gf;rzXS1Uy{K#tUombQGA40+yMr__665hN}yA<8A_yk+{Fk;EjV5H5g}bh zDA(x`l9nioDpV_#C^Z;z3#0XoU)d(SM z-N?B{LmMkA!V-XJD@FK_X$+iBwlWY>jPNH}QjxH2Xs3g;lRZp`yAcx-dSFB)30N-N zVDm%`M@bf^%3fzpcWM-a+)ZS#lA|=qm5xN}Bd(S{gb+2rCl}hnXp~s1cP{EE276Q~Wfxul@*=a2yjU2g$PznQl0z0=^5=w4_IlE;^m|GI?n;Ybs zv6>}|5Ty|YYxe;A4&keiQO8zAw52x8guM)5=*~$xc)O1h9c^;Z=1_sWCX!d!aC25u z)Q=zS@d$qC?MrUGaEQQAf*&@9kiU^8iY#^D#NnU4ycCNsosmmOG71PH1}^IeB9@TM zq>3^!s0k>Z1rrEKY7A^;q6x`t7)!=C(t$$s5A5qF_I2oQa1Nflej^BKG~y&$549*% z6RxKwGjb{LQ$G$zy!|8NG4en8_5+5|70XW5GRva8eo7 zS$ZZ!C&t8pLn7dWv=aI8ADs}(5k?+okMbL*t$$o_l>eAJk@i98+%u>OZ!JoUhttO_ zPXvwG&pzT$T15^eP{m;}als+s$yhubl=e%2ODK$IRKjEvXhixi3-$|S4;bcWhaLjp z=a**965%{`OkDVKEHKQU9R{4k|KJ>Swm&c;8a(Md zbB>a|k+G7YiJp<3fztS6>(Jynw63HZssyLjmEfFtkX2|@BJ|P?fg|hi`M1OC0Qt{H z*8%zO2iM0Ce?PVkh;fJ3G4c@v?0^R6CHN;K!ZZm>j9Lc%XE_>9t^FD5u`q`-o#Zif zFl!l$aO_D63Fv@1ikB$=NH|%+dO86-hu}{Dv1Sy{E?7Zn@~d4MeqxdXX4j-4q` z4&r1DavY*ys-g!@u;=Jl`hj^iZi*o)zj!#Ij|D^rt-!+L{o-T%1IN#0h<;L6*25Y| z7mx8E13BtX)bjy>?_qa$x1!jI-SKS1 z?)E!p?hIZ>(D(hmZ+@`%&i|e{b0+T8-a8u_ofxZ5i-`PjC#eN^Bkku5`O^=ZaldQ! zCvm5=)D$NS6CEDz1iM27ySq8Y$0nu?bc9>X$;HhnHZeRNZ6boy^Q&MOH2u(m{8v#Y z%-d9GyThDf)avA)lnbHBu?oyv*t#J~5hD;$I0Aq?bAWBH`gZTq#4i^oFO!9*V^Duk{l?|ui zZQ(eTGV&mAPZP6D9i1c-gEsk41erQMZ2!yq!E5YPVJ_tKer@e{g z1i7Dyb+&FR6T9(xekRWFD!hqDrhXffKzR#UITMf8CeEO?m5DV(BkJ-s3^MWX`2~Z1 zCH#+KtIc>MaX`Qca!^3y@Wwd2F%Dmof%1wNhwm@Sd<~mH@B*qU6V8Q>CT0^bt=Xt+ zJf?ND9_Y#}qtl0^wb(wt{6i;Bp29peqc?^lh9_kQ^)6H1*2KCSDS0S5Qf?kp4xa5J z4#WCWMjp{7VWF;PVx3i)Shg`S!`hAam72=2_vb|oC4XYk=?X8umvmK*Ul^3&w+E<;CRCwWL87<>l;RJT~3Spbji6M1KP zsJUwE_j#1eM;fJzi{#fgz#(rHzAVP3jFL^60b*bezL2gW>;~y0tVqI zK3MN6e(5CP;zRwe0{?}h_?5mZl;zJ(e44>kxbrg>`VzmZ(46Dplw&zdT@3NK{&=;K zUQD3;Z>cbxr&2ze|j>vn-Auu?WuT6oM zWM?ZXKaa|b^+^!gQ!eh=BnYIh1${j!FQ5$!>05zEF+JpqR6$^GC#L}~Dc+H#@F}J6 zS*7rWrSMI_NqNyPi%I_scJ8CRfHjmf|4uVr4ursEiU$F=^CS5W;}LYE--F{*%5x}Z z{TyzCg!1bsCw(2r<3@WWIDCc*Ay|4$6KE9 zMo^#8p}Y(HGaf48*n2XbCE-%}I%o(uUQY)Jm+DEAaH*b!5-yd`rtK8!$6lM+Gk`p{ zA;v4^<0waU7!<>yn<$aTK9%X2D&Z|8d?u%d$#0R!Y!iyw&sz`Vl+D@UJ zRVAElSA=$ZOSnQJkL?PM|IqnxoY}L7a=u*dm%=}l!p&(r#p|hA3RjoH50t{o;J_Cg z=7TBxGyAJacr^)cAmNw?Oungv*O2f)3CDYZ$#;`*D+v!Tg{MlmwM0Hs!fhlRw^%`k z>8b_)EZ(^iE{%7igx8kH=S#S)grAe}Iud?Y!s|--YYDF>;c_}qMLX>z9Nvs14!OOA z*OqV`gR*qFOSprCcaZP~65dt9rTGvp;f@md%aZz|lyKIqV>gaS|y%XmVKlB`@oV^pq^t_>ZdUJYOP-9~_-h=v+IPOa2(>Y#->L1K;+`ACn81YbS zKaP9Q%@+^F+>i2=9Dh#pXDi3M(|BKSypYCgO2e^ySV{dgIPOEk+jAVZMnuQ@L8ix& z<^ztC(J`Jt^cgZ)`ln(#y74TF1$={M^m)1=Rj) z9B29PkmK%D-k2U)yq9RcRpq!B4R6PBrl$qRSvj@i_zbGQJIC2PHLaQuO2jd&D!+7B=$5}gagX2rYXoW`{52p3uBgf~`c^Nj-RCI+Qo4k z>!Z8G@e?%OmmH50#RWq&1RS&HJFRav9M2NPgr*$7PVMQ)aSs}A9LH%j5XN&H*ACDv z;dmU?pT}{g=OV{D()@qG@kLb6D~=md`EMM@jn~oPrZ4F5GTu_}(F3lQcpw~Yv8MjI z9DhRn^*Mf&`V|~!<0xFKL5K08es^k*J3?@bv-MK(`u z&W|u&FUmX9Bhzz+`nz*{81?tzcnq~ajN`YcKbqr8>W}9*tGE3*j_dyDr1LDa-;u`4 z`gvx58j%)+40>dorIXcn##wsCaq`*JKau0~_7|pdoO+87*d5@1GHrn9Z9^Dx-0l<| z)5qjvs60Is%j0gV=-3)LlQ*LrzZXWwIBY>h92<8qK9DMA>tT!!q1;*wR;(w3a$Alw z{dOE5OXVAI{0ZgG9M7Sg&G(r-_bB(^n=Gmg)q@?IRDM>)G+nEpkSv--&RGRplq zJ*y}Wko|YqCAAtlSg?3#}7~*!|@}O$8-Dy<;ff`pj^%I z^OO(d_+`q6a2&S}mO8vWv2H)65YN#u{zCK?*Js9GQO@cuz&Nd0yk|3>|+ zzA<@X09<4BigDIHGdr<;U~6BfiX{&@u6>oXK8D{ZSi?U$ltG8`?7If^M_ltq$Kqw{X43uw<6`S(te!LZUAiQ=&`mrP>tX9=eL2q7%_2FjNBh%w zj(4D()e{ykTQ?id$@@_G(Hv*%W?GK3b+dms&eqM=bDXW4?c_LHH#^MnSeieqUNHOF zx|tOg6gbA&c%Jn?jQfaUf+r`>)@S@UZcp=}6UW)QSun@hx>-EO*}552cZy4h$> zp4D^w9vK~zXY<~992cboVKv9isr@@R&eqNFN9E8l{cPRrJja{R{QsBZY@O#B$1hX) z&m3p#W=-i$#o}e_W?md;<>JqAwqDeo<7_@2$#J%BhCj6?O)tym;T&iAJf7oh-E2C? zPto));W*2;jT~p|W_cWE`FWD#Y@Mix<18QEbDXVr)u8hUmd|Y6tUkwCzO(1um^{vAk!_Wa9ii9G6$rTXV{Je2aa9G^t_ zMviMJ-$pr$_XwT$7I6GJ#->#a+c3*y|EtUOg@C_m#)`g zdbf(fg#d{jgrk18?z~IFQI8E81}=}|RVY6w;i!j=Lkc7u^{A-)d5(Ki zexKw0DKF$W`yTEYtOJ$mG?0F2vYf)~ElXGyaKCpFQwywzJ+4E(sIC-{C7$D)8 zuBFt@jvQy-=Y?|oGL?_y_$kWMIF7#ri*69d+2)cOj@wZAY>ro^e6oaNd9iic*%FTF zV&jbY9B1Q_B@&K$Si81f!cor@8t-O~XH&jI!ch-f2R{ql%JGv)Wg=> zFG)D+sZ9H`YaBPE{I-Ono^iCDd@SLpCy>g+mO#W|y+Yoaa@abknBy7<>o?&&(PEDB ztlufa@pP)kP{Pq3_Pszw2}eD-RK5zwCsSTi!ck8aZ8z;C9QCZD@(nn?hH@7PM?EPt zf0|0TR8LEeGd;c%j`_pp6 zZz&(i@j#m1(Hw6feea}9f<2$LIITDU~*!MEaBpmfrqva_5egS#$ zJcyHTO6B)(oZY{NDaUNYTdM)>Us$`ycx}pyI6bYY{^uNL??UBeWg#+f>^|yD zc{z@UQf|U=_C1KXgkyd9i`Iwg5{~)9#zWQ|Po(d?1bYFOF*{AI9-9l#k)~G|IIcpF;UmjxVA-m*Wd4pG`SS?>d^^9TIu0pR3>> z-7$`D6R~iSjb zeG~Fkl(*yLk5k@(;|D1Z=J-9z!#RGF@)VBi)A3C@$KO-=!4i)3oQ?CxN;ulj#;?-v zzmR)V{gWi}sE5rX=1Mrq~Dp%I|XeH&8uKO5wV6oQRiE&vB~9fa6CgXV23z`wvt7)g|(1e@n_6 zP|oB}Qr@T(9w5`#<{u>-;{n&rCqw>!s z@~EGE|ENoE94vP!ufTCzOb9qD2}gUHQ2n(z?oK&-&Y6`v8-F*V@;ndZ^!QUfK^$*O zd0$S?BFdvn;lnvSU8y{K{+ZSPAj-#adI~9@&2cu4Un0?u`N`Iuw@5hVTNu@|gX4WE z-z(u#J?wiVW+$63vG0)>?@#qy;PkM0=p6}1d&W}v2OJ+o`E$xyd9|nGm=C3J_S`kI zX9m?%nSNozcrNAm6C&uC{!psFekr^ar-zk$YmP6V`U5yU`zep)_&3V`k?0}q2^t1& z0Vh9?_DB0A@|d3+sGdU{Uq$&vj{i&fRgSay+bs!4d)Ry&HlQPp<)K3@%tnINEPZ_0;A#n@8D6IO@4b^|(to>hYm^nsA)Wms(0VrmH6%|EnY%^+ZuU z0UQsbypx2Z9`>A4IOVKf#nARVz7#%2q6gz0O!aFyK7jJ+9G^(}Y>sDBzJPLO4_oKj z&G9MJ&a)DZQ!=VXxFz9q2>`ANLLtX|*yK=~GlJeJpNs%!_x|DpUC#}83{ zisSn!zfC#IpYt@{LWw-q{~Y*7_eR3eo?BGU2aaE$T!w=KaP0oIq2qf!j@Mx0ehHVx zYbD_rZ!;=io8wI=Z$LRqR|ajz8cF0)|6()_oR@^7{?=5FFUNf;58!wZWN+U?RGGySoy>q66OSRRDHvHNt1=oKn)oUH@Y zP7-;v{}8paE64X!9>wvyl=tKKEy`0VXYnqj>rq2W;Zr$1Z>XMJ zj=!ROKF7aNzL?`*C||>I1I$=(8#rEu@|_&7MEPEhSD^ePg( z<@Dhg^kRMMfJTBV&+(oj7OF}(mSZETrzXdpD0h@_tcOliPe+ck`ljJHd!BYGg98a%PJyslN^M5;zf28saIR2LMMjS6k=YgIaXY>3PlruXgQTuyIc2tTpOqYs!brhwp`6(nLgT$Ck;hZqj|tsX zjyI?LmV{%x?0M|R5{{=CRQ?&q(<%SV@imlx=lBZBb@Ao|$Lt?O?XS-9rIa_J9E%n0 z%)-Fn{5W|tDjzA4M-vXxcw;%foAN{nNB!(M^Fb0$l0rM4p&Wll^^D`Vg33?eczw#J zP|os!eNVBHmqz>BD?1KiPBdbtq@{SmOyeKZ!i% zgCDhD#qs8px0i6VliAZl!ck8KmG8sxbjtg2d=2G^9A80sD&@?6w*H{ycqC2N5{VwP zGmMS{w{ml}X%aiIG`IkS`PD^nSb0Egv5>Mc!IHIDD5+?M0) zflxb+zoYUl99PhJbt8_mb%z#|GdtP)tKB$xZ>pyk$D30g!RcY&cPEs>$8vf)Q$6E3 z-jVXZIX$;&dCe__Z{_s#p?Y?5ycgyBIXxPx{~E{H_YUtkJ#kdeCyulA7kOn;?8W7t zOXc-BoQAHjutCC6PgSaC z3&$-f-z(v$CxhxaBH^gVp30x#I9qSJB;ilI)-)gPmBI@-&YoL)S_%)K z?HsmCIP_-gKQSENP8<3W93MyL`?EOC~g{&yRKIxIS(7*!xK=e=1QP#>umN9HKd1pUTH` zobBV#pX2QL*mRD!rFsT)yfft)9B2DGWN{q#K|?oAJdk>V`OKatnaFY62Myg+@lY(E zP5E?=PosP><>;kDIzryi`-XA$Jzam=Z!^xG3$>gU_I{#zx?0L~<9B0p+vgg8>JbRvYASchtQBb4~N>GP}!BL$e z9%I;9N@RSff@~$GAin~j2un>B6okT7(~5}5u(W8{&OKN>gI&I(k_1IbS3<+WQXSR>a6H@8SP&&HnNq5>ik8y@xB z%gLd^sVSkq6-mUHe<#r|Avr27F+BBmGRbKv@cRdesp{Ve#ey{nNfEH||L>$AUB9_Z zc77wjuK+u_D;j$IS5eqj54Pp|Z_<)I_Y`g}|1C`MhI|S)*Z&p*ck5HQx&28PxAIfC zHTsj7xWS*ot?_>lgx&uXZhy=<&=^t&t)cY;(j`d$8rGUS&z6ph^f6fN7TP|@g*St;&gsA%-ZtdwqYsA%-N3?(UN z;^Gd73im%&TWr%5?tiSQ;)aO|_umy0*+o;)_;(_>#ipY1AIp#afQbTr9ZW5D`W>LJpAK~h0}E}%FJGz=^R>A7fsMO26YUi5_j9DXm1LmHk7bbxL~=S^)v2IHaAsp9>t zabAL)4m03Pbj#>`i22!(4x5-)XaHxZv$XJZ7+NgP;%5NoEmUU)V|Zlov-dFAH9me9 zxKL91&EAP2tZ6zh{g@RjeoOJP5D3ST;y*?O9O?LuiZfZ}6>z>$Quz1u#b`F3X90No zaUN5W{mybx(u>BA_M`2*{aRos3FGw)I25}atQg?f^ZKH%*j8q9wErkAJkDoJ3UA#;48h*FEG<0l4_H$8 zesm$KBE48z_?%M0561=*oIYLe6Me;TF|V+zl<=eJ!j>GaOC4v9@Sv3Nnyz9f_MA1- z!H38F0!vDNZ@N&n70OrY`0x!&32z=EhWf(YzqGOw_ul<+ADqDTa1Fy|E>mJ9?VkzMZ>lq+*eE!un=JbD{!srLmlEEA zei5))sua$7`+JrW{x%K2l~loDRKKn!8c0@5RE zPFVQ;G(4A0LJSR`!G(w0^(VI*!XxwgiQ;>9GzMD#usO#rnZ?h>@26?}Ts4IkjzooC z;-UD{y7){yIaXTy24ehqR377Zhkri)J2d_ZRE{0IX#8dj&?5`aj=sQIUP?s+Y4}(8 zWrD=Gg-?^+PnL)=#7`K9a|OoB>cRI9Ji~Ao_Tncz zXJR5A+2=2^5Wb}HU)NZa%%cI({$}vc+mG)P{h|}(YMv4U!o27w$IDhMCH`dkAO;JM z@wb3~K7RXB;%`smXZr*(Bl!4-!v&t9?77oo2pw)7&dYk1V*fm9|2%qQqW#|R&)bjl zQ`E`Q38%zexGo<5hW1_RSp4j`0WOvlKJJbfY914$N|=`&@qMI{!W-Tb1JLSAL;uJt z7QS;S`R_@?7YF3xXFMFj!=FI2iDAKuhPN&z;t9(?h6mI5`S2k${8+AG;=`vycwJED z#T3$`7yf_~xFa;7Sbj?QXW`lXitPs`#CLN#PBei;`KGxe~{RC%?IzqDXSG7M(La;z2wYKi%Ej$Q2hiXBT&Z zLdp&I^KY#q`=L<=cjyn_k4U{tek8(+U@xJI5G1@dt@-Kjn6Yq&;akPZ>_&L45I>?! zt$YP?T}r*Xd3W{h;-Bq^BHlq=l$x)dm6=Zrl;K^Rv(Bb@Y5go+u4Uy7tEANWnJKl+ zE-N$hWseTQuk(2Ju^j$bsZFp}W<5fmhbBs={zhtAnTrb1%y^W5TmG#u8nS6GrkVu->(v#NnxP)W z`Ey8LD9ru#{W~clNQZYfmF5x_iFc4n^QB8?rRFshhn-SmWb3c-wKY?EUQDqps#Y8x zi$mpk%XCyjh$o||llmF))d63C=Gz_|swp+MRQ5OhHLr*jD$PNXhvp!m(j0;-s&HRh zODJL+l{OwC$o4-7<<&Y6I^ zi@xcY?EqETzP2)dEn2EMqtrZCYDS`fzvedNoO0i7J*BL`U-L<+$&Gx3 z0~w_xhNX2^YIPy0^DtCVyBw9aDOj%5Kq>m$8u)8^+ggg5sRb|8g{)u*D#oY9Ec%4e zXorB*2FO)Wr|Bpk)Sr0(vhk6mlA2n137B~2th}_!E>DYYK>i14z7`fiNLD+QS~Vmk zvxT7UpwznAsPGx@TQeW>*9mD9#uIrKvB} zX-n~@%a=q?^eMAR2dB*X4ssuq;bU?jSmp;ab%pFendTq#DK+ZDX8GiP>i{=fb5!iT z%?v(W@@PDJu*!=q$B&y;)E`dtqeg4gD4NBr8?xUl|3?6&7RnLp3W>rcPmJW(C|G`D zeq<0?0q+8p<^tXbZ@P3g%^HDvG++00hnh=rNu@bOZ>)S$rAb6tPigY~HQ|u&4(g^HOtJsi}b~SPg;f@q!2mE4poJl|l522~lYZ zl$w_=tV~E=x#Ur6E*EQv67wtTJ46vaW*sQNOfx6NfIch+XE7da2Qzh) z7|$;mh56$hL~0AkgDy&~Bihy3UmIa-&D9wVOf(&J5B%9mnMR95sR_!5#y`l`naFB5*+(VHdJx$@ zoa~blWxa^33n%-cL|G+~#XTdX_C769Hjv0(feIs)#r4Hs)7G8H;vSk(S^Q0sUu8px z>5ynRjZ|%7nLZAtsEGlR!Kz{lqfoniq@2h;?SQn;HUdGU#V@! z+Ov`x8*+mb7Lo=&10tY}p1zhHY#dn2V5 zZjC&(zEa%h$R!W^XUTQaPjLOCcaXof4%TBbaQBD7iibZ8(wt4R@JqrUU8UGDV1Gb| z&oI1Y-GL?!#%j;~O?_dA7XG__(sa}uh>7%-q*KHm!AqGPZ|misy~s8XufeU|PnmTs z&8{e1oNvI*io-{ZR_yMA@|{(lPt>iI+Ac)6Io#ZM1^S${^H5!&5A^w6ABeh0TKqll zr|p0~ySS@m_nX*X7xsV=me_xPq_=c{=F!h%8<%V1?cE4Oi^tO>zctOlB!SOw)2vp| ze~J?(m?_~j2{N1XzK2N1Dht4&aZNZ^Y5lANv_lPW!UCgq(d2-v@1~>9!NeGb-Ts=- zFg7LQufgI~rM8+%b_nzCNkDd#OsRpfI1FEYDLBk@xbPMSrUpv;3oy*~w|@x(TV-}L z2gqBP=NwRG?uUuYJ`z?kIK=!2&<=o6G@DL6Q`#R?YW71grKXT5F!ed1w145RdB?&B zXj_8eX@^ys+1s#$HMhk42m1_^*$w2ywaC}j4(Ar0MZe5Xl%6+CM`@uxlKBbo4F#V{ z^Q?sV37A7F>1Sx^#ra7_(oz zVJhYe(+=B!Y~2I?kYLLI&D#K&Gie*x`gR!GZFAu z?(qT$K#j&4QRqne9k>~A8URK236?m>wh}l4!kP2W86e&_;T@fo z8gIMo6q%;Kv%jW6L18uwj7YVhMd})(W_yI!m>r=4cq3voA0V@G@>@ap{LM^qejXVp6Kyu+c zLg^r0N$aN6wub5X0lV+F#s0=WJTEg(rqr55nI`Us|06^|^B~GJY+rk=F5K5fwy4i6 z%Jd?%DBj--IE{L!EuSQW_0KRZ{|Jq}vr;<%;_qe$hE=DA!D;}^+5KVB!$5g>46a$A zQ)ZJ6M0pr6@ylL4stx5z3J!P6R%)l9EE$q70g2b9Nf~)?G%cUm9o9pXnV)2)qq6CR z0`bB?@q&(eAWGjBVXg?}>TrZFM7T|ay6W}_arqGRUKXLA+7qFf2tSChjM^5VwFoWI zvdmBVYEy*HBJ=>L&B2>Xsa4v+%3xh6)9+_6^B_NHahPV=pg`sU=U&ixW`H%qu*=YB zi?@av*Mx5Q!>x+>4-KIu)zyP1zQIQXjKx<)j72@hIz+@+S3Jnb^0~3j z4^=w3RceANqE=^mH9W6pP-QF}bnu-XV=;s|o?DyM&x3ng{3B){Y1;@5|)hjW&fZRGf5AjusM9eD>cT$Ba?=?Nq$rJjx? zY6I~~r}8LeDH`0F7;LE{`htj2*3{R9_-v@JE0MILzHa22GxhZ#J{RVzisriNh^8Nd zb7HzFEzzEG{I-SITwp5iYgQdbZ3Zck{RMfjIr%*VyA*h!Ssr4JA;;3}3N^>NmuD*4 z8Ag0Zn8tAVMG!4V(j95$2Ksb7;lsukKIHfz=wKwGK)Pjx4L0ab^p_XO0?lmcfV3HuxaX$?;6k zQNgDe=boCU;M{ySe2|E9bxklOq&##@%eTjfMUPqeJQ6iAseF0--cPL5x)n%)=1`4$ zYg&T>bJRj|vb#*TqQTW-os}%`8$YVEvIRyUmcFi~1x7%1RG{M_wd@c8BPY7un}wa8e@jB2T!3{00l zX@-SlAgXwxL=`m1Wjz;s4uZs_*H9nJn0nmHVmibe(rZjSVh-tf5RaHcdY;5%Eh=b2 zJa(d|De;I|q}PmiJj5%_iN{OycoC0M^mr2wWCJ+8R>ad?^!Qe~3wDNxp4JwRz!M{S zl*H;}(W4?BwdiSUm<)Obik^T9LEy;{J?%}yz$3nqsn@~aDQL?SuXHs13ZAi|r-w0q zv6CZudR5kk0?QRWy{nW5&pgr7hnTZW^zl-yoDspga6$yl1syEf zDhTSM#&Z9d;5qFIb?|oys`$W%gAU$=q(ypK$eK{%|Z1nLVqq}rh}FWq|g zfg7YoMhm)j6;VzgDbuyDh&$h#iJtluu}WEr9*2t0;fl3EWHPiZ4JzUbtajoRMmMD;fohOF9i2?+RCTYuHu#ZSdqn!snF*f~wWTsfJ%*w(w zf=P(7E+irsq*&0Rk$Alpd09g+xT<692wtIFqTD#3IIx(4g`yR)h|vns6e|?}Tec3U zNw|6-oLZqVde}GR$}EwSG2?WZZnVr4`yFuyCbcY;DN)O6q7w1|ms+O49;&Qf!T@1_jPzh6 z>_C}02`khF1wvODCQUG;fx5~XVX93+)o`Uv9$YbjwLzo>Od@e~lc_MM z9^NxOWM+8JRKj0@g`5hOnV{umF#|(owMZ;NSz?qqOC&m#tUX471<_7aPqV;N)(PZETrFf(@GhZ6Vk5&%m`Pw8nJwOVl@_4EICizA zWy=)Lah&}T$0c%F77V&fY6QrWn06Us+l4<{X$Zl0)gxz^iMtx-fegum zT}s^cMn75DLk3eM%7f%o&_N*`%px+0+JyVg7{VR2$r^7U@pUoXm1dY1%i)rky(=9s z6g>~Xfrvh&ay1!ZVV zHN>*4@+K_Gta@mUA>6B3p4cT(oyo+?p2cFx^)L?6%H$?_AV<&J<2fcWITRC#wx^53 zLlRTJBv66c`&A~|3GACwthcWX>P3OR&XVZ6kR%-_7VBd7Bl<4QFiMiVZsOpUl%0xn z8#gezWI;tHlVYLzkV5^A7eWOeG8Z%q6MP)7oW#@`R+Wu~b2n3(D)5g3KS?2+D_P3n z9BY~QoS#vE4C^uxG76}Md!Wt z4P*pLOfU}WH@1ZzzHVVChYW%T`G1PuR3=lI%fJpZ8?e_2l2G1UCO0uOByrjp;H3)0 z#2+S`*Ck1_P{>+VVTr3(MP=Ts3QAXGk<$cLGL#{%tN^vtCKN_y$!kDZr7_W7m6)L? zCLMXTVqsAHBf9ELub!ukaXn%|4Jt`8z^04{YnnrzG^+xw`j4v+gkH5amqC(kiGE5H}WQo$|6eCgz56t7=weP-*MZoQHu)J*XOx zy>>qpC{zghA7u$+Pm+1GLba@d_BzxB0~*k{46)kOt1?DLE;;_3C1U<7z*ej=L=cnW zM2sgo#Uwcw2ZQ<{nk|fgNc3Q?Gzg9|ne5#wV?5v(6aL}E3Mzl;PDf^?V+gGib>uFA z1`6&6{6H<@)05cxKs4-wh!8J1(~U}tkB3$UUK&mnf>UFXQq*B-Q37;J!Pr6vt2zY3 zJIryxY60Gt#x5aM9TAz5BE%*oga$`MMun!utBDkZA|c3yxOBn>q{ONt2~A5(jg3x> zjIhSltweZRTT~Dn4G&o+2Zu#Q$0iDBNpNzgI!1tZm?I-$K_M95ixv`tp=Si+qT)lN zQ)xJ`EjbBw#e^nC#7CwG!3m)$agizXx~MiWa)7`DgQJpC1kj*XM2lwJHnY`QdqypaCIt>(9}VR;V~&m ziAiaxj%kSlViO}AVNaX*NW4g1#&?8Q@YNullmZGt5R}sk;ZV#m>@w6bxDXyC@&CxY zWY}~Dl&RBFG4r4eI0CR^}eHVO%80HcG$(^67!zX5ef-Jamo`F3bhDpR&r=WBTZ;3BrO-oX3SyHVwP~Khm=WizT&nR0ehXsW;{F^|MpSV@K@ zMGO)zkX@IGwUaw5k+o)U*QJC@>J-+;gh+Kv60LlaT*Ui17^l0%Z5L!0X&)1V#Tp_8 z6iX6~$G$^s{7Iz5%Hms}T;*ic@T2czha^m{Uwr zLZlO1iB59zjZBSGCnY;|h9ZhoJE7$QR`OH`B(|W6aO@Y;!quc`0E_ zPU2(3oMP1KWT)a_sH|85dna{lRBU7fAYu*%hz<{Tf+j22-OUlU14$d`2#uAKi(9d& z%w!U$BoZ_Nx@M+|iv6l8ELNTBMAGw97L+U~V7?QBBfvH|vD@tQ)!GckFgRzB2^HnA zPkAkzMd5{z3i9UW!rwJxeT9il;?{Pl7J9dSw>nR1q;F5X(%Lz5ZL?!j3Qen>ORRn% zY{dGT(beazATIdR@YyZ<$G;xGB(zUU$1xq+bzSphbwp%ap@$G6G+5I&?nCOt)Xpy} z?~S{7Vz%e5k#d8)R!!Fr{r>*#yFIt^6Y>o2ElfGL^ZDDs@2@?*e(mk0fep*&qf*r-mLCos z?&&w@*zp4+>$R9LQ5*g4Nn!3xZIbp}$G=D0_!cF4+`pkdmDcBl<(UMK(is ze=st(-siD;_ZRDRF}Is)mQ};4j?Mft_wQE?etO^b;FabZDvgG zoXoE??Av9F>eZ_^Yk4d8)Qu_)@B6o}*YfD`e`n{ICC_j1dBoxh*F1*S{IqDUBH^m~ zQ77etR&vjwotIx2tEuf$JAajWv|fe0p0;Nfs&1*~#z*=y@T7jHhL>FG#GUU@`^Yi5uzS>u$qO^L zKX~?N!}HaxkDPJn+`-byI-q5{uSR8N1~*7eI^4Hb{SFO#nYd?t-!6weHP&=`nNXJpbw1w=HvO_wk!)k*rU|N9KhE-~Nsss;kxn&9h12N3{@*Db z>}v-mOg3>|eNcV^Tzqt;E|1J>Uo{B-I;w|R!poSQleTR2cbzq*-t=BMBO`zp8HH*21}<&HOXmUc*L(BrnI?;f{Io0&&9 zJ2$#Lut7%C?BhaQ*VhyTgo@Z|I*DmUriF zwYWyJ%-YP>ebIeKV2e{V0^NN>omB5K-){UAa(RzsM|+u@Q{M*W+ao&_^|WZHFu9TD ze0EZ8hdX!HgsiQ6%b|XYT{->soOpWEtNC{S#kIyx9=m;W^Io1dpN6DN^NF!4?6$?C zmzQPSnKm!ht*_l!r`3kLO{dIR+H-=X;lbei*7I`PHW3<`9+>x5s2$ZVUHQ7!{Dm!A z+BR!3p=#TnhHi7FHO>C?c7xxe3AdEB6OP+< zo(aFVxKnUXy4uG0Q{86;w-T~fIk{}rb@aBnzWi+TfbMo}_b+<3c~gZN?b=q}SYxex ze2>OG8?RZtt>>xAO)RF{E@^7oZn}fc_qs#cTw7BY6!+Ft*J#Vh~1@~N^-&TLq zg{><;?S4C8^MEx&*QB>Ud3!~pxHBVfScWgSd#m~8)zy-&MI{s-pZ#fA!NXavH~O6L zoDv^fZGX~clZ0uWOHZ~4nbq-mok2%s|3+O)Z`9#r@9z;q`>gM{&;8n}6^T(^+z=K(hF1>5rv+>1MCJAMtN6(&Ar)YG~ zW3gpz9q;QtJfGqFwQ%;Ehs)h67A{Y_da111-g)iH&5x2UzciXqzn{xP?e>Muv&wdy zw6$H7@A&Z_a;s<+h8`Qzr^U^VoAu7(K)276g35dEnOpl~RGq7;(R#;1=Lg+*6nVhJ zYX89#?Is$Ut@}qmXtL2PMU4(do>T71ygNOb@^D4v7IUmVdKl(>y1nA`jMR}$Jkn3T zb=%)N>x$)9?Qu=H!$OOqo0jjFd)CWNYH@9T!0Kw3zOB0$C;#A;>JfDQ@5`$XG}!1i zX3xzXc^C9IMEIARTUao#OXI#n_FdRt#KSn@tN{EbU{w{^|~J*sSQb#ri8Rv{+8y64?HWxmdvGUCqSI`W${>R4I~*x|mT zQ;f>FMs$$fb;}{EmaiByC8LFd?&AiRg+@h(dY^jlQsC%)#@g;vh)L4sIS2L>Tz?ba z{d-3FbFaeNwDB&u8QUSOd;Bw%P<8#Q5p|Ev>eT<`*j6FB-h=bpPbO6C>EPHiaNeLH zGhfYbeCAGy&a-W8H&&>$yTOs5iPfv+ge*%PaNIe%%Bu-~A9{0Oa=qD8nv6JgenIBF zfWe;RKuaUgT}er z37ws^u{Y*z*FQLZuywhlBjJ5M_$`*z9yxYwp9m|TRqi@VD@NtdUA02_Y}Vpi>z(%c z8{cYXxuUYihpXcb?-_yTB2S;`nj%Z#DneuO~l=aWc*DjOO zr`9f=#gVNBRJgU|!a_yw+h^_#Xz*%jtMaL~mwYQH?Hf4XW$fZN%}msN8jq}=Gb-Hb z^t|py;R#ney-T`#;nDjKugkhL9-i2}NtdLkzB9BHH5V66n`ZiMxN+_4tz#eds1lSB zIpd?_cpbbo2Q8$pKB?R6pu@<&#Z^o@<_!PclEJn3^1Z;m$L6JwIKgPoSS} zyRbd&N5!n#WiVyk(rrd7;_}Z6?LJ=EG^BpuJnhrC;pP!}*(w*=#9Co9-Y=WcQZKJh z&y1R_A`g|x4or61*Gs*&rCk}J8rt5TsBO%b!=qd)bK`+%;mA$Vz(=u?QGvJY9DmwOY}N}$biYds($4c zPdi*qFKyJqr#FUrTA#eXzF&qVY2ZW3-M1DF#Z7GeBFCdfvi50S>il81U(FltsQSBi z-v?&`N0k{B%E51tEdn#Y`{64uYFIgc^W^!WzfXS z&l1brp62sczcHg5=Vtb?=&TLg<>GO=Z}YXU-yYmD^|&dk>H!t>j z8#o1vy+3vP%K`Q3n3Ms-9!$L(zj;@}U5^Pj`}SSi zEqmVhM}6iknmTF3$sHDki@f~IkT>T%T8PZ?RWJ%k=XH47XQ# zUbMq}T>5OJfc5*0+}<3poRHr4k!IzTqlVpDIY%}*^Y^sM8+y7A9DD6n@OPK7Yg(N*?-8PGJ}J|4X#KAL zY&h?$F#0gG`nV0rb}!Da@A2?t#;wNl4Kpq*v+*8nIitL)Q_j>Tfg^1irumsxn3w6O zKlOlJE8PRuU0f?zxalpQRJd(S&t4HpOT2n+ynp*pjV2X*ckfed?H+crRY3jvpUxC~ z?$_k#t-iBr`V1Hmb!A(}CR_c_tY0QPuI-}tkJ-O9e8!E`sXBV3Y0tioR(MWW5||%w zx$M#4t08B~K3E*ve6}k6)>>6t2a|o{oyX1p=g!jXl-@=gu1>1p@T6kQyZ9?ED%6sIP;AATA7t#3WMqm>pKrY;+w z`SJScX+;CgYE6%^^!BxyW_fANAol|kmEUijX|-@f4Z|Z3eg2x=HYZ@r%Fb0P_qR42 zIoVD}6IlONch8Ok$1fUv*Sh1pxMk}LE_v?yIOB4!2VDoX%sO!E_2hAbzBIagb#c=^ zFXm3#cHm*~iH9G*_GsV1Kr!3Vztf3>oBmE7FygH4o{P&II&G*CV0f_Fq3{-kxy{Vf zgT86crR}Nr`ORg6mU(TTzWKb_e7)Hr`M0Wl!p)x?UeT=ZQ#tc5|6Y8aBIuYnx1G4Y zqrJtvW_9$JHZgTiZ8FsD>gCLl4Y%cGl-(Hj*O!8v;2v^C<<{fu43ghm=&4ix)nM1D z({|4vWBJ^tS%>Ix$GHd1VjcLUX$z|i&%%azxnF9>98&fk?Qc+Zpznvw zLAMWfy?JpkkYX z-a9|wWVEqsW{2nt?H?~Xw%m0~;`wW<=e(Pun38_VGU@89 z%&9Y{rapPudCb#UXHQuz&`V3*dM75u@|?#6SL?CIE+1U2a_llcXyd>8XOHc4^31(~ z>K2bqW_s^DX7OlH&jFbe+EiHmxcOr9Ad~uM9^833M>}Sd%x*${*?xC*>cq$TT?TnqfQIwsq@Kp9)@jEXWF)9XRZ4 z*@nSQ>TKHBc4domkMz{`17h1Gjc>48Cw+*UtgOtlXU{Vh)3hdEc2qc|h{=#;OkY-B zwZ!PmSU1&%@v^{?EX5-np^Rclw;CPwID-JzQ2X z#p#K2L87{0b=$sum2*y?tg~xe|4QaQSDU++KhR=l?AFw{7k}A2FPJc*PpjOCckPA_ zX#AjS-))DF=aoO#wd>SIZaKb*vPFH|lLBrIiyAR=N*CLGHq*~+*T#)6nm4CoZeN{n z#i+*LawcVNyteG($R};OUYv1%(e#TA`sNPG->|qK(QVahqnv>!+H6l7oICnm#O5RZ z3b)=B8rzH?yDTJk`rVlID^=AGoj%`jW-ZGFeP_hJ?Gbb8p@CPPpZ=+L=S>?{FuYf= za=T7-^^@A>_VOJSt}JTWBxvu!t;U1CEy`?grbj(t&h#e>~uyO4A+xsWur4P zzAT^eS!d{Oncy{YY=-sVL9nHQOtAjb%2S137m-L@9pHziF!DwuCU^))HWH$^Kl#hw zvf)F8|9`#TbN^3zLy~k3S_to!j#uTK?Gm1IW4~GIb|=@#bA=DtE~%@GuMFv4#*nWGD0Ta>(-c;KsRqK({u1@IJalKnxd92&#roNWAeX+lNngHKk z2#TtuD?4oZrar^pW8nR+?Tp>=Zi`Ct1TyopI>zK!q~b2_UdQ(UVhy!JRAKg zbLqAk#*6Lb@B5yc*=KaMv};b+jN_};ioSCp=v-HQ+g<8MQ$}B$<8*WIT8D{W=UKgd zy>-cwT5n~&kH&PpTm`+3u&okmB#AsPXA--o#vW z%;Y`!tKGg?wEnC&y5{?;8&8KsY^vDHrjo4n%rEIJEa`T~q5oe}Vz1ezx+2mP$MjYFE$7kKZu&0K% z-g(!JobG$M=*HP7{W153t-iPZ%C&V*PIPJ3!fjST&5o8sQnP~VrX0C@a%_^OjB(81 zb?*vgWaRr=zPY*(rQX?YUT()G1~qowUKI2AzFm)s7x$lP@L|(u|;w6%WDKCwFqIamTA|t`=*&f5ZIOL$srE0^YTET`0^EmI{Ni zYSgoSHU3?vRujwBU-!V)D6e*db(DWp%x#)nBSRFR#wu z6SwS69Z!c^X>OzXH+$xGv_s73y!A$|WyVgb(dWyAbq#D9#*Fq0&o&CXI6E=Zr&iqY zIkQr)Eet(-ZODN4JDRTe{K=r1b;E~WW_lfcJYZvmJ|$)hW!U79{qU8a`pJE`ClIS%(i>8w8fNelbWm; zdv8|svL$~xm~L4*GIxVT>?Ak;puOi#I(YPZvhaG}KF0N(axM@4>|4I}lT710 zzX|<^54{tYbHHMyLMSxMuG8n+oBHd^^*fcPA6fUs{xXOE+3`MT_}itk+FlLrXLY{C z*vW_AA3O1ANuP0LtG%t-@#(bnSclE85 zp6D8M_}am+sPDIZm2nMkKD++1pY5rd6Vg)`j9Gal5x$LY(zITC^~H@JZ}(f8c&TaV zu3nn%M*276ANm(~M^;F&zHM~mZKoQ>TTLgJ+<)8Y#`L={hqbTJ=vv0#H_l!?>N8@< zS<`66ec96jqv*En;x?M^UflBG%AJ>P4IZ|2nfk`F_Wd2~ES7mbEO$fJc3DU3M`oS; zCrwiNM)-O^PS&Y1KeDD-NcZskbQ|CKuN|EC_MSS~cg(u!V{UlfHFl34`)Why*Le%4 z-nkPY1id;N+iAva`zncEcR%+$RIR3oc1Ibz#>wq&WXu?#QcZ8x07eKqLr3VDW{)3M z|3=80~l zHAwv7ds0sLPO!L-pu2t%DVsa?aB0R zS6hu8xaxX(W1C@Lntu86&yd@7;%cN+Prvk{&fRTy6KY?cudt! z)G!Cac$24ion6;q{>f2RKFFn69z5*Q_bxEtVg77Hmt_n<%t8UKEf@n1F^IU)LP!DR z@lentkc#VAR5epwSDF(h3y()AYMLE)B2kH%qTOl5Jxp3bO%#(u(bD|bt{Vsd01UcBHmudYfKbEzEz1-tEWGPz-X2bvSmsE zzW}TNw*XC;L}77(Fk7NTO2ANs@uEnFvLm`jOCqIa1Ma1ej-%Zpd2#9pYBhpQskK<- z2e_BEeIq|Y^n!*DLn_7ztT>Ovu5_bUROWNbV@0>b0xSLs$bbr2!?->6W zT3lzuxW0bsT#W0+bAFWJWn*y%#JFnwMgp)A1x(Kt7D)s~h}Vrj5JX0eHC^^>y}0>m zS4$rFbxInw;W+ErvLesn5y_3;;8xY{O+u~JtF^^-^V~L?Z4!2wAie^pD~nR1Z58I} zlc2F#Z5#VkUPXmp<|e0o(8+vx8bsy=q}4b6XGnIe>&C^Zr9_{sbjg^euQL>m+}P@e(6%zjh8;{L%?<8-0qb-i}{Bz?GZ`);L?8yyP`msL$hP0 zV=ma(kUi@|d8oZp+6RGXNrBEqozzU8+AOPLt(CzBz4vyT;>0fbl6s^G-jZ+UWZKBV zgI!VsBL+pe9u)6MsdR~=r=1Uq_oVCjd`mhKOek_ra^f-Re7mL+JS1I@=WANAtDxg4 z@t92Lc22w{-H`1f@MNW97qrf$ra;uBLfa;_1R%BADZ6-}ITI?obewHw3f|~YBDH@+ zUgpOF$pEn^Xt-vHF@jHWW_aEFGcu(iOs&8N1FW@yW1jRzg;`FHIot1dHenx}V7?@2 z5SiDR9JMJtOcWU(YFjuMF_hXD?j=NmG_7l>VLU}0DMS;@C`y{;&?1o|+YxZFg+yVJ z8v7i>?7Am8ce9MP&y!4gA|+56vNX`TNhe@=>LwhGiz4)a7;IJCebc5&nD616 zNZ50Y>-n4xkXC6V{4h}|o=~Jhnbf&jfrB&>+RT)Z4;7zX>V!8^qEvR*GAG=*QMY}; zwgvk(0{-kJJVP~B2JvVkRrKd7kbR;b_3@u7ttx#HsRUx@K+^7rC#R*M$v9#A_KRS4 z${ui&BIRd9G))w^YXW|xT>gdM;x1qxYi?lI$Y*JHR2hZ4=3)*H1;46>{M-oH^pH(E zaAs&Ba;p7pkk|3lm{IB&(?}fIxVtCPWQawGsiFbgOxtal$1qa^9|ngRZg+3u+7&_2 zQcTwx&kZFZRD?rSv|Y1JJ<%+OOacirF6k8m6mMn0>O@5XzOcSm%ZtaEMFr!5G9OI$ z0zsD!14{#mS6m;f1HBf@SD|}-U@OLp(0v&`R!ir(K9{b5?J@Sb3S^a-$~G144o{*< zAnxu1n{}ktH3AcYd{mDh1Rx-w0wFo_0ftQxUW`(_1f-%ZnicEN#(HPi<|-I*yohka za4!qNKWBlKKG6X#TH6{1E1F>oxXk9E0h(B2F)HqP%dK;N@r*juC@8fr{a}Rx)fE61 z>XS>rluk?bvZk^z1IegJm>XUcE`-8UUFx;tiP#@Cd7hx^{5 zwl>yqD|suz8zW*Y>HZzq-v@}V<6Xp8Cb3_ZkKJE7Z5J!$Y1=z}oEmz->3}X$W_lX> zR4A$Ff@Y=c0|(NIZiqGrk;LP|&z$Zy>5|d;!r#~+g3}p&qS$ozPMogji}KwS+Fc2| zlNY_Duxd$+J5EZ>_=oay0 zN%yETOg#7lKX<$SZ^l;^y~}QG@3bnb95n~p zW)tyRjD%8C-9MPug)pw5YUbSi?=ETqFQ-hjyUX$&ij*B35t>boOMyh$rlj57RK*XT z1#`+O{?Lga?j4crSo{bunMdA*#pZKMVCUnfB_e0t)d??$Z5`=o0H^?EqymHj#0^D-0-fB*$Ab*A$=)di zH~>5VIsml0g*%-Q9)6oL^bdPS;zI+H82Yy0bF-j0&?@3+`=Gs2hh3J$15#R$?5-tA zG~M*JO>B$U?+Bu~rVLbsSee3ONY0kO?PS@~=cEV)rrKfG!HU{~pdKXH2H6-sg;xMM zoCy$!R22;;RvT)&V~EFVa1SIC8>a`7_Cn3(Y}vBQ`Iv0PNTRUqIfk&?-4XwS0Ro*X z(AYlMt{2C}vQ@KAqSALs9!oU<@!u#0&yrpy+`Gw!3|1b!EL&oLbmFIm+gX zxMGyg`142CUn&7eiqkcxV-v<*DfPq8tgdXQQ?o?_m5{Q#5z|_hr!r!jWCQplFClqT zj0;W`z)E?rTDu*ByK}C;%?GYO4f*!m{F{8^vhrd&m7bb~-F2Eys9SH_z_x;Ijt2lH zi}56c(wYq%;kFQ@xGSc1k^v~SFa2QN1cf00=Ka}8fEZFb+CBm~DjeadFNHyOgb!*b zbTERaaqDH9AD!oJe4y0!iM4J_Xv?oMMUFyh_WjSR`J~%7`SMcV$9}(GsP;c;gb=xt z495Vz0Kx!CZ$jfh?_RMbX7}D67O_6Xohm`w&)PFJu+FGVueT$ANG=o*vl|RqGhz=fh4H8B5TMjvOb?PZ<;d#pdAe+#ekvBzj zNG6M-K3q>v0LUd&*GzNdX}3qDlkGpBBkLk_6-9M>({S%)3x$k2>(0zhm>I~7Vg=W> zVWyJpCEo&+CNJDs%s9(9ILkZT#m>1i|Mkvux>`nWmfKpks^#d2*_>6hA@ zA-#;aQ}Vi=RIxo}6zfwRA3wem{!_>5$;p!LWVIZlGC+=F7u&tp#QL;{@|#G^x~FGO z;*YUTXUC6OtZ45IB`>RvMQ&hI=8 z<)2@{T&2l1xxUzYM%#u1*thMqyO~-1*dKGqf|i-FFQ-W~TLQxvL7`Dl4B(1XWP>*X+8IJeKPdZ5paA@l;1i*T7bF}S z0*h1z>Nx@qiNYhF(Qr8AYY~LO zU@F`3(v9BtlQ>Wg$wt`vQ1G}fmgo>xxh?1`Nm$d`tF#aaa3XFRICk*h7{Deh?nT>{wOJj`Q~ zPQKa&-gcrh<+p-BU|3~?k=%eF&fTn{5g(K1*+DBC5qT>2gq(g7q`1;L^=i{SyktVZBvI^2y+=8g;Fe~bwr z258;$k2wSY5sG3Q_$p()69WNjGWhs6**m2z051S80GFK)a4!AXG_SN3$%MGvc2^;e z{5$;o*DmmawGIIwcGvI)i{0_I5p0WW*8+|+`}Kz$ta*t&lHeN>&NK~*#5d8IjFy6|{}qNeF}ClZyI zDe9dvx`;_FsEJ~BC|a5Z4hH}L3`OGyi7^D2mQlXd=y8V^?IZ&zwJ-f(Km?5)0JgNe zN|4%72aII(&g-q8A09w3y6aN08Rwq26A4dlH^Rx=^fK=6TJreH9Y|K ztAIgL?*@oa@*?wvO(6-(nTX(JwC}8$vo~pXe$vFu5?}J|uKlOvr#Ch2peX?33Ft8r z=Sv6Bk4```fQqay&*7xPngW_oe1Y+_!b?)82MH}dI;9}bRg8}FH^Socw`4E*#Uos_ zUypQfWi|BGt?wtok~pCJeRY#dml&oWl-sf==iHX*_v9_}?vB#k7`op~-Ht>^cR)y^ z9R&6(`+LF{C!GN-`h623Aw zE)aRTjXIl6xUfNO0lnl*#PQn}%v%)?Y2?EITrSbOLE#0@7j;x7n0{|jJl1x*5Fe5h zHo>bIkggH27q(}4?MLn1c-nu|n+xObCMvS-t39swyte;e@?dhpKYRPLFg>dqFh|HG3NZLn+=c21e?td|`X>2B~J?7dGlD_P2c%(bBGUq)O0Xzy7fxU1z+u6xXZd z*z~lw>yRxgd;BJ5j~~L65SC0=;qT#*Ip<8$a0whg?SHD*W9f6-1Yi8hA_mvLu)A-R z8QD9Q`;-fwEfYo#)FIUnlp>WuDbfRVNWXO$?4&*mbQ0v)az3_ya*ooR2lWUw%H@R6 z4MQAk?Ng)i1USQS1+*G>>r9(4YT&;O_tjbcyr}`w~s&h`6(tasW;JegLWnvg0A28 z57_T*2qgc0>7;z}Pb@vFrJ$Aa-AMC7HwIIvVHk-?V+4%UNFc$C#4Q|P0vS1W9uQEd z#w5cU4L})v)MGC>(z{F`z$4m2u8cjFMss8U78LiW-|Y zvmNBP9F5!|$jS7Ze=t^nsrBJTBmURr_h~shM=7k(|7=E@+(`x+0Sy5U0bp%VtIm_n z9VRhM=HcC#hy3DQ_+W%~Nu;!GJ7gI)o@rGAa7yca+lzl;I6hEfkF_S%ue@|GFPMj4 zeatfWS-$05F6Ch{3Y(P?3qjkmNeOd8Z7m6ywR$t#MzVvL>4wtSltP4*C+cEb8O~7>A;DI7yV`t|M zV#*|l*w}&m0}wU?$amwqs}HzkLkWPeEngCz>f5KkUSV0+#{|dw)03!E))j{17ighv zTfSXkV&~zRIm*mv%t2xmK0WIu$V!HU+OAz_2ko=n=)8Ljbl=R#rF$=+{uQWJJDHj3 zc}ccywJ7lMR5-C`F@9g)8;pc;cFQXn5o&w)IGT0ajGttNr^;Q%JiKf)ygZ;-L^O2j zSty8jwlmP9e}K!Kf39}+xtg`JkS_;?ms!3H9A5sdm)GHC-|%t^FJIy18|dkm8w;Lo z`(w|Yc5Z!Ja_TSltNGRbwV&-j=HId5*S*c{eq~f3wCxbEVjd+v9e>Rp)e6V6x+KnA zQO*>tNLAt~4~uqcqI^8Z{EQXzG|VwCb2Kkga>mTkh7x;!#>}!v92plplz{hfWL!X5 zxHl_bt0UTq!I&c_$(;gaN_`K<{F~J;2R1*=1q}CI16m2)O7oA^p|)uL8hB*VIln&K z`*FbjnH!yJ1AEQE1*Oh``q$?|n?eohs|9s$;cAi+oYGHpd zoDUmAp4QFtE;vDi_wMnqEjWE`+qS-dN1SS97;07jLR63T%DBqUN2jAOE?3W`Zed8A@i9g&dh z)TNS8$fxGg6f2d4YAC2G7QW`vWeF3Il1mXJKsX{!B`-4_Q6-yIORD2kv-xyfp@bsx zQq)p;Y$jVUEk_)umdzH-WQOC?X{l^FCZm>5N2Bvywl+Hl>TIn!LYAmMcL8*HdO%|T z^w-xss8@s?YAm|EG+dFr~qn&KL3<7}7s9`k79Abtx?v*-Bb_-yO>j|m*ek`rZ*@D&e8Af5BA z6R9^k+^KdZXzu_3WH1AGVuTRe!c@rqP2z;6?g zG&UDb{R5OGK+@RU?I0Dp7Hs!IhTD~Z5FdGh(8kuHULTp)d6OKp4YO-d>H5qNRBgy}QM9ceGo$CGQXQ?_^8~*yrvx z;c!m4IfqGTe^Ua5t8AV1C!iE{@^yG((0{n@X8JiPyv>mV(^J@U*9{Ohx@75{&XI0S z%%{7pd`;uIIcEv&e;lp|z#W;At#J=OlV?iaVz zi@QJ+)RR+Fk!i`L?g5<78_DOqk6h2&$mzU`h`5Pf+(R#JAtG)7K)8cm+(0jGq7e6x zi2HqU3t!ys5O?s!-M+Zl$GyI||HX}kxIMwwdE#*JC1)Rh0&^c5CW-U8>$%Ul)A`!% zY0$Lyxt~+pw`qf%g+P^VOqI;myjILM&Y&ns@>A7&JyZg#>ef?6&(?alcAf_#jFWLQ z{-%dl=EYf65IbI(7dpm>@oKATv5yhs1$6^XS~s$9HWW_a@3-eMqcEjlFDvj#H?eQF z=eh5&W5(Uan>H8B z@PmKOwW_naJ!cb z8nBl&TLbKyy?$@#mV;}ANpsE(aIk|$Uyq(~sNThK^!b-&edprE0QkS#!w2kT>leem z*{(NVi~pZh8*5VZ_=9AeP&WFvbY)tmeYj5GMekOwykVnLsNEo3PU8g+#IcD*rLbq% zKI-2O&)Bp}FRq z^BT1jM1;p7(V|V%3)?nPCQ!wqS-$i_VjYj|RhQTC$To{9EM#&;a@nO^am?CEb}hY( zUdyBkY|snUh!6CyHhkg_#hlPQPVaNWKYFKsEMszhPJ}=) zd;@lTI&}jSHof!lX_^kGQZtw_LUDK0=vAd~fp0(fOqc#`nrq1dI9EpbrSYcQC`f>=6Ur)(A&*{7J@$*)g2t(oJ?B0`7aQsTyNw)RU1H8un?>UbBpkTy&`@pkSh_)|b8G$rv- z2M>moISV^x1Fi;k%}cH{d0P)%K>Pz~3khIzDpG^(HWMC8)mHZ!Lm8F1SLmtW6`8p3 z`M9JN`2M5e<5~4(f(s2rQh&}Ze`XSO6{-wPGvw45XUwk{CK5o5+)T3W14A&{pTm0$ zTpGkhe1@i%iXqgg<~%j|xBe6B&e5qTwJ-f(;|Yy40NPk|6GmW~QU?#pzE3qz>6r## zY<~U^rr{;l&Q}s#Fvi=FAHEi%-0~S1_)zW~-XDC-9C+AV7z1pNA53IZqM%LfMzWji zon%S@BLNrzBLQ>WZ@=&=?O1l+)~My2-_9bNt2>}YiN!AW!msoh;`7JM4GEyLZNja* z=zg93?yUAVkLx!m3EXncIgD9G7@(06uCqZ>l)BxnaBe<-aLfe)<_tA*wm$@+Dd9C| z%W^7Ma)HsD^HFbbo%P%kWTw>Ep-UgiInGElXXsH&aGmuiE+wm%AES%;3@}#*#LAkS zp$!`9Ktg9-FAAM~A?@7`4h{~wo3pnNFP-@24Bb}9u8)`PT272}rxDf$O^+I8{&voe zww#w~@cgA3>6QZc4x!o2P9wBqqh(yc`uj_&{yc;`X zT`Le6AAUY{3^vAv-|ajE9O>5>nd5dT=iK;ftcJIacQ>`WU33qZ0l5b_oqV-#4elSU zyBWAk{p!iIbC<7&$2pL52{q$44c)?z*4}?g`h@fc>2^Q&1YY$n@;&dP^LZ1wpZ5?E zw~*2K+za@g`v8Z!3uxQ`Tx=te-1u?3f*)+!P@<8ub8t)To_YrR!03lCv)L_ANfG@-FRouGa?n`;zDPCGU*Mb=J!r zRxt}IVeDS2{0@uwEDmuaL*Y6b6sOd7K~!bDYhyL%_%5Y&f?NbM8 zE}mOL6Fdgp7SGC_2F-;44!$)Ax! z4bPZAwc~rV=)LNA+DaFsDzeQ`>(We~2I~OYpB1tKTG6*p)B{~C+pmPqvhQGK|NiT{ z7ZcYzPl*5Dy_9Ty{tr1rlKNO#Cm=&b)yT9o+#Qpgp@CU)xB^is$b zM<#aa$n;F!;&$@Bn%gQFkhlTvDJry~|fs}@QYNK;l; zDv+9>R{S(mQVE4*g^Y4if?W z9V~_l4QJW4Ulxc*6NV3#N)mvtX5;K{ z&NLn}!H3nyxHS@Y1!Fh1Dtw2S1pT&B!O(j-f^EtLJ<C5ajy5r7z`t=az&#P(!=W|#LgySyd-%pMJhZHty#D=$rg_SKe@CMw5AL;Ts= z>52WCe7VwgbVIlg#9iLe+q)dh#hlE|EYHYGnXFq~0<0=1msF|M$pg(8EnpF)TEnP0 ztM#mdAi`)Zm0%j^jvCGB;a<{zDPc&7vPoO5$qRHxUwuY*qIS)OaP1QNwSdM%TdmF* zN0$PfQ4Ue(-S6`1WVwBs z8F*+)82@BYO1TgaS{o9+XR>)E$>gA$Q&|*hUQno|h5soB5HTg&_e&>ExWtQEOf1@=|`0 zzI!XX|1Qu80X!&C*Km=vYzMQ})qKC!X{>uVd{F^JH-n2TDYUQMwiGY795Ng+Ao@CNMl0u5OmDKbTfC?g%0T078?C92j2Qk zqnpT%S+=^a5x;jc*np3`b(4u1Y2&^>=ID~^&MpUU6Y6TM2kh;nVIJtnh;&r*%-D6& zF&p+qWJNJ+H6FRA^Ey2CWJec-EIu*|cl2fcrkIiQ?9IGr%*wNJo^@_V;05@I$ZoEi6-lHC`(RouaZ&8nzsK-0RyuTn`p&YLd< z=f=C^@#=cKxgTEKjTi0l-d^V0Jl^lP!Rh)^I-=Gmd+<~>6phN`{9pbs|CqlFo18rn zpR=Q~WJaxH$)g&zYez+*_W2>w$JsQWQA}tBC7ZTdYm8a|^imkx8Ix&AfYeJlux%bE z4PJtpxkqg@<*0eAz)dL(JTO|0q5+X1xT7ih$R!SWKi*Bfi`bR8IJ=EwLSJK$k zi^qoix~X}#c4o4~fsb%O4HBSc{wlt>XgTUA6O7>nAq%M4h3D4mZtAX2;e@)^g^msW znS)7{(CD8znbZa3ZptKmfsYhw;IYXVmuFMwFmj&%R%@+4&HO#3oZ;cJFK_DI^hpW>ABm%H#mTZ+$C-4()6q>3(9urKGvg8lA76tJ zFed^xTz9@kscdYInz3v5#QU^#nMOfV*lOeYdbhc2hf^@(thLVI-0GUSQ1|uCp7x?H zBYrrCb*&BI>#sS`iP!mcgX80OQ?ir_AL;As5j)bxZ5q?_;*Fasxn^z=4@#}@R~DUg z1|C8E)I2jf0o1IN@=Er4*8)zWwFm6(6(cF(iCJrnN^9V*)P|!h*0}DZm%{xtP#2)& zSY<1{;b5eGy1SY)j&`quyd1OedUpq>Af<~s*BxH(md7edV@sUvP4Wd?oj1Rl@0Maq ztkdBw`6i00w~+fj_K- zSHWNqU;;!YV6ZslLn!1bi)wwSf>=YVA3|UP#2{8y@oLHkkctUtH3g&y3}OwdfW#>v zL?+-38Nydh1+j|69zApmmNL3_45sN|*pt7uf5I{nfl~4!)HEi^-fdC0mL8>ev zKCFaLSi~%-7{#g)dh|fA9;6yt-HKC8WfklnL1GiHg1t2iuo0XppvH`+-&K&;#}iht zm^H+Lx+)fdK#3p}^4qDZp%AJV4B}&$0o2v77=##n0BZPSD5Qc4Rtj6-the`I9i~x-xn>N=gHf70d;iVFUD1zYw4Y=w3TwanS;F zZpoEoYA>4xBgS1cQ|FdlHqAxDXr3+c%@K?{b(d4G=wB3F;Gn=cY?=fsT7j!j2F0l#r?<+`c=_Gv$BA*LzR^Ec zx%sfXfr*&%g+z!+P0rV@TS7%6wFzUK*m_d$*_N=)k;7TiG6m4cN$L~9Sdw}N##e+% zWh#1ChO6VOJ{S+6b7l$fQ6n_~$P@`589?*wh#lKVC4ok$fgt9XV}?dVM1mwqk`D0% zgdk|8JP#2NwPeoBNRomS>NAW1K>$`=h?FDM-e(X{8~g{VyxA<#tX8AIMPrV_B<=o0Ih!zjQ zW}f>g;?3GH0FI1OrcOX9AcqhSzTYvNhMI2DvPogwZUg-|(!0AE5K^Xn5^tk&h}OTV z*43WWK~6ZoD1lnMg_MNrZ)M3f-&2QfsjIA9zDaY={Myd^J48b55Skwy_?C-~5D3p4 zSdX*zUvwD~y0C)EC;pZeGl9M5d0FbY=ma|rr0#u31XQA$^*X?yF&vI$1Ki5RXzF6J zpSuBOCESuilMhP*ked{p7PjB9M;oUXPk0G3@*!B;yecMj<)I z)c!4m7*{NwV0&E^?9q)Wpv~%35FzpFWz8u?q(HPClwe~f(?r9!LBHc}bheK)h#VmHG(GG1kL{_? zml6PgH^pORfxs^#W}(RfTb;3AnxhOVVncH8cvE^nh!xwynB%-GSDzv-geuSh~0gs4jX(+WX{a|Pf9Yp|2 zb<7z*Kw?fh>&^Vik-a2VA}1IQe@^eCFK8_hx;FpYV(%R8DwEHD!Ca837e=78V5vIN zBeq+1Jkw0g%*-0Gawi#z0d)a~0f<2wC9X)GeJTQIB#IVofBfO${f+Tcnil&p^J(qP z;ZWblflAf6r6NR-9JXz%B6&7yJoNZBJFbS$=D7xrm$q%0XPKEQA^tdpV^^IneIw#_}={+JxLtsaB3JmO|{ zFf-4xOlBuRtzYJg`55Z;cwDM&*Bt3 zv29xiErriFiOFZ=;^N}slWlu8veYjzDJ40Pn#`p#i9E8#hTbQYPv#t!^jRCy<4a0d z;LdbMhRRhkI@g%s`Ss0eyh79i<$Rdjq$YRXCP!NG=C5x`0FPW|9bA$xkz8q1aOjul z*Eb}_CO0c<&+;aBlL!3U{_qUZ!6iA8kIo@Jko-1kmo*~O+^jf%%fFWZo_ zYg}T9dne-#HCo|`3-jyS664a7KxR(nQCZ%m-240!iJ@&fV_m-xU~VKUHcd@i+uZd>s8%a{p-b{R4A*8gx|vTa)ld_PnvE|OJv9M8U? z?)s|TGFw;W+TKR2cXmGXLnORy{j=@(016ZPxb2vkm$R6cBVawaav-(3-dVv7&sG0B zQ%!yEEcL!~)X|)yzidExxxg<&IWH4nULL@_EWmj=fbuc`=H;j6WvAukrsZWOq|4Cj z{Y%WtNzKd77{$_@X&zwh7s(fo;y4>O;hxDf%|qvzKbF7NDkxoTS|Z_ySA5jecR4~|_9 zpU&?*k5cf6Af7Nct>nERo-ieL>fA`8g}k>@=f;gB1Lv3-+ar1{T$vmkmBa#eTE_dp zvClC(zO_oU%^%Df%#+j)g!b(`S{3Ya)uu0?9pbL9deO|FtS?yTuqHKBmsir+>}4Ze z(3#z&YGxxL-X6=A0f=~&>hCSBqE+Z|s;!zmqsHZcpleIWzy5$%Mwz=2`izdljh~T5 zR4~*q$2lKe<>+1Tspjv=py8e^LVwMr?fK;puWjKE1W=MihuRbVQRG~aLj`Nws-4Y4 zQteL=oV}i@{`JuWb$|Ti4#6m?`j#;h2&&F7+19(cD&Uig=mOLgUiYrFI9I)mKs+(W z1V12xtRdq2(_D(LZVVyY<_Ia^^4o|YanHu=kF&0_vbh9vq5A_(uWj3_i{xWlS$ZWP zw9BZeZP4{>ewnlx7ApIEPB+@jDOB9EDf`~dp>>s?=25x2F>G7;a}@hQ-#B?zpbH+= zZTI_=FYis7-)fmWCeYvP7;O!MXqVA}6rzjX+lZqYL-odm@q%aU2mL+9nhi1{c_uRBWtF znguqcv9-m1-NwPDG@8uCWvmEUQx_1huB@KZt}rkob6JT^$;!gSq&CRNVn|STUSVHd(rJyb7}6*+>s4>}g|OOatarA=frA{qF|{4{ zxq&G+2@eAeb<^zfl-jDCgT#r|Y(!e{s;Vx~&qvfMSB?We6le=T#?V#u4gX$TTwF}T z>Kj%y){&0g6a*KlnWk&n)K;c$Ir1Gs^+Meez?$QD7Rs8a+O6G_rV+)ZgT8UN2tl?TuuGn$)QMu=Bc!sY zs2V^+^OzaDZXEalK!cD1vq#ncW44v6S1yl~R?WubR7*MN|53Grz8c=yow`ElQ%kk9 z*)%mSH;4%q$)~=6!ilMy8o4%usik*))x{oBPY_sE2t+j(pQsyevfPyx;00(cv--t z#~UVeHxY_O=3A>&aqV{RHE@v&h;l#z)#FD4+UvD)Cq*B#7SgG6@1a@+mX*x*j(Z(0 zZng*6OK{0N?UQCzIceN5M`52i2W2Rc3~T12p^;7a7OD{=ewyq1A~`PyE1*8w^*1;*7NX^vPBvNP?(wXPQ z*;0G{E)Re3s?r6~SdzJcBB9XE7(R6hOF^7DnM6Y9f*nb)ZKBo%V#Ed&yej&UY1qKA zBkDfJ5rRcr)q_n<@xH-S9AoF{#-Rr#G#_Vk=EFre)O^0hma4mWzJONBh~fZeoL}t$&2eLS_Znh`}W2xgn7h3~^we5Ghj%FaR(B zFaQi20~P$X3i<=#>YKppyCrzMyb3~%%@YGsbJ^7uwp0T?b583<$Z>PG4Pm>%c1u$M zcwFgCNOBzK8h1`6T(uPa|S33z012S z2N8$1E813dzE4r1X=#pql#eQ(#2G2Q>ztqJockV#bg*{%vU^}QG64=PoVpL?ouuje zL~>$eVPJ`pHZ*9cs;Ysd-zyI;(7hh>THi9UdMv5Mkvb%)m!zg6^>supts4rg)T$%6rg{;v4AI*1SB)2CM|W^V8A(%@d_LZA z;#esRbn(CUR0a7`{4AS2LV~88O45JsqV0M*GNO{CskQoC^iX-R7T!*>O}nQTwA8*; z=Fov2Dz+w+p40AZd$?B)L%9c}!hj!+mBT>p0VZMh;oA}>+$qm?+=E?_X`*f3m7?^u z=!(wq;Oz>fU9g=;C(g)r%biHJnr&bG0?`2*V`cP}MkX?2o`mA!;H-sq+w?`&U?b9& z^r8)JZVYo}yYuF%i-vy<$<_kZVL;(wT4)#6TI)#L|6bcsH}<)?w7nCNkgE#KdWkvW zLyYYhfXgKsUVzSJ{<5njcziWD z|H?7EKP(FY=T~L|$noBsC-{*N4l%+D6(c0by8S84>dTWu-3A4RZHUxtfvo^qIwO41 zMn+shDpj`h=)|C+5aL_iSuaEgq&$s5jh~xDh>RVp8F=@Duzp_h^MCM9Kv)@FcA48| zHk8BO>-G-BX(+WX{a^slKrg?N3tc||YHmarKtNX>p>cmjEv$a9lwi~V3$0jF1DGO7R?meAh`L6|+Vbwrv*HuQ zuTRe`YcKur1NXM+%ez-<#TANQZ{}x!u(OK{dAb?c!*k^gqkE+gSo){o*W#UqUt0^G ziG_uQg)iQFHd^PKn3Bk)qfsfTNF1(eE3K2SbSCyDDrjwIQkmG!6#5kUre00cKtD}J zk5rdpW26Tn*-0-4m139FBsF({K83ca70Spp`5l`*sy)YsFM}B}(a#}bjZ#?9pj=5^ z5{VS|DKv_DfRUKq0i!l4N)Ebai&N+mze~wMome8V!_(9n8KQy~{ZQ?z>cG#JCr)c{ z{20%MSQU9jrbgX+%g%(@{u9cTYE>Jaw97%Ys84&U2>RV^lCv>ui5>2}Y>%9wot@77 zFJ>NNR)PkEEEK8()cy7|A(%leO5Pg2o9gHWg;+-nz#i{+ECTfLPS>JX#_R%yec5}< zjjW&iK=5~ef(x8p`-r7uw%_>Aaz$k$GwI(uSVwL1xDTR!#o>h;_Ai^Mg%|L@;KKR1^2=bq* zdbv_7P_QD``7moLZG1k}T`Tu^sAI^)+fAXW}Q#L;R+0#sG z(uE6=lqO)F>|`+@8=vlEG5stWct2(%=Qtfc-}{JL?8w}Ejd$#PsnnPH=TCYu706PLr`ZJo|3h%;5Me=o51Nu4%P^L4WXfVJ#R?^#!@Ck!B-tQY1NOM~14O zSJe-^^2X9*;*H(ia0P{v#44 zPQ39LeihKnCQ#UyP4%a^4e2LC!6_Q{8#4>&4yN zA%ef77yOk)dG;+prb-yK-&723f6AQVic}Qu6@tZ2bYcbEkKtF_RMEU=UxtDUUCbL( zF;=gs7~RFZF{QP7O=&fk4lNw27t?Az#aOdPZSaV;KDHVn?<`+e+m^hNUEO)*+wa3mx#7K0ZlKQ zGdr)?DPLP}%uK_&IkRB6;EY-+&Mn0PJ)%#Rnr*|6BwA`?AX%5OxWHq7&p*X&`lz)y zJ_gLR8A|?Dd*<#S`;GYK@YqU1IzTwP)+~xRwk-n)D-R^TB`-r`f6mFpsyV$Fdl?-P zhlbOn0i$+Qd!hu@#6D$%C)+I9O0A4Um&f_Vrl}C2)EaIC4V9#Nq566bo@}T-Sr^p~ zTp?TB6g|(gH)(rHcMg|r=jaBP0f6SHQ7q;dLyFNzP>>`^h68W{k)gBI0TN*4L9H20 zS}yH>1}{@F_dL8m0Ho7R=@sUZzBn>$3m@8z&x1$Kb_xt~RtyEab1VmR@S$?h?%*~c z8}bm1+WgC&`F;|bbL|me5wW#ppcIZ&!4TeqQ1~440ymL|jEh=<$VSKrr^ZWJ;+??P z8x^@6_xAZFQ7ZQE7B!3j?2nn>9w}0a*)RC1Jk=b$QdEIjjV~rc3TVy4$5V|7D~?{i zW0cHA3@$fRUABh#w;GwGT2!u6hSt}2Ht57ZgAqM3&sWn`#> s6Y|1i%^I0}mv&xDMXF^|Vy*<+!PX&&cDJKBv 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

0D4cFDt&AJjE0W@;<+P@7T2A{a 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 OLGBNp@ypMwSkX*Rx=-PjPr-(Hw~xX{l-1nJ~1d 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 z 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 1 else 8080 + +results = [] + + +def check(name, cond): + print(f"{'ok ' if cond else 'FAIL'} {name}") + results.append(cond) + return cond + + +def connect(timeout=3): + for attempt in range(20): + try: + s = socket.create_connection(("127.0.0.1", PORT)) + break + except OSError: + if attempt == 19: + raise + time.sleep(0.05) + s.settimeout(timeout) + return s + + +def read_all(s): + """Everything until the peer closes, or a timeout: (bytes, closed).""" + buf = b"" + try: + while True: + c = s.recv(65536) + if not c: + return buf, True + buf += c + except socket.timeout: + return buf, False + + +def exchange(raw, timeout=3): + """Send raw bytes, read until close or timeout.""" + s = connect(timeout) + s.sendall(raw) + data, closed = read_all(s) + s.close() + return data, closed + + +def split_responses(data): + """The responses in a byte stream, as (status, headers, body) triples; the head is parsed + strictly so a malformed head shows up as a failure, not as a guess.""" + out = [] + while data: + if b"\r\n\r\n" not in data: + out.append(("MALFORMED", {}, data)) + break + head, _, rest = data.partition(b"\r\n\r\n") + lines = head.split(b"\r\n") + parts = lines[0].split(b" ", 2) + status = int(parts[1]) if parts[0] == b"HTTP/1.1" and len(parts) >= 2 and parts[1].isdigit() else "MALFORMED" + headers = {} + for line in lines[1:]: + k, sep, v = line.partition(b": ") + if not sep: + status = "MALFORMED" + headers[k.decode(errors="replace").lower()] = v.decode(errors="replace") + if "transfer-encoding" in headers: + body, rest = dechunk(rest) + else: + n = int(headers.get("content-length", "0")) + body, rest = rest[:n], rest[n:] + out.append((status, headers, body)) + data = rest + return out + + +def dechunk(raw): + out = b"" + while True: + line, _, raw = raw.partition(b"\r\n") + n = int(line.split(b";")[0], 16) + if n == 0: + _, _, raw = raw.partition(b"\r\n") # the empty trailer section + return out, raw + out += raw[:n] + raw = raw[n + 2:] + + +def one(raw, timeout=3): + """One request: its first response and whether the connection closed after the stream.""" + data, closed = exchange(raw, timeout) + rs = split_responses(data) + return (rs[0] if rs else ("NONE", {}, b"")), closed, len(rs) + + +SMUGGLE = b"GET /health HTTP/1.1\r\nHost: x\r\n\r\n" + +# ── request framing the engine must refuse (400 and close), each one a smuggling vector ────── +for name, head in [ + ("Content-Length with a sign", b"Content-Length: +5\r\n"), + ("Content-Length in hex", b"Content-Length: 0x5\r\n"), + ("Content-Length with trailing junk", b"Content-Length: 5abc\r\n"), + ("Content-Length as a list", b"Content-Length: 5, 5\r\n"), + ("Content-Length past 64 bits", b"Content-Length: 18446744073709551621\r\n"), + ("Content-Length empty", b"Content-Length: \r\n"), + ("two Content-Length that disagree", b"Content-Length: 5\r\nContent-Length: 0\r\n"), + ("Transfer-Encoding and Content-Length", b"Transfer-Encoding: chunked\r\nContent-Length: 5\r\n"), + ("TE.TE: chunked then identity", b"Transfer-Encoding: chunked\r\nTransfer-Encoding: identity\r\n"), + ("an obs-folded Content-Length", b"Content-Length:\r\n 5\r\n"), + ("an obs-folded Transfer-Encoding", b"Transfer-Encoding:\r\n chunked\r\n"), +]: + (st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\n" + head + b"\r\nAAAAA" + SMUGGLE) + check(f"{name} -> 400 and close, nothing smuggled", st == 400 and closed and n == 1) + +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: gzip\r\n\r\nAAAAA" + SMUGGLE) +check("an unknown transfer coding -> 501 and close", st == 501 and closed and n == 1) +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked, gzip\r\n\r\nAAAAA" + SMUGGLE) +check("chunked not the last coding -> 501 and close, nothing smuggled", st == 501 and closed and n == 1) +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\nContent-Length: 5\r\n\r\nhello") +check("two Content-Length that agree -> accepted", st == 200 and body == b"hello") + +# ── Host ───────────────────────────────────────────────────────────────────────────────────── +(st, hd, body), closed, n = one(b"GET /health HTTP/1.1\r\n\r\n") +check("HTTP/1.1 without Host -> 400", st == 400 and closed) +(st, hd, body), closed, n = one(b"GET /health HTTP/1.1\r\nHost: a\r\nHost: b\r\n\r\n") +check("two Host lines -> 400", st == 400 and closed) +(st, hd, body), closed, n = one(b"GET /health HTTP/1.0\r\n\r\n") +check("HTTP/1.0 without Host -> served", st == 200 and body == b"ok") +(st, hd, body), closed, n = one(b"GET http://127.0.0.1:%d/health HTTP/1.1\r\nHost: x\r\n\r\n" % PORT) +check("absolute-form target -> routed by its path", st == 200 and body == b"ok") +(st, hd, body), closed, n = one(b"GET http://x HTTP/1.1\r\nHost: x\r\n\r\n") +check("absolute-form target with no path -> '/'", st == 200 and b"hello" in body) + +# ── Connection: every line counts, close wins ──────────────────────────────────────────────── +data, closed = exchange(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\nConnection: keep-alive\r\n\r\n" + SMUGGLE) +rs = split_responses(data) +check("Connection: close on an earlier line wins -> one reply, closed", + len(rs) == 1 and rs[0][1].get("connection") == "close" and closed) + +# ── chunked bodies ─────────────────────────────────────────────────────────────────────────── +def chunked_post(body_bytes): + return one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n" + body_bytes) + +(st, hd, body), closed, n = chunked_post(b"5\r\nHELLO\r\n0\r\n\r\n") +check("a plain chunked body -> echoed", st == 200 and body == b"HELLO") +(st, hd, body), closed, n = chunked_post(b"5;ext=1\r\nHELLO\r\n0\r\n\r\n") +check("a chunk extension -> accepted", st == 200 and body == b"HELLO") +(st, hd, body), closed, n = chunked_post(b"5 \r\nHELLO\r\n0\r\n\r\n") +check("bare whitespace after the chunk size -> 400", st == 400 and closed) +(st, hd, body), closed, n = chunked_post(b"5;\r\nHELLO\r\n0\r\n\r\n") +check("an empty chunk extension -> 400", st == 400 and closed) +(st, hd, body), closed, n = chunked_post(b"5\r\nHELLO\r\n0\r\nx: 1\r\ny: 2\r\n\r\n") +check("trailers -> taken, body echoed", st == 200 and body == b"HELLO") +(st, hd, body), closed, n = chunked_post(b"0\r\n" + b"x: " + b"y" * 3000 + b"\r\n" + b"z: " + b"w" * 3000 + b"\r\n\r\n") +check("trailers past their cap -> 400 and close", st == 400 and closed) +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n" + b"5;" + b"e" * 20000 + b"\r\nHELLO\r\n0\r\n\r\n") +check("a chunk size line the reader cannot hold -> 400", st == 400 and closed) + +# ── replies that carry no body ─────────────────────────────────────────────────────────────── +data, closed = exchange(b"HEAD / HTTP/1.1\r\nHost: x\r\n\r\nGET / HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +rs = split_responses(data) +check("HEAD / -> the GET's head, no body, then the pipelined GET answered", + len(rs) == 2 and rs[0][0] == 200 and rs[0][1].get("content-length") == rs[1][1].get("content-length") + and rs[0][2] == b"" and rs[1][2] == b"hello from ioxd\n") +data, closed = exchange(b"HEAD /stream HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +rs = split_responses(data) +check("HEAD of a streamed reply -> chunked head, no chunks, next request answered", + len(rs) == 2 and rs[0][0] == 200 and rs[0][1].get("transfer-encoding") == "chunked" and rs[0][2] == b"" + and rs[1][2] == b"ok") +data, closed = exchange(b"HEAD /nope HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +rs = split_responses(data) +check("HEAD of an unrouted path -> 404 head, no body", len(rs) == 2 and rs[0][0] == 404 and rs[0][2] == b"" and rs[1][2] == b"ok") + +for path, code, framing in [("/status/204", 204, None), ("/status/304", 304, None), ("/status/204?body=1", 204, None)]: + data, closed = exchange(b"GET %s HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n" % path.encode()) + rs = split_responses(data) + check(f"{path} -> {code} with no body, no framing header, the next request answered", + len(rs) == 2 and rs[0][0] == code and rs[0][2] == b"" and "content-length" not in rs[0][1] + and "transfer-encoding" not in rs[0][1] and rs[1][2] == b"ok") + +# ── the reply head a handler cannot corrupt ────────────────────────────────────────────────── +(st, hd, body), closed, n = one(b"GET /reflect?name=x-echo&value=safe HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a reflected header value -> sent", st == 200 and hd.get("x-echo") == "safe" and body == b"added") +(st, hd, body), closed, n = one(b"GET /reflect?name=x-echo&value=a%0d%0ax-evil:%201 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a value with CRLF -> refused by ioxd_header, no injected line", + st == 200 and "x-evil" not in hd and "x-echo" not in hd and body == b"refused") +(st, hd, body), closed, n = one(b"GET /reflect?name=x-echo&value=a%00b HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a value with %00 -> kept literal, sent as text", st == 200 and hd.get("x-echo") == "a%00b") +(st, hd, body), closed, n = one(b"GET /reflect?name=bad%20name&value=v HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a name that is not a token -> refused", st == 200 and body == b"refused") +(st, hd, body), closed, n = one(b"GET /reflect?name=Content-Length&value=0 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("an engine-owned header -> refused, the real content-length stands", st == 200 and hd.get("content-length") == "7" and body == b"refused") +(st, hd, body), closed, n = one(b"GET /reflect?name=Content-Type&value=text/x-custom HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("content-type through ioxd_header -> the content type", st == 200 and hd.get("content-type") == "text/x-custom") +(st, hd, body), closed, n = one(b"GET /reflect?name=x-local&value=stack HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a header from a handler-local buffer -> copied, intact on the wire", st == 200 and hd.get("x-local") == "stack") + +# ── the status line ────────────────────────────────────────────────────────────────────────── +(st, hd, body), closed, n = one(b"GET /status/99 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a status outside 100-999 -> 500", st == 500) +(st, hd, body), closed, n = one(b"GET /status/418 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("an unlisted status -> its number, a reason phrase", st == 418) + +# ── a declared length, held to ─────────────────────────────────────────────────────────────── +(st, hd, body), closed, n = one(b"GET /declared?say=100&write=9 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("a declared length larger than a buffered body -> the real length", st == 200 and hd.get("content-length") == "9" and body == b"123456789") +data, closed = exchange(b"GET /declared?say=3&write=19&stream=1 HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\n\r\n") +rs = split_responses(data) +check("a streamed body past its declared length -> cut at the length, connection closed", + len(rs) == 1 and rs[0][1].get("content-length") == "3" and rs[0][2] == b"123" and closed) +data, closed = exchange(b"GET /declared?say=100&write=9&stream=1 HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\n\r\n") +check("a streamed body short of its declared length -> the connection closes (the client sees the cut)", + closed and data.startswith(b"HTTP/1.1 200") and len(split_responses(data + b"")) <= 1) + +# ── Expect: 100-continue ───────────────────────────────────────────────────────────────────── +s = connect() +s.sendall(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\nExpect: 100-continue\r\nConnection: close\r\n\r\n") +first = s.recv(4096) +got_continue = first.startswith(b"HTTP/1.1 100 Continue\r\n\r\n") +s.sendall(b"hello") +rest, closed = read_all(s) +s.close() +rs = split_responses(first[len(b"HTTP/1.1 100 Continue\r\n\r\n"):] + rest) if got_continue else [] +check("Expect: 100-continue -> 100 Continue before the body is read, then the reply", + got_continue and len(rs) == 1 and rs[0][0] == 200 and rs[0][2] == b"hello") +s = connect() +s.sendall(b"POST /health HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\nExpect: 100-continue\r\n\r\n") +data, closed = read_all(s) +s.close() +rs = split_responses(data) +check("Expect with a handler that never reads the body -> final status, connection closed, no wait", + not data.startswith(b"HTTP/1.1 100") and len(rs) == 1 and rs[0][1].get("connection") == "close" and closed) +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\nExpect: 200-please\r\n\r\nhello") +check("an expectation we do not know -> 417", st == 417) + +# ── query parameters: the whole query or nothing ───────────────────────────────────────────── +many = b"&".join(b"p%d=1" % i for i in range(40)) +(st, hd, body), closed, n = one(b"GET /params?" + many + b" HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("more query parameters than fit -> 400, never a partial view", st == 400) +huge = b"v=" + b"%41" * 1500 +(st, hd, body), closed, n = one(b"GET /params?" + huge + b" HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +check("more decoded query than the arena holds -> 414", st == 414) + +failed = results.count(False) +print("all passed" if not failed else f"{failed} FAILED") +sys.exit(1 if failed else 0) diff --git a/tests/server.c b/tests/server.c index 8198f2c..caeecae 100644 --- a/tests/server.c +++ b/tests/server.c @@ -113,7 +113,7 @@ static void greet(ioxd_ctx *ctx) ioxd_slice body = ioxd_body_all(ctx); ioxd_kv form[8]; char arena[512]; - size_t n = ioxd_kv_parse(body.p, body.len, form, 8, arena, sizeof arena); + size_t n = ioxd_kv_parse(body.p, body.len, form, 8, arena, sizeof arena, NULL); ioxd_slice name = { "stranger", 8 }; for (size_t i = 0; i < n; i++) diff --git a/tests/unit.c b/tests/unit.c index c2974c4..4e23215 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -167,7 +167,7 @@ static void test_kv_parse(void) { ioxd_kv kv[8]; char arena[64]; - size_t n = ioxd_kv_parse("a=1&b=hello+world&c=%41%zz&&d&e=", 32, kv, 8, arena, sizeof arena); + size_t n = ioxd_kv_parse("a=1&b=hello+world&c=%41%zz&&d&e=", 32, kv, 8, arena, sizeof arena, NULL); CHECK(n == 5); CHECK(ioxd_slice_eq(kv[0].key, "a") && ioxd_slice_eq(kv[0].value, "1")); CHECK(ioxd_slice_eq(kv[1].key, "b") && ioxd_slice_eq(kv[1].value, "hello world")); @@ -176,15 +176,15 @@ static void test_kv_parse(void) CHECK(ioxd_slice_eq(kv[4].key, "e") && kv[4].value.len == 0); CHECK(kv[0].value.p != arena && kv[1].value.p >= arena); /* a view when undecoded, else in the arena */ - n = ioxd_kv_parse("k%20ey=v&x=y", 12, kv, 8, arena, sizeof arena); + n = ioxd_kv_parse("k%20ey=v&x=y", 12, kv, 8, arena, sizeof arena, NULL); CHECK(n == 2 && ioxd_slice_eq(kv[0].key, "k ey")); - n = ioxd_kv_parse("a=1&b=x+y&c=3", 13, kv, 8, arena, 0); /* no arena: the pair needing it is skipped */ + n = ioxd_kv_parse("a=1&b=x+y&c=3", 13, kv, 8, arena, 0, NULL); /* no arena: the pair needing it is skipped */ CHECK(n == 2 && ioxd_slice_eq(kv[1].key, "c")); - n = ioxd_kv_parse("a=1&b=2&c=3", 11, kv, 1, arena, sizeof arena); + n = ioxd_kv_parse("a=1&b=2&c=3", 11, kv, 1, arena, sizeof arena, NULL); CHECK(n == 1); int v; - CHECK(ioxd_kv_parse("page=12", 7, kv, 8, arena, sizeof arena) == 1 && ioxd_to_int(kv[0].value, &v) && v == 12); + CHECK(ioxd_kv_parse("page=12", 7, kv, 8, arena, sizeof arena, NULL) == 1 && ioxd_to_int(kv[0].value, &v) && v == 12); } /* The JSON writer into memory: what a document looks like, byte for byte. */ From a5a442ca3cb62383d0f51219f992ecb15d2de41a Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:28:06 +0100 Subject: [PATCH 31/49] JSON: the numbers in a private "C" locale, and every call checked against its level A double was formatted with whatever decimal point LC_NUMERIC named and mended one byte afterwards, so a locale whose point is several bytes - fa_IR, ps_AF - turned every double into invalid JSON, quietly: "0.1" came out as 0x30 0x2e 0xab 0x31. The per-double localeconv() handed back a process-wide static besides, read from every worker. The numbers now go through a locale_t made once under pthread_once, worn with uselocale() around the snprintf/strtod pair and handed straight back, and the writer fails if that locale cannot be made. A float has a path of its own - 6 to 9 significant digits, round-tripped with strtof - so 0.1f prints as 0.1 and not as the double it was promoted to; _Generic routes float: to it. What a call may do is checked now: a key belongs in an object, one per value; a value inside an object has to follow a key; an end needs something open and the pair it closes complete. Each refusal marks the writer failed, where an unbalanced end used to return false silently and the writer kept accepting. ioxd_json_done() answers the other half - nothing failed, nothing left open - so a missing end is no longer invisible. Also: the depth is checked before the separator is written, so a document one level too deep leaves no comma behind; IOXD_JSON_DEPTH is 63 with a static_assert under it, since level 64 aliased the root's bit through depth & 63; an empty ioxd_json_raw fails rather than emitting "[,]"; and a run the sink refuses whole is asked for again halved, down to 64 bytes, since the reply and the pipe both refuse a reserve larger than their slab. In the header: IOXD_JSON_FIELD's answer goes through a static inline, so a field written for its effect is a statement and not a value the compiler sees discarded; the USER_FIELDS example no longer shows a // note before a line continuation, which would swallow the lines after it, and points at playground/hello/main.c for the block-comment form; and it says that strings go out byte for byte, invalid UTF-8 included, so untrusted input has to be validated first. The unit tests cover each of these. The locale one tries ps_AF, fa_IR, de_DE and fr_FR and prints a note instead when the box has none of them. include/ioxd/json.h enters the tree here: .gitignore's `ioxd` line, meant for an old binary at the root, also matched include/ioxd/, so none of the split headers were ever committed and this one no longer matches the json.c beside it. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- include/ioxd/json.h | 144 +++++++++++++++++++++++++++++++++++++++++ lib/json/json.c | 154 ++++++++++++++++++++++++++++++++++---------- tests/unit.c | 124 +++++++++++++++++++++++++++++++++-- 3 files changed, 385 insertions(+), 37 deletions(-) create mode 100644 include/ioxd/json.h diff --git a/include/ioxd/json.h b/include/ioxd/json.h new file mode 100644 index 0000000..018f06c --- /dev/null +++ b/include/ioxd/json.h @@ -0,0 +1,144 @@ +/* + * ioxd/json.h - JSON written as you go, and a struct described once, serialized with one call. + */ +#pragma once + +#include +#include +#include + +#include "ioxd/http.h" + +struct ioxd_pipe; /* ioxd/pipe.h */ + +/* ── JSON, written as you go ───────────────────────────────────────────────────────────── */ + +/* A forward-only JSON writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation. The + * bytes go straight into the reply - or a raw pipe, or a buffer - escaped as they are written, + * and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what + * it means: + * + * ioxd_json j = ioxd_json_reply(ctx); // content-type: application/json + * ioxd_json_object(&j); + * ioxd_json_key(&j, "id"); ioxd_json_int(&j, id); + * ioxd_json_key(&j, "name"); ioxd_json_string(&j, name); + * ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + * ioxd_json_cstr(&j, "new"); + * ioxd_json_end(&j); + * ioxd_json_end(&j); + * if (!ioxd_json_done(&j)) { ... } // whole: nothing failed, nothing open + * + * Strings are emitted byte for byte, with only '"', '\' and the control characters escaped: + * invalid UTF-8 goes out exactly as it came in, so untrusted input has to be validated first. + * Every call returns false once the sink is gone (the peer left; the buffer is full), the nesting + * passed IOXD_JSON_DEPTH, or the call had no place in the document - a key outside an object, a + * value where a key was due, an end with nothing open. The rest is then dropped, so checking the + * last call is enough; check done() after it to catch an end that was never written. */ +#define IOXD_JSON_DEPTH 63 /* levels: one bit of each mask below apiece */ +typedef struct ioxd_json { + enum { + IOXD_JSON_TO_REPLY, + IOXD_JSON_TO_PIPE, + IOXD_JSON_TO_MEM, + } kind; + + union { + ioxd_ctx *ctx; + struct ioxd_pipe *pipe; + struct { char *p; size_t cap, *len; } mem; + } to; + + uint64_t has_value; /* per level: a value is there, so a comma is due */ + uint64_t is_object; /* per level: it closes with '}' rather than ']' */ + unsigned depth; + bool after_key; /* the next value follows a key: no comma */ + bool failed; +} ioxd_json; + +ioxd_json ioxd_json_reply(ioxd_ctx *ctx); /* into the reply; sets its content type */ +ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe); /* into a raw pipe's slab */ +ioxd_json ioxd_json_mem (char *buf, size_t cap, size_t *len); /* into memory; *len is what was written */ + +bool ioxd_json_object(ioxd_json *j); /* { */ +bool ioxd_json_array (ioxd_json *j); /* [ */ +bool ioxd_json_end (ioxd_json *j); /* } or ], whichever is open */ +bool ioxd_json_done (ioxd_json *j); /* nothing failed, all closed */ +bool ioxd_json_key (ioxd_json *j, const char *name); /* "name": */ +bool ioxd_json_string(ioxd_json *j, ioxd_slice s); /* "...", escaped */ +bool ioxd_json_cstr (ioxd_json *j, const char *s); /* NULL is null */ +bool ioxd_json_int (ioxd_json *j, int64_t v); +bool ioxd_json_uint (ioxd_json *j, uint64_t v); +bool ioxd_json_double(ioxd_json *j, double v); /* the shortest that reads back the same; nan and inf become null */ +bool ioxd_json_float (ioxd_json *j, float v); /* the same, read back as a float: 0.1f is 0.1 */ +bool ioxd_json_bool (ioxd_json *j, bool v); +bool ioxd_json_null (ioxd_json *j); +bool ioxd_json_raw (ioxd_json *j, ioxd_slice json); /* already JSON: copied as is */ + +/* A value by its C type, and a key with one: the _Generic picks ioxd_json_int for the integer + * types, _uint for the unsigned ones, _float and _double for those two, _bool, _cstr for a char + * pointer, _string for a slice. */ +#define IOXD_JSON_VALUE(j, x) _Generic((x), \ + bool: ioxd_json_bool, \ + char: ioxd_json_int, signed char: ioxd_json_int, short: ioxd_json_int, \ + int: ioxd_json_int, long: ioxd_json_int, long long: ioxd_json_int, \ + unsigned char: ioxd_json_uint, unsigned short: ioxd_json_uint, unsigned: ioxd_json_uint, \ + unsigned long: ioxd_json_uint, unsigned long long: ioxd_json_uint, \ + float: ioxd_json_float, double: ioxd_json_double, \ + char *: ioxd_json_cstr, const char *: ioxd_json_cstr, \ + ioxd_slice: ioxd_json_string)((j), (x)) + +/* A key and its value in one line. The answer goes through a function so that a field written for + * its effect - `IOXD_JSON_FIELD(j, "n", n);` - is a plain statement and not a value the compiler + * sees discarded, while `if (IOXD_JSON_FIELD(j, "n", n))` still reads it. */ +static inline bool ioxd__json_wrote(bool ok) { return ok; } +#define IOXD_JSON_FIELD(j, name, x) \ + ioxd__json_wrote(ioxd_json_key((j), (name)) && IOXD_JSON_VALUE((j), (x))) + +/* A struct described once, serialized with one call. The description is a list of fields, each + * line its kind, its C type (or, for a nested struct, that struct's name) and its name: + * + * #define USER_FIELDS(X) \ + * X(VALUE, int64_t, id) \ + * X(VALUE, const char *, name) \ + * X(OBJECT, address, address) \ + * X(OPTIONAL, address, billing) \ + * X(ARRAY, const char *, tags, n_tags) \ + * X(OBJECTS, order, orders, n_orders) + * IOXD_JSON_STRUCT(user, USER_FIELDS) + * + * VALUE is a scalar, written by its C type; OBJECT a nested struct held by value; OPTIONAL a + * pointer to one, null where the pointer is NULL; ARRAY scalars and the field holding their + * count; OBJECTS the same for nested structs. IOXD_JSON_STRUCT defines the struct and the + * function - struct user, and user_to_json(ioxd_json *, const struct user *); IOXD_JSON_WRITER + * only the function, for a struct declared elsewhere with the same fields. A nested struct's own + * IOXD_JSON_STRUCT comes first. Counts are size_t; arrays are pointers to their first element. + * A note beside a field is written as a block comment, the way playground/hello/main.c writes + * them: a // one would run on through the backslash and swallow the lines after it. */ +#define IOXD_JSON_STRUCT(name, FIELDS) \ + struct name { FIELDS(IOXD__JSON_MEMBER) }; \ + IOXD_JSON_WRITER(name, FIELDS) +#define IOXD_JSON_WRITER(name, FIELDS) \ + static inline bool name##_to_json(ioxd_json *j, const struct name *v) \ + { \ + ioxd_json_object(j); \ + FIELDS(IOXD__JSON_WRITE) \ + return ioxd_json_end(j); \ + } + +/* What each kind of line becomes: a member, and a piece of the writer. */ +#define IOXD__JSON_MEMBER(kind, ...) IOXD__JSON_MEMBER_##kind(__VA_ARGS__) +#define IOXD__JSON_MEMBER_VALUE(type, field) type field; +#define IOXD__JSON_MEMBER_OBJECT(sname, field) struct sname field; +#define IOXD__JSON_MEMBER_OPTIONAL(sname, field) const struct sname *field; +#define IOXD__JSON_MEMBER_ARRAY(type, field, count) type *field; size_t count; +#define IOXD__JSON_MEMBER_OBJECTS(sname, field, count) const struct sname *field; size_t count; +#define IOXD__JSON_WRITE(kind, ...) IOXD__JSON_WRITE_##kind(__VA_ARGS__) +#define IOXD__JSON_WRITE_VALUE(type, field) ioxd_json_key(j, #field); IOXD_JSON_VALUE(j, v->field); +#define IOXD__JSON_WRITE_OBJECT(sname, field) ioxd_json_key(j, #field); sname##_to_json(j, &v->field); +#define IOXD__JSON_WRITE_OPTIONAL(sname, field) ioxd_json_key(j, #field); if (v->field) sname##_to_json(j, v->field); else ioxd_json_null(j); +#define IOXD__JSON_WRITE_ARRAY(type, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { IOXD_JSON_VALUE(j, v->field[i_]); } \ + ioxd_json_end(j); +#define IOXD__JSON_WRITE_OBJECTS(sname, field, count) ioxd_json_key(j, #field); ioxd_json_array(j); \ + for (size_t i_ = 0; i_ < v->count; i_++) { sname##_to_json(j, &v->field[i_]); } \ + ioxd_json_end(j); diff --git a/lib/json/json.c b/lib/json/json.c index c3843a0..11e612e 100644 --- a/lib/json/json.c +++ b/lib/json/json.c @@ -8,11 +8,16 @@ #include #include +#include #include #include #include #define RUN_MAX 1024 /* bytes asked of the sink at a time */ +#define RUN_MIN 64 /* and the least worth asking for */ + +/* One bit per level in has_value and is_object, the root's included: the deepest must still fit. */ +static_assert(IOXD_JSON_DEPTH < 64, "a level per bit of has_value and is_object, plus the root"); /* n bytes of the sink to write into, or nullptr; the caller then advances by what it wrote. */ static char *reserve(ioxd_json *j, size_t n) @@ -20,7 +25,8 @@ static char *reserve(ioxd_json *j, size_t n) switch (j->kind) { case IOXD_JSON_TO_REPLY: return ioxd_reserve(j->to.ctx, n); case IOXD_JSON_TO_PIPE: return ioxd_pipe_reserve(j->to.pipe, n); - case IOXD_JSON_TO_MEM: return *j->to.mem.len + n <= j->to.mem.cap ? j->to.mem.p + *j->to.mem.len : nullptr; + case IOXD_JSON_TO_MEM: return j->to.mem.p && *j->to.mem.len + n <= j->to.mem.cap + ? j->to.mem.p + *j->to.mem.len : nullptr; } return nullptr; } @@ -34,12 +40,18 @@ static void advance(ioxd_json *j, size_t n) } } -/* Raw bytes to the sink, in runs the slab can take; false marks the writer failed. */ +/* Raw bytes to the sink, in runs the slab can take; false marks the writer failed. A sink refuses + * a reserve larger than its slab outright, so a refused run is halved and asked for again, down + * to RUN_MIN: a slab smaller than RUN_MAX still takes the document. */ static bool put(ioxd_json *j, const char *p, size_t n) { while (n) { size_t run = n < RUN_MAX ? n : RUN_MAX; char *at = reserve(j, run); + while (!at && run > RUN_MIN) { + run = run / 2 > RUN_MIN ? run / 2 : RUN_MIN; + at = reserve(j, run); + } if (!at) { j->failed = true; return false; @@ -106,7 +118,7 @@ static bool put_string(ioxd_json *j, const char *p, size_t n) return put(j, "\"", 1); } -/* Before a value: the comma its level owes, unless it follows a key. */ +/* Before a value or a key: the comma its level owes, unless it follows a key. */ static bool separator(ioxd_json *j) { if (j->failed) @@ -115,13 +127,26 @@ static bool separator(ioxd_json *j) j->after_key = false; return true; } - uint64_t bit = (uint64_t)1 << (j->depth & 63U); + uint64_t bit = (uint64_t)1 << j->depth; if (j->has_value & bit) return put(j, ",", 1); j->has_value |= bit; return true; } +/* A value may start here: inside an object it has to follow a key, or the document is broken and + * the writer fails. Outside one - in an array, or at the top level - anything goes. */ +static bool value_ok(ioxd_json *j) +{ + if (j->failed) + return false; + if ((j->is_object & ((uint64_t)1 << j->depth)) && !j->after_key) { + j->failed = true; + return false; + } + return separator(j); +} + /* ── the sinks ─────────────────────────────────────────────────────────────────────────── */ ioxd_json ioxd_json_reply(ioxd_ctx *ctx) @@ -151,17 +176,20 @@ ioxd_json ioxd_json_mem(char *buf, size_t cap, size_t *len) /* ── the values ────────────────────────────────────────────────────────────────────────── */ -/* Open a container: its own level starts empty. */ +/* Open a container: its own level starts empty. The depth is checked before anything is written, + * so a document that goes one level too deep leaves no comma behind. */ static bool open_level(ioxd_json *j, char bracket) { - if (!separator(j)) + if (j->failed) return false; if (j->depth == IOXD_JSON_DEPTH) { j->failed = true; return false; } + if (!value_ok(j)) + return false; j->depth++; - uint64_t bit = (uint64_t)1 << (j->depth & 63U); + uint64_t bit = (uint64_t)1 << j->depth; j->has_value &= ~bit; if (bracket == '{') j->is_object |= bit; @@ -181,19 +209,36 @@ bool ioxd_json_array(ioxd_json *j) } /* Close the innermost container. Which bracket is remembered by what was written: an object's - * level is one that took keys - tracked as a bit too. */ + * level is one that took keys - tracked as a bit too. Nothing open, or a key still waiting for + * its value, is a document that cannot be finished: the writer fails, and says so. */ bool ioxd_json_end(ioxd_json *j) { - if (j->failed || j->depth == 0) + if (j->failed) + return false; + if (j->depth == 0 || j->after_key) { + j->failed = true; return false; - bool object = j->is_object & ((uint64_t)1 << (j->depth & 63U)); + } + bool object = j->is_object & ((uint64_t)1 << j->depth); j->depth--; - j->after_key = false; return put(j, object ? "}" : "]", 1); } +/* Nothing failed, and nothing is left open: the document is whole. */ +bool ioxd_json_done(ioxd_json *j) +{ + return !j->failed && j->depth == 0; +} + +/* A key belongs in an object, and one key per value: anything else is a broken document. */ bool ioxd_json_key(ioxd_json *j, const char *name) { + if (j->failed) + return false; + if (!(j->is_object & ((uint64_t)1 << j->depth)) || j->after_key) { + j->failed = true; + return false; + } if (!separator(j)) return false; if (!put_string(j, name, strlen(name)) || !put(j, ":", 1)) @@ -204,14 +249,14 @@ bool ioxd_json_key(ioxd_json *j, const char *name) bool ioxd_json_string(ioxd_json *j, ioxd_slice s) { - return separator(j) && put_string(j, s.p, s.len); + return value_ok(j) && put_string(j, s.p, s.len); } bool ioxd_json_cstr(ioxd_json *j, const char *s) { if (!s) return ioxd_json_null(j); /* a null pointer is JSON null */ - return separator(j) && put_string(j, s, strlen(s)); + return value_ok(j) && put_string(j, s, strlen(s)); } /* Decimal digits of a magnitude, right-aligned in tmp; the start of them. */ @@ -229,7 +274,7 @@ bool ioxd_json_uint(ioxd_json *j, uint64_t v) { char tmp[24]; char *p = digits(tmp + sizeof tmp, v); - return separator(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); + return value_ok(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); } bool ioxd_json_int(ioxd_json *j, int64_t v) @@ -239,46 +284,89 @@ bool ioxd_json_int(ioxd_json *j, int64_t v) char *p = digits(tmp + sizeof tmp, magnitude); if (v < 0) *--p = '-'; - return separator(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); + return value_ok(j) && put(j, p, (size_t)(tmp + sizeof tmp - p)); +} + +/* snprintf and strtod spell the decimal point the way LC_NUMERIC says, and JSON knows only '.'; + * a locale like fa_IR spells it with several bytes, so mending one byte afterwards is not enough. + * The numbers are formatted in a private "C" locale instead - made once for the process, worn by + * the thread for the two calls and handed straight back, so no worker disturbs another and + * nothing reads the shared static localeconv returns. */ +static pthread_once_t c_locale_once = PTHREAD_ONCE_INIT; +static locale_t c_locale; + +static void make_c_locale(void) +{ + c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); +} + +/* The shortest decimal that reads back as the same value: the precisions from first to last, the + * first that round-trips. The length written, or -1 if it did not fit or there is no "C" locale. */ +static int shortest(char *tmp, size_t cap, double v, int first, int last, bool as_float) +{ + pthread_once(&c_locale_once, make_c_locale); + if (!c_locale) + return -1; + locale_t previous = uselocale(c_locale); + if (!previous) + return -1; + int n = -1; + for (int precision = first; precision <= last; precision++) { + n = snprintf(tmp, cap, "%.*g", precision, v); + if (n < 0 || (size_t)n >= cap) + break; + if (as_float ? strtof(tmp, nullptr) == (float)v : strtod(tmp, nullptr) == v) + break; + } + uselocale(previous); + return n < 0 || (size_t)n >= cap ? -1 : n; } -/* The shortest decimal that reads back as the same double: 15, 16 or 17 significant digits, the - * first that round-trips. snprintf follows the locale's decimal point; JSON wants '.'. */ +/* A double: 15, 16 or 17 significant digits. */ bool ioxd_json_double(ioxd_json *j, double v) { if (!isfinite(v)) return ioxd_json_null(j); char tmp[32]; - int n = 0; - for (int precision = 15; precision <= 17; precision++) { - n = snprintf(tmp, sizeof tmp, "%.*g", precision, v); - if (n < 0 || strtod(tmp, nullptr) == v) - break; - } - if (n < 0 || (size_t)n >= sizeof tmp) { + int n = shortest(tmp, sizeof tmp, v, 15, 17, false); + if (n < 0) { j->failed = true; return false; } - const char *point = localeconv()->decimal_point; - if (point[0] != '.') { - char *at = strchr(tmp, point[0]); - if (at) - *at = '.'; + return value_ok(j) && put(j, tmp, (size_t)n); +} + +/* A float: 6 to 9, round-tripped against the float, so 0.1f is 0.1 and not the wider double it + * would otherwise be promoted to. */ +bool ioxd_json_float(ioxd_json *j, float v) +{ + if (!isfinite(v)) + return ioxd_json_null(j); + char tmp[32]; + int n = shortest(tmp, sizeof tmp, (double)v, 6, 9, true); + if (n < 0) { + j->failed = true; + return false; } - return separator(j) && put(j, tmp, (size_t)n); + return value_ok(j) && put(j, tmp, (size_t)n); } bool ioxd_json_bool(ioxd_json *j, bool v) { - return separator(j) && put_cstr(j, v ? "true" : "false"); + return value_ok(j) && put_cstr(j, v ? "true" : "false"); } bool ioxd_json_null(ioxd_json *j) { - return separator(j) && put_cstr(j, "null"); + return value_ok(j) && put_cstr(j, "null"); } +/* Already JSON, copied as is. Nothing is not a value: an empty slice would leave "[,]" behind. */ bool ioxd_json_raw(ioxd_json *j, ioxd_slice json) { - return separator(j) && put(j, json.p, json.len); + if (json.len == 0) { + j->failed = true; + return false; + } + return value_ok(j) && put(j, json.p, json.len); } diff --git a/tests/unit.c b/tests/unit.c index c2974c4..970e19a 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -218,6 +219,24 @@ static void doc_numbers(ioxd_json *j) ioxd_json_double(j, INFINITY); ioxd_json_double(j, NAN); ioxd_json_end(j); } +/* A float is not a double: 6 to 9 significant digits, round-tripped against the float itself. */ +static void doc_floats(ioxd_json *j) +{ + ioxd_json_array(j); + ioxd_json_float(j, 0.1F); ioxd_json_float(j, 1.0F / 3.0F); ioxd_json_float(j, 16777217.0F); + ioxd_json_float(j, -0.0F); ioxd_json_float(j, 1e20F); + ioxd_json_float(j, INFINITY); ioxd_json_float(j, NAN); + ioxd_json_end(j); +} +/* The reals whose text the decimal point of a locale would spoil. */ +static void doc_reals(ioxd_json *j) +{ + ioxd_json_array(j); + ioxd_json_double(j, 0.1); ioxd_json_double(j, -2.5e-7); ioxd_json_float(j, 0.5F); + ioxd_json_end(j); +} +/* Bytes are bytes: what is not valid UTF-8 goes out exactly as it came in. */ +static void doc_bad_utf8(ioxd_json *j) { ioxd_json_string(j, S("\xff\xfe\x80 ok")); } static void doc_top_level(ioxd_json *j) { ioxd_json_cstr(j, "just a string"); } static void doc_array_of_arrays(ioxd_json *j) { @@ -269,28 +288,97 @@ static void doc_struct_empty(ioxd_json *j) struct user u = { .id = 1, .name = NULL, .handle = S(""), .address = { NULL, NULL } }; user_to_json(j, &u); } +/* The field macro as a statement, which must not be a discarded value, and as a condition. */ static void doc_field_macro(ioxd_json *j) { ioxd_json_object(j); IOXD_JSON_FIELD(j, "n", 5); IOXD_JSON_FIELD(j, "x", 2.5); + IOXD_JSON_FIELD(j, "f", 0.1F); /* a float takes the float writer */ IOXD_JSON_FIELD(j, "s", "str"); IOXD_JSON_FIELD(j, "b", false); - IOXD_JSON_FIELD(j, "u", 7U); + if (!IOXD_JSON_FIELD(j, "u", 7U)) + return; IOXD_JSON_FIELD(j, "sl", S("slice")); ioxd_json_end(j); } +/* Where a value may go: a key only in an object, one key per value, an end only once the pair it + * closes is complete. Every refusal is marked failed, so nothing goes unreported. */ +static void test_json_levels(void) +{ + char buf[128]; + size_t len; + + ioxd_json j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(!ioxd_json_key(&j, "k") && j.failed); /* a key at the top level */ + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_array(&j) && !ioxd_json_key(&j, "k") && j.failed); /* a key in an array */ + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_object(&j) && !ioxd_json_int(&j, 1) && j.failed); /* a value, no key */ + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_object(&j) && ioxd_json_key(&j, "a") && !ioxd_json_key(&j, "b") && j.failed); + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_object(&j) && ioxd_json_key(&j, "a") && !ioxd_json_end(&j) && j.failed); + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(!ioxd_json_end(&j) && j.failed); /* nothing open, and it says so */ + CHECK(!ioxd_json_object(&j)); /* failed stays failed */ + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_array(&j) && !ioxd_json_raw(&j, S("")) && j.failed); /* nothing is no value */ + + j = ioxd_json_mem(buf, sizeof buf, &len); + CHECK(ioxd_json_done(&j)); /* nothing written, none wrong */ + CHECK(ioxd_json_object(&j) && !ioxd_json_done(&j)); /* the object is still open */ + CHECK(ioxd_json_key(&j, "a") && ioxd_json_int(&j, 1) && !ioxd_json_done(&j)); + CHECK(ioxd_json_end(&j) && ioxd_json_done(&j)); /* now it is whole */ + CHECK(!ioxd_json_end(&j) && !ioxd_json_done(&j)); /* one end too many */ +} + +/* The decimal point is '.' whatever LC_NUMERIC says: the numbers are formatted in the writer's + * own "C" locale and the thread's is handed straight back. A locale with a point of its own is + * not installed everywhere, so this says so and skips when there is none. */ +static void test_json_locale(void) +{ + static const char *const others[] = { + "ps_AF.UTF-8", "fa_IR.UTF-8", /* a point two bytes long */ + "de_DE.UTF-8", "fr_FR.UTF-8", /* a comma */ + }; + char saved[64]; + const char *was = setlocale(LC_NUMERIC, NULL); + snprintf(saved, sizeof saved, "%s", was ? was : "C"); + + const char *set = NULL; + for (size_t i = 0; i < sizeof others / sizeof *others && !set; i++) + set = setlocale(LC_NUMERIC, others[i]); + if (!set) { + printf("note: no locale with a point of its own installed; that check skipped\n"); + return; + } + CHECK(strcmp(localeconv()->decimal_point, ".") != 0); /* the locale really differs */ + CHECK(json_is("[0.1,-2.5e-07,0.5]", doc_reals)); /* and the JSON does not */ + CHECK(strcmp(localeconv()->decimal_point, ".") != 0); /* the thread's was handed back */ + setlocale(LC_NUMERIC, saved); +} + static void test_json(void) { CHECK(json_is("{\"id\":42,\"name\":\"Zo\xc3\xab \\\"Z\\\"\",\"active\":true,\"handle\":\"zoe\",\"visits\":3," "\"address\":{\"city\":\"Porto\",\"zip\":null},\"billing\":{\"city\":\"Lisboa\",\"zip\":\"1000-001\"}," "\"tags\":[\"new\",\"vip\"],\"orders\":[{\"number\":1,\"total\":9.5,\"items\":[7,9]},{\"number\":2,\"total\":0.25,\"items\":[]}]}", doc_struct)); CHECK(json_is("{\"id\":1,\"name\":null,\"active\":false,\"handle\":\"\",\"visits\":0,\"address\":{\"city\":null,\"zip\":null},\"billing\":null,\"tags\":[],\"orders\":[]}", doc_struct_empty)); - CHECK(json_is("{\"n\":5,\"x\":2.5,\"s\":\"str\",\"b\":false,\"u\":7,\"sl\":\"slice\"}", doc_field_macro)); + CHECK(json_is("{\"n\":5,\"x\":2.5,\"f\":0.1,\"s\":\"str\",\"b\":false,\"u\":7,\"sl\":\"slice\"}", doc_field_macro)); CHECK(json_is("{\"id\":42,\"name\":\"Zo\xc3\xab \\\"Z\\\" O'Neil\\n\\t\\u0001\",\"tags\":[\"a\",\"b\"],\"empty\":{},\"none\":null,\"ok\":true,\"raw\":[1,2]}", doc_nested)); CHECK(json_is("[0,-7,-9223372036854775808,9223372036854775807,18446744073709551615,0.1,2.5,-0,1e+21,9007199254740992,0.3333333333333333,null,null]", doc_numbers)); + CHECK(json_is("[0.1,0.33333334,16777216,-0,1e+20,null,null]", doc_floats)); + CHECK(json_is("[0.1,-2.5e-07,0.5]", doc_reals)); + CHECK(json_is("\"\xff\xfe\x80 ok\"", doc_bad_utf8)); CHECK(json_is("\"just a string\"", doc_top_level)); CHECK(json_is("[[1],[]]", doc_array_of_arrays)); @@ -301,14 +389,42 @@ static void test_json(void) CHECK(!ioxd_json_cstr(&j, "too long for what is left") && j.failed); CHECK(!ioxd_json_int(&j, 1)); /* failed stays failed */ + /* Every level has a bit of its own, the deepest included: all the way down and out again. */ char deep[512]; j = ioxd_json_mem(deep, sizeof deep, &len); bool ok = true; for (int i = 0; i < IOXD_JSON_DEPTH; i++) ok = ok && ioxd_json_array(&j); - CHECK(ok && !ioxd_json_array(&j)); /* one level too many */ + for (int i = 0; i < IOXD_JSON_DEPTH; i++) + ok = ok && ioxd_json_end(&j); + CHECK(ok && ioxd_json_done(&j) && len == 2 * (size_t)IOXD_JSON_DEPTH); + j = ioxd_json_mem(deep, sizeof deep, &len); - CHECK(!ioxd_json_end(&j)); /* nothing open */ + ok = true; + for (int i = 0; i < IOXD_JSON_DEPTH; i++) + ok = ok && ioxd_json_array(&j); + ok = ok && ioxd_json_int(&j, 1); /* the deepest level owes a comma */ + size_t written = len; + CHECK(ok && !ioxd_json_array(&j) && len == written); /* too deep: not even that comma */ + + /* Longer than one run of the sink, byte for byte through the run loop. */ + char big[4096]; + char longer[2000]; + memset(longer, 'x', sizeof longer); + j = ioxd_json_mem(big, sizeof big, &len); + CHECK(ioxd_json_string(&j, (ioxd_slice){ longer, sizeof longer }) && ioxd_json_done(&j)); + CHECK(len == sizeof longer + 2 && big[0] == '"' && big[len - 1] == '"' + && memcmp(big + 1, longer, sizeof longer) == 0); + + /* A run the sink refuses whole is asked for again halved, down to 64 bytes: what is left of + * the buffer is filled to within a short run of the end before the writer gives up. */ + char tight[700]; + j = ioxd_json_mem(tight, sizeof tight, &len); + CHECK(!ioxd_json_string(&j, (ioxd_slice){ longer, sizeof longer }) && j.failed); + CHECK(len >= sizeof tight - 64); + + test_json_levels(); + test_json_locale(); } int main(void) From c7171f91530862374ac778d1b47cf9a7467a8691 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:32:48 +0100 Subject: [PATCH 32/49] I/O plane: a shutdown that drains, accept back-pressure, and the state machine's stranded corners Stopping used to abandon whatever was open: parked coroutines, their stacks, the conn_t and the socket, and then it unmapped the recv slab while multishot recvs could still be in flight. A worker now drains instead - it cancels the accepts by name, asks the kernel to cancel everything else with one ASYNC_CANCEL_ANY, ends by hand the recvs parked on -ENOBUFS that hold no operation to cancel, and keeps running the loop, ignoring the stop flag, until the last connection has closed itself or two seconds are up. Parked coroutines wake with errors, handlers unwind, stacks go back to the pool; if any are still open the slab stays mapped and the log says so. Twenty idle keep-alive connections now go from SIGINT to "0 still open" in under 100 ms. conn.c's pause/resume had corners that stranded a coroutine for good. The -ENOBUFS branch ignored c->pausing, so a TLS prologue parked in recv_pause was never woken under buffer starvation, and ignored c->eof, so a connection the queue-full policy had already finished was parked on the starved list instead of ending. recv_pause reported success with the input already ended and recv_resume armed a recv on a dead connection; both say so now, and resume during a drain ends the input rather than arming an operation nothing will cancel. A positive result without IORING_CQE_F_BUFFER used a buffer id that was never set. The queue-full policy staged a cancel per arrival while the queue stayed full: one flag now bounds it to one in flight. A terminal -EIO on a TLS listener is the peer's control record, which TLS.md calls the end of input, so it reads as a clean close rather than an error. Closing a socket goes through an IORING_OP_CLOSE on both paths - the plain close(2) raced SQEs already staged for that same descriptor. A persistent accept error (-ENFILE when the file table is full, -EMFILE, -ENOMEM, -ENOBUFS) was an unbounded re-arm spin with one log line per turn. The listener now stalls and is re-armed once p->live has dropped, or once a second in case the shortage was someone else's, and it does not accept past the registered-file ceiling in the first place; the error log is rate-limited and counts what it stands for. With an eight-slot table, forty clients: eight served, two log lines, and everything works again when they let go. ioxd__sqe discarded uring_submit's return, so on -EBUSY - the CQ overflowing, the kernel refusing submissions - all sixteen retries were identical and the worker aborted. The CQ head is now published per entry, so a handler resuming inline always has room for its completions, and the retry enters with GETEVENTS to flush the backlog; the abort, if it comes, names the errno. CQ overflow was invisible: sq_off.flags is mapped, an overflow forces an enter that flushes it, and the count is in the stop line. uring_init left a half-built struct behind on an mmap failure - sqe_mem was MAP_FAILED, which passes `if (ring->sqe_mem)` - so uring_exit double-unmapped and closed a stale fd; the struct is emptied on every failure path and only owns an fd once both mappings are up. Also: fd 0 is a legal descriptor, the -EINVAL retry no longer claims every -EINVAL was NO_SQARRAY, RING_FDS returns a count that must be 1 before up.offset means anything, sq_array is null under NO_SQARRAY instead of aliasing sq_head, and the compat block covers the flags and the getevents arg that older headers lack. The guard below a coroutine stack was one 4 KB page under frames of 25 KB and 10 KB - a deep frame would have stepped clean over it into the neighbour. It is 64 KB of PROT_NONE now (address space only), and STACK_SIZE is 128 KB against a measured 44 KB of use. swap_ctx and the coro_* API are hidden, so nothing outside the library can interpose the scheduler; the switch carries CFI, so gdb and perf unwind through it; and coro_resume's loop-only rule is checked in every build rather than compiled out with -DNDEBUG. run.c never cleared g_stop and never removed the port it added, so a second ioxd_run was a silent no-op with doubled listeners; both are undone before it returns, and it returns non-zero when a worker's ring died. A failed pthread_create now stops and joins the workers already running instead of leaking them and their allocations. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- lib/http/run.c | 34 +++++-- lib/io/bufring.c | 18 +++- lib/io/bufring.h | 12 ++- lib/io/conn.c | 167 +++++++++++++++++++++--------- lib/io/conn.h | 7 +- lib/io/coro.c | 41 ++++++-- lib/io/coro.h | 23 +++-- lib/io/internal.h | 14 ++- lib/io/proactor.c | 224 ++++++++++++++++++++++++++++++++++++----- lib/io/proactor.h | 24 ++++- lib/io/switch_x86_64.S | 33 ++++++ lib/io/uring.c | 97 ++++++++++++------ lib/io/uring.h | 38 ++++++- 13 files changed, 588 insertions(+), 144 deletions(-) diff --git a/lib/http/run.c b/lib/http/run.c index 3a57f9d..9059336 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -79,13 +79,18 @@ static int run_workers(int workers, int port, handler_fn handler) { if (workers <= 0) workers = cpu_count(); - if (port != 0 && ioxd_listen(port, nullptr) < 0) - return 2; + int added = 0; /* listeners this call added: taken out again before returning */ + if (port != 0) { + if (ioxd_listen(port, nullptr) < 0) + return 2; + added = 1; + } if (g_n_listeners == 0) { fprintf(stderr, "ioxd_run: nothing to listen on\n"); return 2; } + g_stop = 0; /* a previous run's signal must not stop this one at once */ raise_nofile(); signal(SIGPIPE, SIG_IGN); struct sigaction sa; @@ -101,9 +106,11 @@ static int run_workers(int workers, int port, handler_fn handler) perror("calloc"); free(ws); free(th); + g_n_listeners -= added; return 1; } + int rc = 0, started = 0; for (int i = 0; i < workers; i++) { ws[i].id = i; ws[i].cpu = i; @@ -113,19 +120,28 @@ static int run_workers(int workers, int port, handler_fn handler) ws[i].stop = &g_stop; if (pthread_create(&th[i], nullptr, worker_thread, &ws[i]) != 0) { perror("pthread_create"); - return 1; + g_stop = 1; /* the ones already running must retire, not serve on alone */ + rc = 1; + break; } + started++; + } + if (started) { + fprintf(stderr, "ioxd: %d workers on", started); + for (int i = 0; i < g_n_listeners; i++) + fprintf(stderr, " :%u%s", g_listeners[i].port, g_listeners[i].tls ? "/tls" : ""); + fputc('\n', stderr); } - fprintf(stderr, "ioxd: %d workers on", workers); - for (int i = 0; i < g_n_listeners; i++) - fprintf(stderr, " :%u%s", g_listeners[i].port, g_listeners[i].tls ? "/tls" : ""); - fputc('\n', stderr); - for (int i = 0; i < workers; i++) + for (int i = 0; i < started; i++) pthread_join(th[i], nullptr); + for (int i = 0; i < started; i++) + if (ws[i].failed) /* a worker whose ring died: the run did not succeed */ + rc = 1; free(th); free(ws); - return 0; + g_n_listeners -= added; /* so a second ioxd_run does not serve this port twice */ + return rc; } /* A TLS listener's connection runs the handshake before its handler; a plain one goes straight in. */ diff --git a/lib/io/bufring.c b/lib/io/bufring.c index a53e4fd..628b6e2 100644 --- a/lib/io/bufring.c +++ b/lib/io/bufring.c @@ -19,11 +19,21 @@ static void *map_pages(size_t bytes) return m; } +/* The kernel named a buffer we never offered: the slab pointer it implies is outside the mapping, + * so there is nothing safe to do with it. */ +[[noreturn]] void ioxd__bufring_bad_id(uint16_t buf_id) +{ + fprintf(stderr, "ioxd: provided buffer id %u is outside the ring (BUF_COUNT %d)\n", buf_id, BUF_COUNT); + abort(); +} + /* Map the slab and the ring, register the ring as buffer group BGID, and offer every buffer. */ void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker) { - b->ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); - b->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); + b->ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); + b->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); + b->dirty = false; + b->returned = 0; struct io_uring_buf_reg reg; memset(®, 0, sizeof reg); @@ -57,8 +67,8 @@ void ioxd__bufring_return(struct bufring *b, uint16_t buf_id) slot->len = BUF_SIZE; slot->bid = buf_id; b->tail++; - b->returned = true; /* lets the loop re-arm starved recvs */ - b->dirty = true; /* tail needs publishing before the enter */ + b->returned++; /* how many recvs the loop may re-arm */ + b->dirty = true; /* tail needs publishing before the enter */ } /* Publish staged returns to the kernel. */ diff --git a/lib/io/bufring.h b/lib/io/bufring.h index 0faca31..9676cc6 100644 --- a/lib/io/bufring.h +++ b/lib/io/bufring.h @@ -14,7 +14,8 @@ #ifndef BUF_COUNT #define BUF_COUNT 4096 /* provided recv buffers per worker, power of two */ #endif -static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COUNT <= 65536, "BUF_COUNT: a power of two, at most 65536 (16-bit buffer ids)"); +static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COUNT >= 2 && BUF_COUNT <= 32768, + "BUF_COUNT: a power of two, at most 32768 (the kernel refuses a ring of 65536 entries)"); #ifndef BUF_SIZE #define BUF_SIZE 2048 /* bytes per recv buffer (a request rarely needs more) */ #endif @@ -26,7 +27,7 @@ struct bufring { uint8_t *slab; /* BUF_COUNT x BUF_SIZE */ unsigned tail; /* local tail, published to ring->tail */ bool dirty; /* staged returns awaiting one publish */ - bool returned; /* any return since the loop's last starved sweep */ + unsigned returned; /* returns since the loop's last starved sweep */ }; void ioxd__bufring_init (struct bufring *b, struct uring *ring, int worker); /* map, register, offer every buffer */ @@ -35,8 +36,13 @@ void ioxd__bufring_publish (struct bufring *b); void ioxd__bufring_unregister(struct bufring *b, struct uring *ring); /* before uring_exit */ void ioxd__bufring_unmap (struct bufring *b); /* after uring_exit */ -/* Where a buffer's bytes are. */ +[[noreturn]] void ioxd__bufring_bad_id(uint16_t buf_id); /* a buffer id outside the slab: abort */ + +/* Where a buffer's bytes are. The id comes from the kernel, so it is checked: a wrong one would + * hand the reader a pointer past the slab. One predicted branch, twice per request. */ static inline uint8_t *ioxd__bufring_at(const struct bufring *b, uint16_t buf_id) { + if (buf_id >= BUF_COUNT) + ioxd__bufring_bad_id(buf_id); return b->slab + (size_t)buf_id * BUF_SIZE; } diff --git a/lib/io/conn.c b/lib/io/conn.c index 97c2493..e18b7d6 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -33,6 +33,26 @@ static void submit_cancel(proactor_t *p, uint64_t target_user_data) sqe->user_data = TAG_IGNORE; } +/* Cancel the multishot recv, at most one cancel in flight: the queue-full policy would otherwise + * stage another on every arrival while the queue stays full. Cleared on the terminal CQE. */ +static void cancel_recv(proactor_t *p, conn_t *c) +{ + if (c->cancelling) + return; + c->cancelling = true; + submit_cancel(p, UD(c, TAG_RECV)); +} + +/* End the input once: the first reason wins, so a cancel we asked for afterwards does not + * overwrite the peer's FIN or the error that really ended it. */ +static void end_input(conn_t *c, int err) +{ + if (!c->eof) { + c->eof = true; + c->err = err; + } +} + /* ── the object ────────────────────────────────────────────────────────────────────────── */ /* Take a conn_t from the pool (or calloc one) and reset it for a fresh fd. Two owners hold it: @@ -50,18 +70,20 @@ conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd) abort(); } } - c->fd = fd; - c->p = p; - c->listener = l; - c->waiter = nullptr; - c->rx_head = 0; - c->rx_tail = 0; - c->recv = RECV_ARMED; - c->refs = 2; - c->closed = false; - c->eof = false; - c->err = 0; - c->pool_next = nullptr; + c->fd = fd; + c->p = p; + c->listener = l; + c->waiter = nullptr; + c->rx_head = 0; + c->rx_tail = 0; + c->recv = RECV_ARMED; + c->pausing = false; + c->cancelling = false; + c->refs = 2; + c->closed = false; + c->eof = false; + c->err = 0; + c->pool_next = nullptr; p->live++; return c; } @@ -106,7 +128,8 @@ void ioxd__arm_recv(proactor_t *p, conn_t *c) sqe->ioprio = IORING_RECV_MULTISHOT; sqe->buf_group = BGID; sqe->user_data = UD(c, TAG_RECV); - c->recv = RECV_ARMED; + c->recv = RECV_ARMED; + c->cancelling = false; /* a fresh arm: no cancel of ours is in flight */ } /* Resume the coroutine parked waiting for bytes, if there is one. It pops the queue itself. */ @@ -152,12 +175,14 @@ static void starved_push(proactor_t *p, conn_t *c) p->starved[p->nstarved++] = c; } -/* Forget a parked connection (it closed before any buffer came back). */ +/* Forget a parked connection (it closed before any buffer came back). The tail slides down rather + * than the last entry taking its place: the loop re-arms the list oldest first. */ static void starved_remove(proactor_t *p, conn_t *c) { for (unsigned i = 0; i < p->nstarved; i++) { if (p->starved[i] == c) { - p->starved[i] = p->starved[--p->nstarved]; + p->nstarved--; + memmove(&p->starved[i], &p->starved[i + 1], (p->nstarved - i) * sizeof *p->starved); return; } } @@ -174,12 +199,27 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) trace("[w%d] recv fd=%d result=%d more=%d buf=%d buf_id=%u queued=%u state=%d closed=%d eof=%d\n", p->id, c->fd, result, more, has_buf, buf_id, c->rx_tail - c->rx_head, c->recv, c->closed, c->eof); + if (!more) + c->cancelling = false; /* the multishot ends here: no cancel is left in flight */ + if (result == -ENOBUFS) { if (c->closed) { c->recv = RECV_DONE; conn_unref(c); return; } + if (c->pausing) { /* the pause we asked for; starvation stopped it first */ + c->pausing = false; + c->recv = RECV_PAUSED; + wake_reader(c); + return; + } + if (c->eof) { /* the input already ended: there is nothing to re-arm */ + c->recv = RECV_DONE; + wake_reader(c); + conn_unref(c); + return; + } c->recv = RECV_STARVED; note_starved(p); starved_push(p, c); @@ -189,34 +229,37 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) if (result <= 0) { /* peer FIN (0), an error, or our own cancel */ if (has_buf) ioxd__bufring_return(&p->bufs, buf_id); - if (c->pausing && result == -ECANCELED) { /* our pause, not the end of input */ + if (c->pausing && !c->closed && result == -ECANCELED) { /* our pause, not the end of input */ c->pausing = false; c->recv = RECV_PAUSED; wake_reader(c); return; } - if (!c->eof) { - c->eof = true; - c->err = result; - } + /* Kernel TLS reports a control record - the peer's alert, a KeyUpdate it cannot honour - + * as -EIO. TLS.md calls that the end of input, so a close_notify reads like a FIN. */ + end_input(c, result == -EIO && c->listener->tls ? 0 : result); c->recv = RECV_DONE; wake_reader(c); /* a parked reader sees 0 / -errno */ conn_unref(c); /* the recv's ref; may recycle c */ return; } - if (c->closed) { + if (!has_buf) { + /* A positive result must name the buffer it landed in. Nothing can be done with bytes we + * cannot find, so end the input the way the queue-full policy does. */ + end_input(c, -EPROTO); + if (more) + cancel_recv(p, c); + wake_reader(c); + } else if (c->closed) { ioxd__bufring_return(&p->bufs, buf_id); /* the handler is gone; nobody will read it */ } else if (c->rx_tail - c->rx_head == RX_QUEUE) { /* The handler is not draining. Rather than let one peer hoard the buffer group, end its * input: the next read sees -ENOBUFS. */ ioxd__bufring_return(&p->bufs, buf_id); - if (!c->eof) { - c->eof = true; - c->err = -ENOBUFS; - } + end_input(c, -ENOBUFS); if (more) - submit_cancel(p, UD(c, TAG_RECV)); + cancel_recv(p, c); wake_reader(c); } else { struct rx_item *item = &c->rx[c->rx_tail++ & RX_MASK]; @@ -227,7 +270,7 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) } if (!more) { /* the kernel ended the multishot: re-arm */ - if (c->pausing) { /* ended on its own while a pause was asked */ + if (c->pausing && !c->closed) { /* ended on its own while a pause was asked */ c->pausing = false; c->recv = RECV_PAUSED; wake_reader(c); @@ -237,23 +280,37 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) c->recv = RECV_DONE; conn_unref(c); } + } else if (p->cancel_each && !c->closed) { /* shutting down without a blanket cancel */ + cancel_recv(p, c); } } +/* Shutdown: a recv parked on -ENOBUFS holds no operation the kernel can cancel, so end its input + * by hand. Its handler wakes with an error, unwinds and closes the connection like any other. */ +void ioxd__recv_drain(conn_t *c) +{ + if (c->recv != RECV_STARVED) + return; + end_input(c, -ECANCELED); + c->recv = RECV_DONE; + wake_reader(c); + conn_unref(c); +} + /* ── close ─────────────────────────────────────────────────────────────────────────────── */ -/* Close the socket: a plain close, or under fixed files a CLOSE SQE on its slot, which rides the - * next enter with the rest of the batch instead of costing a syscall here. */ -static void close_socket(proactor_t *p, int fd) +/* Close the socket with a CLOSE SQE, which rides the next enter with the rest of the batch: no + * syscall here, and the close stays in order behind the SQEs already staged for that same socket - + * a plain close(2) would race them. A file slot is named by index, a real fd by itself. */ +void ioxd__close_socket(proactor_t *p, int fd) { - if (!p->ring.fixed_files) { - close(fd); - return; - } struct io_uring_sqe *sqe = ioxd__sqe(p); - sqe->opcode = IORING_OP_CLOSE; - sqe->file_index = (uint32_t)fd + 1; /* slot + 1; 0 would mean "a real fd" */ - sqe->user_data = TAG_IGNORE; + sqe->opcode = IORING_OP_CLOSE; + sqe->user_data = TAG_CLOSE; /* only a negative result is news */ + if (p->ring.fixed_files) + sqe->file_index = (uint32_t)fd + 1; /* slot + 1; 0 would mean "a real fd" */ + else + sqe->fd = fd; } /* Runs once when the handler returns: cancel the recv, hand unread buffers back, close the fd, @@ -266,7 +323,7 @@ static void conn_close(conn_t *c) p->id, c->fd, c->recv, c->eof, c->err, c->rx_tail - c->rx_head); if (c->recv == RECV_ARMED) { - submit_cancel(p, UD(c, TAG_RECV)); + cancel_recv(p, c); } else if (c->recv == RECV_STARVED || c->recv == RECV_PAUSED) { if (c->recv == RECV_STARVED) starved_remove(p, c); @@ -276,7 +333,7 @@ static void conn_close(conn_t *c) while (c->rx_head != c->rx_tail) ioxd__bufring_return(&p->bufs, c->rx[c->rx_head++ & RX_MASK].buf_id); - close_socket(p, c->fd); + ioxd__close_socket(p, c->fd); conn_unref(c); } @@ -295,8 +352,6 @@ void ioxd__conn_main(void *arg) /* ── awaits ────────────────────────────────────────────────────────────────────────────── */ -/* Copy the next delivered slice into buf, parking while the queue is empty. Returns the byte - * count, 0 when the peer closed, or -errno. A fully consumed buffer goes back to the ring. */ /* The next received buffer, whole: the caller owns it until ioxd__bufring_return. Suspends until one * arrives; 1 with the item, 0 at the end of input, <0 an error. */ int ioxd__await_item(conn_t *c, struct rx_item *out) @@ -315,13 +370,14 @@ int ioxd__await_item(conn_t *c, struct rx_item *out) } -/* Send all of buf: a SEND SQE per round, parked until its CQE. Returns len, or -errno. */ +/* Stop the multishot recv so nothing more leaves the socket, and park until it has stopped. + * 0 once it is paused, -1 when the input ended instead - the caller has nothing left to program. */ int ioxd__recv_pause(conn_t *c) { proactor_t *p = c->p; if (c->recv == RECV_ARMED) { c->pausing = true; - submit_cancel(p, UD(c, TAG_RECV)); + cancel_recv(p, c); while (c->recv == RECV_ARMED) { /* data may still land meanwhile: fine, it is queued */ c->waiter = coro_current(); coro_yield(); @@ -332,13 +388,28 @@ int ioxd__recv_pause(conn_t *c) starved_remove(p, c); c->recv = RECV_PAUSED; } + if (c->eof) /* it ended while we were stopping it */ + return -1; return c->recv == RECV_PAUSED ? 0 : -1; } -void ioxd__recv_resume(conn_t *c) +/* Arm the recv again after a pause. False when there is nothing to arm - the input ended, or the + * handler is already gone - so a prologue learns that its connection went away under it. */ +bool ioxd__recv_resume(conn_t *c) { - if (c->recv == RECV_PAUSED) - ioxd__arm_recv(c->p, c); + if (c->recv != RECV_PAUSED || c->eof || c->closed) + return false; + if (c->p->draining) { + /* The worker is stopping and its blanket cancel has already been and gone: a recv armed + * now would never be cancelled and the handler would park behind it until the grace period + * ran out. End the input instead, and let the handler unwind like everyone else's. */ + end_input(c, -ECANCELED); + c->recv = RECV_DONE; + conn_unref(c); /* the recv's ref; the handler still holds its own */ + return false; + } + ioxd__arm_recv(c->p, c); + return true; } int ioxd__recv_exact(conn_t *c, void *dst, size_t n) @@ -378,6 +449,9 @@ int ioxd__setsockopt(conn_t *c, int level, int name, const void *val, size_t len sqe->optval = (uint64_t)(uintptr_t)val; sqe->optlen = (uint32_t)len; int rc = await_op(sqe, &op); + /* The plain fallback needs a real descriptor, and under registered files (the default) c->fd is + * a slot index, so it is dead code there: kernel TLS then wants a kernel with + * SOCKET_URING_OP_SETSOCKOPT (6.7+), or a build with -DFIXED_FILES=0. */ if ((rc == -EOPNOTSUPP || rc == -EINVAL) && !c->p->ring.fixed_files) /* a kernel without the command */ rc = setsockopt(c->fd, level, name, val, (socklen_t)len) < 0 ? -errno : 0; return rc; @@ -396,6 +470,7 @@ int ioxd__sendmsg(conn_t *c, const struct msghdr *msg) return await_op(sqe, &op); } +/* Send all of buf: a SEND SQE per round, parked until its CQE. Returns len, or -errno. */ int await_send(conn_t *c, const void *buf, size_t len) { const uint8_t *src = buf; diff --git a/lib/io/conn.h b/lib/io/conn.h index 0798a33..2778f5a 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -14,6 +14,8 @@ #ifndef RX_QUEUE #define RX_QUEUE 64 /* undelivered slices one connection may hold, pow 2 */ #endif +static_assert(((unsigned)RX_QUEUE & ((unsigned)RX_QUEUE - 1U)) == 0 && RX_QUEUE >= 2, + "RX_QUEUE: a power of two (RX_MASK is a bit mask over it)"); #define RX_MASK (RX_QUEUE - 1U) #ifndef CONN_POOL_MAX #define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker */ @@ -47,6 +49,7 @@ struct conn { unsigned rx_head, rx_tail; enum recv_state recv; bool pausing; /* a cancel is in flight to pause the recv */ + bool cancelling; /* a cancel is in flight: do not stage a second one */ int refs; /* the handler coroutine + the armed/starved recv */ bool closed; /* the handler returned; fd closed */ bool eof; /* recv ended: peer FIN, error, or queue overflow */ @@ -64,7 +67,7 @@ int ioxd__await_item(conn_t *c, struct rx_item *out); /* the next received bu * what it already delivered, read exact byte counts straight from the socket, program the * socket, then resume. All suspend like any await. */ int ioxd__recv_pause (conn_t *c); /* 0 once stopped; -1 if the input already ended */ -void ioxd__recv_resume(conn_t *c); +bool ioxd__recv_resume(conn_t *c); /* true once re-armed; false if it ended meanwhile */ int ioxd__recv_exact (conn_t *c, void *dst, size_t n); /* n bytes into dst, or <0 */ int ioxd__setsockopt (conn_t *c, int level, int name, const void *val, size_t len); /* 0 or -errno; over the ring */ int ioxd__sendmsg (conn_t *c, const struct msghdr *msg); /* one sendmsg, for a message with control data */ @@ -74,4 +77,6 @@ conn_t *ioxd__conn_new(proactor_t *p, struct listener *l, int fd); /* from the void ioxd__conn_main(void *arg); /* the connection's coroutine body */ void ioxd__arm_recv(proactor_t *p, conn_t *c); /* one multishot recv */ void ioxd__on_recv(proactor_t *p, conn_t *c, int res, unsigned flags); /* a recv CQE */ +void ioxd__recv_drain(conn_t *c); /* shutdown: end a recv parked on -ENOBUFS */ +void ioxd__close_socket(proactor_t *p, int fd); /* close a socket through the ring */ void ioxd__conn_pool_drain(proactor_t *p); /* free the pool at teardown */ diff --git a/lib/io/coro.c b/lib/io/coro.c index 9660465..0587291 100644 --- a/lib/io/coro.c +++ b/lib/io/coro.c @@ -15,6 +15,14 @@ static thread_local void *loop_sp; /* the loop's stack pointer while a coro #ifndef CORO_POOL_MAX #define CORO_POOL_MAX 512 /* warm stacks kept per worker, reused instead of munmap/mmap */ #endif +#ifndef CORO_GUARD +#define CORO_GUARD (64UL * 1024) /* PROT_NONE below every stack. Big enough that a frame cannot + * step over it into the neighbour below: ioxd__conn_main's is + * 25 KB and ioxd__serve's 10 KB, so one page would not do. + * Address space only - PROT_NONE pages have no RSS. */ +#endif +/* Pooled stacks keep their pages: no madvise(MADV_DONTNEED) on the way in. The trade is deliberate, + * a warm stack for the next connection against the RSS of an idle one, and the pool is capped. */ static thread_local coro_t *pool_head; /* free list of whole stack blocks, linked via ->next */ static thread_local int pool_count; @@ -34,17 +42,25 @@ static void coro_entry(void) abort(); /* a finished coroutine must never be resumed */ } -/* Get a stack - pooled, or freshly mapped with a guard page - and forge its first frame so the +/* Get a stack - pooled, or freshly mapped with its guard - and forge its first frame so the * first switch into it 'returns' into coro_entry. */ coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes) { size_t page = (size_t)sysconf(_SC_PAGESIZE); stack_bytes = (stack_bytes + page - 1) & ~(page - 1); - size_t total = stack_bytes + page; /* plus the guard page */ + size_t guard = (CORO_GUARD + page - 1) & ~(page - 1); + size_t total = stack_bytes + guard; coro_t *c; - if (pool_head && pool_head->size == total) { - /* a warm stack: guard page still armed, no mmap, no mprotect */ + if (pool_head) { + /* Every caller passes STACK_SIZE, so the pool holds one size. A mismatch would mean a + * second size is in play and this reuse would hand back the wrong stack. */ + if (pool_head->size != total) { + fprintf(stderr, "ioxd: coroutine stack size %zu does not match the pooled %zu\n", + total, pool_head->size); + abort(); + } + /* a warm stack: guard still armed, no mmap, no mprotect */ c = pool_head; pool_head = c->next; pool_count--; @@ -55,7 +71,7 @@ coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes) perror("mmap(stack)"); abort(); } - if (mprotect(mem, page, PROT_NONE) < 0) { /* overflow faults here, not a neighbour */ + if (mprotect(mem, guard, PROT_NONE) < 0) { /* overflow faults here, not a neighbour */ perror("mprotect(guard)"); abort(); } @@ -89,6 +105,7 @@ coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes) * idle stacks kept, not how many coroutines may run. */ static void coro_destroy(coro_t *c) { + c->sp = nullptr; /* the frame it named is gone; a stale sp must not be switched to */ if (pool_count < CORO_POOL_MAX) { c->next = pool_head; pool_head = c; @@ -109,10 +126,20 @@ void coro_pool_drain(void) pool_count = 0; } -/* Loop only: switch into c until it yields; if it finished, recycle its stack. */ +/* Loop only: switch into c until it yields; if it finished, recycle its stack. Both rules are + * checked in every build: an assert would go away under -DNDEBUG, and breaking either corrupts the + * loop's saved stack pointer or switches to a stack that has been recycled - neither of which + * shows up as anything but a crash somewhere else. */ void coro_resume(coro_t *c) { - assert(cur == nullptr && "coro_resume is loop-only; a coroutine spawns, it never resumes"); + if (cur) { + fprintf(stderr, "ioxd: coro_resume from inside a coroutine; only the loop resumes\n"); + abort(); + } + if (c->done) { + fprintf(stderr, "ioxd: coro_resume of a coroutine that already finished\n"); + abort(); + } cur = c; swap_ctx(&loop_sp, c->sp); cur = nullptr; diff --git a/lib/io/coro.h b/lib/io/coro.h index 5fe003b..eeebe66 100644 --- a/lib/io/coro.h +++ b/lib/io/coro.h @@ -9,14 +9,25 @@ * Discipline: only the loop calls coro_resume, only a coroutine calls coro_yield. A coroutine * that wants to start another one hands it to the scheduler (proactor_spawn); resuming from * inside a coroutine would overwrite the loop's saved stack pointer. + * + * Two things the switch does not carry, both deliberate. It saves the six callee-saved registers + * and nothing else, so MXCSR and the x87 control word - the rounding mode, the denormal and + * exception masks - are whatever the last coroutine left behind: a handler that changes an FP mode + * must put it back before it yields. And switch_x86_64.S carries no .note.gnu.property, which + * leaves the whole linked program without the IBT/SHSTK markings, so no shadow stack is ever armed + * around a stack this file forged by hand. */ #pragma once #include +/* Private to libioxd: hidden symbols cannot be interposed, so nothing outside the library can + * substitute a scheduler primitive (the .S hides swap_ctx the same way). */ +#define CORO_API __attribute__((visibility("hidden"))) + typedef struct coro { void *sp; /* saved stack pointer while suspended */ - void *stack; /* mmap base; the lowest page is the guard */ + void *stack; /* mmap base; the low CORO_GUARD bytes are the guard */ size_t size; /* mapping size, guard included */ void (*fn)(void *); void *arg; @@ -25,16 +36,16 @@ typedef struct coro { } coro_t; /* Allocate a stack and forge its first frame. The descriptor lives at the top of that stack. */ -coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes); +CORO_API coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes); /* Loop only. Run c until it yields; if it finished, its stack is unmapped before returning. */ -void coro_resume(coro_t *c); +CORO_API void coro_resume(coro_t *c); /* Coroutine only. Back to the loop; returns when the loop resumes this coroutine again. */ -void coro_yield(void); +CORO_API void coro_yield(void); /* The running coroutine, nullptr on the loop stack. */ -coro_t *coro_current(void); +CORO_API coro_t *coro_current(void); /* Unmap the per-thread free list of pooled stacks. Call at worker teardown, on the worker thread. */ -void coro_pool_drain(void); +CORO_API void coro_pool_drain(void); diff --git a/lib/io/internal.h b/lib/io/internal.h index d94475b..24719d6 100644 --- a/lib/io/internal.h +++ b/lib/io/internal.h @@ -19,12 +19,16 @@ /* ── completion routing ────────────────────────────────────────────────────────────────── */ -/* user_data is a pointer with a tag in its low three bits; everything pointed at is 8-aligned. */ +/* user_data is a pointer with a tag in its low three bits; everything pointed at is 8-aligned. + * TAG_IGNORE is the zero tag on purpose: an SQE whose user_data was never set then dispatches as + * "nobody waits for this" instead of as an op with a null pointer. */ enum { - TAG_OP = 0, /* an op_t: a one-shot await */ - TAG_RECV = 1, /* a conn_t: its multishot recv */ - TAG_ACCEPT = 2, /* the listener's multishot accept */ - TAG_IGNORE = 3, /* a completion nobody waits for */ + TAG_IGNORE = 0, /* a completion nobody waits for */ + TAG_OP = 1, /* an op_t: a one-shot await */ + TAG_RECV = 2, /* a conn_t: its multishot recv */ + TAG_ACCEPT = 3, /* the listener's multishot accept */ + TAG_CLOSE = 4, /* a socket's close: only a failure is news */ + TAG_DRAIN = 5, /* the shutdown's blanket cancel */ }; #define UD(ptr, tag) ((uint64_t)(uintptr_t)(ptr) | (uint64_t)(tag)) diff --git a/lib/io/proactor.c b/lib/io/proactor.c index 4521a0f..273d927 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -14,20 +14,40 @@ #include #include #include +#include #include +#define DRAIN_GRACE_MS 2000 /* how long a stopping worker waits for its connections */ + +/* Coarse monotonic milliseconds: for the drain deadline and the once-a-second retries, never for + * anything that needs better than a tick. */ +static uint64_t now_ms(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + return (uint64_t)ts.tv_sec * 1000U + (uint64_t)(ts.tv_nsec / 1000000L); +} + /* ── submission ────────────────────────────────────────────────────────────────────────── */ -/* Claim an SQE. If the SQ is full mid-batch, flush without waiting and retry. */ +/* Claim an SQE. If the SQ is full mid-batch, submit what is staged and retry. -EBUSY means the + * kernel is holding completions it could not fit in the CQ and will not take more submissions, so + * the retry enters with GETEVENTS to flush them: safe mid-batch, since the loop dispatches whatever + * lands next time round. */ struct io_uring_sqe *ioxd__sqe(proactor_t *p) { struct io_uring_sqe *sqe = uring_get_sqe(&p->ring); + int rc = 0; for (int i = 0; !sqe && i < 16; i++) { - uring_submit(&p->ring); + ioxd__bufring_publish(&p->bufs); /* the kernel must see staged returns before this enter */ + rc = uring_submit(&p->ring); + if (rc == -EBUSY || rc == -EAGAIN || rc == -EINTR) + rc = uring_submit_wait(&p->ring, 0, nullptr); /* reap without waiting; the CQ has room again */ sqe = uring_get_sqe(&p->ring); } if (!sqe) { - fprintf(stderr, "[w%d] SQ still full after flushing\n", p->id); + fprintf(stderr, "[w%d] SQ still full after flushing: %s\n", + p->id, rc < 0 ? strerror(-rc) : "the kernel is not consuming it"); abort(); } return sqe; @@ -35,9 +55,29 @@ struct io_uring_sqe *ioxd__sqe(proactor_t *p) /* ── accept ────────────────────────────────────────────────────────────────────────────── */ +/* Whether this worker may take another connection. Under registered files a socket lives in a + * slot, so the table is a hard ceiling: better to stop arming than to fail one accept per arrival. */ +static bool accept_room(const proactor_t *p) +{ + return !p->draining && (p->file_slots == 0 || p->live < p->file_slots); +} + +/* Leave the accept unarmed until there is room again. */ +static void stall_accept(struct listener *l) +{ + l->stalled = true; + l->stalled_live = l->p->live; + l->retry_at = (time_t)(now_ms() / 1000U) + 1; +} + /* Arm the multishot accept: one SQE, then a CQE per new connection. */ static void arm_accept(struct listener *l) { + if (!accept_room(l->p)) { + stall_accept(l); + return; + } + l->stalled = false; struct io_uring_sqe *sqe = ioxd__sqe(l->p); sqe->opcode = IORING_OP_ACCEPT; sqe->fd = l->fd; @@ -47,21 +87,67 @@ static void arm_accept(struct listener *l) sqe->file_index = IORING_FILE_INDEX_ALLOC; /* land each socket in a free slot, not an fd */ } +/* Re-arm a listener that stalled: once a connection has closed (p->live below what it was), and + * once a second regardless, since the shortage may be another thread's and no close of ours would + * ever announce it. Only ever a handful of listeners, and only after an accept ran out of room. */ +static void rearm_stalled(proactor_t *p) +{ + bool any = false; + for (int i = 0; i < p->n_listeners; i++) + any |= p->listeners[i].stalled; + if (!any) + return; + + time_t now = (time_t)(now_ms() / 1000U); + for (int i = 0; i < p->n_listeners; i++) { + struct listener *l = &p->listeners[i]; + if (l->stalled && (p->live < l->stalled_live || now >= l->retry_at)) + arm_accept(l); + } +} + +/* Out of descriptors, slots or memory: the next accept would fail the same way. */ +static bool accept_exhausted(int err) +{ + return err == -ENFILE || err == -EMFILE || err == -ENOMEM || err == -ENOBUFS; +} + +/* Log an accept error at most once a second per listener, with how many it stands for: a full file + * table would otherwise write one line per arrival, forever. */ +static void note_accept_error(struct listener *l, int result) +{ + time_t now = (time_t)(now_ms() / 1000U); + l->err_since_log++; + if (now < l->err_log_at) + return; + fprintf(stderr, "[w%d] accept :%u: %s (%llu since the last line)\n", + l->p->id, l->port, strerror(-result), (unsigned long long)l->err_since_log); + l->err_since_log = 0; + l->err_log_at = now + 1; +} + /* An accept CQE: wrap the new fd in a conn, arm its recv, spawn its handler coroutine. */ static void on_accept(struct listener *l, int result, unsigned flags) { proactor_t *p = l->p; trace("[w%d] accept :%u result=%d more=%d\n", p->id, l->port, result, !!(flags & IORING_CQE_F_MORE)); - if (result >= 0) { + if (result >= 0 && p->draining) { + ioxd__close_socket(p, result); /* accepted just before the cancel: no new work */ + } else if (result >= 0) { conn_t *c = ioxd__conn_new(p, l, result); /* TCP_NODELAY came with the listener */ ioxd__arm_recv(p, c); proactor_spawn(p, ioxd__conn_main, c); p->accepted++; - } else { - fprintf(stderr, "[w%d] accept :%u: %s\n", p->id, l->port, strerror(-result)); + } else if (!(p->draining && result == -ECANCELED)) { /* our own shutdown cancel is not an error */ + note_accept_error(l, result); } - if (!(flags & IORING_CQE_F_MORE)) - arm_accept(l); + if (flags & IORING_CQE_F_MORE) /* still armed: nothing to do */ + return; + if (result < 0 && accept_exhausted(result)) { + stall_accept(l); /* rearm_stalled picks it up when there is room */ + return; + } + arm_accept(l); } /* ── completions ───────────────────────────────────────────────────────────────────────── */ @@ -85,6 +171,17 @@ static void dispatch(proactor_t *p, struct io_uring_cqe *cqe) case TAG_ACCEPT: on_accept(ptr, cqe->res, cqe->flags); break; + case TAG_CLOSE: /* a failed close leaks a slot: say so */ + if (cqe->res < 0) + fprintf(stderr, "[w%d] close: %s\n", p->id, strerror(-cqe->res)); + break; + case TAG_DRAIN: /* the shutdown's one blanket cancel */ + if (cqe->res < 0 && cqe->res != -ENOENT) { + fprintf(stderr, "[w%d] cancel all: %s; cancelling connections one at a time\n", + p->id, strerror(-cqe->res)); + p->cancel_each = true; + } + break; default: /* TAG_IGNORE: cancel acknowledgements */ break; } @@ -116,16 +213,21 @@ static void run_ready(proactor_t *p) } } -/* Re-arm every recv parked on -ENOBUFS, but only once a buffer actually came back, so a parked - * connection never spins the loop. */ +/* Re-arm recvs parked on -ENOBUFS, at most one per buffer that actually came back since the last + * sweep: re-arming the whole list on a single return would send them all back to the empty ring. + * Oldest first, so a connection parked early is not starved by later ones. */ static void rearm_starved(proactor_t *p) { - if (p->nstarved == 0 || !p->bufs.returned) + unsigned room = p->bufs.returned; + p->bufs.returned = 0; /* only this round's returns count as room */ + if (p->nstarved == 0 || room == 0) return; - p->bufs.returned = false; - for (unsigned i = 0; i < p->nstarved; i++) + + unsigned n = room < p->nstarved ? room : p->nstarved; + for (unsigned i = 0; i < n; i++) ioxd__arm_recv(p, p->starved[i]); /* keeps the ref it already holds */ - p->nstarved = 0; + p->nstarved -= n; + memmove(p->starved, p->starved + n, p->nstarved * sizeof *p->starved); } /* ── listener ──────────────────────────────────────────────────────────────────────────── */ @@ -160,6 +262,39 @@ static int listener_open(uint16_t port) return fd; } +/* ── shutdown ──────────────────────────────────────────────────────────────────────────── */ + +/* Stop is set: take nothing new and ask the kernel to end everything in flight, so the loop can + * keep running until the connections have closed themselves. The accepts are cancelled by name + * (they must stop even on a kernel without CANCEL_ANY), then one ASYNC_CANCEL with + * IORING_ASYNC_CANCEL_ANY (5.19+) takes every recv and every send a coroutine is parked on. Their + * awaits fail with -ECANCELED, the handlers unwind, and conn_close returns the stacks and the fds. + * A recv parked on -ENOBUFS holds no operation to cancel, so it is ended here by hand. */ +static void begin_drain(proactor_t *p) +{ + p->draining = true; + for (int i = 0; i < p->n_listeners; i++) { + struct listener *l = &p->listeners[i]; + if (!l->stalled) { + struct io_uring_sqe *sqe = ioxd__sqe(p); + sqe->opcode = IORING_OP_ASYNC_CANCEL; + sqe->fd = -1; + sqe->addr = UD(l, TAG_ACCEPT); + sqe->user_data = TAG_IGNORE; + } + l->stalled = true; /* nothing re-arms it from here on */ + } + + struct io_uring_sqe *sqe = ioxd__sqe(p); + sqe->opcode = IORING_OP_ASYNC_CANCEL; + sqe->fd = -1; + sqe->cancel_flags = IORING_ASYNC_CANCEL_ANY; + sqe->user_data = UD(p, TAG_DRAIN); /* its result says whether the kernel knew it */ + + while (p->nstarved) + ioxd__recv_drain(p->starved[--p->nstarved]); +} + /* ── the loop ──────────────────────────────────────────────────────────────────────────── */ /* Pin this thread to the idx-th CPU the process may run on. Reading the inherited affinity mask @@ -210,7 +345,8 @@ void proactor_run(proactor_t *p) int rc = uring_init(&p->ring, RING_ENTRIES); /* on this thread: DEFER_TASKRUN ties it here */ if (rc < 0) { - fprintf(stderr, "[w%d] io_uring_setup: %s\n", p->id, strerror(-rc)); + fprintf(stderr, "[w%d] io_uring_setup: %s%s\n", p->id, strerror(-rc), + rc == -EPERM ? " (io_uring is disabled: see /proc/sys/kernel/io_uring_disabled)" : ""); abort(); } #ifndef NO_REG_RING @@ -218,16 +354,20 @@ void proactor_run(proactor_t *p) #endif unsigned slots = fixed_slots(); /* optional: sockets live in a file table */ - if (slots) - uring_register_files_sparse(&p->ring, slots); + if (slots && uring_register_files_sparse(&p->ring, slots) == 0) + p->file_slots = slots; /* the ceiling accept_room holds us to */ ioxd__bufring_init(&p->bufs, &p->ring, p->id); - char ports[IOXD_MAX_LISTENERS * 12] = "", *at = ports; + char ports[IOXD_MAX_LISTENERS * 12] = ""; + size_t at = 0; for (int i = 0; i < p->n_listeners; i++) { struct listener *l = &p->listeners[i]; l->p = p; l->fd = listener_open(l->port); arm_accept(l); - at += snprintf(at, sizeof ports - (size_t)(at - ports), "%s:%u%s", i ? " " : "", l->port, l->tls ? "/tls" : ""); + int n = snprintf(ports + at, sizeof ports - at, "%s:%u%s", i ? " " : "", l->port, l->tls ? "/tls" : ""); + if (n < 0) + break; + at += (size_t)n < sizeof ports - at ? (size_t)n : sizeof ports - at - 1; /* truncated: stop growing */ } fprintf(stderr, "[w%d] listening on %s (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", p->id, ports, p->cpu, BUF_COUNT, BUF_SIZE, p->ring.sq_entries, @@ -236,7 +376,15 @@ void proactor_run(proactor_t *p) p->ring.fixed_files ? ", fixed files" : ""); struct __kernel_timespec wait_at_most = { .tv_sec = 0, .tv_nsec = 100000000L }; /* 100 ms: so an idle worker notices *stop */ - while (!*p->stop) { + uint64_t deadline = 0; + for (;;) { + if (*p->stop && !p->draining) { + begin_drain(p); /* from here the stop flag is not read again */ + deadline = now_ms() + DRAIN_GRACE_MS; + } + if (p->draining && (p->live == 0 || now_ms() >= deadline)) + break; + run_ready(p); rearm_starved(p); ioxd__bufring_publish(&p->bufs); @@ -244,17 +392,30 @@ void proactor_run(proactor_t *p) rc = uring_submit_wait(&p->ring, 1, &wait_at_most); /* one syscall per batch */ if (rc < 0 && rc != -ETIME && rc != -EINTR && rc != -EAGAIN && rc != -EBUSY) { fprintf(stderr, "[w%d] io_uring_enter: %s\n", p->id, strerror(-rc)); + p->failed = rc; /* ioxd_run returns non-zero for it */ + *p->stop = 1; /* one ring is gone: retire the others too */ break; } - unsigned ready = uring_cq_ready(&p->ring); /* read the tail once */ - for (unsigned i = 0; i < ready; i++) - dispatch(p, uring_cqe_at(&p->ring, i)); /* handlers run in here */ - uring_cq_advance(&p->ring, ready); /* publish the head once */ + /* One CQE at a time, the head published per entry: a handler resuming in dispatch stages + * SQEs, and the kernel needs somewhere to put their completions before the batch is over. */ + unsigned ready = uring_cq_ready(&p->ring); /* read the tail once */ + for (unsigned i = 0; i < ready; i++) { + struct io_uring_cqe cqe = *uring_cqe_at(&p->ring, 0); + uring_cq_advance(&p->ring, 1); + dispatch(p, &cqe); /* handlers run in here */ + } + rearm_stalled(p); /* a close may have made room to accept again */ } - fprintf(stderr, "[w%d] stopping: %llu accepted, %u still open\n", - p->id, (unsigned long long)p->accepted, p->live); + /* The closes the last handlers staged have to reach the kernel before the ring goes, or their + * sockets stay open until the process exits. */ + ioxd__bufring_publish(&p->bufs); + uring_submit(&p->ring); + + fprintf(stderr, "[w%d] stopping: %llu accepted, %u still open, %llu cq overflows\n", + p->id, (unsigned long long)p->accepted, p->live, + (unsigned long long)p->ring.cq_overflows); /* Sockets, then the ring (which cancels every in-flight op and drops its buffer references), * then the memory the kernel could still have referenced. */ @@ -262,8 +423,17 @@ void proactor_run(proactor_t *p) close(p->listeners[i].fd); ioxd__bufring_unregister(&p->bufs, &p->ring); uring_exit(&p->ring); - ioxd__bufring_unmap(&p->bufs); + if (p->live == 0) { + ioxd__bufring_unmap(&p->bufs); + } else { + /* Connections that outlived the grace period may still have a recv the kernel is holding + * a buffer for. Unmapping the slab under it would be worse than leaking it at exit. */ + fprintf(stderr, "[w%d] %u connections did not close in %d ms: the recv buffers stay mapped\n", + p->id, p->live, DRAIN_GRACE_MS); + } free(p->starved); + p->starved = nullptr; + p->nstarved = p->cap_starved = 0; ioxd__conn_pool_drain(p); coro_pool_drain(); } diff --git a/lib/io/proactor.h b/lib/io/proactor.h index 0e964a5..bb6094b 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -4,9 +4,13 @@ * here is touched by any other thread except the stop flag. * * The loop: run freshly spawned coroutines, re-arm recvs parked on -ENOBUFS, publish and enter - * once (submit everything staged, wait for >= 1 completion), dispatch the whole CQ batch, advance - * the head once. Dispatching resumes handler coroutines inline, so the sends they stage ride the - * next enter together with the batch. + * once (submit everything staged, wait for >= 1 completion), then dispatch the CQ batch one entry + * at a time, publishing the head per entry so the ring keeps room mid-batch. Dispatching resumes + * handler coroutines inline, so the sends they stage ride the next enter together with the batch. + * + * On stop the loop does not simply leave: it cancels the accepts and everything in flight, then + * keeps running until the last connection has closed itself or a two-second grace period is up, + * so parked coroutines wake with errors and their handlers unwind before anything is torn down. */ #pragma once @@ -24,7 +28,7 @@ #define RING_ENTRIES 4096 /* SQ depth; the CQ is twice that */ #endif #ifndef STACK_SIZE -#define STACK_SIZE (64UL * 1024) /* per coroutine, plus a guard page */ +#define STACK_SIZE (128UL * 1024) /* per coroutine, plus a 64 KB guard; only touched pages cost RSS */ #endif #ifndef FIXED_FILES #define FIXED_FILES 16384 /* registered file slots per worker; 0 disables */ @@ -45,6 +49,14 @@ struct listener { int fd; /* the socket, or its file slot under fixed files */ uint16_t port; void *tls; /* the port's certificate store, or nullptr: plain */ + + /* accept back-pressure: out of descriptors, file slots or memory, re-arming at once would + * spin, so the accept is left unarmed until there is room again (see rearm_stalled). */ + bool stalled; + unsigned stalled_live; /* p->live when it stalled: re-arm once that drops */ + time_t retry_at; /* ... or at this second, whichever comes first */ + time_t err_log_at; /* the next second an accept error may be logged */ + uint64_t err_since_log; /* accept errors swallowed since the last line */ }; struct proactor { @@ -66,9 +78,13 @@ struct proactor { time_t starved_log_at; /* the next second a log line may go out */ coro_t *ready_head, *ready_tail; /* spawned, not yet started */ unsigned live; /* open connections */ + unsigned file_slots; /* registered file table size, 0 when there is none */ uint64_t accepted; conn_t *conn_free; /* recycled conn_t objects, reused on accept */ unsigned conn_free_count; + bool draining; /* stop was seen: take nothing new, let the rest end */ + bool cancel_each; /* ... and CANCEL_ANY was refused: one at a time */ + int failed; /* 0, or the -errno that retired this worker */ }; /* The worker thread's whole life: ring, buffers, listener, loop until *stop, teardown. */ diff --git a/lib/io/switch_x86_64.S b/lib/io/switch_x86_64.S index 72b6171..c9f0f4f 100644 --- a/lib/io/switch_x86_64.S +++ b/lib/io/switch_x86_64.S @@ -7,28 +7,61 @@ * with them at the call site. (MXCSR and the x87 control word are technically callee-saved too; * nothing here changes them, so they are not preserved.) * + * Hidden: the scheduler's switch is not a symbol anything outside libioxd may interpose. + * + * The CFI describes one frame of six pushes. It is still right after the stack swap, because the + * stack being loaded was left in exactly that shape by its own trip through here (or forged that + * way by coro_create), so gdb and perf unwind out of either coroutine. + * * No .note.gnu.property on purpose: an unmarked object leaves the linked binary without the * IBT/SHSTK flags, so a shadow stack is never enabled around this hand-built frame. */ .text .globl swap_ctx + .hidden swap_ctx .type swap_ctx, @function swap_ctx: + .cfi_startproc pushq %rbp + .cfi_adjust_cfa_offset 8 + .cfi_offset %rbp, -16 pushq %rbx + .cfi_adjust_cfa_offset 8 + .cfi_offset %rbx, -24 pushq %r12 + .cfi_adjust_cfa_offset 8 + .cfi_offset %r12, -32 pushq %r13 + .cfi_adjust_cfa_offset 8 + .cfi_offset %r13, -40 pushq %r14 + .cfi_adjust_cfa_offset 8 + .cfi_offset %r14, -48 pushq %r15 + .cfi_adjust_cfa_offset 8 + .cfi_offset %r15, -56 movq %rsp, (%rdi) movq %rsi, %rsp popq %r15 + .cfi_restore %r15 + .cfi_adjust_cfa_offset -8 popq %r14 + .cfi_restore %r14 + .cfi_adjust_cfa_offset -8 popq %r13 + .cfi_restore %r13 + .cfi_adjust_cfa_offset -8 popq %r12 + .cfi_restore %r12 + .cfi_adjust_cfa_offset -8 popq %rbx + .cfi_restore %rbx + .cfi_adjust_cfa_offset -8 popq %rbp + .cfi_restore %rbp + .cfi_adjust_cfa_offset -8 ret + .cfi_endproc .size swap_ctx, .-swap_ctx .section .note.GNU-stack,"",@progbits diff --git a/lib/io/uring.c b/lib/io/uring.c index 44bd76b..8257723 100644 --- a/lib/io/uring.c +++ b/lib/io/uring.c @@ -31,10 +31,26 @@ int uring_register(struct uring *ring, unsigned opcode, void *arg, unsigned nr_a return rc < 0 ? -errno : (int)rc; } -/* Create the ring and mmap both rings plus the SQE array. 0, or -errno. */ -int uring_init(struct uring *ring, unsigned entries) +/* The struct owning nothing: no descriptor, no mapping. uring_exit over this unmaps nothing and + * closes nothing, which is what a failed init has to leave behind. */ +static void ring_clear(struct uring *ring) { memset(ring, 0, sizeof *ring); + ring->fd = ring->enter_fd = -1; +} + +/* Give up on a half-built ring: empty the struct and hand back the error. */ +static int ring_failed(struct uring *ring, int err) +{ + ring_clear(ring); + return err; +} + +/* Create the ring and mmap both rings plus the SQE array. 0, or -errno. On any failure the struct + * is left empty, so a caller that calls uring_exit anyway unmaps nothing and closes nothing. */ +int uring_init(struct uring *ring, unsigned entries) +{ + ring_clear(ring); /* SINGLE_ISSUER: only this thread submits, the kernel skips SQ locking. * DEFER_TASKRUN: completion work runs batched inside enter(GETEVENTS), never as an interrupt. @@ -42,51 +58,64 @@ int uring_init(struct uring *ring, unsigned entries) struct io_uring_params params; memset(¶ms, 0, sizeof params); params.flags = IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_NO_SQARRAY; - int fd = sys_setup(entries, ¶ms); - if (fd == -EINVAL) { + int fd = sys_setup(entries, ¶ms); + bool sq_array = false; + if (fd == -EINVAL) { /* maybe NO_SQARRAY, maybe not: try without it */ memset(¶ms, 0, sizeof params); params.flags = IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN; fd = sys_setup(entries, ¶ms); - ring->has_sq_array = true; + if (fd < 0) + return ring_failed(ring, -EINVAL); /* the first error was the real one */ + sq_array = true; } if (fd < 0) - return fd; + return ring_failed(ring, fd); if (!(params.features & IORING_FEAT_SINGLE_MMAP)) { /* every kernel since 5.4 */ close(fd); - return -ENOSYS; + return ring_failed(ring, -ENOSYS); } - ring->fd = fd; - ring->enter_fd = fd; - ring->sq_entries = params.sq_entries; - /* one mapping holds both rings; size it for whichever ends later */ - size_t sq_bytes = params.sq_off.array + (size_t)params.sq_entries * sizeof(unsigned); + /* One mapping holds both rings; size it for whichever ends later. Without the SQ index array + * sq_off.array is 0, so the SQ side ends after the last of its header words. */ + size_t sq_bytes = sq_array ? params.sq_off.array + (size_t)params.sq_entries * sizeof(unsigned) + : params.sq_off.dropped + sizeof(unsigned); size_t cq_bytes = params.cq_off.cqes + (size_t)params.cq_entries * sizeof(struct io_uring_cqe); - ring->ring_bytes = sq_bytes > cq_bytes ? sq_bytes : cq_bytes; - ring->ring_mem = mmap(nullptr, ring->ring_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, - fd, IORING_OFF_SQ_RING); - if (ring->ring_mem == MAP_FAILED) { + size_t ring_bytes = sq_bytes > cq_bytes ? sq_bytes : cq_bytes; + void *ring_mem = mmap(nullptr, ring_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, + fd, IORING_OFF_SQ_RING); + if (ring_mem == MAP_FAILED) { int e = -errno; close(fd); - return e; + return ring_failed(ring, e); } - ring->sqe_bytes = (size_t)params.sq_entries * sizeof(struct io_uring_sqe); - ring->sqe_mem = mmap(nullptr, ring->sqe_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, - fd, IORING_OFF_SQES); - if (ring->sqe_mem == MAP_FAILED) { + size_t sqe_bytes = (size_t)params.sq_entries * sizeof(struct io_uring_sqe); + void *sqe_mem = mmap(nullptr, sqe_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, + fd, IORING_OFF_SQES); + if (sqe_mem == MAP_FAILED) { int e = -errno; - munmap(ring->ring_mem, ring->ring_bytes); + munmap(ring_mem, ring_bytes); close(fd); - return e; + return ring_failed(ring, e); } - char *base = ring->ring_mem; + /* Everything is up: only now does the struct own an fd and two mappings. */ + ring->fd = fd; + ring->enter_fd = fd; + ring->sq_entries = params.sq_entries; + ring->has_sq_array = sq_array; + ring->ring_mem = ring_mem; + ring->ring_bytes = ring_bytes; + ring->sqe_mem = sqe_mem; + ring->sqe_bytes = sqe_bytes; + + char *base = ring_mem; ring->sq_head = (unsigned *)(base + params.sq_off.head); ring->sq_tail = (unsigned *)(base + params.sq_off.tail); - ring->sq_array = (unsigned *)(base + params.sq_off.array); + ring->sq_array = sq_array ? (unsigned *)(base + params.sq_off.array) : nullptr; + ring->sq_flags = (unsigned *)(base + params.sq_off.flags); ring->sq_mask = *(unsigned *)(base + params.sq_off.ring_mask); - ring->sqes = ring->sqe_mem; + ring->sqes = sqe_mem; ring->cq_head = (unsigned *)(base + params.cq_off.head); ring->cq_tail = (unsigned *)(base + params.cq_off.tail); @@ -105,6 +134,8 @@ int uring_register_ring_fd(struct uring *ring) int rc = uring_register(ring, IORING_REGISTER_RING_FDS, &up, 1); if (rc < 0) return rc; + if (rc != 1) /* the count registered: up.offset is only ours then */ + return -ENOSPC; ring->enter_fd = (int)up.offset; ring->enter_flags = IORING_ENTER_REGISTERED_RING; return 0; @@ -135,8 +166,8 @@ void uring_exit(struct uring *ring) } if (ring->sqe_mem) munmap(ring->sqe_mem, ring->sqe_bytes); if (ring->ring_mem) munmap(ring->ring_mem, ring->ring_bytes); - if (ring->fd > 0) close(ring->fd); - memset(ring, 0, sizeof *ring); + if (ring->fd >= 0) close(ring->fd); /* fd 0 is a legal descriptor */ + ring_clear(ring); } /* Claim the next SQE against the local tail, zeroed. nullptr when the SQ is full. */ @@ -168,6 +199,14 @@ static int flush_and_enter(struct uring *ring, unsigned wait_nr, unsigned flags, if (*ring->sq_tail != ring->sqe_tail) store_release(ring->sq_tail, ring->sqe_tail); + /* The CQ filled and the kernel is holding the rest in its overflow list, where nothing we do + * to the ring will find them. Only an enter flushes that backlog, so make one even when there + * is nothing to submit and nothing to wait for. */ + if (load_acquire(ring->sq_flags) & IORING_SQ_CQ_OVERFLOW) { + ring->cq_overflows++; + flags |= IORING_ENTER_GETEVENTS; + } + if (to_submit == 0 && wait_nr == 0 && !(flags & IORING_ENTER_GETEVENTS)) return 0; return sys_enter(ring->enter_fd, to_submit, wait_nr, flags | ring->enter_flags, arg, argsz); @@ -201,5 +240,7 @@ unsigned uring_cq_ready(struct uring *ring) /* Release n consumed CQEs; publishes the head once. */ void uring_cq_advance(struct uring *ring, unsigned n) { + if (n == 0) /* nothing consumed: no store, no barrier */ + return; store_release(ring->cq_head, *ring->cq_head + n); } diff --git a/lib/io/uring.h b/lib/io/uring.h index e38a315..dcd5bdf 100644 --- a/lib/io/uring.h +++ b/lib/io/uring.h @@ -13,6 +13,31 @@ /* Names for the newer bits, in case the build box's headers predate them (the kernel decides at * runtime; unsupported features fall back). */ +#ifndef IORING_SETUP_SINGLE_ISSUER +#define IORING_SETUP_SINGLE_ISSUER (1U << 12) +#endif +#ifndef IORING_SETUP_DEFER_TASKRUN +#define IORING_SETUP_DEFER_TASKRUN (1U << 13) +#endif +#ifndef IORING_SETUP_NO_SQARRAY +#define IORING_SETUP_NO_SQARRAY (1U << 16) +#endif +#ifndef IORING_SQ_CQ_OVERFLOW +#define IORING_SQ_CQ_OVERFLOW (1U << 1) +#endif +#ifndef IORING_ASYNC_CANCEL_ANY +#define IORING_ASYNC_CANCEL_ANY (1U << 2) +#endif +/* EXT_ARG and the struct it points at arrived together, so one guard covers both. */ +#ifndef IORING_ENTER_EXT_ARG +#define IORING_ENTER_EXT_ARG (1U << 3) +struct io_uring_getevents_arg { + uint64_t sigmask; + uint32_t sigmask_sz; + uint32_t pad; + uint64_t ts; +}; +#endif #ifndef IORING_REGISTER_RING_FDS #define IORING_REGISTER_RING_FDS 20 #define IORING_UNREGISTER_RING_FDS 21 @@ -28,7 +53,7 @@ #endif struct uring { - int fd; + int fd; /* -1 until both mappings are up (see uring_init) */ int enter_fd; /* fd, or the registered-ring index (see enter_flags) */ unsigned enter_flags; /* 0, or IORING_ENTER_REGISTERED_RING */ bool fixed_files; /* a sparse registered file table exists */ @@ -36,7 +61,8 @@ struct uring { /* submission side */ unsigned *sq_head; /* kernel-written consumer index */ unsigned *sq_tail; /* our published producer index */ - unsigned *sq_array; /* SQ index array; unused under NO_SQARRAY */ + unsigned *sq_array; /* SQ index array; nullptr under NO_SQARRAY */ + unsigned *sq_flags; /* kernel-written: IORING_SQ_CQ_OVERFLOW */ unsigned sq_mask, sq_entries; unsigned sqe_tail; /* local tail: claimed, not yet published */ struct io_uring_sqe *sqes; @@ -47,6 +73,7 @@ struct uring { unsigned *cq_tail; /* kernel-written producer index */ unsigned cq_mask; struct io_uring_cqe *cqes; + uint64_t cq_overflows; /* enters that found the kernel holding overflowed CQEs */ /* mappings */ void *ring_mem; size_t ring_bytes; @@ -61,8 +88,11 @@ void uring_exit(struct uring *ring); struct io_uring_sqe *uring_get_sqe(struct uring *ring); /* Publish claimed SQEs and enter. uring_submit never waits; uring_submit_wait blocks until - * wait_nr completions are available or ts (may be nullptr) expires. Return: submitted count or - * -errno (-ETIME on timeout). Under DEFER_TASKRUN only the waiting form reaps completions. */ + * wait_nr completions are available or ts (may be nullptr) expires. Return: the number of SQEs the + * kernel consumed, or -errno. A timeout reads as -ETIME only when there was nothing to submit; + * with SQEs in hand the kernel returns the count it took and says nothing about the wait, so a + * non-negative return is not "completions are ready" - always drain the CQ. + * Under DEFER_TASKRUN only the waiting form reaps completions. */ int uring_submit(struct uring *ring); int uring_submit_wait(struct uring *ring, unsigned wait_nr, struct __kernel_timespec *ts); From 48a12972d2d5a3604e3ecc14ea1e0155721d83e2 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:34:27 +0100 Subject: [PATCH 33/49] TLS: the prologue notices when the input ended before the recv could be re-armed ioxd__recv_resume now says whether it re-armed; a false return means the peer is gone or the worker is draining, so the handler is not run. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- lib/tls/handshake.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index f197801..3b73432 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -318,7 +318,8 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) why = "early application data does not fit"; goto out; } - ioxd__recv_resume(c); + if (!ioxd__recv_resume(c)) + why = "input ended after the handshake"; /* or the worker is draining: nothing to serve */ out: if (why) fprintf(stderr, "ioxd_tls: connection dropped: %s\n", why); From c050c0845bf1a669c06d31b56a86b2a0b38d93ac Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:35:07 +0100 Subject: [PATCH 34/49] Router: the whole allow list, HEAD on GET, joined prefixes, decoded captures A 405's allow header now names every method the path has. The walk latched only the first end-of-path node, so a path that ends a static route and a capture route both - "/users/new" beside "/users/:id" - answered with one node's methods and hid the other's: DELETE /users/new said "allow: POST" while GET /users/new was served. Every such node is remembered, and the union of their methods, each once and in registration order, is built into a small arena in the request (route_arena), which outlives the handler whether or not ioxd_header copies. The per-node allow strings are gone with it. HEAD is served by the GET of a path that has none of its own (RFC 9110 9.3.2) and is listed behind that GET in the allow header, so DELETE /health answers "GET, HEAD". A group's prefix and what follows it are joined by a '/' when neither side brings one: ioxd_get(api, "users", h) under "/api" registered "/apiusers" and now registers "/api/users"; a repeated slash still counts once. Captured values arrive percent-decoded into that same arena ("/users/a%2Fb" gives "a/b"), while the matching itself stays on the raw bytes, so an encoded '/' cannot split a segment - and a value that does not fit the arena is handed over raw. Method, path and prefix are copied at registration, so a caller may pass temporaries and the method is no longer compared against the caller's memory for the life of the process. ioxd_group_use, ioxd_use, ioxd_endpoint_use and ioxd_default now carry ioxd_route's "registered after ioxd_run started" guard: middleware added once the workers are running raced them, and an endpoint's was dropped in silence. ioxd_next_run advances its cursor in place, so a middleware that calls it twice no longer replays the rest of the chain - the second call runs nothing. An IOXD_GROUP block left early by break, return or goto used to leave the group open and nest every later registration inside it; the block's variable now carries __attribute__((cleanup)) where the compiler has it, and ioxd_run reports any group still open. Seventeen middleware on an IOXD_GROUP compiled with a warning and dropped the last one - the slot is an undefined sentinel now, a compile error like the endpoint form's. tests/router_test.c drives ioxd__dispatch with a context built by hand: the allow union, the prefix joining, %2F and %65 in a capture, HEAD on GET, the group-depth diagnostic, the guards, and a second ioxd_next_run. make check runs it after the unit test. The smoke suite's allow check follows HEAD onto GET. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .gitignore | 1 + Makefile | 9 +- include/ioxd/http.h | 146 +++++++++++++++++++ include/ioxd/router.h | 127 +++++++++++++++++ lib/http/router.c | 279 +++++++++++++++++++++++++++--------- tests/router_test.c | 325 ++++++++++++++++++++++++++++++++++++++++++ tests/smoke.py | 2 +- 7 files changed, 820 insertions(+), 69 deletions(-) create mode 100644 include/ioxd/http.h create mode 100644 include/ioxd/router.h create mode 100644 tests/router_test.c diff --git a/.gitignore b/.gitignore index 620fb71..99dc604 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ compile_commands.json tests/ioxd-test-server tests/ioxd-unit tests/ioxd-pipe-server +tests/ioxd-router-test tests/certs/ diff --git a/Makefile b/Makefile index 77e4fa2..4c53dae 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ EXAMPLES := ioxd-hello TESTSRV := tests/ioxd-test-server PIPESRV := tests/ioxd-pipe-server UNIT := tests/ioxd-unit +ROUTER := tests/ioxd-router-test .PHONY: all lib examples check clean install uninstall all: lib examples @@ -100,13 +101,15 @@ $(UNIT): tests/unit.c libioxd.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) $(PIPESRV): tests/pipe-server.c libioxd.a $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) +$(ROUTER): tests/router_test.c libioxd.a + $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) CHECK_PORT ?= 8099 PIPE_PORT ?= 8102 # the fixture takes CHECK_PORT and the two after (plain, TLS) TLS_PYTHON ?= python3 # a python with tlslite-ng, for tests/tls_early.py (skips itself otherwise) TLSFUZZER ?= # a tlsfuzzer checkout, for `make check-tlsfuzzer` (TLS_PYTHON must have its requirements) -check: $(TESTSRV) $(UNIT) $(PIPESRV) - @./$(UNIT) || exit 1; \ +check: $(TESTSRV) $(UNIT) $(PIPESRV) $(ROUTER) + @./$(UNIT) || exit 1; ./$(ROUTER) || exit 1; \ [ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null; \ IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) IOXD_CERTS=tests/certs ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ @@ -140,7 +143,7 @@ uninstall: rm -f $(DESTDIR)$(PCDIR)/ioxd.pc clean: - rm -rf obj libioxd.a libioxd.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioxd.pc + rm -rf obj libioxd.a libioxd.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) $(ROUTER) ioxd.pc # tlsfuzzer's TLS 1.3 conformance scripts that apply to a TLS 1.3-only, one-suite server; the # fixture must be up on CHECK_PORT with IOXD_CERTS (as `make check` runs it). Expected to pass: diff --git a/include/ioxd/http.h b/include/ioxd/http.h new file mode 100644 index 0000000..7a2107c --- /dev/null +++ b/include/ioxd/http.h @@ -0,0 +1,146 @@ +/* + * ioxd/http.h - the request, the response, the context a handler receives, the body read on + * demand, the reply written as you go, and the run. + */ +#pragma once + +#include +#include +#include + +#include "ioxd/slice.h" + + +#ifndef IOXD_MAX_HEADERS +#define IOXD_MAX_HEADERS 64 /* request headers kept */ +#endif +#ifndef IOXD_MAX_PARAMS +#define IOXD_MAX_PARAMS 32 /* query parameters kept */ +#endif +#ifndef IOXD_MAX_ROUTE_PARAMS +#define IOXD_MAX_ROUTE_PARAMS 8 /* :name captures a route pattern may have */ +#endif +#ifndef IOXD_MAX_RESP_HEADERS +#define IOXD_MAX_RESP_HEADERS 16 /* headers a reply may add */ +#endif +#ifndef IOXD_ROUTE_ARENA +#define IOXD_ROUTE_ARENA 256 /* per-request bytes the router decodes into */ +#endif + +/* ── the request ───────────────────────────────────────────────────────────────────────── */ + +/* All the data of a request, as slices into the connection's read buffer (decoded parameters + * into a per-request arena), valid only until the handler returns. Read the arrays directly; + * header names are lower-cased, so compare them with lowercase literals. The body is not here + * until you ask for it: ioxd_body reads it whole, ioxd_body_read streams it. */ +typedef struct ioxd_request { + ioxd_slice method; /* "GET", "POST", ... */ + ioxd_slice target; /* raw request target: path plus any query */ + ioxd_slice path; /* the path, query stripped */ + ioxd_slice query; /* raw text after '?', undecoded */ + int minor_version; /* 0 or 1 for HTTP/1.0 or 1.1 */ + + ioxd_kv headers[IOXD_MAX_HEADERS]; /* names lower-cased, values as received */ + size_t n_headers; + ioxd_kv params[IOXD_MAX_PARAMS]; /* query parameters, percent-decoded */ + size_t n_params; + ioxd_kv route_params[IOXD_MAX_ROUTE_PARAMS]; /* the :name captures, percent-decoded */ + size_t n_route_params; + + size_t content_length; /* what the head declared; 0 if nothing */ + bool chunked; /* the body is chunked: length unknown */ + ioxd_slice body; /* the whole body, once ioxd_body read it */ + bool keep_alive; /* computed from version + Connection */ + + char route_arena[IOXD_ROUTE_ARENA]; /* private: the router's per-request scratch */ +} ioxd_request; + +/* ── the response ──────────────────────────────────────────────────────────────────────── */ + +/* The reply being shaped, and the write slab. Body bytes wait in buf[0, len); a full slab is + * sent and emptied, and the head (status, content type, headers) goes out in front of the first + * send - after the chain when everything fit, earlier when the body streams - and is frozen from + * then on (head_sent). You may write into buf + len yourself and advance len, up to cap. */ +typedef struct ioxd_response { + int status; /* 200 by default */ + ioxd_slice content_type; /* "text/plain" by default; any slice */ + ioxd_kv headers[IOXD_MAX_RESP_HEADERS]; /* added with ioxd_header */ + size_t n_headers; + bool close; /* close the connection after this reply */ + bool head_sent; + size_t content_length; /* declared with ioxd_content_length */ + bool has_length; + + bool chunked, failed; /* private: how a stream is framed; peer gone */ +} ioxd_response; + +/* ── the context ───────────────────────────────────────────────────────────────────────── */ + +typedef struct ioxd_ctx { + ioxd_request req; + ioxd_response res; + void *user; /* free slot: middleware hands data to the handler */ + void *priv; /* the engine's own state */ +} ioxd_ctx; + +typedef void (*ioxd_handler)(ioxd_ctx *ctx); + +/* Middleware runs around the handler (the onion model): shape the context, call ioxd_next_run to + * run the rest of the chain and then the endpoint, then act on the result - or write a reply and + * return WITHOUT calling ioxd_next_run to short-circuit (auth failure, cache hit). */ +typedef struct ioxd_next ioxd_next; +typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next); +void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next); + +/* ── the body ──────────────────────────────────────────────────────────────────────────── */ + +/* The whole body, read into the request buffer once and returned as a slice (also req.body). It + * must fit the buffer (16 KB by default): otherwise the slice is empty and res.status is 413, + * which becomes the reply - a handler that streams its reply should check and stop. Not after + * one of the reads below. */ +ioxd_slice ioxd_body_all(ioxd_ctx *ctx); + +/* The next bytes of the body into dst, reading until n are there or the body ends. Returns the + * count (less than n only at the end), 0 once it is all consumed, -1 on error (the connection + * then closes after the reply). Any size of body, nothing kept in the engine. */ +int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n); + +/* The next chunk of a chunked body, exactly as the sender framed it, into dst: the rest of the + * current chunk when a read stopped inside one, else the next whole one. Returns its length, 0 at + * the last chunk, -1 on error - a chunk larger than cap is a 413 - or when the body is not + * chunked. */ +int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap); + +/* ── the reply ─────────────────────────────────────────────────────────────────────────── */ + +/* Body writes into the slab. When it fills, it is sent - head first - and the body streams from + * then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. + * Return 0, or -1 once the peer is gone (further writes are ignored). */ +int ioxd_write (ioxd_ctx *ctx, const void *data, size_t len); +/* Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr + * once the peer is gone or n exceeds the slab) and advance by what was written. */ +void *ioxd_reserve(ioxd_ctx *ctx, size_t n); +void ioxd_advance(ioxd_ctx *ctx, size_t n); +int ioxd_text (ioxd_ctx *ctx, const char *s); /* a C string */ +int ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /* formatted, into the slab */ + +/* Shape the head. Only before it is sent: ioxd_header returns false afterwards. */ +bool ioxd_header (ioxd_ctx *ctx, const char *name, const char *value); /* both stay valid until sent; the name is sent lower-cased */ +void ioxd_content_type (ioxd_ctx *ctx, const char *type); +void ioxd_content_length(ioxd_ctx *ctx, size_t n); /* stream a large body with a known length */ +int ioxd_flush (ioxd_ctx *ctx); /* send what is in the slab now (starts streaming) */ + +/* ── run ───────────────────────────────────────────────────────────────────────────────── */ + +/* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port` and on every + * listener added below, and block until SIGINT/SIGTERM. Returns 0 on clean shutdown. */ +int ioxd_run(int workers, int port); + +/* More ports: each ioxd_listen before the run adds one, plain when tls is NULL, TLS 1.3 terminated + * in the kernel otherwise (a certificate store from ioxd_tls_new; TLS.md). ioxd_run's own port + * joins them as a plain one; 0 there means only the listeners added. At most 8. -1 if refused. */ +typedef struct ioxd_tls ioxd_tls; +int ioxd_listen(int port, ioxd_tls *tls); + +/* The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted. */ +const char *ioxd_reason(int status); diff --git a/include/ioxd/router.h b/include/ioxd/router.h new file mode 100644 index 0000000..604f845 --- /dev/null +++ b/include/ioxd/router.h @@ -0,0 +1,127 @@ +/* + * ioxd/router.h - groups, endpoints and middleware, and the same as a script. + */ +#pragma once + +#include + +#include "ioxd/http.h" + +/* ── routing ───────────────────────────────────────────────────────────────────────────── */ + +/* Endpoints live in groups, and groups nest. A group is a path prefix plus middleware: an + * endpoint "/users" in a group "/api" under a group "/v1" answers at "/v1/api/users", wrapped by + * the middleware of every group above it, outermost first, then its own. NULL as the group is + * the root: no prefix, and the middleware given to ioxd_use. A prefix and what follows it are + * joined by a '/' when neither side brings one ("/api" and "users" is "/api/users"), and a + * repeated slash counts once. + * + * Register everything before ioxd_run, from the main thread; methods, paths and prefixes are + * copied, so temporaries are fine, and anything registered once ioxd_run has started is ignored + * with a line on stderr. ioxd_run resolves it once: every endpoint's full path into a segment + * tree and its middleware into one flat chain, which the workers then share read-only. A request + * costs one walk down the tree - no scan, no regex - and one call through its chain. */ +typedef struct ioxd_group ioxd_group; +typedef struct ioxd_endpoint ioxd_endpoint; + +ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix); /* "/api"; "" for middleware only */ +void ioxd_group_use(ioxd_group *group, ioxd_mw mw); /* wraps everything below it */ + +/* An endpoint: method matched exactly, except that HEAD is answered by the GET of a path that + * has no HEAD of its own; path matched by segment below the group's prefix, with :name captures + * ("/users/:id") landing in req.route_params. A static segment beats a capture at any depth, and + * a static path that lacks the method falls through to a capture route that has it. A trailing + * slash is tolerated. Segments are matched as they arrive on the wire, so an escape in a static + * segment does not match it, but a captured value is handed over percent-decoded ("/users/a%2Fb" + * captures "a/b") - raw in the rare case that it does not fit IOXD_ROUTE_ARENA. */ +ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn); +void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw); /* wraps this one only */ + +/* The verbs, for short: ioxd_get(api, "/users/:id", user). */ +static inline ioxd_endpoint *ioxd_get (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "GET", path, fn); } +static inline ioxd_endpoint *ioxd_post (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "POST", path, fn); } +static inline ioxd_endpoint *ioxd_put (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PUT", path, fn); } +static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "PATCH", path, fn); } +static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn) { return ioxd_route(g, "DELETE", path, fn); } + +/* Root middleware: every request, the fallbacks included. */ +void ioxd_use(ioxd_mw mw); +/* The fallback when no path matches (a built-in 404 by default). A path that matches without the + * method gets a built-in 405 whose allow header lists every method that path has, on a capture + * route too. Both run behind the root's middleware only, so that allow header names methods a + * group's own middleware would otherwise have gated. */ +void ioxd_default(ioxd_handler fn); + +/* ── the same, as a script ─────────────────────────────────────────────────────────────── */ + +/* Registration as a block-structured script: a current group, which the block after IOXD_GROUP + * sets (the root outside any block), endpoints registered into it, with their own middleware + * listed after the handler, and IOXD_USE adding middleware to it - so a group's middleware is + * either listed after its prefix or added with IOXD_USE inside its block. Plain functions + * underneath, so everything is type-checked; a group's block runs exactly once, and leaving it + * early - break, return, goto - still closes the group. + * + * IOXD_USE(log); + * IOXD_GET("/", home); + * IOXD_GROUP("/api", api_header) { + * IOXD_GET("/ping", ping); + * IOXD_GROUP("/admin", require_token) { + * IOXD_GET("/stats", stats, timing); + * } + * } + */ +#define IOXD_MAX_MW 16 /* middleware per group and per endpoint */ +struct ioxd_group_args { const char *prefix; ioxd_mw mws[IOXD_MAX_MW + 1]; }; /* +1: the ending null */ +struct ioxd_endpoint_args { const char *path; ioxd_handler fn; ioxd_mw mws[IOXD_MAX_MW + 1]; }; + +/* What the macros call: the current group's stack and an endpoint with a middleware list. */ +ioxd_group *ioxd__group_begin(struct ioxd_group_args args); +ioxd_group *ioxd__group_end(void); +void ioxd__group_pop(ioxd_group **open); +ioxd_group *ioxd__group_current(void); +ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args); + +/* The argument lists become the structs above. An argument count picks the expansion, so the + * middleware list always has its own braces and no macro is ever invoked with an empty variadic + * part: clean under -Wall -Wextra -pedantic, in C11 and later. */ +#define IOXD__CAT2(a, b) a##b +#define IOXD__CAT(a, b) IOXD__CAT2(a, b) +#define IOXD__PICK(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, name, ...) name +#define IOXD__RW(path, fn, ...) (struct ioxd_endpoint_args){ (path), (fn), { __VA_ARGS__, NULL } } +#define IOXD__RB(path, fn) (struct ioxd_endpoint_args){ (path), (fn), { NULL } } +#define IOXD__ROUTE_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, IOXD__RW, \ + IOXD__RW, IOXD__RW, IOXD__RB, IOXD__RB, IOXD__RB)(__VA_ARGS__) +#define IOXD__GW(prefix, ...) (struct ioxd_group_args){ (prefix), { __VA_ARGS__, NULL } } +#define IOXD__GB(prefix) (struct ioxd_group_args){ (prefix), { NULL } } +/* IOXD__TOO_MANY_GROUP_MW is left undefined on purpose: a 17th middleware lands on it and does + * not compile, rather than overflowing the list and losing the last one quietly. The endpoint + * form fails on its own - a 17th middleware there is taken for the macro name. */ +#define IOXD__GROUP_ARGS(...) IOXD__PICK(__VA_ARGS__, IOXD__TOO_MANY_GROUP_MW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, IOXD__GW, \ + IOXD__GW, IOXD__GW, IOXD__GB, IOXD__GB)(__VA_ARGS__) + +/* A break, a return or a goto out of the block skips the loop's increment, so where the compiler + * has __attribute__((cleanup)) the pop is hung on the block's variable and runs on every way out; + * a block that ended on its own has already popped and nulled it. Elsewhere the plain form + * stands, and a group still open at ioxd_run is reported. */ +#ifdef __GNUC__ +#define IOXD_GROUP(...) \ + for (ioxd_group *IOXD__CAT(ioxd__block_, __LINE__) __attribute__((cleanup(ioxd__group_pop))) \ + = ioxd__group_begin(IOXD__GROUP_ARGS(__VA_ARGS__)); \ + IOXD__CAT(ioxd__block_, __LINE__); IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_end()) +#else +#define IOXD_GROUP(...) \ + for (ioxd_group *IOXD__CAT(ioxd__block_, __LINE__) \ + = ioxd__group_begin(IOXD__GROUP_ARGS(__VA_ARGS__)); \ + IOXD__CAT(ioxd__block_, __LINE__); IOXD__CAT(ioxd__block_, __LINE__) = ioxd__group_end()) +#endif +#define IOXD_USE(mw) ioxd_group_use(ioxd__group_current(), (mw)) +#define IOXD_ROUTE(method, ...) ioxd__endpoint((method), IOXD__ROUTE_ARGS(__VA_ARGS__)) +#define IOXD_GET(...) IOXD_ROUTE("GET", __VA_ARGS__) +#define IOXD_POST(...) IOXD_ROUTE("POST", __VA_ARGS__) +#define IOXD_PUT(...) IOXD_ROUTE("PUT", __VA_ARGS__) +#define IOXD_PATCH(...) IOXD_ROUTE("PATCH", __VA_ARGS__) +#define IOXD_DELETE(...) IOXD_ROUTE("DELETE", __VA_ARGS__) +#define IOXD_DEFAULT(fn) ioxd_default(fn) diff --git a/lib/http/router.c b/lib/http/router.c index b3a180a..d978939 100644 --- a/lib/http/router.c +++ b/lib/http/router.c @@ -6,14 +6,18 @@ */ #include "http/router.h" +#include "http/internal.h" + #include #include #include +#define SEEN_MAX 8 /* end-of-path nodes one walk remembers */ +#define ALLOW_MAX 16 /* methods a 405's allow header lists */ struct ioxd_group { ioxd_group *parent; /* nullptr only for the root */ - const char *prefix; + const char *prefix; /* our copy of the caller's */ ioxd_mw mws[IOXD_MAX_MW]; int n_mws; }; @@ -21,9 +25,10 @@ struct ioxd_group { struct ioxd_endpoint { ioxd_endpoint *next; /* the registration list */ ioxd_group *group; - const char *method; + const char *method; /* our copy of the caller's */ size_t method_len; - const char *path; /* below the group's prefix */ + const char *path; /* below the group's prefix; our copy too */ + int seq; /* registration order, for the allow header */ ioxd_handler fn; ioxd_mw own[IOXD_MAX_MW]; int n_own; @@ -43,7 +48,14 @@ struct node { struct node *param; /* the child that takes any segment */ ioxd_endpoint **eps; /* the endpoints here, one per method */ int n_eps; - char *allow; /* "GET, POST": the methods here, for a 405 */ +}; + +/* Every end-of-path node a walk reached, for a 405's allow header: a path can end more than one + * route ("/users/new" is also the "/users/:id" of a capture route), and all of their methods are + * allowed. A path that ends more than SEEN_MAX of them loses the rest of the list. */ +struct seen { + const struct node *nodes[SEEN_MAX]; + int n; }; /* The chain cursor handed to each middleware; ioxd_next_run advances it. */ @@ -59,6 +71,7 @@ static void not_found(ioxd_ctx *ctx); static ioxd_group g_root = { .prefix = "" }; /* no prefix; ioxd_use's middleware */ static ioxd_group *g_current = &g_root; /* the script form's open group */ static ioxd_endpoint *g_first, *g_last; /* endpoints in registration order */ +static int g_n_eps; /* how many, so each gets its seq */ static struct node g_tree; /* the root node */ static ioxd_handler g_fallback = not_found; static bool g_built; @@ -69,6 +82,10 @@ static bool same(ioxd_slice a, ioxd_slice b) return a.len == b.len && memcmp(a.p, b.p, a.len) == 0; } +/* Is this the endpoint's method? name must be a literal, for the sizeof. */ +#define method_is(ep, name) ((ep)->method_len == sizeof(name) - 1 && \ + memcmp((ep)->method, (name), sizeof(name) - 1) == 0) + /* Out of memory at startup: nothing sensible to continue with. */ static void *must(void *p) { @@ -81,12 +98,22 @@ static void *must(void *p) /* ── registration ──────────────────────────────────────────────────────────────────────── */ +/* Registration is over once ioxd_run has resolved the table: it is read-only from then on and + * the workers are already reading it, so anything later is dropped with a word about it. */ +static bool too_late(const char *what, const char *which) +{ + if (!g_built) + return false; + fprintf(stderr, "ioxd: %s %s registered after ioxd_run started; ignored\n", what, which); + return true; +} + /* A group below parent (nullptr: the root) at prefix. */ ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix) { ioxd_group *group = must(calloc(1, sizeof *group)); group->parent = parent ? parent : &g_root; - group->prefix = prefix; + group->prefix = must(strdup(prefix)); return group; } @@ -95,6 +122,8 @@ void ioxd_group_use(ioxd_group *group, ioxd_mw mw) { if (!group) group = &g_root; + if (too_late("middleware for", group == &g_root ? "the root" : group->prefix)) + return; if (group->n_mws == IOXD_MAX_MW) { fprintf(stderr, "ioxd: group %s already has %d middleware, dropping one\n", group->prefix, IOXD_MAX_MW); return; @@ -105,21 +134,22 @@ void ioxd_group_use(ioxd_group *group, ioxd_mw mw) /* Root middleware: every request. */ void ioxd_use(ioxd_mw mw) { + if (too_late("middleware for", "the root")) + return; ioxd_group_use(&g_root, mw); } /* An endpoint in a group (nullptr: the root). */ ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn) { - if (g_built) { - fprintf(stderr, "ioxd: %s %s registered after ioxd_run started; ignored\n", method, path); + if (too_late(method, path)) return nullptr; - } ioxd_endpoint *ep = must(calloc(1, sizeof *ep)); ep->group = group ? group : &g_root; - ep->method = method; + ep->method = must(strdup(method)); ep->method_len = strlen(method); - ep->path = path; + ep->path = must(strdup(path)); + ep->seq = g_n_eps++; ep->fn = fn; if (g_last) g_last->next = ep; @@ -134,6 +164,8 @@ void ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw) { if (!endpoint) return; + if (too_late("middleware for", endpoint->path)) + return; if (endpoint->n_own == IOXD_MAX_MW) { fprintf(stderr, "ioxd: %s %s already has %d middleware, dropping one\n", endpoint->method, endpoint->path, IOXD_MAX_MW); return; @@ -161,6 +193,15 @@ ioxd_group *ioxd__group_end(void) return nullptr; } +/* The block's cleanup handler, where the compiler has one: a break, return or goto out of an + * IOXD_GROUP skips the loop's increment, so the group is popped here instead. A block that ended + * on its own already popped and nulled the variable, and this does nothing. */ +void ioxd__group_pop(ioxd_group **open) +{ + if (*open) + ioxd__group_end(); +} + /* The group a script-form registration goes into. */ ioxd_group *ioxd__group_current(void) { @@ -179,6 +220,8 @@ ioxd_endpoint *ioxd__endpoint(const char *method, struct ioxd_endpoint_args args /* Replace the built-in 404 fallback. */ void ioxd_default(ioxd_handler fn) { + if (too_late("a fallback", "handler")) + return; g_fallback = fn; } @@ -202,21 +245,33 @@ static bool next_segment(const char **at, const char *end, ioxd_slice *seg) return true; } +/* Put one part of n bytes in front of what is already at buf + *at, with a '/' between them when + * neither side brought one - so a group "/api" and a path "users" join as "/api/users". */ +static void prepend(char *buf, size_t *at, const char *part, size_t n) +{ + if (n && buf[*at] && part[n - 1] != '/' && buf[*at] != '/') + buf[--*at] = '/'; + *at -= n; + memcpy(buf + *at, part, n); +} + /* The endpoint's whole path: its groups' prefixes, outermost first, then its own path. Written - * right to left, from the innermost group up, so no list of the groups is needed. */ + * right to left, from the innermost group up, so no list of the groups is needed, then moved to + * the front of the buffer over whatever the joining slashes did not need. */ static char *full_path(const ioxd_endpoint *ep) { - size_t path_len = strlen(ep->path), len = path_len; - for (const ioxd_group *g = ep->group; g; g = g->parent) - len += strlen(g->prefix); - char *full = must(malloc(len + 1)); - size_t at = len - path_len; - memcpy(full + at, ep->path, path_len + 1); /* the path last, with its NUL */ + size_t len = strlen(ep->path), parts = 1; for (const ioxd_group *g = ep->group; g; g = g->parent) { - size_t n = strlen(g->prefix); - at -= n; - memcpy(full + at, g->prefix, n); + len += strlen(g->prefix); + parts++; } + char *full = must(malloc(len + parts + 1)); /* at most one joining '/' per part */ + size_t at = len + parts; + full[at] = '\0'; + prepend(full, &at, ep->path, strlen(ep->path)); + for (const ioxd_group *g = ep->group; g; g = g->parent) + prepend(full, &at, g->prefix, strlen(g->prefix)); + memmove(full, full + at, len + parts + 1 - at); return full; } @@ -285,28 +340,14 @@ static void insert(ioxd_endpoint *ep) node->eps[node->n_eps++] = ep; } -/* The allow header of every node with endpoints: its methods, comma-separated. */ -static void set_allow(struct node *node) +/* How deep the open group is; anything but zero at ioxd_run means an IOXD_GROUP block was left + * without its end, and every registration after it silently nested inside. */ +static int group_depth(void) { - if (node->n_eps) { - size_t len = 1; - for (int i = 0; i < node->n_eps; i++) - len += node->eps[i]->method_len + 2; - char *at = node->allow = must(malloc(len)); - for (int i = 0; i < node->n_eps; i++) { - if (i) { - memcpy(at, ", ", 2); - at += 2; - } - memcpy(at, node->eps[i]->method, node->eps[i]->method_len); - at += node->eps[i]->method_len; - } - *at = '\0'; - } - for (int i = 0; i < node->n_kids; i++) - set_allow(node->kids[i]); - if (node->param) - set_allow(node->param); + int depth = 0; + for (const ioxd_group *g = g_current; g->parent; g = g->parent) + depth++; + return depth; } /* Resolve everything registered: full paths into the tree, middleware into flat chains. */ @@ -314,38 +355,48 @@ void ioxd__router_build(void) { if (g_built) return; + int depth = group_depth(); + if (depth) + fprintf(stderr, "ioxd: %d group(s) still open at ioxd_run, the innermost \"%s\": everything " + "registered after it nested inside\n", depth, g_current->prefix); g_built = true; for (ioxd_endpoint *ep = g_first; ep; ep = ep->next) { ep->full = full_path(ep); insert(ep); flatten_chain(ep); } - set_allow(&g_tree); } /* ── a request ─────────────────────────────────────────────────────────────────────────── */ -/* The endpoint at a node for the method, or nullptr. */ +/* The endpoint at a node for the method, or nullptr. A node with a GET and no HEAD answers HEAD + * with its GET endpoint (RFC 9110 9.3.2): the handler still sees "HEAD" as the method, and the + * engine drops the body it writes. */ static const ioxd_endpoint *endpoint_for(const struct node *node, ioxd_slice method) { - for (int i = 0; i < node->n_eps; i++) + const ioxd_endpoint *get = nullptr; + for (int i = 0; i < node->n_eps; i++) { if (node->eps[i]->method_len == method.len && memcmp(node->eps[i]->method, method.p, method.len) == 0) return node->eps[i]; - return nullptr; + if (method_is(node->eps[i], "GET")) + get = node->eps[i]; + } + return method.len == 4 && memcmp(method.p, "HEAD", 4) == 0 ? get : nullptr; } /* Walk the tree along the path from at, the segments that capture nodes take going into - * req->route_params (values; the names come with the endpoint). The static child is tried before - * the capture, so a static segment wins, and the capture is tried when the static branch comes - * to nothing - including when it reaches the end without this method. Returns the endpoint for - * the method, or nullptr; *seen is the first node the path itself reached, for a 405. */ + * req->route_params (raw values; the names come with the endpoint, and dispatch decodes). The + * static child is tried before the capture, so a static segment wins, and the capture is tried + * when the static branch comes to nothing - including when it reaches the end without this + * method. Returns the endpoint for the method, or nullptr; every node the path itself reached + * with endpoints on it lands in *seen, for a 405. */ static const ioxd_endpoint *walk(const struct node *node, const char *at, const char *end, - ioxd_request *req, const struct node **seen) + ioxd_request *req, struct seen *seen) { ioxd_slice seg; if (!next_segment(&at, end, &seg)) { - if (node->n_eps && !*seen) - *seen = node; + if (node->n_eps && seen->n < SEEN_MAX) + seen->nodes[seen->n++] = node; return endpoint_for(node, req->method); } for (int i = 0; i < node->n_kids; i++) { @@ -367,17 +418,109 @@ static const ioxd_endpoint *walk(const struct node *node, const char *at, const return nullptr; } +/* Percent-decode a captured segment into the request's arena and point it there ('+' is a plain + * '+' in a path, and a malformed %XX is kept as is). Untouched when it has nothing to decode, or + * when the arena has no room for it. */ +static ioxd_slice decoded(ioxd_slice raw, char *arena, size_t cap, size_t *used) +{ + if (!memchr(raw.p, '%', raw.len) || *used + raw.len > cap) + return raw; + char *dst = arena + *used; + size_t out = 0; + for (size_t i = 0; i < raw.len; i++) { + if (raw.p[i] == '%' && i + 2 < raw.len) { + int hi = ioxd__hexval((unsigned char)raw.p[i + 1]); + int lo = ioxd__hexval((unsigned char)raw.p[i + 2]); + if (hi >= 0 && lo >= 0) { + dst[out++] = (char)(hi * 16 + lo); + i += 2; + continue; + } + } + dst[out++] = raw.p[i]; + } + *used += out; + return (ioxd_slice){ dst, out }; +} + +/* Is this method already in the list? Two nodes of one walk can allow the same one. */ +static bool listed(const ioxd_endpoint *out[], int n, const ioxd_endpoint *ep) +{ + for (int i = 0; i < n; i++) + if (out[i]->method_len == ep->method_len && + memcmp(out[i]->method, ep->method, ep->method_len) == 0) + return true; + return false; +} + +/* The endpoints of every node the walk reached, each method once, in registration order: an + * insertion sort by seq, which is all the ordering a handful of methods needs. */ +static int allowed_endpoints(const struct seen *seen, const ioxd_endpoint *out[ALLOW_MAX]) +{ + int n = 0; + for (int i = 0; i < seen->n; i++) { + for (int j = 0; j < seen->nodes[i]->n_eps && n < ALLOW_MAX; j++) { + const ioxd_endpoint *ep = seen->nodes[i]->eps[j]; + if (listed(out, n, ep)) + continue; + int at = 0; + while (at < n && out[at]->seq < ep->seq) + at++; + memmove(out + at + 1, out + at, (size_t)(n - at) * sizeof *out); + out[at] = ep; + n++; + } + } + return n; +} + +/* Those methods as "GET, HEAD, POST" in the request's arena, HEAD written after a GET that has + * no HEAD of its own since that is what answers it. nullptr when there is nothing to say, or + * when the list would not fit. */ +static const char *allow_value(ioxd_request *req, const struct seen *seen) +{ + const ioxd_endpoint *eps[ALLOW_MAX]; + int n = allowed_endpoints(seen, eps); + bool get = false, head = false; + size_t len = n ? (size_t)(n - 1) * 2 + 1 : 0; + for (int i = 0; i < n; i++) { + len += eps[i]->method_len; + get = get || method_is(eps[i], "GET"); + head = head || method_is(eps[i], "HEAD"); + } + bool add_head = get && !head; + if (n == 0 || len + (add_head ? 6 : 0) > sizeof req->route_arena) + return nullptr; + char *at = req->route_arena; + for (int i = 0; i < n; i++) { + if (i) { + memcpy(at, ", ", 2); + at += 2; + } + memcpy(at, eps[i]->method, eps[i]->method_len); + at += eps[i]->method_len; + if (add_head && method_is(eps[i], "GET")) { + memcpy(at, ", HEAD", 6); + at += 6; + } + } + *at = '\0'; + return req->route_arena; +} + /* Run the next middleware, or the endpoint once the chain is exhausted. A middleware that does - * not call this short-circuits the request. */ + * not call this short-circuits the request. The cursor moves in place, so a middleware that calls + * this a second time does not replay what is behind it: once the chain has run out the call does + * nothing at all. */ void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next) { - if (next->i < next->n) { - ioxd_mw mw = next->mws[next->i]; - ioxd_next inner = { next->mws, next->n, next->i + 1, next->handler }; - mw(ctx, &inner); + if (next->i > next->n) /* the chain and the handler are both spent */ return; - } - next->handler(ctx); + int at = next->i++; + if (at < next->n) + next->mws[at](ctx, next); + else + next->handler(ctx); } /* A handler behind a chain; a direct call when the chain is empty. */ @@ -405,20 +548,26 @@ static void not_allowed(ioxd_ctx *ctx) /* status and allow are set /* Find the request's endpoint and run it behind its chain; the fallbacks run behind the root's. */ void ioxd__dispatch(ioxd_ctx *ctx) { - ioxd_request *req = &ctx->req; - const struct node *seen = nullptr; + ioxd_request *req = &ctx->req; + struct seen seen = { .n = 0 }; req->n_route_params = 0; const ioxd_endpoint *ep = walk(&g_tree, req->path.p, req->path.p + req->path.len, req, &seen); if (ep) { - for (size_t i = 0; i < req->n_route_params; i++) - req->route_params[i].key = ep->names[i]; + size_t used = 0; + for (size_t i = 0; i < req->n_route_params; i++) { + req->route_params[i].key = ep->names[i]; + req->route_params[i].value = decoded(req->route_params[i].value, req->route_arena, + sizeof req->route_arena, &used); + } run(ctx, ep->chain, ep->n_chain, ep->fn); return; } req->n_route_params = 0; - if (seen) { /* the path is known, the method is not */ + if (seen.n) { /* the path is known, the method is not */ + const char *allow = allow_value(req, &seen); ctx->res.status = 405; - ioxd_header(ctx, "allow", seen->allow); + if (allow) + ioxd_header(ctx, "allow", allow); run(ctx, g_root.mws, g_root.n_mws, not_allowed); return; } diff --git a/tests/router_test.c b/tests/router_test.c new file mode 100644 index 0000000..629cedf --- /dev/null +++ b/tests/router_test.c @@ -0,0 +1,325 @@ +/* + * router_test.c - the router without a server: paths joined into the segment tree, the allow + * header of a 405, HEAD answered by GET, decoded captures, the middleware chain, and the + * diagnostics that guard registration. Requests are driven straight through the dispatcher with + * a context built by hand - one whose reply is marked failed, so the body writes of the built-in + * fallbacks go nowhere and nothing here touches the wire. `make check` runs it after the unit + * test. + */ +#include + +#include +#include +#include +#include + +/* What the engine calls, from the library's private lib/http/router.h. */ +void ioxd__router_build(void); +void ioxd__dispatch(ioxd_ctx *ctx); + +static int checks, failures; + +/* Count a check; report a failed one by line. */ +static void check(const char *what, bool ok, int line) +{ + checks++; + if (!ok) { + failures++; + printf("FAIL line %d: %s\n", line, what); + } +} +#define CHECK(cond) check(#cond, (cond), __LINE__) + +/* A slice over a C string. */ +static ioxd_slice S(const char *cstr) +{ + return (ioxd_slice){ cstr, strlen(cstr) }; +} + +/* ── the routes under test ─────────────────────────────────────────────────────────────── */ + +static const char *ran; /* the handler the request reached */ +static char trace[64]; /* the chain, in the order it ran */ +static size_t n_trace; + +/* One letter of the trace: a middleware's on the way in, its capital on the way out. */ +static void mark(char c) +{ + if (n_trace < sizeof trace - 1) + trace[n_trace++] = c; + trace[n_trace] = '\0'; +} + +/* Every handler is the same: it says which one ran and puts an 'h' in the trace. */ +#define HANDLER(name) static void name(ioxd_ctx *ctx) { (void)ctx; ran = #name; mark('h'); } +HANDLER(h_health) +HANDLER(h_new) +HANDLER(h_user) +HANDLER(h_patch) +HANDLER(h_api_users) +HANDLER(h_items) +HANDLER(h_leak) +HANDLER(h_after) +HANDLER(h_twice) +HANDLER(h_late) /* registered too late: never reached */ + +static void mw_root(ioxd_ctx *ctx, ioxd_next *next) { mark('r'); ioxd_next_run(ctx, next); mark('R'); } +static void mw_api (ioxd_ctx *ctx, ioxd_next *next) { mark('a'); ioxd_next_run(ctx, next); mark('A'); } +static void mw_own (ioxd_ctx *ctx, ioxd_next *next) { mark('o'); ioxd_next_run(ctx, next); mark('O'); } +static void mw_late(ioxd_ctx *ctx, ioxd_next *next) { mark('!'); ioxd_next_run(ctx, next); } + +/* A middleware that runs the rest of the chain twice; the second call must run nothing. */ +static void mw_twice(ioxd_ctx *ctx, ioxd_next *next) +{ + mark('t'); + ioxd_next_run(ctx, next); + ioxd_next_run(ctx, next); + mark('T'); +} + +static ioxd_endpoint *g_health; /* for a middleware added after the build */ + +/* The whole table, registered as a script. The order is the order the allow header lists. */ +static void register_routes(void) +{ + IOXD_USE(mw_root); + g_health = IOXD_GET("/health", h_health); /* no HEAD: its GET answers one */ + IOXD_POST("/users/new", h_new); + IOXD_GET("/users/:id", h_user); + IOXD_PATCH("/users/new", h_patch); + IOXD_POST("/users/:id", h_user); /* a method on both nodes: listed once */ + IOXD_GET("/twice", h_twice, mw_twice); + + IOXD_GROUP("/api", mw_api) { + IOXD_GET("users", h_api_users, mw_own); /* neither side brings a '/': "/api/users" */ + IOXD_GROUP("/v2/") { + IOXD_GET("/items", h_items); /* both do: "/api/v2/items" */ + } + } + + ioxd_group *outer = ioxd__group_current(); + IOXD_GROUP("/leak") { + IOXD_GET("/x", h_leak); + break; /* leaving early must still close the group */ + } + CHECK(ioxd__group_current() == outer); + IOXD_GET("/after", h_after); /* so this is "/after", not "/leak/after" */ +} + +/* ── driving one request ───────────────────────────────────────────────────────────────── */ + +static ioxd_ctx g_ctx; + +/* The connection, stood in for. ioxd_write takes the address of the writer inside the pipe that + * the engine's private state points at, and only then sees res.failed and gives up, so ctx.priv + * needs something shaped like that state: one pointer, to something big enough that the writer's + * address lands inside it. With failed set nothing is ever read or written through it. */ +static alignas(max_align_t) char g_pipe[8192]; +static void *g_priv[1] = { g_pipe }; + +/* Dispatch one request against a context shaped like the engine's, minus the connection: the + * reply is failed from the start, so the body a handler or a built-in fallback writes is + * dropped and nothing here touches the wire. */ +static void request(const char *method, const char *path) +{ + memset(&g_ctx, 0, sizeof g_ctx); + g_ctx.req.method = S(method); + g_ctx.req.path = S(path); + g_ctx.res.status = 200; + g_ctx.res.failed = true; + g_ctx.priv = g_priv; + ran = ""; + n_trace = 0; + trace[0] = '\0'; + ioxd__dispatch(&g_ctx); +} + +/* Did the request reach this handler? */ +static bool reached(const char *name) +{ + return strcmp(ran, name) == 0; +} + +/* Is the reply's header this text? */ +static bool replied_header(const char *name, const char *value) +{ + for (size_t i = 0; i < g_ctx.res.n_headers; i++) + if (ioxd_slice_eq(g_ctx.res.headers[i].key, name)) + return ioxd_slice_eq(g_ctx.res.headers[i].value, value); + return false; +} + +/* Is the capture of this name this text? */ +static bool captured(const char *name, const char *value) +{ + for (size_t i = 0; i < g_ctx.req.n_route_params; i++) + if (ioxd_slice_eq(g_ctx.req.route_params[i].key, name)) + return ioxd_slice_eq(g_ctx.req.route_params[i].value, value); + return false; +} + +/* Run fn with stderr in a temporary file and leave what it printed in buf: the diagnostics are + * part of what is being tested. */ +static void capture_stderr(void (*fn)(void), char *buf, size_t cap) +{ + buf[0] = '\0'; + fflush(stderr); + FILE *tmp = tmpfile(); + int saved = tmp ? dup(STDERR_FILENO) : -1; + if (saved < 0) { /* no capture; run it anyway */ + if (tmp) + fclose(tmp); + fn(); + return; + } + dup2(fileno(tmp), STDERR_FILENO); + fn(); + fflush(stderr); + dup2(saved, STDERR_FILENO); + close(saved); + if (fseek(tmp, 0, SEEK_SET) == 0) + buf[fread(buf, 1, cap - 1, tmp)] = '\0'; + fclose(tmp); +} + +/* ── the checks ────────────────────────────────────────────────────────────────────────── */ + +/* A group opened and never closed: everything after it nested inside, so ioxd_run says so. */ +static void build_with_a_group_left_open(void) +{ + ioxd__group_begin((struct ioxd_group_args){ "/stray", { NULL } }); + ioxd__router_build(); +} + +static void test_build(void) +{ + char said[512]; + capture_stderr(build_with_a_group_left_open, said, sizeof said); + CHECK(strstr(said, "1 group(s) still open") != NULL); + CHECK(strstr(said, "/stray") != NULL); +} + +static void test_paths(void) +{ + request("GET", "/api/users"); /* "/api" and "users", joined */ + CHECK(reached("h_api_users")); + request("GET", "/apiusers"); /* what the missing '/' used to make */ + CHECK(g_ctx.res.status == 404); + request("GET", "/api/v2/items"); /* "/v2/" and "/items": one slash */ + CHECK(reached("h_items")); + request("GET", "/api/v2//items"); /* a repeated slash counts once */ + CHECK(reached("h_items")); + request("GET", "/health/"); /* a trailing slash is tolerated */ + CHECK(reached("h_health")); + + request("GET", "/leak/x"); /* the block's own endpoint is still there */ + CHECK(reached("h_leak")); + request("GET", "/after"); /* and the one after it did not nest */ + CHECK(reached("h_after")); + request("GET", "/leak/after"); + CHECK(g_ctx.res.status == 404); +} + +static void test_captures(void) +{ + request("GET", "/users/7"); + CHECK(reached("h_user") && captured("id", "7")); + request("GET", "/users/a%2Fb"); /* an encoded '/' does not split the segment */ + CHECK(reached("h_user") && captured("id", "a/b")); + request("GET", "/users/%65"); + CHECK(reached("h_user") && captured("id", "e")); + request("GET", "/users/a%2b"); /* no '+' rules in a path */ + CHECK(captured("id", "a+")); + request("GET", "/users/100%25"); + CHECK(captured("id", "100%")); + request("GET", "/users/%zz"); /* a malformed escape stays as it came */ + CHECK(captured("id", "%zz")); + + request("GET", "/us%65rs/7"); /* static segments match the raw bytes */ + CHECK(g_ctx.res.status == 404); + request("GET", "/users/new"); /* a static path without GET falls through */ + CHECK(reached("h_user") && captured("id", "new")); + request("POST", "/users/new"); /* while the static one wins where it has it */ + CHECK(reached("h_new")); +} + +static void test_allow(void) +{ + /* "/users/new" ends the static route and the capture route both, so the 405 allows the + * methods of each: POST and PATCH here, GET (and the HEAD its GET answers) there. */ + request("DELETE", "/users/new"); + CHECK(g_ctx.res.status == 405); + CHECK(replied_header("allow", "POST, GET, HEAD, PATCH")); + + request("DELETE", "/health"); /* HEAD is listed behind the GET that serves it */ + CHECK(g_ctx.res.status == 405 && replied_header("allow", "GET, HEAD")); + + request("DELETE", "/users/7"); /* the capture node alone */ + CHECK(g_ctx.res.status == 405 && replied_header("allow", "GET, HEAD, POST")); + + request("DELETE", "/nowhere"); /* no path at all: the fallback, no allow */ + CHECK(g_ctx.res.status == 404 && g_ctx.res.n_headers == 0); +} + +static void test_head(void) +{ + request("HEAD", "/health"); /* served by the GET, method left alone */ + CHECK(reached("h_health") && g_ctx.res.status == 200); + CHECK(ioxd_slice_eq(g_ctx.req.method, "HEAD")); + request("HEAD", "/api/users"); + CHECK(reached("h_api_users")); + request("HEAD", "/users/7"); /* through a capture too */ + CHECK(reached("h_user") && captured("id", "7")); + request("HEAD", "/nowhere"); + CHECK(g_ctx.res.status == 404); +} + +static void test_chain(void) +{ + request("GET", "/api/users"); /* root, group, own, handler, and back out */ + CHECK(strcmp(trace, "raohOAR") == 0); + request("GET", "/twice"); /* the second ioxd_next_run runs nothing */ + CHECK(strcmp(trace, "rthTR") == 0); + request("GET", "/nowhere"); /* the fallbacks run behind the root's only */ + CHECK(strcmp(trace, "rR") == 0); +} + +/* Everything the guards must refuse once ioxd_run has resolved the table. */ +static void register_after_the_build(void) +{ + CHECK(ioxd_route(NULL, "GET", "/late", h_late) == NULL); + ioxd_use(mw_late); + ioxd_group_use(NULL, mw_late); + ioxd_endpoint_use(g_health, mw_late); + ioxd_default(h_late); +} + +static void test_registration_is_closed(void) +{ + char said[1024]; + capture_stderr(register_after_the_build, said, sizeof said); + int ignored = 0; + for (const char *at = said; (at = strstr(at, "; ignored")); at++) + ignored++; + CHECK(ignored == 5); /* one line for each of the five */ + + request("GET", "/late"); /* and none of them took */ + CHECK(g_ctx.res.status == 404 && !reached("h_late")); + CHECK(strcmp(trace, "rR") == 0); /* the built-in fallback, behind the root's */ + request("GET", "/health"); + CHECK(reached("h_health") && strcmp(trace, "rhR") == 0); /* the endpoint's chain is as it was */ +} + +int main(void) +{ + register_routes(); + test_build(); + test_paths(); + test_captures(); + test_allow(); + test_head(); + test_chain(); + test_registration_is_closed(); + printf("router: %d checks, %d failed\n", checks, failures); + return failures ? 1 : 0; +} diff --git a/tests/smoke.py b/tests/smoke.py index 1f2971b..5cb501c 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -143,7 +143,7 @@ def check(name, cond): s.send(b"DELETE / HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") st, hd, body = read_response(s) s.close() -results.append(check("DELETE / -> 405 with allow (path known, method not)", st == 405 and hd.get("allow") == "GET")) +results.append(check("DELETE / -> 405 with allow (path known, method not; HEAD rides on GET)", st == 405 and hd.get("allow") == "GET, HEAD")) # keep-alive: five requests on one connection s = connect() From 4283d026ef3200f298b95e56dc04bce0bd0a72d8 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:42:59 +0100 Subject: [PATCH 35/49] Tests: the check sequence in one script, a starved build to run it against, assertions that can fail The sequence make check ran inline is now tests/run-suites.sh, which CMake's check target and its ctest entries run as well, so it lives in one place. It keeps the fixture's output in a log instead of /dev/null, takes its exit status after the kill -INT, and fails - printing the log - when a worker reported an error or stopped with connections still open. The TLS suites are gated on the TLS port answering a socket probe rather than on a certificate file existing, so make check TLS=0 skips them with a line instead of a traceback. The fixture serves a copy of tests/certs, so a suite may rewrite what it serves. make check-tiny builds the fixture and the objects under it with BUF_COUNT=8, BUF_SIZE=64 and RX_QUEUE=4 into obj-tiny/ and runs the stress suite against it on 8410, where every request empties the buffer group: the -ENOBUFS parking, the re-arm and the queue-full path are exercised for real. check-all is check plus check-tiny. make tidy runs clang-tidy over the library with the flags the objects are built with, and .clang-tidy enables concurrency-*. Assertions that a hang would have passed now say what they mean: the read helpers return whether the peer really closed, and the oversized-header, 5 KB reply header, quit and long-line cases assert a close rather than a swallowed timeout. The flood without reading asserts the server stopped taking it, and within a time bound, instead of check(..., True). New coverage: HEAD of a buffered, a declared-length and a chunked route, each asking for the GET reply's head and no body (all three fail until the engine routes HEAD); ioxd_content_length and ioxd_flush through GET /declared, checked byte-exact and followed by another request on the same connection; ioxd_reserve and ioxd_advance through GET /raw, and a reserve past the slab; ioxd_pipe_copy, keep, release, write and send through the pipe fixture's copy and hold commands; the allow header of a path with two methods; //health and /api//admin/stats; a group registered with prefix ""; a wildcard _.example.com certificate by SNI; and a TLS reload - new files for a host, POST /tls/reload, the new certificate served and the connection in flight unharmed. mkcerts.sh makes the wildcard host and remakes any certificate within three days of expiry. The build: TLS=0/1 is a dependency at last - the effective flags are written to obj/flags whenever they differ and every object depends on it, so make TLS=0 lib after a normal build rebuilds instead of linking -DIOXD_TLS=1 objects without -lssl. The library is compiled with -fstack-clash-protection (the coroutine guard page needs the probes) and libioxd.so is linked through cmake/ioxd.map, so nm -D shows ioxd_* and nothing else. cmake/ioxdConfig.cmake.in carries IOXD_TLS and find_dependency(OpenSSL 3) when it is on, so find_package(ioxd) works downstream: verified with a consumer built against an installed prefix, and with pkg-config --libs --static. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .clang-tidy | 10 +- .gitignore | 3 + CMakeLists.txt | 39 +++++++- Makefile | 111 +++++++++++++++------ cmake/ioxd.map | 8 ++ cmake/ioxdConfig.cmake.in | 8 +- tests/mkcerts.sh | 50 ++++++++-- tests/pipe-server.c | 91 +++++++++++++++-- tests/pipes.py | 36 +++++-- tests/run-suites.sh | 172 ++++++++++++++++++++++++++++++++ tests/server.c | 105 ++++++++++++++++++-- tests/smoke.py | 199 +++++++++++++++++++++++++++++--------- tests/stress.py | 19 ++-- 13 files changed, 733 insertions(+), 118 deletions(-) create mode 100644 cmake/ioxd.map mode change 100644 => 100755 tests/mkcerts.sh create mode 100755 tests/run-suites.sh diff --git a/.clang-tidy b/.clang-tidy index dbf6e9c..08bb449 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,12 +1,15 @@ # clang-tidy configuration for libioxd. CLion picks this file up (it prefers a project .clang-tidy -# over its own settings); from the shell, with the compile flags the Makefile uses: +# over its own settings); from the shell, `make tidy` runs it with the flags the objects are built +# with, which is # # clang-tidy lib/io/*.c lib/http/*.c tests/server.c -- -std=gnu23 -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser # # (CLion's bundled clang-tidy ships without clang's builtin headers; give it gcc's with -# --extra-arg=-isystem/usr/lib/gcc/x86_64-linux-gnu/13/include, or it cascades phantom warnings.) +# --extra-arg=-isystem$(gcc -print-file-name=include), or it cascades phantom warnings - which is +# what `make tidy TIDY=/bin/clang/linux/x64/bin/clang-tidy` does for you.) # -# The checks that matter for a C library, minus the ones that only add noise here: the Annex K +# The checks that matter for a C library - the threading ones included, since the workers share a +# certificate store and a stop flag - minus the ones that only add noise here: the Annex K # "memcpy is insecure" nag (glibc has no *_s functions), include-what-you-use over deliberately # transitive private headers, the pragma-once portability nag, int-to-pointer casts that ARE the # tagged user_data design, and the readability checks that argue with idiomatic C. @@ -14,6 +17,7 @@ Checks: > -*, bugprone-*, clang-analyzer-*, + concurrency-*, misc-*, performance-*, portability-*, diff --git a/.gitignore b/.gitignore index 620fb71..8d5e175 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ obj/ +obj-tiny/ *.o # libraries and examples libioxd.a libioxd.so libioxd.so.* +libioxd-tiny.a ioxd-hello ioxd.pc @@ -26,6 +28,7 @@ compile_commands.json # IDE .idea/ tests/ioxd-test-server +tests/ioxd-test-server-tiny tests/ioxd-unit tests/ioxd-pipe-server tests/certs/ diff --git a/CMakeLists.txt b/CMakeLists.txt index a338687..d777df3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,18 @@ if(IOXD_HAVE_FAT_LTO) target_compile_options(ioxd PRIVATE -flto -ffat-lto-objects) target_link_options(ioxd PRIVATE -flto) endif() +# A coroutine's stack ends at a guard page, which only stops a frame that touches every page as it +# grows: stack clash protection makes the compiler emit those probes. +check_c_compiler_flag(-fstack-clash-protection IOXD_HAVE_STACK_CLASH) +if(IOXD_HAVE_STACK_CLASH) + target_compile_options(ioxd PRIVATE -fstack-clash-protection) +endif() +# A shared build exports ioxd_* and nothing else, through the version script the make build uses. +set(IOXD_VERSION_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ioxd.map) +if(BUILD_SHARED_LIBS) + target_link_options(ioxd PRIVATE -Wl,--version-script,${IOXD_VERSION_SCRIPT}) + set_target_properties(ioxd PROPERTIES LINK_DEPENDS ${IOXD_VERSION_SCRIPT}) +endif() target_link_libraries(ioxd PUBLIC Threads::Threads) set_target_properties(ioxd PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 0) @@ -114,8 +126,32 @@ if(IOXD_EXAMPLES) target_link_libraries(ioxd-pipe-server PRIVATE ioxd::ioxd) add_executable(ioxd-unit tests/unit.c) target_link_libraries(ioxd-unit PRIVATE ioxd::ioxd) + # The suites, through the one script `make check` runs, so the sequence lives in one place. + # The three that talk to the HTTP fixture share one entry, and so one fixture on one port, as + # they do under make: a fixture bound to a port the suite before it filled with TIME_WAIT + # connections has some of its new ones reset. Both entries bind fixed ports, so neither may + # run beside anything else. enable_testing() + set(IOXD_CHECK_PORT 8099 CACHE STRING "first port the fixture listens on; it takes the two after it") + set(IOXD_PIPE_PORT 8102 CACHE STRING "port the pipe fixture listens on") + set(IOXD_TLS_PYTHON python3 CACHE STRING "a python with tlslite-ng, for tests/tls_early.py") add_test(NAME unit COMMAND ioxd-unit) + add_test(NAME suites COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-suites.sh + --suite smoke --suite stress --suite tls + --port ${IOXD_CHECK_PORT} + --server $ + --tls-python ${IOXD_TLS_PYTHON} + --work ${CMAKE_CURRENT_BINARY_DIR}/check/suites) + add_test(NAME pipes COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-suites.sh + --suite pipes + --pipe-port ${IOXD_PIPE_PORT} + --pipe-server $ + --work ${CMAKE_CURRENT_BINARY_DIR}/check/pipes) + set_tests_properties(suites pipes PROPERTIES RUN_SERIAL TRUE) + add_custom_target(check + COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure + DEPENDS ioxd-unit ioxd-test-server ioxd-pipe-server + USES_TERMINAL) if(IOXD_HAVE_FAT_LTO) target_compile_options(ioxd-hello PRIVATE -flto) target_link_options(ioxd-hello PRIVATE -flto) @@ -135,7 +171,8 @@ install(EXPORT ioxdTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ioxd FILE ioxdTargets.cmake) -# A config file that re-finds the public Threads dependency, then loads the exported targets. +# A config file that re-finds the public dependencies - Threads, and OpenSSL when this build has +# TLS, which it is told through IOXD_TLS - then loads the exported targets. include(CMakePackageConfigHelpers) configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ioxdConfig.cmake.in diff --git a/Makefile b/Makefile index 77e4fa2..93131ed 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ # # make build libioxd.a, libioxd.so and the examples # make lib just the libraries +# make check the unit test and the suites, against the fixture servers +# make check-tiny the stress suite against a build with the buffers starved on purpose +# make check-all both +# make tidy clang-tidy over the library # make install install libs, ioxd.h and ioxd/*.h (under /include) and ioxd.pc # sudo make install PREFIX=/usr/local # @@ -24,6 +28,9 @@ AR ?= ar LTO := $(shell $(CC) -Werror -flto -ffat-lto-objects -x c -c /dev/null -o /dev/null 2>/dev/null && echo -flto -ffat-lto-objects) CFLAGS ?= -O3 -g $(LTO) WARN := -Wall -Wextra $(STD) +# A coroutine's stack ends at a guard page, which only stops a frame that touches every page as it +# grows: stack clash protection makes the compiler emit those probes. +HARDEN := $(shell $(CC) -Werror -fstack-clash-protection -x c -c /dev/null -o /dev/null 2>/dev/null && echo -fstack-clash-protection) CPP := -D_GNU_SOURCE -Iinclude -Ilib -Ithird_party/picohttpparser # TLS: OpenSSL for the handshake only; the kernel does the records (TLS.md). make TLS=0 leaves it out. TLS ?= 1 @@ -53,73 +60,117 @@ EXAMPLES := ioxd-hello TESTSRV := tests/ioxd-test-server PIPESRV := tests/ioxd-pipe-server UNIT := tests/ioxd-unit +# The linker version script: the .so exports ioxd_* and nothing else. +MAP := cmake/ioxd.map -.PHONY: all lib examples check clean install uninstall +# Every flag an object is built with, in a file. TLS=0/1 - or a different CC or CFLAGS - changes +# what the objects must be, and a stamp they all depend on is what makes that a build dependency: +# the recipe rewrites it only when it differs, so an unchanged build stays untouched. +FLAGS := $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $(LIBS) + +.PHONY: all lib examples check check-tiny check-all tidy clean install uninstall force all: lib examples lib: libioxd.a libioxd.so +force: +obj/flags: force + @mkdir -p $(@D) + @printf '%s\n' '$(FLAGS)' | cmp -s - $@ || printf '%s\n' '$(FLAGS)' > $@ + libioxd.a: $(OBJ) $(AR) rcs $@ $^ -libioxd.so: $(PICOBJ) - $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(PTHREAD) $(LIBS) +# The version script keeps the library's own names out of the dynamic symbol table: what a +# consumer may bind to is ioxd_*, and nothing else (nm -D libioxd.so says so). +libioxd.so: $(PICOBJ) $(MAP) + $(CC) $(CFLAGS) -shared -Wl,-soname,$(SONAME) -Wl,--version-script,$(MAP) -o $@ $(PICOBJ) $(PTHREAD) $(LIBS) # --- static objects (used by libioxd.a and the examples) --- -obj/%.o: lib/%.c $(HDRS) +obj/%.o: lib/%.c $(HDRS) obj/flags @mkdir -p $(@D) - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -c $< -o $@ -obj/io/switch_x86_64.o: lib/io/switch_x86_64.S + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) -c $< -o $@ +obj/io/switch_x86_64.o: lib/io/switch_x86_64.S obj/flags @mkdir -p $(@D) $(CC) $(CFLAGS) $(CPP) -c $< -o $@ -obj/picohttpparser.o: third_party/picohttpparser/picohttpparser.c +obj/picohttpparser.o: third_party/picohttpparser/picohttpparser.c obj/flags @mkdir -p $(@D) - $(CC) $(CFLAGS) -w -Ithird_party/picohttpparser -c $< -o $@ + $(CC) $(CFLAGS) -w $(HARDEN) -Ithird_party/picohttpparser -c $< -o $@ # --- position-independent objects (used by libioxd.so) --- -obj/pic/%.o: lib/%.c $(HDRS) +obj/pic/%.o: lib/%.c $(HDRS) obj/flags @mkdir -p $(@D) - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) -fPIC -c $< -o $@ -obj/pic/io/switch_x86_64.o: lib/io/switch_x86_64.S + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) -fPIC -c $< -o $@ +obj/pic/io/switch_x86_64.o: lib/io/switch_x86_64.S obj/flags @mkdir -p $(@D) $(CC) $(CFLAGS) $(CPP) -fPIC -c $< -o $@ -obj/pic/picohttpparser.o: third_party/picohttpparser/picohttpparser.c +obj/pic/picohttpparser.o: third_party/picohttpparser/picohttpparser.c obj/flags @mkdir -p $(@D) - $(CC) $(CFLAGS) -w -fPIC -Ithird_party/picohttpparser -c $< -o $@ + $(CC) $(CFLAGS) -w $(HARDEN) -fPIC -Ithird_party/picohttpparser -c $< -o $@ # --- examples link the static library --- examples: $(EXAMPLES) # Link the static archive directly so the example runs in-tree without installing the .so. ioxd-hello: playground/hello/main.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) # --- tests: the unit test, then the fixture server with both suites against it --- $(TESTSRV): tests/server.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) $(UNIT): tests/unit.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) $(PIPESRV): tests/pipe-server.c libioxd.a - $(CC) $(CFLAGS) $(WARN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $< libioxd.a -o $@ $(PTHREAD) $(LIBS) CHECK_PORT ?= 8099 PIPE_PORT ?= 8102 # the fixture takes CHECK_PORT and the two after (plain, TLS) TLS_PYTHON ?= python3 # a python with tlslite-ng, for tests/tls_early.py (skips itself otherwise) TLSFUZZER ?= # a tlsfuzzer checkout, for `make check-tlsfuzzer` (TLS_PYTHON must have its requirements) +# The sequence itself is tests/run-suites.sh, so CMake's `check` target runs exactly this one. check: $(TESTSRV) $(UNIT) $(PIPESRV) - @./$(UNIT) || exit 1; \ - [ -f tests/certs/default/cert.pem ] || sh tests/mkcerts.sh tests/certs >/dev/null; \ - IOXD_WORKERS=2 IOXD_PORT=$(CHECK_PORT) IOXD_CERTS=tests/certs ./$(TESTSRV) >/dev/null 2>&1 & pid=$$!; \ - for i in $$(seq 1 50); do ss -ltn | grep -q ":$(CHECK_PORT) " && break; sleep 0.1; done; \ - python3 tests/smoke.py $(CHECK_PORT); s=$$?; python3 tests/stress.py $(CHECK_PORT); t=$$?; \ - $(TLS_PYTHON) tests/tls_early.py $$(($(CHECK_PORT) + 2)); e=$$?; \ - kill -INT $$pid; wait $$pid 2>/dev/null; \ - ./$(PIPESRV) $(PIPE_PORT) >/dev/null 2>&1 & pid=$$!; \ - for i in $$(seq 1 50); do ss -ltn | grep -q ":$(PIPE_PORT) " && break; sleep 0.1; done; \ - python3 tests/pipes.py $(PIPE_PORT); u=$$?; \ - kill -INT $$pid; wait $$pid 2>/dev/null; exit $$((s | t | e | u)) + @sh tests/run-suites.sh --port $(CHECK_PORT) --pipe-port $(PIPE_PORT) \ + --unit ./$(UNIT) --server ./$(TESTSRV) --pipe-server ./$(PIPESRV) --tls-python $(TLS_PYTHON) + +# --- the same stress suite, against a build starved on purpose --- +# 8 x 64 B receive buffers and a 4-deep per-connection queue: every request empties the buffer +# group, so recvs park on -ENOBUFS and are re-armed as handlers give buffers back, and the queue +# overflows at the first stall. The defines change every object, so it has its own directory. +TINY := -DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4 +TINYOBJ := $(addprefix obj-tiny/,$(addsuffix .o,$(UNITS))) obj-tiny/io/switch_x86_64.o obj-tiny/picohttpparser.o +TINYSRV := tests/ioxd-test-server-tiny +TINY_PORT ?= 8410 + +obj-tiny/%.o: lib/%.c $(HDRS) obj/flags + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(TINY) $(PTHREAD) -c $< -o $@ +obj-tiny/io/switch_x86_64.o: lib/io/switch_x86_64.S obj/flags + @mkdir -p $(@D) + $(CC) $(CFLAGS) $(CPP) $(TINY) -c $< -o $@ +obj-tiny/picohttpparser.o: third_party/picohttpparser/picohttpparser.c obj/flags + @mkdir -p $(@D) + $(CC) $(CFLAGS) -w $(HARDEN) -Ithird_party/picohttpparser -c $< -o $@ +libioxd-tiny.a: $(TINYOBJ) + $(AR) rcs $@ $^ +$(TINYSRV): tests/server.c libioxd-tiny.a + $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(TINY) $(PTHREAD) $< libioxd-tiny.a -o $@ $(PTHREAD) $(LIBS) + +check-tiny: $(TINYSRV) + @sh tests/run-suites.sh --suite stress --port $(TINY_PORT) --server ./$(TINYSRV) --work obj-tiny/check + +# Everything: the default build's suites, then the starved build's. +check-all: check check-tiny + +# --- clang-tidy over the library with the flags its objects are built with (.clang-tidy holds the +# checks). CLion's bundled binary ships without clang's builtin headers, so gcc's own are handed +# to it: make tidy TIDY=/bin/clang/linux/x64/bin/clang-tidy --- +TIDY ?= clang-tidy +TIDY_ARGS ?= --extra-arg=-isystem$(shell $(CC) -print-file-name=include) +TIDY_SRC := $(wildcard lib/*/*.c) tests/server.c tests/pipe-server.c tests/unit.c +tidy: + $(TIDY) $(TIDY_ARGS) $(TIDY_SRC) -- $(STD) $(CPP) $(PTHREAD) # --- pkg-config --- -ioxd.pc: ioxd.pc.in +ioxd.pc: ioxd.pc.in obj/flags sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' -e 's|@LIBS@|$(LIBS)|g' $< > $@ # --- install / uninstall --- @@ -140,7 +191,7 @@ uninstall: rm -f $(DESTDIR)$(PCDIR)/ioxd.pc clean: - rm -rf obj libioxd.a libioxd.so $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(UNIT) ioxd.pc + rm -rf obj obj-tiny libioxd.a libioxd.so libioxd-tiny.a $(EXAMPLES) $(TESTSRV) $(PIPESRV) $(TINYSRV) $(UNIT) ioxd.pc # tlsfuzzer's TLS 1.3 conformance scripts that apply to a TLS 1.3-only, one-suite server; the # fixture must be up on CHECK_PORT with IOXD_CERTS (as `make check` runs it). Expected to pass: diff --git a/cmake/ioxd.map b/cmake/ioxd.map new file mode 100644 index 0000000..92cb4d7 --- /dev/null +++ b/cmake/ioxd.map @@ -0,0 +1,8 @@ +/* The dynamic symbol table of libioxd.so: the public names and nothing else. Everything the + * library uses internally - the vendored parser included - stays local, so a consumer can neither + * bind to it nor have one of its own names interposed on it. Both build systems pass this to the + * linker with -Wl,--version-script. */ +{ + global: ioxd_*; + local: *; +}; diff --git a/cmake/ioxdConfig.cmake.in b/cmake/ioxdConfig.cmake.in index 063e440..59fb25c 100644 --- a/cmake/ioxdConfig.cmake.in +++ b/cmake/ioxdConfig.cmake.in @@ -1,7 +1,13 @@ @PACKAGE_INIT@ -# ioxd links pthreads publicly, so a consumer must re-find it before the targets load. +# What ioxd links publicly has to be found again before its targets load: pthreads always, and +# OpenSSL when the library was built with TLS - the option below is what that build decided. +set(IOXD_WITH_TLS @IOXD_TLS@) + include(CMakeFindDependencyMacro) find_dependency(Threads) +if(IOXD_WITH_TLS) + find_dependency(OpenSSL 3) +endif() include("${CMAKE_CURRENT_LIST_DIR}/ioxdTargets.cmake") diff --git a/tests/mkcerts.sh b/tests/mkcerts.sh old mode 100644 new mode 100755 index 5c86383..9530761 --- a/tests/mkcerts.sh +++ b/tests/mkcerts.sh @@ -1,11 +1,45 @@ #!/bin/sh -# Self-signed certificates for the test fixture: `default` (CN=localhost) and one SNI host. +# Self-signed certificates for the test fixture: `default` (CN=localhost), one SNI host, and a +# wildcard host, so the store's exact match, its fallback and its `_.example.com` -> *.example.com +# rule are all exercised. +# +# sh tests/mkcerts.sh [dir] make the three, each only when missing or about to expire +# sh tests/mkcerts.sh [dir] host ... remake exactly those, whatever their state +# +# They are short-lived on purpose, so a stale checkout is not served an expired certificate: one +# within three days of its end date is made again. set -e dir=${1:-tests/certs} -# default: RSA (what most clients and test suites assume); sni.test: ECDSA, so both key types serve -mkdir -p "$dir/default" "$dir/sni.test" -openssl req -x509 -newkey rsa:2048 -nodes -subj "/CN=localhost" -days 30 \ - -keyout "$dir/default/key.pem" -out "$dir/default/cert.pem" 2>/dev/null -openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -subj "/CN=sni.test" -days 30 \ - -keyout "$dir/sni.test/key.pem" -out "$dir/sni.test/cert.pem" 2>/dev/null -echo "certificates in $dir" +[ $# -gt 0 ] && shift || true + +# One host: `default` is RSA (what most clients and test suites assume), the rest ECDSA, so both +# key types serve. $force remakes it even when what is there is still good. +make_host() { + host=$1 + force=${2:-no} + cert="$dir/$host/cert.pem" + if [ "$force" = no ] && [ -f "$cert" ] && openssl x509 -in "$cert" -noout -checkend 259200 >/dev/null 2>&1; then + return 0 # 3 days: still good for a while + fi + mkdir -p "$dir/$host" + case $host in + default) key="-newkey rsa:2048" ; cn=localhost ;; + _.*) key="-newkey ec -pkeyopt ec_paramgen_curve:prime256v1" ; cn="*.${host#_.}" ;; + *) key="-newkey ec -pkeyopt ec_paramgen_curve:prime256v1" ; cn=$host ;; + esac + # shellcheck disable=SC2086 + openssl req -x509 $key -nodes -subj "/CN=$cn" -days 30 \ + -keyout "$dir/$host/key.pem" -out "$dir/$host/cert.pem" 2>/dev/null +} + +if [ $# -gt 0 ]; then + for host in "$@"; do + make_host "$host" force + done + echo "certificates for $* in $dir" +else + make_host default + make_host sni.test + make_host _.example.com + echo "certificates in $dir" +fi diff --git a/tests/pipe-server.c b/tests/pipe-server.c index 8fa36ee..528c59f 100644 --- a/tests/pipe-server.c +++ b/tests/pipe-server.c @@ -1,13 +1,82 @@ /* * pipe-server.c - a line echo server on ioxd_run_pipes: the pipe API without HTTP. Each line * comes back as "echo: "; "quit" ends the connection; a line longer than the pipe's - * buffer ends it too (the reader reports no room). `make check` runs tests/pipes.py against it. + * buffer ends it too (the reader reports no room). Two commands beside the echo take the rest of + * the API: "copy N" reads the next N bytes into a buffer of the handler's own and sends them + * back, "hold N" waits for them where the kernel left them - however many receives that takes - + * keeps them (which consumes them, so nothing is read twice), writes them back out and gives the + * reader its room again. `make check` runs tests/pipes.py against it. */ #include #include #include +/* The count on a " N" line, or -1 when the line is not one of them. */ +static long command(ioxd_slice line, const char *name) +{ + size_t len = strlen(name); + if (line.len < len + 3 || memcmp(line.p, name, len) != 0 || line.p[len] != ' ') + return -1; + char digits[16]; + size_t n = line.len - len - 2; /* without the name, the space, the newline */ + if (n >= sizeof digits) + return -1; + memcpy(digits, line.p + len + 1, n); + digits[n] = '\0'; + char *end; + long value = strtol(digits, &end, 10); + return *end == '\0' && value >= 0 ? value : -1; +} + +/* "copy N": the next n bytes into a buffer of ours. ioxd_pipe_copy hands over what it has, so the + * loop asks again until they are all in; ioxd_pipe_send is the write and the flush in one. */ +static int copy_back(ioxd_pipe *pipe, size_t n) +{ + char out[6 + 256 + 1]; /* "copy: " + the bytes + '\n' */ + if (n > 256) + return -1; + memcpy(out, "copy: ", 6); /* NOLINT(bugprone-not-null-terminated-result): bytes, not a C string */ + size_t got = 0; + while (got < n) { + int rc = ioxd_pipe_copy(pipe, out + 6 + got, n - got); + if (rc <= 0) + return -1; + got += (size_t)rc; + } + out[6 + n] = '\n'; + return ioxd_pipe_send(pipe, out, 6 + n + 1); +} + +/* "hold N": wait until n bytes are live - they may arrive over several receives - then keep them + * where they lie, write them back out and release the run. Keeping consumes them, so the read + * after this waits for new bytes instead of seeing these again. */ +static int hold_back(ioxd_pipe *pipe, size_t n) +{ + const char *kept = NULL; + while (!kept) { + ioxd_slice live = { NULL, 0 }; + if (ioxd_pipe_read(pipe, &live) <= 0) + return -1; + if (live.len < n) { + ioxd_pipe_examine(pipe, live.len); /* seen, not consumed: wait for the rest */ + continue; + } + kept = ioxd_pipe_keep(pipe, n); + if (!kept) + return -1; + } + int rc = ioxd_pipe_write(pipe, "hold: ", 6); + if (rc == 0) + rc = ioxd_pipe_write(pipe, kept, n); + if (rc == 0) + rc = ioxd_pipe_write(pipe, "\n", 1); + if (rc == 0) + rc = ioxd_pipe_flush(pipe); + ioxd_pipe_release(pipe); /* the kept run's room, back to the reader */ + return rc; +} + /* One connection: lines in, echoes out, until the peer leaves. */ static void echo(ioxd_pipe *pipe) { @@ -20,16 +89,24 @@ static void echo(ioxd_pipe *pipe) ioxd_pipe_examine(pipe, live.len); continue; } - size_t n = (size_t)(nl - live.p) + 1; - if (n == 5 && memcmp(live.p, "quit\n", 5) == 0) + ioxd_slice line = { live.p, (size_t)(nl - live.p) + 1 }; + if (line.len == 5 && memcmp(line.p, "quit\n", 5) == 0) return; - char *out = ioxd_pipe_reserve(pipe, 6 + n); /* format straight into the slab */ + long copy = command(line, "copy"); + long hold = command(line, "hold"); + if (copy >= 0 || hold >= 0) { + ioxd_pipe_drop(pipe, line.len); /* the command goes; live.p is stale after this */ + if ((copy >= 0 ? copy_back(pipe, (size_t)copy) : hold_back(pipe, (size_t)hold)) < 0) + return; + continue; + } + char *out = ioxd_pipe_reserve(pipe, 6 + line.len); /* format straight into the slab */ if (!out) return; memcpy(out, "echo: ", 6); /* NOLINT(bugprone-not-null-terminated-result): bytes, not a C string */ - memcpy(out + 6, live.p, n); - ioxd_pipe_advance(pipe, 6 + n); - ioxd_pipe_drop(pipe, n); + memcpy(out + 6, line.p, line.len); + ioxd_pipe_advance(pipe, 6 + line.len); + ioxd_pipe_drop(pipe, line.len); if (ioxd_pipe_flush(pipe) < 0) return; } diff --git a/tests/pipes.py b/tests/pipes.py index 3735b44..6f43d3c 100644 --- a/tests/pipes.py +++ b/tests/pipes.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 """The pipe API through tests/pipe-server.c, a line echo: whole lines, a line split across -sends, two lines in one packet, a quit, and a line too long for the pipe's buffer.""" +sends, two lines in one packet, bytes copied into a buffer of the handler's own, bytes kept where +the kernel left them, a quit, and a line too long for the pipe's buffer.""" import socket, sys, time PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8100 @@ -28,16 +29,20 @@ def read_until(s, want): def read_to_close(s): + """Everything until the server closes: (data, closed). closed is False when the read timed out + instead - the connection is still open, which is a hang, not a close, and an assertion about a + close must not pass on one.""" data = b"" while True: try: chunk = s.recv(65536) except socket.timeout: - break + return data, False + except ConnectionResetError: + return data, True if not chunk: - break + return data, True data += chunk - return data results = [] @@ -50,7 +55,6 @@ def check(name, cond): s = connect() s.sendall(b"hello\n") -results and None check("a line comes back echoed", read_until(s, 12) == b"echo: hello\n") s.sendall(b"ab") time.sleep(0.05) @@ -58,13 +62,31 @@ def check(name, cond): check("a line split across sends is echoed whole", read_until(s, 10) == b"echo: abc\n") s.sendall(b"x\ny\n") check("two lines in one packet -> two echoes", read_until(s, 16) == b"echo: x\necho: y\n") + +# copy: the bytes after the command line, read into the handler's own buffer and sent back +s.sendall(b"copy 5\nhello") +check("copy N -> the next N bytes, copied out and sent back", read_until(s, 12) == b"copy: hello\n") + +# keep: the bytes are waited for where the kernel left them, however many receives that takes, +# then kept - which consumes them, so the line after is read fresh rather than seen twice +s.sendall(b"hold 9\n") +for part in (b"abc", b"def", b"ghi"): + s.sendall(part) + time.sleep(0.05) +check("hold N -> N bytes gathered over three receives, kept and written back", + read_until(s, 16) == b"hold: abcdefghi\n") +s.sendall(b"after\n") +check("the held bytes were consumed: the next line is echoed on its own", read_until(s, 12) == b"echo: after\n") + s.sendall(b"quit\n") -check("quit closes the connection", read_to_close(s) == b"") +data, closed = read_to_close(s) +check("quit closes the connection", closed and data == b"") s.close() s = connect() s.sendall(b"z" * 20000) -check("a line longer than the pipe's buffer closes the connection", read_to_close(s) == b"") +data, closed = read_to_close(s) +check("a line longer than the pipe's buffer closes the connection", closed and data == b"") s.close() s = connect() diff --git a/tests/run-suites.sh b/tests/run-suites.sh new file mode 100755 index 0000000..60ccb01 --- /dev/null +++ b/tests/run-suites.sh @@ -0,0 +1,172 @@ +#!/bin/sh +# run-suites.sh - the check sequence, in one place: the unit test, then the HTTP fixture with the +# smoke, stress and early-TLS suites against it, then the pipe fixture with the pipe suite. Both +# `make check` and CMake's `check` target run this, so the sequence lives here and nowhere else. +# +# sh tests/run-suites.sh --unit tests/ioxd-unit --server tests/ioxd-test-server \ +# --pipe-server tests/ioxd-pipe-server [--port 8099] [--pipe-port 8102] +# +# --port N the fixture's first port: N and N+1 plain, N+2 TLS [8099] +# --pipe-port N the pipe fixture's port [8102] +# --unit PATH the unit test binary +# --server PATH the HTTP fixture (tests/server.c) +# --pipe-server PATH the pipe fixture (tests/pipe-server.c) +# --python PY the python the suites run under [python3] +# --tls-python PY the python for tls_early.py (needs tlslite-ng) [--python] +# --work DIR scratch: the fixture's log and the certificates it serves [obj/check] +# --suite NAME run only this one (repeatable): unit smoke stress tls pipes +# +# The suites named in one run share the fixture they talk to, and are meant to: a fixture bound to +# a port the suite before it left full of TIME_WAIT connections has some of its new connections +# reset, so restarting one per suite on the same port is not the same thing at all. +# +# A fixture's output goes to a log in the work directory instead of /dev/null, and the log is +# printed - and the run fails - when the fixture exits non-zero, when a worker reported an error, +# or when a worker stopped with connections still open. The certificates the fixture serves are a +# copy of tests/certs, so a suite may rewrite them (smoke.py's TLS reload does). +set -u + +tests=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +root=$(dirname "$tests") + +port=8099 +pipe_port=8102 +unit= +server= +pipe_server= +python=python3 +tls_python= +work= +suites= + +while [ $# -gt 0 ]; do + case $1 in + --port) port=$2; shift 2 ;; + --pipe-port) pipe_port=$2; shift 2 ;; + --unit) unit=$2; shift 2 ;; + --server) server=$2; shift 2 ;; + --pipe-server) pipe_server=$2; shift 2 ;; + --python) python=$2; shift 2 ;; + --tls-python) tls_python=$2; shift 2 ;; + --work) work=$2; shift 2 ;; + --suite) suites="$suites $2"; shift 2 ;; + -h|--help) sed -n '2,26p' "$0"; exit 0 ;; + *) echo "run-suites: unknown option $1" >&2; exit 2 ;; + esac +done +[ -n "$tls_python" ] || tls_python=$python +[ -n "$work" ] || work=$root/obj/check +[ -n "$suites" ] || suites="unit smoke stress tls pipes" +tls_port=$((port + 2)) + +wanted() { + for s in $suites; do + [ "$s" = "$1" ] && return 0 + done + return 1 +} + +# A socket probe: the only honest answer to "is it listening". +port_open() { + "$python" -c "import socket,sys +s = socket.socket() +s.settimeout(0.5) +sys.exit(0 if s.connect_ex(('127.0.0.1', $1)) == 0 else 1)" 2>/dev/null +} + +# Up when the port answers AND every worker has said it is listening: each worker opens its own +# SO_REUSEPORT socket, and a reuseport group that grows while connections are arriving resets some +# of them, so waiting for the first worker alone would hand a suite a fixture that is still +# assembling itself. +workers=2 + +wait_for_fixture() { + i=0 + while [ $i -lt 100 ]; do + if port_open "$1" && [ "$(grep -c 'listening on' "$2")" -ge $workers ]; then + return 0 + fi + i=$((i + 1)) + sleep 0.1 + done + return 1 +} + +# What a worker prints when something went wrong, and the shutdown line with connections left on +# it. A dropped TLS connection is not one of these: tls_early.py corrupts a record on purpose. +log_faults() { + grep -nE 'io_uring_(setup|enter):|SQ still full|register pbuf ring:|accept :[0-9]+:' "$1" + grep -nE 'stopping: .* still open' "$1" | grep -v ', 0 still open' +} + +rc=0 +mkdir -p "$work" + +# --- the unit test: no fixture needed --- +if wanted unit && [ -n "$unit" ]; then + "$unit" || rc=1 +fi + +# --- the HTTP fixture, with every suite that talks to it --- +if wanted smoke || wanted stress || wanted tls; then + [ -n "$server" ] || { echo "run-suites: --server is required for the http suites" >&2; exit 2; } + certs= + if wanted smoke || wanted tls; then + sh "$tests/mkcerts.sh" "$tests/certs" >/dev/null || rc=1 + rm -rf "$work/certs" + cp -r "$tests/certs" "$work/certs" # the fixture serves a copy: a suite may rewrite it + certs=$work/certs + fi + log=$work/fixture.log + if [ -n "$certs" ]; then # unset means no TLS listener, not an empty path + IOXD_WORKERS=$workers IOXD_PORT=$port IOXD_CERTS="$certs" "$server" >"$log" 2>&1 & + else + IOXD_WORKERS=$workers IOXD_PORT=$port "$server" >"$log" 2>&1 & + fi + pid=$! + if wait_for_fixture "$port" "$log"; then + wanted smoke && { IOXD_CERTS="$certs" "$python" "$tests/smoke.py" "$port" || rc=1; } + wanted stress && { "$python" "$tests/stress.py" "$port" || rc=1; } + if wanted tls; then + if port_open "$tls_port"; then + "$tls_python" "$tests/tls_early.py" "$tls_port" || rc=1 + else + echo "skip tls_early: nothing listening on $tls_port (a TLS=0 build?)" + fi + fi + else + echo "FAIL the fixture never listened on $port" + rc=1 + fi + kill -INT "$pid" 2>/dev/null + wait "$pid"; status=$? + [ $status -eq 0 ] || { echo "FAIL the fixture exited $status"; rc=1; } + grep -q 'stopping:' "$log" || { echo "FAIL no worker reported stopping"; rc=1; } + faults=$(log_faults "$log") + [ -z "$faults" ] || { echo "FAIL the fixture's log: $faults"; rc=1; } + [ $rc -eq 0 ] || { echo "--- $log ---"; cat "$log"; echo "--- end of $log ---"; } +fi + +# --- the pipe fixture --- +if wanted pipes; then + [ -n "$pipe_server" ] || { echo "run-suites: --pipe-server is required for the pipe suite" >&2; exit 2; } + log=$work/pipe.log + inner=0 + "$pipe_server" "$pipe_port" >"$log" 2>&1 & + pid=$! + if wait_for_fixture "$pipe_port" "$log"; then + "$python" "$tests/pipes.py" "$pipe_port" || inner=1 + else + echo "FAIL the pipe fixture never listened on $pipe_port" + inner=1 + fi + kill -INT "$pid" 2>/dev/null + wait "$pid"; status=$? + [ $status -eq 0 ] || { echo "FAIL the pipe fixture exited $status"; inner=1; } + grep -q 'stopping:' "$log" || { echo "FAIL no pipe worker reported stopping"; inner=1; } + faults=$(log_faults "$log") + [ -z "$faults" ] || { echo "FAIL the pipe fixture's log: $faults"; inner=1; } + [ $inner -eq 0 ] || { echo "--- $log ---"; cat "$log"; echo "--- end of $log ---"; rc=1; } +fi + +exit $rc diff --git a/tests/server.c b/tests/server.c index 8198f2c..baeecf6 100644 --- a/tests/server.c +++ b/tests/server.c @@ -135,6 +135,60 @@ static void stream(ioxd_ctx *ctx) ioxd_printf(ctx, "line %lld of %lld\n", (long long)i, (long long)n); } +/* GET /declared?n=N - a body of a length known up front: ioxd_content_length declares it, so the + * reply streams framed by Content-Length instead of chunked, and the handler sends it in four + * ioxd_flush calls rather than waiting for the slab to fill. The bytes are 'a'..'z' cycling, so + * the client can check them exactly. */ +static void declared(ioxd_ctx *ctx) +{ + int64_t n = 4096; + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioxd_slice_eq(ctx->req.params[i].key, "n")) + ioxd_to_i64(ctx->req.params[i].value, &n); + if (n < 0 || n > (1 << 20)) + n = 4096; + char tile[260]; /* 10 x 'a'..'z': tiles the body exactly */ + for (size_t i = 0; i < sizeof tile; i++) + tile[i] = (char)('a' + i % 26); + + ioxd_content_length(ctx, (size_t)n); + size_t written = 0, quarter = ((size_t)n + 3) / 4, next_flush = quarter; + while (written < (size_t)n) { + size_t take = (size_t)n - written; + if (take > sizeof tile) + take = sizeof tile; + if (ioxd_write(ctx, tile, take) < 0) + return; + written += take; + if (written < (size_t)n && written >= next_flush) { /* another quarter is in: on its way */ + if (ioxd_flush(ctx) < 0) + return; + next_flush += quarter; + } + } +} + +/* GET /raw?n=N - the reply written into the slab directly: reserve the room, fill it, advance by + * what was written. More than the slab holds cannot be reserved, and says so. */ +static void raw(ioxd_ctx *ctx) +{ + int64_t n = 64; + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioxd_slice_eq(ctx->req.params[i].key, "n")) + ioxd_to_i64(ctx->req.params[i].value, &n); + if (n < 0 || n > (1 << 20)) + n = 64; + char *at = ioxd_reserve(ctx, (size_t)n); + if (!at) { + ctx->res.status = 500; + ioxd_text(ctx, "no room\n"); + return; + } + for (int64_t i = 0; i < n; i++) + at[i] = (char)('0' + i % 10); + ioxd_advance(ctx, (size_t)n); +} + /* POST /upload - a body of any size, streamed: each ioxd_body_read_until hands over the next bytes * straight from the wire (suspending the handler while they arrive), nothing is buffered. A * handler that never asks for the body does not pay for it either: the framework drains it. */ @@ -217,6 +271,18 @@ static void require_token(ioxd_ctx *ctx, ioxd_next *next) ioxd_text(ctx, "token required\n"); } +/* GET /rooted - in a group whose prefix is "": no path of its own, just middleware around what is + * registered inside it. */ +static void rooted(ioxd_ctx *ctx) +{ + ioxd_text(ctx, "rooted\n"); +} +static void rooted_header(ioxd_ctx *ctx, ioxd_next *next) +{ + ioxd_header(ctx, "x-rooted", "yes"); + ioxd_next_run(ctx, next); +} + /* Middleware on one endpoint only. */ static void endpoint_header(ioxd_ctx *ctx, ioxd_next *next) { @@ -317,6 +383,21 @@ static void add_server(ioxd_ctx *ctx, ioxd_next *next) ioxd_next_run(ctx, next); } +/* POST /tls/reload - the certificate store read again, registered only when the fixture has one. + * smoke.py rewrites a host's cert.pem and key.pem and calls this, then checks the new certificate + * is what the handshake serves. */ +static ioxd_tls *g_tls; + +static void tls_reload(ioxd_ctx *ctx) +{ + if (!g_tls || ioxd_tls_reload(g_tls) != 0) { + ctx->res.status = 500; + ioxd_text(ctx, "reload failed\n"); + return; + } + ioxd_text(ctx, "reloaded\n"); +} + /* The fallback for anything unrouted, replacing the built-in text 404. */ static void not_found(ioxd_ctx *ctx) { @@ -325,10 +406,11 @@ static void not_found(ioxd_ctx *ctx) ioxd_text(ctx, "{\"error\":\"not found\"}"); } -/* An environment variable as a number, or the fallback when unset or not a whole number. */ +/* An environment variable as a number, or the fallback when unset or not a whole number. Read + * from main, before ioxd_run starts a worker, so the environment is nobody else's yet. */ static long env_number(const char *name, long fallback) { - const char *text = getenv(name); + const char *text = getenv(name); /* NOLINT(concurrency-mt-unsafe): no threads yet */ if (!text) return fallback; char *end; @@ -352,6 +434,8 @@ int main(void) IOXD_POST("/echo", echo); IOXD_POST("/greet", greet); IOXD_GET ("/stream", stream); + IOXD_GET ("/declared", declared); /* a declared length, streamed in flushes */ + IOXD_GET ("/raw", raw); /* written into the slab directly */ IOXD_POST("/upload", upload); IOXD_POST("/chunks", chunks); IOXD_GET ("/json/:id", json_item); @@ -372,15 +456,22 @@ int main(void) } } + /* a group with no prefix of its own: middleware around what is inside it, nothing else */ + IOXD_GROUP("", rooted_header) { + IOXD_GET("/rooted", rooted); + } + int workers = (int)env_number("IOXD_WORKERS", 0); /* 0: one per core */ int port = (int)env_number("IOXD_PORT", 8080); int p = port > 0 && port < 65536 ? port : 8080; ioxd_listen(p + 1, NULL); /* a second plain port: the same routes */ - const char *certs = getenv("IOXD_CERTS"); /* and a TLS port, given a certificate directory */ - if (certs) { - ioxd_tls *tls = ioxd_tls_new(certs); - if (tls) - ioxd_listen(p + 2, tls); + const char *certs = getenv("IOXD_CERTS"); /* NOLINT(concurrency-mt-unsafe): a TLS port, given a certificate directory */ + if (certs && *certs) { + g_tls = ioxd_tls_new(certs); + if (g_tls) { + ioxd_listen(p + 2, g_tls); + IOXD_POST("/tls/reload", tls_reload); /* only a build with certificates has it */ + } } return ioxd_run(workers, p); } diff --git a/tests/smoke.py b/tests/smoke.py index 1f2971b..668e584 100644 --- a/tests/smoke.py +++ b/tests/smoke.py @@ -50,6 +50,33 @@ def read_response(s): return status, headers, body +def read_to_close(s): + """Everything until the server closes: (data, closed). closed is False when the read timed out + instead - the connection is still open, which is a hang, not a close, and an assertion about a + close must not pass on one.""" + data = b"" + while True: + try: + chunk = s.recv(65536) + except socket.timeout: + return data, False + except ConnectionResetError: + return data, True + if not chunk: + return data, True + data += chunk + + +def port_open(port, timeout=1): + """Whether anything is listening there: the only honest test of a port (a TLS=0 build has no + third one, and the suites that need it say so and skip).""" + try: + socket.create_connection(("127.0.0.1", port), timeout=timeout).close() + return True + except OSError: + return False + + def dechunk(raw): """A chunked body, decoded.""" out = b"" @@ -107,26 +134,48 @@ def check(name, cond): # a body far larger than the reply buffer streams: chunked on HTTP/1.1 (http.client decodes it) import http.client -hc = http.client.HTTPConnection("127.0.0.1", int(sys.argv[1]), timeout=10) +hc = http.client.HTTPConnection("127.0.0.1", PORT, timeout=10) hc.request("GET", "/stream?n=5000") r = hc.getresponse(); data = r.read(); hc.close() results.append(check("GET /stream -> chunked stream, every line arrives", r.status == 200 and r.getheader("transfer-encoding") == "chunked" and data.count(b"\n") == 5000 and data.endswith(b"line 5000 of 5000\n"))) # the same on HTTP/1.0: no length known, so it streams until close -s = socket.create_connection(("127.0.0.1", int(sys.argv[1])), timeout=10) +s = socket.create_connection(("127.0.0.1", PORT), timeout=10) s.send(b"GET /stream?n=3000 HTTP/1.0\r\nHost: x\r\n\r\n") -raw = b"" -while True: - chunk = s.recv(65536) - if not chunk: break - raw += chunk +raw, closed = read_to_close(s) s.close() head, _, body = raw.partition(b"\r\n\r\n") results.append(check("GET /stream on HTTP/1.0 -> until close, no length, all lines", - b"connection: close" in head and b"content-length" not in head + closed and b"connection: close" in head and b"content-length" not in head and b"chunked" not in head and body.count(b"\n") == 3000)) +# a declared length: the reply streams framed by Content-Length instead of chunked, sent by the +# handler in four ioxd_flush calls (ioxd_content_length + ioxd_flush) +def tiles(n): + """The body /declared writes: 'a'..'z', cycling.""" + return bytes((ord("a") + i % 26) for i in range(n)) + + +s = connect() +s.send(b"GET /declared?n=5000 HTTP/1.1\r\nHost: x\r\n\r\n") +st, hd, body = read_response(s) +results.append(check("GET /declared -> the declared length, framed by it, and every byte in order", + st == 200 and hd.get("content-length") == "5000" + and hd.get("transfer-encoding") is None and body == tiles(5000))) +s.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +st, hd, body = read_response(s) +s.close() +results.append(check(" a request after it on the same connection -> still in sync", st == 200 and body == b"ok")) + +# the reply written into the slab directly (ioxd_reserve + ioxd_advance), and a reserve past it +st, hd, body = get("/raw?n=100") +results.append(check("GET /raw -> the bytes written straight into the reserved room", + st == 200 and hd.get("content-length") == "100" + and body == bytes((ord("0") + i % 10) for i in range(100)))) +st, hd, body = get("/raw?n=20000") +results.append(check("GET /raw past the slab -> the reserve is refused, the handler says so", st == 500)) + # POST /echo reflects the body s = connect() s.send(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 11\r\nConnection: close\r\n\r\nhello world") @@ -145,6 +194,38 @@ def check(name, cond): s.close() results.append(check("DELETE / -> 405 with allow (path known, method not)", st == 405 and hd.get("allow") == "GET")) +# a path registered for two methods lists both in allow, in the order they were registered +s = connect() +s.send(b"PUT /users/42 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") +st, hd, body = read_response(s) +s.close() +results.append(check("PUT /users/:id -> 405 with both methods of that path, in registration order", + st == 405 and hd.get("allow") == "GET, POST")) + +# --- HEAD asks for the head of what GET would answer: the same status and length, no body --- +def head_request(path): + """A HEAD read to the close: (status, headers, the bytes after the head).""" + s = connect() + s.send(f"HEAD {path} HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n".encode()) + raw, _ = read_to_close(s) + s.close() + head, _, body = raw.partition(b"\r\n\r\n") + lines = head.split(b"\r\n") + parts = lines[0].split(b" ") + headers = {} + for line in lines[1:]: + k, _, v = line.partition(b": ") + headers[k.decode().lower()] = v.decode() + return (int(parts[1]) if len(parts) > 1 else 0), headers, body + + +for path in ("/", "/declared?n=5000", "/stream?n=50"): + gst, ghd, _ = get(path) + st, hd, body = head_request(path) + results.append(check(f"HEAD {path} -> the GET reply's head, and not one byte of its body", + st == 200 and st == gst + and hd.get("content-length") == ghd.get("content-length") and body == b"")) + # keep-alive: five requests on one connection s = connect() good = True @@ -191,13 +272,10 @@ def check(name, cond): s = connect(timeout=3) try: s.send(b"GET / HTTP/1.1\r\nX-Pad: " + b"a" * 20000) - got = b"" - try: - got = s.recv(64) - except (ConnectionResetError, socket.timeout): - got = b"" - # either a 431 status or a clean close is acceptable - results.append(check("oversized headers refused/closed", got == b"" or got.startswith(b"HTTP/1.1 431"))) + got, closed = read_to_close(s) + # either a 431 status or a clean close is acceptable; a read that times out is neither + results.append(check("oversized headers refused/closed", + closed and (got == b"" or got.startswith(b"HTTP/1.1 431")))) finally: s.close() @@ -220,17 +298,14 @@ def check(name, cond): # a handler that ignores the body (here the 404 fallback) still leaves the connection in sync s = connect() s.send(b"POST /nope HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\n\r\nhelloGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") -raw = b"" -while True: # both replies may arrive in one packet: read to the close - chunk = s.recv(65536) - if not chunk: break - raw += chunk +raw, closed = read_to_close(s) # both replies may arrive in one packet: read to the close s.close() results.append(check("unread body drained, pipelined next request served", - raw.startswith(b"HTTP/1.1 404") and raw.count(b"HTTP/1.1 200") == 1 and raw.endswith(b"ok"))) + closed and raw.startswith(b"HTTP/1.1 404") + and raw.count(b"HTTP/1.1 200") == 1 and raw.endswith(b"ok"))) # a 1 MB upload streamed through a 4 KB loop (the request buffer is 16 KB), then chunked -hc = http.client.HTTPConnection("127.0.0.1", int(sys.argv[1]), timeout=10) +hc = http.client.HTTPConnection("127.0.0.1", PORT, timeout=10) hc.request("POST", "/upload", body=b"x" * 1048576) r = hc.getresponse(); data = r.read() results.append(check("POST /upload 1 MB streamed in", r.status == 200 and data == b"1048576 bytes in 256 reads\n")) @@ -245,20 +320,14 @@ def gen(): # --- chunk-exact reads on a raw socket: split size lines, an extension, trailers, pipelining --- def raw_exchange(pieces, pause=0.03): """Send the pieces with a pause between them, read until the server closes, and return the - responses as (status, body) pairs (all these replies carry a Content-Length).""" + responses as (status, body) pairs (all these replies carry a Content-Length). Whether the + server really closed is left in raw_exchange.closed, so an assertion about a close can say so + rather than pass on a read that timed out.""" s = connect() for piece in pieces: s.sendall(piece) time.sleep(pause) - data = b"" - while True: - try: - chunk = s.recv(65536) - except socket.timeout: - break - if not chunk: - break - data += chunk + data, raw_exchange.closed = read_to_close(s) s.close() out = [] while b"\r\n\r\n" in data: @@ -340,7 +409,8 @@ def raw_exchange(pieces, pause=0.03): st, hd, body = get("/bighead?len=3000") results.append(check("a 3 KB reply header -> served", st == 200 and len(hd.get("x-big", "")) == 3000)) rs = raw_exchange([b"GET /bighead?len=5000 HTTP/1.1\r\nHost: x\r\n\r\n"]) -results.append(check("a 5 KB reply header -> the reply cannot be built; the connection closes", rs == [])) +results.append(check("a 5 KB reply header -> the reply cannot be built; the connection closes", + rs == [] and raw_exchange.closed)) # the request keeps 32 query parameters; the rest are dropped st, hd, body = get("/params?" + "&".join(f"p{i}=1" for i in range(40))) results.append(check("40 query parameters -> 32 kept", st == 200 and body == b"32\n")) @@ -348,10 +418,12 @@ def raw_exchange(pieces, pause=0.03): rs = raw_exchange([b"GET /health HTTP/1.1\r\nHost: x\r\n" + b"".join(b"x-h%d: v\r\n" % i for i in range(70)) + b"\r\n"]) results.append(check("70 request headers -> 400 (the table holds 64)", len(rs) == 1 and rs[0][0] == 400)) -# --- TLS: the third port, kernel TLS after an OpenSSL handshake (tests/certs from mkcerts.sh) --- -import os, ssl -CERTS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "certs") -if os.path.exists(os.path.join(CERTS, "default", "cert.pem")): +# --- TLS: the third port, kernel TLS after an OpenSSL handshake (the certificates the fixture was +# started with, IOXD_CERTS, which run-suites.sh points at a copy of tests/certs) --- +import os, ssl, subprocess +HERE = os.path.dirname(os.path.abspath(__file__)) +CERTS = os.environ.get("IOXD_CERTS") or os.path.join(HERE, "certs") +if port_open(PORT + 2): def cert_der(host): return ssl.PEM_cert_to_DER_cert(open(os.path.join(CERTS, host, "cert.pem")).read()) @@ -373,6 +445,10 @@ def tls_connect(server_hostname="localhost", max_version=None): s = tls_connect(server_hostname="sni.test") results.append(check("TLS: SNI sni.test -> that host's certificate", s.getpeercert(True) == cert_der("sni.test"))) s.close() + s = tls_connect(server_hostname="a.example.com") + results.append(check("TLS: SNI a.example.com -> the _.example.com wildcard certificate", + s.getpeercert(True) == cert_der("_.example.com"))) + s.close() s = tls_connect(server_hostname="nobody.example") results.append(check("TLS: unknown SNI -> the default certificate", s.getpeercert(True) == cert_der("default"))) s.close() @@ -411,8 +487,35 @@ def tls_connect(server_hostname="localhost", max_version=None): results.append(check("TLS: a TLS 1.2 client is refused", False)) except ssl.SSLError: results.append(check("TLS: a TLS 1.2 client is refused", True)) + + # --- the store read again while it serves: a host's files are rewritten and POST /tls/reload + # switches to them; what was handed out before the reload came from the table in memory --- + live = tls_connect() # kept open across the reload + live.send(b"GET /health HTTP/1.1\r\nHost: x\r\n\r\n") + st, hd, body = read_response(live) + before = cert_der("sni.test") + subprocess.run(["sh", os.path.join(HERE, "mkcerts.sh"), CERTS, "sni.test"], + check=True, stdout=subprocess.DEVNULL) + after = cert_der("sni.test") + s = tls_connect(server_hostname="sni.test") + stale = s.getpeercert(True) + s.close() + s = tls_connect() + s.send(b"POST /tls/reload HTTP/1.1\r\nHost: x\r\nContent-Length: 0\r\nConnection: close\r\n\r\n") + st, hd, body = read_response(s) + s.close() + results.append(check("TLS: POST /tls/reload -> the directory read again", st == 200 and body == b"reloaded\n")) + s = tls_connect(server_hostname="sni.test") + fresh = s.getpeercert(True) + s.close() + results.append(check("TLS: new files for sni.test are served only after the reload", + after != before and stale == before and fresh == after)) + live.send(b"GET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") + st, hd, body = read_response(live) + live.close() + results.append(check("TLS: the connection open across the reload still answers", st == 200 and body == b"ok")) else: - print("skip TLS: no tests/certs (run tests/mkcerts.sh)") + print(f"skip TLS: nothing listening on {PORT + 2} (a TLS=0 build has no third port)") # --- a second listener: the port after ours serves the same routes --- s = socket.create_connection(("127.0.0.1", PORT + 1), timeout=5) @@ -432,17 +535,13 @@ def tls_connect(server_hostname="localhost", max_version=None): s = connect() s.send(b"GET /json/big?n=3000 HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") -raw = b"" -while True: - piece = s.recv(65536) - if not piece: - break - raw += piece +raw, closed = read_to_close(s) s.close() head, _, rest = raw.partition(b"\r\n\r\n") doc = __import__("json").loads(dechunk(rest)) results.append(check("GET /json/big -> 3000 objects streamed chunked, valid JSON", - b"transfer-encoding: chunked" in head.lower() and len(doc) == 3000 and doc[2999] == {"i": 2999, "sq": 2999 * 2999})) + closed and b"transfer-encoding: chunked" in head.lower() + and len(doc) == 3000 and doc[2999] == {"i": 2999, "sq": 2999 * 2999})) # --- groups: prefixes chain, middleware wraps outer to inner, one endpoint's own middleware --- st, hd, body = get("/api/ping") @@ -465,6 +564,16 @@ def tls_connect(server_hostname="localhost", max_version=None): rs == [(200, b"updated new\n")])) rs = raw_exchange([b"PUT /users/new HTTP/1.1\r\nHost: x\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"]) results.append(check("PUT /users/new -> 405 (the path is known, no PUT anywhere on it)", len(rs) == 1 and rs[0][0] == 405)) +# an empty segment is no segment: the walk skips it, wherever it is +st, hd, body = get("//health") +results.append(check("GET //health -> the empty segment collapses: the same endpoint", st == 200 and body == b"ok")) +st, hd, body = get("/api//admin/stats") +results.append(check("GET /api//admin/stats -> collapsed too, and still gated by the subgroup", + st == 401 and hd.get("x-api") == "v1")) +# a group whose prefix is "": middleware around what is in it, no prefix of its own +st, hd, body = get("/rooted") +results.append(check("GET /rooted -> a group with an empty prefix wraps it and adds no path", + st == 200 and body == b"rooted\n" and hd.get("x-rooted") == "yes" and hd.get("server") == "ioxd")) print("all passed" if all(results) else "FAILURES") sys.exit(0 if all(results) else 1) diff --git a/tests/stress.py b/tests/stress.py index b076243..8f63dfb 100644 --- a/tests/stress.py +++ b/tests/stress.py @@ -1,13 +1,9 @@ #!/usr/bin/env python3 """Pressure on the ugly paths: python3 tests/stress.py [port]. -Run it against the default build, and against a tiny-buffer build that starves the provided -buffer group on every request and overflows the per-connection queue at the first stall: - - gcc -O2 -g -Wall -Iinclude -Ithird_party/picohttpparser -pthread \\ - -DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4 \\ - playground/hello/main.c lib/*/*.c lib/io/*.S \\ - third_party/picohttpparser/picohttpparser.c -o ioxd-tiny +`make check` runs it against the default build; `make check-tiny` runs it against a build with +-DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4, which starves the provided buffer group on every +request and overflows the per-connection queue at the first stall. At shutdown the server must report "0 still open" on every worker. """ @@ -81,19 +77,24 @@ def healthy(): # point the server ends its input and cancels the multishot. Our sendall then stalls (the # server stopped reading); closing with unread data RSTs the socket, which fails the parked # send and lets the handler finish. Nothing may wedge. +FLOOD_LIMIT = 20 # seconds: the send timeout above, with room s = connect(timeout=3) s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 4096) t0 = time.time() +outcome = "sent all" # what must not happen: the whole flood taken in try: s.sendall(REQ * 400000) # ~11 MB of requests -> ~28 MB of answers - outcome = "sent all" except socket.timeout: outcome = "stalled (server stopped reading)" except (ConnectionResetError, BrokenPipeError): outcome = "reset by server" +took = time.time() - t0 s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack("ii", 1, 0)) # RST on close s.close() -results.append(check(f"flood without reading: {outcome} after {time.time() - t0:.1f}s", True)) +# Taking it all would mean ~28 MB of answers buffered for a client that reads none; the server +# must end our input instead, and decide it while we are still sending, not eventually. +results.append(check(f"flood without reading: {outcome} after {took:.1f}s", + outcome != "sent all" and took < FLOOD_LIMIT)) results.append(check("server healthy after flood", healthy())) # 3. Reset in the middle of a request: the multishot recv completes with -ECONNRESET. From 0587faf4417b528400685617e35c64065b2a68f8 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:43:38 +0100 Subject: [PATCH 36/49] Proactor: the CQ head is published once per batch again, and ahead of any enter made inside one Publishing per entry cost measurable throughput; what the mid-batch flush needs is only that the head be current before it enters, so the loop counts the entries it has taken and ioxd__sqe publishes them first. The conformance suite reads a HEAD reply as ending at its blank line, and files a Transfer-Encoding that names identity with the unimplemented codings (501). Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- lib/http/engine.c | 2 +- lib/io/proactor.c | 21 +++++++++++++++++---- lib/io/proactor.h | 1 + tests/conformance.py | 18 +++++++++++------- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/http/engine.c b/lib/http/engine.c index 644e221..6c1a142 100644 --- a/lib/http/engine.c +++ b/lib/http/engine.c @@ -971,7 +971,7 @@ static bool starts_ci(ioxd_slice s, const char *lit) static int fill_request(ioxd_request *req, char *params_arena, size_t arena_cap) { ioxd_slice target = req->target; - if (starts_ci(target, "http://") || starts_ci(target, "https://")) { /* absolute-form: RFC 9112 3.2.2 */ + if (target.len && target.p[0] != '/' && (starts_ci(target, "http://") || starts_ci(target, "https://"))) { /* absolute-form: RFC 9112 3.2.2 */ size_t skip = target.p[4] == ':' ? 7 : 8; const char *slash = memchr(target.p + skip, '/', target.len - skip); target = slash ? (ioxd_slice){ slash, (size_t)(target.p + target.len - slash) } : (ioxd_slice){ "/", 1 }; diff --git a/lib/io/proactor.c b/lib/io/proactor.c index 273d927..40bdeeb 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -34,12 +34,23 @@ static uint64_t now_ms(void) * kernel is holding completions it could not fit in the CQ and will not take more submissions, so * the retry enters with GETEVENTS to flush them: safe mid-batch, since the loop dispatches whatever * lands next time round. */ +/* Publish the CQ head for the entries taken so far: once per batch in the loop, and before any + * enter in the middle of one, so the kernel has room for what the enter completes. */ +static void publish_cq(proactor_t *p) +{ + if (p->cq_taken) { + uring_cq_advance(&p->ring, p->cq_taken); + p->cq_taken = 0; + } +} + struct io_uring_sqe *ioxd__sqe(proactor_t *p) { struct io_uring_sqe *sqe = uring_get_sqe(&p->ring); int rc = 0; for (int i = 0; !sqe && i < 16; i++) { ioxd__bufring_publish(&p->bufs); /* the kernel must see staged returns before this enter */ + publish_cq(p); /* and have room in the CQ for what it completes */ rc = uring_submit(&p->ring); if (rc == -EBUSY || rc == -EAGAIN || rc == -EINTR) rc = uring_submit_wait(&p->ring, 0, nullptr); /* reap without waiting; the CQ has room again */ @@ -397,14 +408,16 @@ void proactor_run(proactor_t *p) break; } - /* One CQE at a time, the head published per entry: a handler resuming in dispatch stages - * SQEs, and the kernel needs somewhere to put their completions before the batch is over. */ + /* The batch, one CQE at a time, copied out before the handler runs: the head is published + * once at the end - or in ioxd__sqe, ahead of an enter in the middle of the batch, so the + * kernel has somewhere to put what that enter completes. */ unsigned ready = uring_cq_ready(&p->ring); /* read the tail once */ for (unsigned i = 0; i < ready; i++) { - struct io_uring_cqe cqe = *uring_cqe_at(&p->ring, 0); - uring_cq_advance(&p->ring, 1); + struct io_uring_cqe cqe = *uring_cqe_at(&p->ring, p->cq_taken); + p->cq_taken++; dispatch(p, &cqe); /* handlers run in here */ } + publish_cq(p); rearm_stalled(p); /* a close may have made room to accept again */ } diff --git a/lib/io/proactor.h b/lib/io/proactor.h index bb6094b..aba156c 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -70,6 +70,7 @@ struct proactor { /* owned by the worker thread */ struct uring ring; + unsigned cq_taken; /* CQEs taken from the ring this batch, head not yet published */ struct bufring bufs; /* the provided buffers recvs deliver into */ conn_t **starved; /* connections parked on -ENOBUFS */ unsigned nstarved, cap_starved; diff --git a/tests/conformance.py b/tests/conformance.py index 977faff..ec48085 100644 --- a/tests/conformance.py +++ b/tests/conformance.py @@ -54,9 +54,10 @@ def exchange(raw, timeout=3): return data, closed -def split_responses(data): +def split_responses(data, head_first=False): """The responses in a byte stream, as (status, headers, body) triples; the head is parsed - strictly so a malformed head shows up as a failure, not as a guess.""" + strictly so a malformed head shows up as a failure, not as a guess. head_first: the first + response answers a HEAD, so it ends at its blank line whatever its headers say.""" out = [] while data: if b"\r\n\r\n" not in data: @@ -72,7 +73,9 @@ def split_responses(data): if not sep: status = "MALFORMED" headers[k.decode(errors="replace").lower()] = v.decode(errors="replace") - if "transfer-encoding" in headers: + if head_first and not out: + body = b"" + elif "transfer-encoding" in headers: body, rest = dechunk(rest) else: n = int(headers.get("content-length", "0")) @@ -113,7 +116,6 @@ def one(raw, timeout=3): ("Content-Length empty", b"Content-Length: \r\n"), ("two Content-Length that disagree", b"Content-Length: 5\r\nContent-Length: 0\r\n"), ("Transfer-Encoding and Content-Length", b"Transfer-Encoding: chunked\r\nContent-Length: 5\r\n"), - ("TE.TE: chunked then identity", b"Transfer-Encoding: chunked\r\nTransfer-Encoding: identity\r\n"), ("an obs-folded Content-Length", b"Content-Length:\r\n 5\r\n"), ("an obs-folded Transfer-Encoding", b"Transfer-Encoding:\r\n chunked\r\n"), ]: @@ -124,6 +126,8 @@ def one(raw, timeout=3): check("an unknown transfer coding -> 501 and close", st == 501 and closed and n == 1) (st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked, gzip\r\n\r\nAAAAA" + SMUGGLE) check("chunked not the last coding -> 501 and close, nothing smuggled", st == 501 and closed and n == 1) +(st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\nTransfer-Encoding: identity\r\n\r\nAAAAA" + SMUGGLE) +check("TE.TE: chunked then identity -> 501 and close, nothing smuggled", st == 501 and closed and n == 1) (st, hd, body), closed, n = one(b"POST /echo HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\nContent-Length: 5\r\n\r\nhello") check("two Content-Length that agree -> accepted", st == 200 and body == b"hello") @@ -167,17 +171,17 @@ def chunked_post(body_bytes): # ── replies that carry no body ─────────────────────────────────────────────────────────────── data, closed = exchange(b"HEAD / HTTP/1.1\r\nHost: x\r\n\r\nGET / HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") -rs = split_responses(data) +rs = split_responses(data, head_first=True) check("HEAD / -> the GET's head, no body, then the pipelined GET answered", len(rs) == 2 and rs[0][0] == 200 and rs[0][1].get("content-length") == rs[1][1].get("content-length") and rs[0][2] == b"" and rs[1][2] == b"hello from ioxd\n") data, closed = exchange(b"HEAD /stream HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") -rs = split_responses(data) +rs = split_responses(data, head_first=True) check("HEAD of a streamed reply -> chunked head, no chunks, next request answered", len(rs) == 2 and rs[0][0] == 200 and rs[0][1].get("transfer-encoding") == "chunked" and rs[0][2] == b"" and rs[1][2] == b"ok") data, closed = exchange(b"HEAD /nope HTTP/1.1\r\nHost: x\r\n\r\nGET /health HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n") -rs = split_responses(data) +rs = split_responses(data, head_first=True) check("HEAD of an unrouted path -> 404 head, no body", len(rs) == 2 and rs[0][0] == 404 and rs[0][2] == b"" and rs[1][2] == b"ok") for path, code, framing in [("/status/204", 204, None), ("/status/304", 304, None), ("/status/204?body=1", 204, None)]: From 96bd91a71e3f2b6f0df8b2519890e0cf10a8c9f5 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 02:51:26 +0100 Subject: [PATCH 37/49] REVIEW.md: what the sixteen reviewers found and what became of it; ctest runs the router test and the conformance suite Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- CMakeLists.txt | 7 +- REVIEW.md | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 REVIEW.md diff --git a/CMakeLists.txt b/CMakeLists.txt index d777df3..a4b07c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,6 +126,8 @@ if(IOXD_EXAMPLES) target_link_libraries(ioxd-pipe-server PRIVATE ioxd::ioxd) add_executable(ioxd-unit tests/unit.c) target_link_libraries(ioxd-unit PRIVATE ioxd::ioxd) + add_executable(ioxd-router-test tests/router_test.c) + target_link_libraries(ioxd-router-test PRIVATE ioxd::ioxd) # The suites, through the one script `make check` runs, so the sequence lives in one place. # The three that talk to the HTTP fixture share one entry, and so one fixture on one port, as # they do under make: a fixture bound to a port the suite before it filled with TIME_WAIT @@ -136,8 +138,9 @@ if(IOXD_EXAMPLES) set(IOXD_PIPE_PORT 8102 CACHE STRING "port the pipe fixture listens on") set(IOXD_TLS_PYTHON python3 CACHE STRING "a python with tlslite-ng, for tests/tls_early.py") add_test(NAME unit COMMAND ioxd-unit) + add_test(NAME router COMMAND ioxd-router-test) add_test(NAME suites COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-suites.sh - --suite smoke --suite stress --suite tls + --suite smoke --suite conformance --suite stress --suite tls --port ${IOXD_CHECK_PORT} --server $ --tls-python ${IOXD_TLS_PYTHON} @@ -150,7 +153,7 @@ if(IOXD_EXAMPLES) set_tests_properties(suites pipes PROPERTIES RUN_SERIAL TRUE) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure - DEPENDS ioxd-unit ioxd-test-server ioxd-pipe-server + DEPENDS ioxd-unit ioxd-router-test ioxd-test-server ioxd-pipe-server USES_TERMINAL) if(IOXD_HAVE_FAT_LTO) target_compile_options(ioxd-hello PRIVATE -flto) diff --git a/REVIEW.md b/REVIEW.md new file mode 100644 index 0000000..0efb2e6 --- /dev/null +++ b/REVIEW.md @@ -0,0 +1,177 @@ +# The review of 2026-09-09 + +Sixteen independent reviewers, one per area, read the whole tree at commit 1f00207 (branch +`streams`, the state after TLS shipped) with the brief "only what you verified by reading the +code; quote the line". Their findings were consolidated, verified again where the fix depended on +it, and fixed in the commits that follow 1f00207. This is the record: what was found, what was +done about it, and what was deliberately left. + +Severity is the reviewer's, kept even where the fix turned out to be small. "Fixed" means the +code changed and a test exercises the new behaviour; the test suites are named in README.md. + +## The ones that mattered most + +- **A request sent in the same segment as the client's TLS Finished was lost** (critical). The + handshake loop wrote every delivered byte into OpenSSL's read BIO; an application record that + arrived with the Finished vanished into it, the drain found nothing, and kernel RX was installed + one sequence number behind - the connection hung. The test meant to catch this held the + Finished through `send()`, but tlslite sends it through `sendall()`, so its three coalescing + cases never coalesced. Fixed: one record per feed, the drain assembles records in its own + scratch; the test holds both calls and fails on the old code. `lib/tls/handshake.c`, + `tests/tls_early.py`. +- **The public headers were never in the repository.** `.gitignore` had a bare `ioxd` line for + an old binary; it also matched `include/ioxd/`, so `slice.h`, `http.h`, `router.h`, `json.h`, + `pipe.h` and `tls.h` were never committed and a fresh clone did not build. Found by the fix + agents, not the reviewers. Fixed: `/ioxd`, headers added. +- **Request smuggling through the framing headers** (critical, four ways). `Content-Length` + stopped at the first non-digit and did not check overflow (`+5`, `0x5`, `5abc`, 2^64+5 all + read as something else), duplicates were last-wins, `Transfer-Encoding` was last-wins and + matched `chunked` anywhere in the list, both framings together were accepted, a folded + continuation line was skipped, Host was never checked. Every one verified live as a desync + behind a proxy. Fixed with 400 (501 for a transfer coding we do not implement) and close; + `tests/conformance.py` sends each. `lib/http/engine.c`. +- **Response splitting through `ioxd_header`** (critical). Values went on the wire byte for + byte, and a percent-decoded `%0d%0a` in a query value became a second header line. Fixed: + names must be tokens, values may hold no control byte, the engine's own headers cannot be set, + and both are copied into a per-reply arena - the pointers used to be read after the handler's + frame was gone, which sent stack garbage. `lib/http/api.c`, `include/ioxd/http.h`. +- **HEAD, 204 and 304 carried bodies** (critical), and `HEAD` of a GET route was a 405. Fixed: + the router serves HEAD from GET, the engine sends the head alone (Content-Length as the GET + would have had; no framing header on a 1xx or 204). `lib/http/router.c`, `lib/http/engine.c`. +- **A kept pointer from `ioxd_pipe_keep` could dangle** (critical, public pipe API only). A run + started in a fresh kernel buffer was copied out by `gather` and the buffer went back to the + ring, where another connection's recv refilled it. Fixed: the buffer is pinned until release. + `lib/io/pipe.c`. +- **A paused recv was stranded under buffer starvation** (high, three reviewers). The + `-ENOBUFS` completion never looked at `pausing`, so a TLS handshake that hit starvation parked + its coroutine forever, leaking the connection. Fixed, along with the rest of the pause/resume + corners (eof, closed, a stale cancel). `lib/io/conn.c`. +- **Shutdown abandoned every live connection** (high). The loop exited on the stop flag, parked + coroutines never unwound, their stacks and sockets leaked, and the recv slab was unmapped while + recvs could still land in it; `ioxd_run` returned 0 and could not be called again. Fixed: a + drain (accepts cancelled, one `ASYNC_CANCEL_ANY`, run until nothing is live or 2 s pass), the + stop flag and listener table reset per run, a worker failure returned. `lib/io/proactor.c`, + `lib/http/run.c`. +- **A reload could free a table a stalled handshake still used** (critical, not yet reachable: + nothing called reload). The ClientHello callback's argument was re-pointed on an `SSL_CTX` + shared between two tables. Fixed: the table rides on the SSL. Also: certificates are checked + for validity dates, a missing `default` is an error, reloads serialise. `lib/tls/store.c`. + +## By area + +### I/O plane (uring, bufring, conn, proactor, coro) + +| Sev | Finding | Status | +|---|---|---| +| high | mmap failure in `uring_init` left the struct populated; `uring_exit` double-freed | fixed | +| high | persistent accept error (-ENFILE with the file table full) spun re-arming at 100 % CPU | fixed: stalled listeners re-arm when connections drop or after a second; the table is a ceiling | +| high | `ioxd__sqe` ignored `uring_submit`'s -EBUSY and aborted the process | fixed: the CQ head is published before a mid-batch enter, which retries with GETEVENTS | +| high | slab unmapped with recvs in flight; live connections abandoned at stop | fixed: the drain | +| high | one 4 KB guard page below 25 KB frames, no stack probes in our own flags | fixed: 64 KB guard, `-fstack-clash-protection`, 128 KB stacks | +| high | `swap_ctx` and `coro_*` exported and interposable from the .so | fixed: hidden, plus a version script exporting `ioxd_*` only | +| medium | CQ overflow invisible | fixed: the flag forces an enter; overflows counted in the stop line | +| medium | starved sweep re-armed every parked connection per returned buffer | fixed: at most as many as were returned, FIFO | +| medium | fatal enter error retired one worker silently | fixed: stop set, `ioxd_run` non-zero | +| medium | no CFI in the context switch; loop-only invariant was an `assert` | fixed | +| medium | `BUF_COUNT` bound one power of two too permissive; compat `#ifndef`s missing for the newer flags | fixed | +| medium | pooled stacks never trimmed | left: warm stacks are the point of the pool (`CORO_POOL_MAX` bounds it); noted in coro.c | +| medium | a stack per accepted connection before any handler runs | left: pooled, and admission is now bounded by the file table | +| low | TAG_OP was 0 (a forgotten user_data dispatched as a null op); direct close untagged; `fd > 0`; banner snprintf; dangling `starved` | fixed | +| low | MXCSR/x87 not switched; CET off for the whole program by the switch's missing note | documented in coro.h and switch_x86_64.S | +| low | setsockopt fallback dead under registered files | documented: kernel TLS needs `SOCKET_URING_OP_SETSOCKOPT` (6.7+) or `FIXED_FILES=0` | + +### Pipes + +| Sev | Finding | Status | +|---|---|---| +| critical | kept pointers dangled after `gather` | fixed: the buffer is pinned | +| high | `inject` with a run held in `cur` broke the live-in-buf invariant | fixed | +| high | the gathering buffer (16 KB) is smaller than a maximal TLS record | fixed on the TLS side: records are assembled in the prologue's scratch, never in the reader | +| medium | `drop` past the live bytes, `keep` of more than is live, `advance` past the slab | fixed: clamped | +| low | `avail` collapsed error and empty; `inject` ignored a sticky error; a raw handler's unsent slab was dropped at close | fixed | + +### HTTP engine, request side + +| Sev | Finding | Status | +|---|---|---| +| critical | `Content-Length` parse, duplicates, `Transfer-Encoding` last-wins, both framings | fixed: 400/501 and close | +| high | obs-fold skipped; Host never checked | fixed | +| medium | trailers unbounded; absolute-form targets 404; `Connection` last-wins | fixed | +| low | bare whitespace after a chunk size; `int` overflow on huge reads; bytes copied lost on a chunk-end error | fixed | +| low | `ioxd_kv_parse` dropped pairs silently past its limits | fixed: `truncated` out-parameter; the engine answers 400/414 | + +### HTTP engine, reply side + +| Sev | Finding | Status | +|---|---|---| +| critical | header values unvalidated; HEAD/204/304 bodies | fixed | +| high | handler-set `content-length`/`transfer-encoding` reached the wire; a declared length never reconciled | fixed: refused; buffered replies get the real length, streams are cut at it and close when short | +| medium | framing headers on 1xx/204; status not validated; no `100 Continue`; drain cap decided after the head froze | fixed | +| low | a head past its cap closed silently; `ioxd_advance` unbounded; OOM in `ioxd_printf` not sticky | fixed | + +### Router + +| Sev | Finding | Status | +|---|---|---| +| high | the 405 `allow` list omitted methods reachable through a capture route | fixed: the union of every path node reached, HEAD after GET | +| high | four registration functions lacked the after-`ioxd_run` guard | fixed | +| medium | `break` inside `IOXD_GROUP` left the group open; prefix and path glued without a slash; 17 middleware silently dropped one; captures raw while `params` are decoded | fixed | +| low | caller strings kept by pointer; `ioxd_next_run` twice replayed the chain; allow behind group middleware | fixed / fixed / documented | + +### Slices, conversions, helpers + +| Sev | Finding | Status | +|---|---|---| +| critical | `ioxd_header` accepted CRLF (see above) | fixed | +| medium | `%00` decoded to a NUL and `ioxd_cstr` reported success on it | fixed: `%00` stays literal, `ioxd_cstr` refuses an embedded NUL | +| low | NULL C strings crashed; a locale failure fell back to the process locale; 128-byte numbers refused | fixed / fixed / left (documented) | + +### JSON + +| Sev | Finding | Status | +|---|---|---| +| high | a multi-byte decimal point corrupted every double; an unbalanced `end` went unreported | fixed: a private C locale; `failed` set; `ioxd_json_done` | +| medium | no level rules (a key in an array, a value without a key); `float` printed as a double; the header example's `//` swallowed macro lines | fixed | +| low | depth 64 aliased the root level; a trailing comma on a too-deep open; empty `raw`; refused reserves not retried | fixed | + +### TLS + +| Sev | Finding | Status | +|---|---|---| +| critical | early data lost with the Finished (see above); the reload callback argument | fixed | +| high | early plaintext of 64 KB could not be delivered after the keys were installed; a split record could be spliced wrongly | fixed: bounded by the reader, assembled in scratch | +| high | no validity-period check on load | fixed | +| medium | close_notify in the drain window lost the request before it; a KeyUpdate desynchronised silently; reload raced itself; the fallback host followed `readdir` order | fixed | +| low | SNI case-fold matched control bytes; a trailing dot; error queue leftovers; no `ioxd_tls_free`; key file permissions | fixed | + +### Public API and documentation + +| Sev | Finding | Status | +|---|---|---| +| critical | the limits that size `ioxd_ctx` could be redefined by an application | fixed: `ioxd_run` passes `sizeof(ioxd_ctx)` and the library refuses a mismatch | +| high | `ioxd_header` pointer lifetime; strings kept by the router | fixed: copied | +| medium | `ioxd_run` one-shot; `pthread_create` failure path; comments naming members and functions that do not exist; the umbrella header's example did not compile | fixed | +| medium | README said "no TLS", lacked the prerequisites; `IOXD_REQ_CAP`; the rotation watcher described as built; DESIGN.md claiming to describe what shipped | fixed in the docs pass | + +### Tests and build + +| Sev | Finding | Status | +|---|---|---| +| critical | no negative framing tests at all | fixed: `tests/conformance.py` | +| high | an assertion that could not fail; the starvation test never starved; the fixture's exit status discarded; `TLS=0` not a build dependency; the CMake package unusable downstream | fixed: `check-tiny`, `tests/run-suites.sh`, an `obj/flags` stamp, `find_dependency(OpenSSL)` | +| medium | assertions that passed on a hang; untested public functions; wildcard SNI and reload untested; `ctest` ran one test | fixed | +| low | no `make tidy`; `concurrency-*` off | fixed | + +## What the reviewers confirmed correct + +The io_uring memory ordering, the two-owner reference count on a connection, the buffer-ring +contract and every buffer's path back to the ring, the context switch and its forged frame, the +chunked framing of replies, the front/back arithmetic of the writer, the key schedule and nonce +split of the TLS handoff, the SNI parser under ASan, the JSON escaping and number formatting, and +the conversions under four million fuzzed inputs. The defects were at the edges: failure paths, +shutdown, what a handler may hand the engine, and the framing a peer declares. + +## Cost + +The hardening costs about 1 % on the saturated keep-alive benchmark (PERF.md). It is the price +of checking what a request declares before acting on it. From 626933e595d2bfece2c9ddd7327cc6f86082fed4 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 03:02:56 +0100 Subject: [PATCH 38/49] Docs: what the review changed, written where each thing is described README lists the real prerequisites (gcc 14, OpenSSL 3, the TLS opt-out) and every check target; ARCHITECTURE follows the code again - the file map, the 128 KB stacks and their guard, the tag table, the loop and its drain, the pipe's pinning, the engine's framing and reply rules, the router's HEAD and allow union, the JSON writer's float path and level rules; PERF names the knobs' files and records the hardening's cost; TLS.md separates what is built from the watcher that is planned and describes the record-at-a-time handshake; STREAMS lists the shipped verbs; DESIGN.md is marked as the historical v1 record; FILES.md says none of it exists yet. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 268 ++++++++++++++++++++++++++++++++------------ DESIGN.md | 10 +- FILES.md | 9 +- PERF.md | 15 ++- README.md | 31 +++-- STREAMS.md | 60 +++++----- TLS.md | 121 ++++++++++++++------ lib/io/coro.h | 16 ++- lib/io/proactor.h | 17 +-- tests/router_test.c | 2 +- 10 files changed, 387 insertions(+), 162 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ed3937f..0508854 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -10,17 +10,23 @@ process │ ├─ io_uring one ring, one syscall per batch │ ├─ SO_REUSEPORT listeners one per port; the kernel spreads connections across workers │ ├─ provided buffer ring where the kernel puts received bytes - │ ├─ coroutine per connection runs serve(): parse → handler → reply + │ ├─ coroutine per connection runs ioxd__serve(): parse → handler → reply │ └─ pools: conn objects, coroutine stacks ``` -`include/ioxd.h` is the whole public API, an umbrella over `include/ioxd/`: `slice.h`, `http.h`, -`router.h`, `json.h` and `pipe.h`, one per concern, each usable on its own. Under `lib/` there are two planes, one concern per file: -`io/` is the I/O plane - `uring.c` (the ring), `coro.c` + `switch_x86_64.S` (coroutines), -`bufring.c` (the buffer ring), `conn.c` (a connection and its awaits), `proactor.c` (the worker -loop), with `proactor.h` as the interface the other plane uses - and `http/` is the HTTP plane - +`include/ioxd.h` is the whole public API, an umbrella over `include/ioxd/`: `slice.h` (slices and +conversions), `http.h` (request, response, context, body, reply, `ioxd_run`), `router.h` (groups, +endpoints, middleware, the script macros), `json.h` (the writer and `IOXD_JSON_STRUCT`), `pipe.h` +(a connection as a pipe) and `tls.h` (a certificate store), one per concern, each usable on its +own. Under `lib/` there are three planes, one concern per file: `io/` is the I/O plane - +`uring.c` (the ring), `coro.c` + `switch_x86_64.S` (coroutines), `bufring.c` (the buffer ring), +`conn.c` (a connection and its awaits), `pipe.c` (the reader and the writer), `proactor.c` (the +worker loop), with `proactor.h` as the interface the other planes use; `http/` is the HTTP plane - `engine.c` (parse, body, reply, the serve loop), `router.c` (routes and middleware), `api.c` -(handler helpers), `run.c` (`ioxd_run`). Each plane has an `internal.h` for what its files share. +(handler helpers), `run.c` (`ioxd_run`, `ioxd_listen`, `ioxd_run_pipes`); and `tls/` is the TLS +prologue - `store.c` (certificates, SNI, reload) and `handshake.c` (the OpenSSL handshake and the +handoff to the kernel). `json/json.c` is the JSON writer, which depends on neither plane. Each +plane has an `internal.h` for what its files share. --- @@ -91,8 +97,10 @@ nanoseconds. ### Creating one -`coro_create` maps a 64 KB stack with an unmapped **guard page** below it (a stack overflow faults -instead of corrupting a neighbour). The `coro_t` descriptor sits at the top of that same block. +`coro_create` maps a 128 KB stack with a 64 KB unmapped **guard** below it (a stack overflow faults +instead of corrupting a neighbour; one page would not do, since `ioxd__conn_main`'s frame is 25 KB +and `ioxd__serve`'s 10 KB, and a frame that big could step clean over it). `PROT_NONE` pages cost +address space and no RSS. The `coro_t` descriptor sits at the top of that same block. Then it forges a first frame: six zeros and a return address pointing at `coro_entry`. The first `swap_ctx` into it pops the zeros and "returns" into `coro_entry`, which calls the coroutine's function. When the function returns, `coro_entry` marks it done and yields for the last time. @@ -102,28 +110,41 @@ function. When the function returns, `coro_entry` marks it done and yields for t - Only the **loop** resumes coroutines. A coroutine never resumes another; it *spawns* one, which goes on a ready list the loop drains. Two thread-locals track the current coroutine and the loop's saved stack pointer, and that is the whole scheduler. -- A finished coroutine's stack goes into a per-worker **pool** (guard page still armed) and is - reused by the next connection, so churn pays no `mmap`/`munmap`. +- A finished coroutine's stack goes into a per-worker **pool** (guard still armed) and is + reused by the next connection, so churn pays no `mmap`/`munmap` and no cross-core TLB shootdown. + Past `CORO_POOL_MAX` idle stacks the extra ones are unmapped; the cap bounds what is kept warm, + not how many coroutines may run. --- ## 3. The proactor (the worker loop) -Each worker thread runs `proactor_run`: pin to a CPU, create the ring and buffer ring, open the -listener, arm the multishot accept, then loop: +Each worker thread runs `proactor_run`: pin to a CPU, create the ring and buffer ring, open one +socket per listener, arm each multishot accept, then loop: ``` loop: + stop? the flag is read once: begin_drain, then run until the last connection ends run_ready start coroutines spawned since last time rearm_starved re-arm recvs that hit -ENOBUFS, if buffers came back publish buffer returns staged during the last batch enter submit everything staged, wait for >= 1 completion (the one syscall) - dispatch handle every CQE in the batch; handlers resume inline - advance publish the CQ head once + dispatch read the CQ tail once, then copy out and handle one CQE at a time; + handlers resume inline + advance publish the CQ head once, for everything taken this batch + rearm_stalled a close may have made room for an accept that ran out of it ``` Handlers run *inside* dispatch, on their own stacks. A resumed handler that reaches `await_send` stages a SEND SQE and parks; the SQE rides the next `enter` together with the rest of the batch. +Each CQE is copied out of the ring before its handler runs, since the handler may need the slot: +`ioxd__sqe` enters again when the SQ fills mid-batch, and it publishes the CQ head first, so the +kernel has somewhere to put what that enter completes. The head is published once per batch +otherwise, which is the one barrier the batch costs. + +An accept that runs out of descriptors, file slots or memory is not re-armed at once - that would +spin - so its listener stalls; `rearm_stalled` arms it again once a connection has closed, or once +a second, whichever comes first. ### Routing a completion @@ -132,10 +153,15 @@ low bits (everything it points at is 8-byte aligned): | tag | points at | meaning | |---|---|---| -| `OP` | an `op_t` on the awaiting coroutine's stack | a one-shot op (send) finished: resume that coroutine | +| `IGNORE` (0) | – | a cancel acknowledgement | +| `OP` | an `op_t` on the awaiting coroutine's stack | a one-shot op (send, recv-exact, setsockopt, sendmsg) finished: resume that coroutine | | `RECV` | the connection | multishot recv delivered data, or ended | -| `ACCEPT` | the worker | a new connection | -| `IGNORE` | – | a cancel acknowledgement | +| `ACCEPT` | the `struct listener` | a new connection on that port | +| `CLOSE` | – | a socket closed; only a failure is news | +| `DRAIN` | the worker | the shutdown's one blanket cancel: its result says whether the kernel knew it | + +`IGNORE` is the zero tag on purpose: an SQE whose `user_data` was never set then dispatches as +"nobody waits for this" instead of as an op with a null pointer. The `op_t` can live on the coroutine's stack because a parked coroutine's frame is frozen: its address stays valid for exactly as long as the operation is in flight. @@ -156,11 +182,27 @@ therefore never recycled while a completion for it is still coming. `ioxd__await_item` hands the next queued buffer over whole - the pipe's reader owns it from then until it returns it to the ring - and parks if the queue is empty. `await_send` stages a SEND SQE (the loop around it finishes short sends; kernel TLS refuses `MSG_WAITALL`) and parks until its CQE; the pipe's -writer is the only caller. Nothing above the pipe touches either. +writer is the only caller. Nothing above the pipe touches either. The TLS prologue adds three more +that nothing else uses: `ioxd__recv_pause` and `ioxd__recv_resume` stop and restart the multishot +recv, `ioxd__recv_exact` reads an exact count straight from the socket, and `ioxd__setsockopt` +programs it - all over the ring, all suspending like any await. + +### Stopping + +The stop flag is read once. `begin_drain` cancels each armed accept by name (they must stop even on +a kernel without `CANCEL_ANY`), marks every listener stalled so nothing re-arms one, stages a single +`ASYNC_CANCEL` with `IORING_ASYNC_CANCEL_ANY` that takes every recv and every send a coroutine is +parked on, and ends by hand the recvs parked on `-ENOBUFS`, which hold no operation to cancel. If +the kernel refuses the blanket cancel, the worker falls back to cancelling connections one at a +time. Then the loop keeps running: the parked awaits fail with `-ECANCELED`, the handlers unwind, +`conn_close` returns the stacks and the fds, and the loop leaves once `live == 0` or a two-second +grace period is up. A connection accepted in the window before the cancel landed is closed unserved. +If any are still open at the deadline, the ring goes but the buffer slab stays mapped: the kernel +may still hold a buffer for a recv, and leaking the slab at exit beats unmapping it underneath. ### Shared nothing -Nothing crosses workers: each has its own ring, listener, buffers, pools and coroutines. The +Nothing crosses workers: each has its own ring, sockets, buffers, pools and coroutines. The kernel balances connections over the listeners (`SO_REUSEPORT`), and worker *i* is pinned to the *i*-th CPU the process is allowed on, so it is correct under a container cpuset. @@ -178,61 +220,114 @@ runs - the shape of .NET's PipeReader and PipeWriter, with coroutines in place o them as provided buffers, 2 KB each, and the reader keeps them as such: when everything live lies in one buffer - a whole request head in one receive, the common case - `read` returns that buffer's bytes in place, no copy. Only when the bytes span buffers, or when the consumer keeps -bytes it wants contiguous, are they gathered into the consumer's buffer (the 16 KB request -buffer, for HTTP). Four verbs drive it: `examine` (looked at n bytes without consuming them, so +bytes it wants contiguous, are they gathered into the consumer's buffer (`IOXD_PIPE_GATHER`, +16 KB). Six verbs drive it besides `read`: `examine` (looked at n bytes without consuming them, so the next `read` waits for more instead of returning the same incomplete head), `drop` (consume), `keep` (consume, but the bytes stay where they are, contiguous with the run and valid -until `release`) and `copy` (the plain read into a buffer of your own). A run is a stretch of +until `release`), `release` (forget every kept byte; the live ones stay) and `copy` (the plain read +into a buffer of your own), with `run_begin` and `run` below them. A run is a stretch of kept bytes: the head is one and a whole-read body another; `run_begin` freezes the head's so -the body's can move without it. At most two kernel buffers are held at a time, one with frozen -kept bytes and one with the live bytes, so a slow handler pins one 2 KB buffer per request in -flight; the starvation log says when `BUF_COUNT` should grow. +the body's can move without it. + +Kept bytes are what the request model is made of, so `keep` never invalidates a pointer it +handed out. Bytes kept in place stay in the kernel buffer they arrived in, and `run_begin` **pins** +that buffer: it is not returned to the ring when the live bytes move on, but held until `release`. +Only one buffer can be pinned, so a run that would need a second is copied into the gathering +buffer instead, and `ioxd_pipereader_run` says where it ended up. At most two kernel buffers are +held at a time, the pinned one and the live one, so a slow handler pins one 2 KB buffer per request +in flight; the starvation log says when `BUF_COUNT` should grow. The counts are clamped rather than +trusted: `drop` consumes at most what is live, `keep` refuses an n past it (and refuses, as +`IOXD_PIPE_FULL`, kept plus live bytes that would outgrow the gathering buffer). **The writer** is the slab: `reserve` n bytes to format into directly and `advance` by what was -written, `write` to copy in, `flush` to send (a suspension), `send` for both. The HTTP reply -keeps its own head-building and chunk framing on its slab and sends through the same await; a -raw pipe writes straight. +written - never past the room that was there, whatever was claimed - `write` to copy in (data +larger than the slab goes straight from the caller's memory), `flush` to send (a suspension), +`send` for both. In front of the slab is a lead and behind it a slack, so a frame's front and back +go out in the same send as the data between them: the HTTP reply puts its head and a chunk's size +line in the lead and the chunk's CRLF in the slack, and sends through the same await; a raw pipe +writes straight and never touches either. Whatever a handler leaves in the slab is flushed when +the pipe closes, so a raw handler that just wrote and returned still has its bytes sent. ## 5. HTTP -`serve()` in `http.c` is the coroutine every connection runs. Per request: +`ioxd__serve` in `lib/http/engine.c` is the coroutine every connection runs - behind the TLS +prologue when the listener has a certificate store. Per request: 1. **Parse** with picohttpparser, straight into `req.headers` (the layouts match, so there is no copy). `-2` means "incomplete": read more and parse again, so a request split at any byte works. -2. **Body, on demand**: one pass over the headers picks out `Content-Length`, - `Transfer-Encoding` and `Connection` (a length test rejects almost every header before a byte - is compared), but the body stays on the wire. `ioxd_body_all` keeps it whole in the reader - in place - after the head when it all arrived in one receive, gathered otherwise, a chunked one slid - together chunk by chunk; `ioxd_body_read_until` streams it, any + `-1` is a 400. A head that outgrows the reader's 16 KB is a 431. The parsed head is `keep`t, so + every slice in the request points at bytes that stay put, and `run_begin` closes it off so the + body's kept bytes can be a run of their own. +2. **Check the framing** before a handler ever sees the request, because a proxy in front that + reads it differently is how one request smuggles another (RFC 9112 6.1). A `Content-Length` is + decimal digits and nothing else; repeated, its values must agree; both a `Content-Length` and a + `Transfer-Encoding` is a 400. A `Transfer-Encoding` must end in `chunked` and name no other + coding - another coding is a 501, a `chunked` that is not last (across every line, since the + lines join into one list) or an empty list is a 400. A folded continuation line (obs-fold) + reaches the engine with no name and is refused rather than interpreted. HTTP/1.1 needs exactly + one `Host`, HTTP/1.0 at most one. Every `Connection` line is read and its tokens counted, with + `close` winning over `keep-alive`. An `Expect` other than `100-continue` is a 417. An + absolute-form target loses its scheme and authority (RFC 9112 3.2.2) before the path and query + are split off. A query with more parameters than fit is a 400, one whose decoded bytes outgrow + the arena a 414 - never a request acted on in part. Anything refused is answered and the + connection closes. +3. **Body, on demand**: the pass that lower-cases the header names is the one that picks out + `Content-Length`, `Transfer-Encoding`, `Host`, `Connection` and `Expect` (a switch on the name + length rejects nearly every header before a byte is compared), but the body stays on the wire. + `ioxd_body_all` keeps it whole in the reader - in place after the head when it all arrived in + one receive, gathered otherwise, a chunked one slid together chunk by chunk; a + `Content-Length` past the reader's buffer is a 413; `ioxd_body_read_until` streams it, any size, filling the caller's buffer; `ioxd_body_read_next_chunk` hands over one chunk exactly as the - sender framed it. All three chunked paths share one small parser (a raw stage after the head, a - size-line reader, a data mover) that survives a split at any byte. Whatever a handler leaves - unread is drained after it returns, up to a limit, past which the reply says close. -3. **Keep-alive**: HTTP/1.1 unless `Connection: close`; HTTP/1.0 only with `Connection: keep-alive`. -4. **Dispatch** a context to the middleware chain and the route (section 5). The context holds + sender framed it. All three chunked paths share one small parser (a size-line reader, a data + mover, the CRLF after each chunk) that survives a split at any byte. A size line is held to the + grammar - hex digits, then the CRLF, or blanks and a `;` with an extension after it - and + trailers are dropped unread and bounded at `IOXD_TRAILER_MAX`, so a peer cannot hold the + connection open with an endless one; anything else is a 400. With `Expect: 100-continue` the + first of these reads sends `100 Continue` ahead of anything the handler buffered. Whatever a + handler leaves unread is drained after it returns, up to `IOXD_DRAIN_MAX`, past which the reply + says close; a body an expecting client was never asked for is not waited for at all - the reply + goes out and the connection closes. +4. **Keep-alive**: HTTP/1.1 unless `Connection: close`; HTTP/1.0 only with `Connection: keep-alive`. +5. **Dispatch** a context to the middleware chain and the route (section 6). The context holds the request and the response; the response holds the reply being shaped (status, content type, headers); the bytes go into the pipe's writer, an 8 KB slab with a lead in front of it for the head and a chunk's size line, and slack behind it for a chunk's CRLF. -5. **Write**: the handler calls `ioxd_write` / `ioxd_printf`; bytes land in the buffer. If it - fills, the framework sends what it has — head first, framed chunked on HTTP/1.1 or until close - on HTTP/1.0 (or with a length the handler declared) — and the handler suspends on that send. -6. **Finish**: after the chain returns, whatever is buffered goes out. The usual case is that +6. **Write**: the handler calls `ioxd_write` / `ioxd_printf`, or reserves slab bytes with + `ioxd_reserve` and says how many it used with `ioxd_advance`. If the slab fills, the framework + sends what it has — head first, framed chunked on HTTP/1.1 or until close on HTTP/1.0 (or with + a length the handler declared) — and the handler suspends on that send. +7. **Finish**: after the chain returns, whatever is buffered goes out. The usual case is that everything fit: the head (with `Content-Length`, serialized by `memcpy` of precomposed pieces - plus a small integer writer, no `snprintf`) is copied into the reserve right before the body + plus a small integer writer, no `snprintf`) is copied into the lead right before the body and the reply is one send. Every header name goes out lower-cased, the engine's and the handler's alike; HTTP/1.1 treats names case-insensitively and HTTP/2 requires lowercase, so - one spelling is the only one there is. A streamed reply gets its terminating chunk. Then loop; leftover - bytes of a pipelined next request are carried over. + one spelling is the only one there is. A streamed reply gets its terminating chunk. Then loop; + `release` gives this request's bytes back and leftover bytes of a pipelined next one stay. + +What goes on the wire follows the request and the status, not only what the handler wrote. A reply +to HEAD, and a 1xx, 204 or 304, carries no body however much was written (RFC 9112 6.3) - HEAD +keeps the `Content-Length` its GET would have had, while a 1xx and a 204 carry no framing header at +all. A status outside 100-999 goes out as 500. A declared `Content-Length` is held to: a reply that +was buffered whole is corrected to what was actually written, a stream is cut at the declared byte +and the reply fails there, and one that falls short closes the connection so the client can see it +was cut. Whether the reply says `connection: close` because of an undrainable body is settled with +the head, before any of it is sent. Because the head is built at the first send, middleware can shape headers and status until then, -and `head_sent` tells a handler when that moment has passed. - -Everything in a request is a slice (pointer + length) into the read buffer, valid only during -the handler. Three key/value arrays hang off it, read directly: `headers` (names lower-cased once -at parse time, so a plain compare works), `params` (the query, split and percent-decoded into a -small per-request arena only when a value needs it, otherwise a zero-copy view), and `route_params` (the -`:name` captures the router filled in, in pattern order). A `scratch` arena is there for building -a body (`ioxd_textf`). +and `head_sent` tells a handler when that moment has passed. `ioxd_header` copies the name and the +value into the response's own arena as the line they will become, so temporaries are fine; it +lower-cases the name and refuses one that is not an HTTP token, a value with a control byte (no +response splitting), and the three headers the engine owns - `content-length`, +`transfer-encoding`, `connection` - while `content-type` through it is taken as `ioxd_content_type`. + +Everything in a request is a slice (pointer + length) into the bytes the reader kept, valid only +during the handler. Three key/value arrays hang off it, read directly: `headers` (names lower-cased +once at parse time, so a plain compare works), `params` (the query, split and percent-decoded into +a per-request arena only when a value needs it, otherwise a zero-copy view), and `route_params` +(the `:name` captures the router filled in, in pattern order). There are three arenas and no more: +that query arena on the serve coroutine's stack, `req.route_arena` (`IOXD_ROUTE_ARENA`) where the +router decodes captures and writes a 405's `allow` value, and `res.head` (`IOXD_RESP_HEAD_CAP`) +where the reply's added header lines and a copied content type live. --- @@ -244,23 +339,34 @@ middleware, groups nest, and the root (`NULL`) is the group with no prefix whose every worker reads it without a lock. The resolution turns each endpoint's full path (the prefixes of its groups, outermost first, then -its own path) into a segment tree: a node per static segment, plus at most one capture child per +its own path) into a segment tree. The parts are joined with a `/` between them only when neither +side brought one, so a group `/api` and a path `users` make `/api/users` and a repeated slash +counts once. The tree is a node per static segment, plus at most one capture child per node for a `:name` segment, with the endpoints at a node kept one per method. A request is one walk down the tree along its path segments. The static child is tried before the capture, so a static segment wins at any depth, and the walk backs up to the capture when the static branch comes to nothing - including when it reaches the end without the request's method, so a static -path with only a GET lets a POST fall through to a capture route that has one. Captured segments -land in `req->route_params`, named from the endpoint that matched. A path the tree knows without -the method is a 405 with an `allow` header; a path it does not know goes to the fallback -(`ioxd_default`, a plain 404 unless replaced). Nothing is scanned and nothing is compiled per -request; the tree is the map. +path with only a GET lets a POST fall through to a capture route that has one. A node with a GET +and no HEAD of its own answers HEAD with that GET (RFC 9110 9.3.2): the handler still sees `HEAD` +as the method, and the engine drops the body it writes. Captured segments land in +`req->route_params`, named from the endpoint that matched and percent-decoded into the request's +arena when they need it (a `/users/a%2Fb` captures `a/b`), left raw when they do not fit. + +A path the tree knows without the method is a 405 whose `allow` header is the union of the methods +reachable at that path, not one route's: a path can end more than one route - `/users/new` also +ends the `/users/:id` of a capture route - so the walk remembers every end-of-path node it reached +and the header lists each of their methods once, in registration order, with `HEAD` written after +a GET that has no HEAD of its own since that is what would answer it. A path the tree does not know +goes to the fallback (`ioxd_default`, a plain 404 unless replaced). Nothing is scanned and nothing +is compiled per request; the tree is the map. Middleware is an onion: each layer receives the context and a `next`; it does work, calls `ioxd_next_run` to continue, and can do more on the way back out, or it replies and returns to short-circuit the request. Each endpoint's chain is flattened at resolution - the root's middleware, then each group's from outermost to innermost, then the endpoint's own - into one -array, so dispatch is a call through it with no walking of groups. The fallbacks run behind the -root's middleware only. +array, so dispatch is a call through it with no walking of groups. Both fallbacks run behind the +root's middleware only, so a 405's `allow` header names methods a group's own middleware would +otherwise have gated. The `IOXD_` macros are the same registrations as a script: `IOXD_GROUP(prefix, middleware...)` opens a group for the block that follows (a run-once `for`, the group popped when it ends), @@ -272,12 +378,14 @@ so every argument is type-checked and a wrong signature is a compile error. 1. Bytes arrive. The kernel copies them into a provided buffer and posts a `RECV` CQE. 2. `enter` returns; dispatch queues the slice on the connection and resumes its coroutine. -3. The reader hands `serve` the slice in place - no copy; the buffer stays the request's until it is done. -4. picohttpparser parses; the route runs; the response is serialized into the head buffer. +3. The reader hands `ioxd__serve` the slice in place - no copy; the head is `keep`t there, so the + buffer stays pinned to the request until it is done. +4. picohttpparser parses; the framing is checked; the route runs; the head is serialized into the + slab's lead, right in front of the body the handler wrote. 5. `await_send` stages a SEND SQE and yields back to the loop. 6. The loop finishes the batch and calls `enter` once: the SEND is submitted and the loop waits. -7. The SEND CQE (`OP` tag) resumes the coroutine; `serve` releases the request's bytes, the buffer - goes back to the ring, and the next `read` parks. +7. The SEND CQE (`OP` tag) resumes the coroutine; `release` gives the request's bytes back, the + buffer goes to the ring, and the next `read` parks. Two switches in, two out — tens of nanoseconds. The cost of a request is the kernel's, not ours. @@ -290,9 +398,19 @@ Two switches in, two out — tens of nanoseconds. The cost of a request is the k bytes straight into a sink - the reply through `ioxd_reserve`/`ioxd_advance`, a raw pipe, or a memory buffer - with no tree and no allocation. Strings are escaped as they are copied, a safe run at a time; integers go through a digit loop; a double takes the shortest of 15, 16 or 17 -significant digits that reads back as the same value, with the decimal point forced to '.' -whatever the locale says. Nesting and the commas it owes are two bits per level, so a document -deeper than `IOXD_JSON_DEPTH` fails cleanly. A reply larger than the slab streams out chunked +significant digits that `strtod` reads back as the same value, and a float the shortest of 6 to 9 +that `strtof` reads back as the same float, so `0.1f` is written `0.1` and not the wider double it +would be promoted to. Both are formatted under a private "C" locale - made once for the process, +worn by the thread for the `snprintf` and the read-back and handed straight back - since a locale +like `fa_IR` spells the decimal point in several bytes and mending one afterwards is not enough. + +Nesting and the commas it owes are two bits per level - one saying the level has a value already, +one saying it closes with `}` rather than `]` - so a document deeper than `IOXD_JSON_DEPTH` fails +cleanly, and so does one whose calls do not make a document: a key needs an object under it and no +key already waiting for its value, a value inside an object needs a key in front of it, and an +`end` needs something open and no pending key. The first such call fails, the rest are dropped, so +checking the last one is enough; `ioxd_json_done` is the check after it - nothing failed and +nothing is left open. A reply larger than the slab streams out chunked while the writer keeps going, which is the whole point of writing as you go. A struct can be described once and serialized with one call: `IOXD_JSON_STRUCT(user, USER_FIELDS)` @@ -309,8 +427,12 @@ generated function is the code one would write by hand, with no table and nothin | `RING_ENTRIES` | 4096 | SQ depth (CQ is twice that) | | `BUF_COUNT` × `BUF_SIZE` | 4096 × 2 KB | provided recv buffers per worker | | `RX_QUEUE` | 64 | slices a connection may hold undelivered | -| `STACK_SIZE` | 64 KB | per coroutine, plus a guard page | +| `STACK_SIZE` | 128 KB | per coroutine, plus a 64 KB guard (`CORO_GUARD`) | | `CORO_POOL_MAX`, `CONN_POOL_MAX` | 512, 1024 | idle stacks / conns kept warm per worker (not connection limits) | -| `IOXD_REQ_CAP` | 16 KB | a request must fit here, else 413/431 | +| `FIXED_FILES` | 16384 | registered file slots per worker, and so its connection ceiling; 0 disables the table | +| `IOXD_PIPE_GATHER` | 16 KB | the reader's gathering buffer: a head must fit here (else 431) and so must a body read whole (else 413) | +| `IOXD_PIPE_LEAD` / `IOXD_PIPE_CAP` / `IOXD_PIPE_SLACK` | 512 / 8 KB / 8 | the writer's slab and the room in front of and behind it | -Override any of them with `-D` at build time. +Override any of them with `-D` at build time. The library's own limits - `IOXD_MAX_HEADERS` and the +rest of the `IOXD_MAX_*` in `ioxd/http.h` - are not among them: they lay out the context, so +`ioxd_run` checks that the application and the library agree and refuses to start otherwise. diff --git a/DESIGN.md b/DESIGN.md index cfe6614..2f6892a 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,6 +1,14 @@ # ioxide's TCP core, read for a minimal stackful C runtime -> Note: this is the design record for **ioxd** (github.com/MDA2AV/ioxd). Paths like `ioxide/...` and `ringzero/...` refer to the author's sibling repos (github.com/MDA2AV/ioxide, github.com/MDA2AV/ringzero); ioxd itself is the `stackful/`→`ioxd/` runtime described in section 3 and shipped in this repository. +> **Historical.** This is the v1 design record for **ioxd** (github.com/MDA2AV/ioxd): the reading +> of ioxide's TCP core and the ~500-line runtime planned from it, written before any of it was +> built. It does **not** describe what shipped. The v1 sketched here uses liburing, one-shot +> accept/recv/send, no provided buffers and files named `worker.c`/`listener.c`; the library has +> raw io_uring with no liburing, multishot accept and recv over a provided buffer ring, and the +> layout in [`ARCHITECTURE.md`](ARCHITECTURE.md), which supersedes this document. Kept for the +> reasoning - why a stackful coroutine removes half of ioxide's machinery, and the pitfalls in +> section 4, which still hold. Paths like `ioxide/...` and `ringzero/...` are the author's sibling +> repos (github.com/MDA2AV/ioxide, github.com/MDA2AV/ringzero). Scope: `ioxide/src/ioxide` — `io_uring/Ring.cs`, `Native/*`, `Reactor/*`, `Reactor/Transport/Tcp/*`, diff --git a/FILES.md b/FILES.md index 60256a9..94f707d 100644 --- a/FILES.md +++ b/FILES.md @@ -1,5 +1,8 @@ # Static files over the ring (design, branch `streams`) +**Status.** None of this is built: there is no `ioxd_files_*` in the library, no tail capture in +the router and no `lib/io/watch.c`. This is the design, written down before the work. + The model is ioxide.file's: small, hot files served from a baked, immutable snapshot; large files as positional ring reads or, better, spliced from the descriptor straight into the socket - no thread pool either way, and with kernel TLS the splice is encrypted on its way through. @@ -27,8 +30,10 @@ old name, a new inode, and the old watch dies with the old one. So the watch is one per directory in the tree (inotify watches are cheap; an asset tree of a few hundred directories is nothing), and the events that mean "the content under this name is different" are `IN_CLOSE_WRITE` (a write in place finished), `IN_MOVED_TO` (the atomic replace landed), -`IN_CREATE` and `IN_DELETE`. The descriptor is read as an ordinary ring read by the same control -coroutine that watches certificates - it is one facility, `lib/io/watch.c`, with two clients. +`IN_CREATE` and `IN_DELETE`. The descriptor would be read as an ordinary ring read by the same +control coroutine that watches certificates - one facility, `lib/io/watch.c`, with two clients. +Neither the watcher nor that file exists yet; the certificate store's own rotation watcher is +planned in the same terms (TLS.md), and today it reloads only when the application says so. Events are debounced, then the changed entries are confirmed with `statx` against the snapshot (inode, size, mtime), re-baked, and a new snapshot is published: an atomic pointer with a diff --git a/PERF.md b/PERF.md index abbb212..de50655 100644 --- a/PERF.md +++ b/PERF.md @@ -31,13 +31,18 @@ profiles score. | Request model: the query split into `params` eagerly, header names lower-cased at parse (8 bytes a step) so handlers compare with plain `ioxd_slice_eq` | about −1% each; the price of direct data access | | Parse straight from the provided buffer when a whole request sits in one (the pipe's reader keeps it in place; the copy happens only for a request that spans receives) | neutral, as predicted: the copy it removes was under 1% | | gcc 14 and C23 (was gcc 13 and gnu11) | neutral: 1.23M vs 1.22M req/s keep-alive and equal churn, wrk and oha, three interleaved rounds on 4 reactors. The standard changes what the compiler accepts, not the code it emits | +| The review hardening: the request framing checked before a handler sees it, reply headers copied and validated into the response's arena, and the loop's own bookkeeping | about −1%: 1.258M → 1.245M req/s keep-alive, medians of interleaved wrk rounds on 4 reactors. Paid for correctness; the CQ head is still published once per batch | + +The `-D` switches: `FIXED_FILES=0` disables the registered file table and `NO_REG_RING` the +registered ring fd - both features fall back at runtime on kernels that lack them anyway. The rest +are the tunables, each defined where it is used: `BUF_SIZE` and `BUF_COUNT` in `lib/io/bufring.h`, +`RX_QUEUE` and `CONN_POOL_MAX` in `lib/io/conn.h`, `CORO_POOL_MAX` (and `CORO_GUARD`) in +`lib/io/coro.c`, `RING_ENTRIES`, `STACK_SIZE` and `FIXED_FILES` itself in `lib/io/proactor.h`. -The `-D` switches: `FIXED_FILES=0` disables the file table, `NO_REG_RING` the registered ring fd, -`BUF_SIZE`/`BUF_COUNT`/`RING_ENTRIES`/`RX_QUEUE`/`STACK_SIZE`/`CORO_POOL_MAX`/`CONN_POOL_MAX` are A recv that finds the ring empty is logged, at most once a second per worker, with counts: -`ioxd: [w3] recv found no provided buffer N times ...: raise BUF_COUNT`. That line is the signal to raise -`-DBUF_COUNT` (a power of two, up to 65536; each buffer is `BUF_SIZE` bytes of the per-worker slab). -in `lib/io/bufring.h` and `lib/io/proactor.h`. Both ring features fall back at runtime on kernels that lack them. +`ioxd: [w3] recv found no provided buffer N times (M in total, K connections parked): raise +BUF_COUNT`. That line is the signal to raise `-DBUF_COUNT` (a power of two, at most 32768 - the +kernel refuses a ring of 65536 entries; each buffer is `BUF_SIZE` bytes of the per-worker slab). ### How to do PGO diff --git a/README.md b/README.md index c44c10f..35a3994 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,11 @@ runtime works is in [`ARCHITECTURE.md`](ARCHITECTURE.md). ## Build Run `make` in the repo root. It produces `libioxd.a`, `libioxd.so` and the demo server -`ioxd-hello`. CMake works too. Requirements: Linux 6.x, x86-64, gcc 14 or newer: the code is C23. On Ubuntu 24.04 -`sudo apt install gcc-14`; make and CMake pick the newest gcc they find unless told otherwise. +`ioxd-hello`. CMake works too. Requirements: Linux 6.x, x86-64, gcc 14 or newer (the code is C23), +and OpenSSL 3 with its headers, which the TLS handshake links against. On Ubuntu 24.04 +`sudo apt install gcc-14 libssl-dev`; make and CMake pick the newest gcc they find unless told +otherwise. TLS is built by default: `make TLS=0`, or CMake's `-DIOXD_TLS=OFF`, leaves it out and +with it the OpenSSL dependency, and `ioxd_tls_new` then returns NULL with a line saying so. ## Run @@ -38,8 +41,9 @@ body into its slab with `ioxd_write`, `ioxd_text` or `ioxd_printf`; the framewor in front of it, in one send when it fits and streamed when it does not. Endpoints live in groups: a group is a path prefix plus middleware, groups nest, and `ioxd_get(api, "/users/:id", user)` under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware of every group above it; the root is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it all once into a segment tree and flat -chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port; more ports, plain or TLS, come -from `ioxd_listen` before it. +chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port; more ports come +from `ioxd_listen` before it - plain with a `NULL`, or TLS with a certificate store from +`ioxd_tls_new("

")`, a directory of `/cert.pem` and `key.pem` ([`TLS.md`](TLS.md)). Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills; a struct @@ -49,6 +53,19 @@ nesting the routes below it; the hello example and `tests/server.c` are written ## Tests and limits -`make check` builds the fixture server, runs `tests/smoke.py` and `tests/stress.py` against it -and stops it. HTTP/1.1 only, no TLS, a request head and a body read whole up to 16 KB (streamed -bodies have no limit). MIT licensed. +`make check` builds the fixtures and runs the router test, then `tests/run-suites.sh`: the unit +test, then the smoke, conformance, stress and early-TLS suites against one HTTP fixture - one +fixture for all four, since a port the suite before it left full of `TIME_WAIT` connections resets +some of the next one's - then the pipe suite against the pipe fixture. `make check-tiny` runs the +stress suite alone against a second build starved on purpose (`-DBUF_COUNT=8 -DBUF_SIZE=64 +-DRX_QUEUE=4`), so every request empties the buffer group; `make check-all` runs both. `make tidy` +runs clang-tidy over the library, and `make check-tlsfuzzer TLSFUZZER=` runs six of +tlsfuzzer's TLS 1.3 scripts against the fixture. The suites need python3 and the `openssl` command +(`tests/mkcerts.sh` makes the certificates); `tests/tls_early.py` needs tlslite-ng and skips itself +without it, so pass a python that has it as `make check TLS_PYTHON=...`; tlsfuzzer needs its own +requirements in that python; `make tidy` needs clang-tidy. CMake runs the same script: a `check` +target over ctest, with `unit`, `router`, `suites` and `pipes` entries. + +HTTP/1.1 only. TLS 1.3, terminated in the kernel after an OpenSSL handshake, one cipher suite, no +tickets and no client certificates ([`TLS.md`](TLS.md)). A request head, and a body read whole, must +fit 16 KB; streamed bodies have no limit. MIT licensed. diff --git a/STREAMS.md b/STREAMS.md index 684677c..a482d9b 100644 --- a/STREAMS.md +++ b/STREAMS.md @@ -2,19 +2,21 @@ **Status.** Steps 1 to 4 below are on the branch: `io/pipe.h` (reader, writer), the HTTP engine reading through the reader with the in-place fast path, and the public `ioxd_pipe` with -`ioxd_run_pipes`, a line-echo fixture and its tests. The reader's verbs ended up as examine / -drop / keep / copy rather than one `advance(consumed, examined)`, because kept bytes - the -request model's slices - need to stay put, which Pipelines has no notion of. Open, to talk -about: the public surface (run_begin/run stay private for now); outbound connections -(`ioxd_connect` on IORING_OP_CONNECT, the same pipe over a socket to a database or a peer); -a second transport (QUIC, TLS) and whether that wants a vtable; letting the live bytes sit in a -second kernel buffer while a run continues in the first, so streamed bodies never copy twice. +`ioxd_run_pipes`, a line-echo fixture and its tests. The reader's verbs ended up as read / +examine / drop / keep / release / copy, with run_begin and run below them, rather than one +`advance(consumed, examined)`, because kept bytes - the request model's slices - need to stay +put, which Pipelines has no notion of. TLS arrived as a prologue over the same pipe rather than +as a second transport (TLS.md), so no vtable was needed. Open, to talk about: the public surface +(run_begin/run stay private for now); outbound connections (`ioxd_connect` on +IORING_OP_CONNECT, the same pipe over a socket to a database or a peer); QUIC, and whether that +wants a vtable; letting the live bytes sit in a second kernel buffer while a run continues in +the first, so streamed bodies never copy twice. ## Why -Today the I/O plane offers two primitives, `await_recv` and `await_send`, and the HTTP engine -builds everything else on them: a 16 KB request buffer it fills and parses, a reply slab it -appends to and flushes. Both are streams in all but name. Naming them, and moving them below the +Before this work the I/O plane offered two primitives, a recv await and a send await, and the +HTTP engine built everything else on them: a 16 KB request buffer it filled and parsed, a reply +slab it appended to and flushed. Both are streams in all but name. Naming them, and moving them below the HTTP engine, gives three things: 1. a transport-independent surface, so a raw TCP server, a WebSocket upgrade or a TLS layer @@ -45,9 +47,14 @@ on the context, for handlers that format straight into the reply. **`ioxd_pipereader`** - the connection's received bytes, one contiguous span at a time. - int ioxd_pipereader_read (r, ioxd_slice *span); /* what is buffered, contiguous; waits for more when the caller examined it all; 0 at EOF, -1 on error */ - void ioxd_pipereader_advance(r, size_t consumed, size_t examined); /* consumed: gone (provided buffers returned to the ring); examined: do not wake me until more than this arrives */ - int ioxd_pipereader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ + int ioxd_pipereader_read (r, ioxd_slice *live); /* the live bytes, contiguous, once some are unexamined; waits for more otherwise; 0 at EOF, <0 on error */ + void ioxd_pipereader_examine (r, size_t n); /* looked at n of them: do not hand back the same bytes, wait for more */ + void ioxd_pipereader_drop (r, size_t n); /* consume n (clamped to what is live); the kernel buffer goes back once nothing is left in it */ + const char *ioxd_pipereader_keep (r, size_t n); /* consume n but leave them where they are, contiguous with the run; where they are, or NULL: no room, or n past the live bytes */ + void ioxd_pipereader_run_begin(r); /* freeze the run in progress; the next keep starts another */ + ioxd_slice ioxd_pipereader_run (r); /* the run in progress, wherever it ended up */ + void ioxd_pipereader_release (r); /* forget every kept byte; the live ones stay */ + int ioxd_pipereader_copy (r, void *dst, size_t n); /* the Stream-style read: up to n bytes into dst */ Why one span and not a list of segments. io_uring hands data over as provided buffers, each a pointer and a length, and the reader keeps them as such internally (the rx queue does already). @@ -59,25 +66,28 @@ ours to write and to keep fast. So the reader coalesces, and it does so lazily: - when everything buffered lies in one provided buffer - a whole request head in one receive, the common case - `read` returns that buffer's bytes in place: zero copy, the buffer stays - owned by the connection until `advance` consumes past it; -- when the data spans buffers, `read` copies the pieces into the connection's request buffer + owned by the connection until `drop` consumes past it; +- when the data spans buffers, `read` copies the pieces into the connection's gathering buffer (16 KB, on the coroutine's stack: no allocation) and returns that. Spanning requests pay the copy they pay today; nothing else does. That is Kestrel's `IsSingleSegment` fast path, kept inside the reader rather than in every -parser, and `advance(consumed, examined)` is Pipelines' contract: `consumed` releases buffers, -`examined` keeps `read` from returning the same incomplete head twice - it suspends until more -arrives instead. +parser. Pipelines' one `advance(consumed, examined)` became two verbs, `drop` and `examine`, plus +`keep` for the third case Pipelines has no name for: `drop` releases buffers, `examine` keeps +`read` from returning the same incomplete head twice - it suspends until more arrives instead - and +`keep` consumes without moving, because the request model's slices have to stay valid. Kept bytes +form a run; `run_begin` closes one off and pins the kernel buffer it sits in, so pointers already +handed out stay good until `release`. -**`ioxd_stream`** - one connection's reader and writer together, what a handler of a non-HTTP -protocol would receive. +**`ioxd_pipe`** - one connection's reader and writer together, what a handler of a non-HTTP +protocol receives (`include/ioxd/pipe.h` for the public verbs, `lib/io/pipe.h` for the rest). ## The HTTP engine on top - `read_head`: `reader_read` gives a span; `phr_parse_request` runs on it. In the common case that is the provided buffer itself - no copy - and the request's slices point into it; the - buffer stays owned by the connection until the reply is finished, when `advance` returns it. - A head that spans receives arrives coalesced in the request buffer, as today. + head is `keep`t, so the buffer stays owned by the connection until the reply is finished, when + `release` returns it. A head that spans receives arrives coalesced in the gathering buffer. - Body reads (`ioxd_body_all`, `read_until`, `read_next_chunk`) run the chunk parser on spans the same way; the whole read wants contiguous output and gets it from the same coalescing. - Pipelining falls out: the bytes after a request are simply not consumed. @@ -99,8 +109,8 @@ protocol would receive. 1. Writer: reserve/advance/write/flush/send in the io plane; the response on it; `ioxd_reserve`/`ioxd_advance` public. Small, no behaviour change, measurable. 2. Reader with `copy` only (Stream semantics) and the engine's `read_head` and body stage on it, - still copying. Same behaviour, same numbers expected. Removes `await_recv` from the engine. -3. Spans + `advance(consumed, examined)`, then the zero-copy single-buffer path. This is the + still copying. Same behaviour, same numbers expected. Removes the recv await from the engine. +3. Spans + examine/drop/keep, then the zero-copy single-buffer path. This is the step with a payoff and the risk; it gets the fragmentation validator and the raw-socket smoke tests. -4. `ioxd_stream` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. +4. `ioxd_pipe` public, with a raw TCP entry point, once the HTTP engine is a clean client of it. diff --git a/TLS.md b/TLS.md index a3a9ee2..9404d61 100644 --- a/TLS.md +++ b/TLS.md @@ -1,19 +1,35 @@ # TLS: one way, in the kernel (design, branch `streams`) -**Status.** Built: `lib/tls/store.c` (the store, SNI, reload) and `lib/tls/handshake.c` (the prologue -and the handoff); `ioxd_listen(port, ioxd_tls_new(dir))`. Verified by the smoke suite through -Python's `ssl` (default certificate, SNI, an unknown name, a POST body and a 1 MB upload through -kernel RX, keep-alive, a 3000-object reply through kernel TX, a refused TLS 1.2 client), by +**Status.** Built: `lib/tls/store.c` (the store, SNI, `ioxd_tls_reload`, `ioxd_tls_free`) and +`lib/tls/handshake.c` (the prologue and the handoff); `ioxd_listen(port, ioxd_tls_new(dir))`. +Built by default; `make TLS=0` or `-DIOXD_TLS=OFF` leaves it out, and `ioxd_tls_new` then says so +and returns NULL. Verified by the smoke suite through +Python's `ssl` (default certificate, SNI, the `_.example.com` wildcard, an unknown name, a POST +body and a 1 MB upload through kernel RX, keep-alive, a 3000-object reply through kernel TX, a +refused TLS 1.2 client, and a reload while it serves), by `tests/tls_early.py` with tlslite-ng at the wire level (the request in the same TCP write as the client's Finished, whole and with its record cut in two with a pause; two early requests; a close_notify; a corrupted record), by six of tlsfuzzer's TLS 1.3 scripts (`make check-tlsfuzzer`), and -by a testssl.sh scan (TLS 1.3 only, forward-secret AEAD only). Known limits, all deliberate for now: +by a testssl.sh scan (TLS 1.3 only, forward-secret AEAD only). The certificates the suites use come +from `tests/mkcerts.sh`, which makes three short-lived self-signed hosts - `default` (RSA), +`sni.test` and the wildcard `_.example.com` (ECDSA) - and remakes one that is within three days of +expiring. + +Kernel TLS programs the socket with `setsockopt`, and the plane sends that over the ring +(`IORING_OP_URING_CMD` with `SOCKET_URING_OP_SETSOCKOPT`): under the registered file table, which +is the default, a connection is a slot index and not a descriptor `setsockopt(2)` could be called +on. So a TLS listener wants a kernel that knows that command, 6.7 or newer - or a build with +`-DFIXED_FILES=0`, where the plain call is the fallback. + +Known limits, all deliberate for now: one suite, TLS_AES_128_GCM_SHA256 - AES-256-GCM and ChaCha20-Poly1305 are one table entry each in the store and one key-size case in the handoff; no tickets, no 0-RTT, no client certificates; the server sends close_notify when it closes, but a control record from the peer after the handoff (an alert, a KeyUpdate, an over-long record) ends the connection without an alert of ours, since the plain recv only reports it as an error - seeing record types would mean recvmsg with control -data on the multishot recv. The rotation watcher is the next step (FILES.md shares it). +data on the multishot recv. Still open: the rotation watcher below (FILES.md shares it), and +letting `ctx->req` carry the negotiated server name and the fact that the connection is TLS, for +handlers and redirects - neither is built. ## The shape @@ -42,47 +58,82 @@ to: a client that cannot do this suite fails the handshake. **The receive handoff, precisely.** A TLS 1.3 client may send its first request in the same segment as its Finished, so when the handshake completes the reader may hold ciphertext past it. +OpenSSL is therefore fed exactly one record per call all the way through the handshake: a whole +record is assembled out of the reader and written into the read BIO, and nothing more, so what the +client sent behind its Finished is still in the reader when the handshake ends rather than +swallowed by the BIO. + Kernel RX can only start at a record boundary in the socket's own queue, so before installing RX -the prologue feeds whatever the reader holds through OpenSSL - `SSL_read` - until it ends on a -record boundary (waiting for the tail of a split record if it has to), hands the plaintext it got -to the reader as if it had just arrived, and installs `TLS_RX` with the record sequence those -records consumed. A control record after the handoff - close_notify, or a KeyUpdate the kernel -cannot honour - surfaces as `-EIO` on the recv, which the connection treats as end of input. -Browsers do not send KeyUpdate; that is the accepted limit. +the prologue stops the multishot recv and drains what is left. The drain assembles records into a +scratch buffer of its own, one at a time, never waiting: while records are there they go through +OpenSSL and the plaintext is kept aside; when nothing delivered is left, the socket is at a record +boundary and the drain is done. The tail of a record the pause cut in two is fetched straight from +the socket (`ioxd__recv_exact`). The plaintext is then handed to the reader as if it had just +arrived, and `TLS_RX` is installed with the record sequence those records consumed. + +Three things end the connection there, each with a line saying which: a record that is not +application data (an alert, or a handshake message), a post-handshake message OpenSSL wants to +answer - a KeyUpdate, seen as bytes appearing in the write BIO, which the handoff cannot follow - +and early plaintext larger than the reader can hold, since the plaintext has to fit the reader's +gathering buffer (`IOXD_PIPE_GATHER`, 16 KB). A client's close_notify during the drain is not a +failure: the records before it are still served, and the connection then ends normally. -## Certificates: files on disk, SNI, a default, rotation +After the handoff the kernel owns the records, and a control record from the peer - close_notify, +or a KeyUpdate the kernel cannot honour - surfaces as `-EIO` on the recv, which the connection +treats as end of input. Browsers do not send KeyUpdate; that is the accepted limit. + +## Certificates: files on disk, SNI, a default, a reload - **Layout.** A directory per listener: `//cert.pem` (the chain) and `key.pem`, plus `/default/` for no SNI or no match. Matching is exact hostname, then one wildcard level - (`*.example.com` as the directory name `_.example.com`). + (`*.example.com` as the directory name `_.example.com`). `default` is required: without it there + is nothing to answer a name we do not have, so `ioxd_tls_new` says so and returns NULL. Only a + reload may go without one, and only by carrying the host that was already answering forward. +- **What a host must be to load.** The key has to match the certificate and the chain has to parse, + and the certificate's validity dates are checked as well: one that has expired, or that does not + start until later, is a load failure like any other. A key file readable past its owner is + logged, once per host per load. - **SNI.** `SSL_CTX_set_client_hello_cb` reads the server-name extension, looks the host up, and - switches the connection's context with `SSL_set_SSL_CTX`. Unknown or absent: the default. -- **Rotation without a restart.** One control coroutine on worker 0 watches the directory tree - with inotify - `IN_CLOSE_WRITE` for a file rewritten in place, `IN_MOVED_TO` for the atomic - replace (`rename` over the old file; a watch on the file itself would be lost with the inode), - `IN_CREATE`/`IN_DELETE` for hosts added and removed - read off the inotify descriptor as an - ordinary ring read. Events are debounced (500 ms: editors and certbot touch a directory several - times), then each changed host is confirmed with `statx` (inode, size, mtime against what is - loaded), parsed, checked (the key matches the certificate, the chain parses, not yet expired), - and built into a new `SSL_CTX`. The new table is published with an atomic pointer and a - generation; every handshake takes a reference to the table it started with, so an in-flight - handshake finishes on the old certificate and the old table is freed when the last reference - drops. A `statx` sweep every 60 s is the safety net for filesystems where inotify is silent - (NFS, some bind mounts), and `ioxd_tls_reload()` / SIGHUP force it for deployments that prefer - to say when. A rejected file (bad key, mismatch) is logged and the old certificate stays. + switches the connection's context with `SSL_set_SSL_CTX`. Unknown or absent: the default. The + callback goes on a context once, when it is built, and finds the table through the SSL that its + handshake holds a reference to - not through the context - because a reload shares a carried-over + context between two tables, and a published `SSL_CTX` is never written to again. +- **Reload.** `ioxd_tls_reload(tls)` reads the directory again and switches to what it holds. It is + manual: nothing watches the tree, and nothing sends it a signal. Reloads serialise against each + other, and the table is reference-counted - every handshake takes a reference to the table it + started with - so a handshake in flight finishes on the certificate it began with and the old + table is freed when the last reference drops. A host that fails to load keeps the context it was + serving, so an expired replacement changes nothing but a line on stderr; the host answering for + unmatched SNI keeps answering. It returns -1 when nothing at all could be loaded, and what was + serving still is. `ioxd_tls_free(tls)` gives the store back once no handshake holds a table of + it: for a store never listened on, or for after `ioxd_run` has returned. ## Where it plugs in Listeners become explicit, one per port and per worker, so plain and TLS can coexist and more than one port can be served (ioxide's multi-port): - ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree, starts watching + ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree ioxd_listen(8443, tls); // TLS, besides ioxd_run's plain port ioxd_run(0, 8080); // workers over every listener -Per connection, `conn_main` runs the prologue when its listener has a TLS context, then the same -handler as always. `ctx->req` gains the negotiated server name and the fact that the connection is -TLS, for handlers and redirects. The dependency is libssl at handshake time; the data path is the -kernel's. Test surface: the fixture on a self-signed default certificate plus one SNI host; the -smoke suite through Python's `ssl` module; a rotation test that rewrites `cert.pem` atomically and -checks the next handshake presents the new one. +Per connection, `ioxd__conn_main` runs the pipe's handler, and `run.c` puts the prologue in front +of it when the listener has a TLS store; a close_notify goes out when the handler is done. The +dependency is libssl at handshake time; the data path is the kernel's. The test fixture +(`tests/server.c`) serves `IOXD_CERTS` on the port two above its own and exposes +`POST /tls/reload`, which is how the smoke suite rewrites `sni.test`'s files, checks that the old +certificate is still served until the reload, and checks that a connection open across it keeps +answering. + +## Planned: rotation without a restart + +Not built. One control coroutine on worker 0 would watch the directory tree +with inotify - `IN_CLOSE_WRITE` for a file rewritten in place, `IN_MOVED_TO` for the atomic +replace (`rename` over the old file; a watch on the file itself would be lost with the inode), +`IN_CREATE`/`IN_DELETE` for hosts added and removed - reading the inotify descriptor as an +ordinary ring read. Events would be debounced (500 ms: editors and certbot touch a directory +several times), then each changed host confirmed with `statx` (inode, size, mtime against what is +loaded) before the reload the store already does. A `statx` sweep every 60 s is the safety net for +filesystems where inotify is silent (NFS, some bind mounts), and a SIGHUP would force one for +deployments that prefer to say when. `ioxd_tls_reload` is what all of that would call; today it is +the whole of it, and the application decides when. FILES.md shares the same watch facility. diff --git a/lib/io/coro.h b/lib/io/coro.h index eeebe66..504334e 100644 --- a/lib/io/coro.h +++ b/lib/io/coro.h @@ -1,10 +1,13 @@ /* * coro.h - stackful coroutines for one proactor thread. * - * A coroutine runs on its own mmap'd stack with a guard page. Suspending saves the callee-saved - * registers and switches to the loop's stack; resuming is the reverse. Everything on the - * coroutine's stack stays exactly where it was while it is parked, which is what lets an - * io_uring completion be routed to a struct that lives in an await's frame. + * A coroutine runs on its own mmap'd stack with an unmapped guard region (CORO_GUARD) below it. + * Suspending saves the callee-saved registers and switches to the loop's stack; resuming is the + * reverse. Everything on the coroutine's stack stays exactly where it was while it is parked, + * which is what lets an io_uring completion be routed to a struct that lives in an await's frame. + * + * A finished coroutine's stack is not unmapped but pooled per thread, guard still armed, and + * handed to the next coro_create; past CORO_POOL_MAX idle stacks it is unmapped instead. * * Discipline: only the loop calls coro_resume, only a coroutine calls coro_yield. A coroutine * that wants to start another one hands it to the scheduler (proactor_spawn); resuming from @@ -31,14 +34,15 @@ typedef struct coro { size_t size; /* mapping size, guard included */ void (*fn)(void *); void *arg; - bool done; /* fn returned; the next resume-return frees the stack */ + bool done; /* fn returned; the next resume-return recycles the stack */ struct coro *next; /* scheduler's ready-list link */ } coro_t; /* Allocate a stack and forge its first frame. The descriptor lives at the top of that stack. */ CORO_API coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes); -/* Loop only. Run c until it yields; if it finished, its stack is unmapped before returning. */ +/* Loop only. Run c until it yields; if it finished, its stack goes to the pool (or is unmapped + * past CORO_POOL_MAX) before returning. */ CORO_API void coro_resume(coro_t *c); /* Coroutine only. Back to the loop; returns when the loop resumes this coroutine again. */ diff --git a/lib/io/proactor.h b/lib/io/proactor.h index aba156c..f81a088 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -1,12 +1,15 @@ /* - * proactor.h - one worker: one thread, one io_uring, one SO_REUSEPORT listener, one provided - * buffer ring, and the coroutines that run on it. The connections it serves are io/conn.h. Thread-per-core, shared-nothing: nothing in - * here is touched by any other thread except the stop flag. + * proactor.h - one worker: one thread, one io_uring, one SO_REUSEPORT socket per listening port, + * one provided buffer ring, and the coroutines that run on it. The connections it serves are + * io/conn.h. Thread-per-core, shared-nothing: nothing in here is touched by any other thread + * except the stop flag. * * The loop: run freshly spawned coroutines, re-arm recvs parked on -ENOBUFS, publish and enter - * once (submit everything staged, wait for >= 1 completion), then dispatch the CQ batch one entry - * at a time, publishing the head per entry so the ring keeps room mid-batch. Dispatching resumes - * handler coroutines inline, so the sends they stage ride the next enter together with the batch. + * once (submit everything staged, wait for >= 1 completion), then dispatch the CQ batch, each CQE + * copied out of the ring before its handler runs. The head is published once at the end of the + * batch - and in ioxd__sqe ahead of an enter made in the middle of one, so the kernel has room for + * what that enter completes. Dispatching resumes handler coroutines inline, so the sends they + * stage ride the next enter together with the batch. * * On stop the loop does not simply leave: it cancels the accepts and everything in flight, then * keeps running until the last connection has closed itself or a two-second grace period is up, @@ -88,7 +91,7 @@ struct proactor { int failed; /* 0, or the -errno that retired this worker */ }; -/* The worker thread's whole life: ring, buffers, listener, loop until *stop, teardown. */ +/* The worker thread's whole life: ring, buffers, listeners, loop until *stop, drain, teardown. */ void proactor_run(proactor_t *p); /* Start a coroutine on this worker. Safe from the loop or from any coroutine on it. */ diff --git a/tests/router_test.c b/tests/router_test.c index 629cedf..5787b77 100644 --- a/tests/router_test.c +++ b/tests/router_test.c @@ -3,7 +3,7 @@ * header of a 405, HEAD answered by GET, decoded captures, the middleware chain, and the * diagnostics that guard registration. Requests are driven straight through the dispatcher with * a context built by hand - one whose reply is marked failed, so the body writes of the built-in - * fallbacks go nowhere and nothing here touches the wire. `make check` runs it after the unit + * fallbacks go nowhere and nothing here touches the wire. `make check` runs it beside the unit * test. */ #include From 4d2b128204c52b54e003830976241be9f207f878 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 11:37:21 +0100 Subject: [PATCH 39/49] hello: the same routes over TLS when given a certificate directory ./ioxd-hello certs listens on 8443 with the store from that directory beside the plain 8080; the header shows the curl lines, SNI included. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- README.md | 2 +- playground/hello/main.c | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35a3994..66a0a28 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ with it the OpenSSL dependency, and `ioxd_tls_new` then returns NULL with a line ## Run `./ioxd-hello` is the smallest server: three routes, `GET /hello/:name`, a `GET /users/:id` that writes JSON, and a `POST /repeat/:times` -that reads the body and streams it back, one worker per core on port 8080. Ctrl-C stops it. A server exercising every feature of the request and response model +that reads the body and streams it back, one worker per core on port 8080; given a directory of certificates (`sh tests/mkcerts.sh certs && ./ioxd-hello certs`) it serves the same routes over TLS on 8443 too. Ctrl-C stops it. A server exercising every feature of the request and response model is `tests/server.c`, the fixture the test suites run against. ## Use it in your project diff --git a/playground/hello/main.c b/playground/hello/main.c index 250174f..3866590 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -1,11 +1,16 @@ /* - * playground/hello - a small libioxd server: three routes, one worker per core. + * playground/hello - a small libioxd server: three routes, one worker per core, and the same + * routes over TLS when it is given a directory of certificates. * * make && ./ioxd-hello * curl http://127.0.0.1:8080/hello/diogo * curl http://127.0.0.1:8080/users/42 * curl -d 'knock' http://127.0.0.1:8080/repeat/25 * + * sh tests/mkcerts.sh certs && ./ioxd-hello certs # self-signed, so curl needs -k + * curl -k https://127.0.0.1:8443/hello/diogo + * curl -k --resolve sni.test:8443:127.0.0.1 https://sni.test:8443/users/42 + * * Against an installed libioxd: cc main.c $(pkg-config --cflags --libs ioxd) -o hello */ #include @@ -89,10 +94,23 @@ static void user_endpoint(ioxd_ctx *ctx) user_to_json(&j, &u); } -int main(void) +/* The routes, then the ports. ioxd_run serves plain HTTP on 8080; with a certificate directory + * on the command line a second listener serves the same routes on 8443 over TLS 1.3. The store + * holds one host per subdirectory - //cert.pem and key.pem - and the client's SNI + * picks the host, `default` answering for no name or an unknown one (TLS.md). The handshake is + * OpenSSL's; from then on the kernel encrypts and decrypts, and a handler cannot tell the two + * listeners apart. */ +int main(int argc, char **argv) { IOXD_GET ("/hello/:name", hello); IOXD_GET ("/users/:id", user_endpoint); IOXD_POST("/repeat/:times", repeat); + + if (argc > 1) { + ioxd_tls *tls = ioxd_tls_new(argv[1]); + if (!tls) + return 1; /* the reason is on stderr: no `default`, a bad key, a TLS=0 build */ + ioxd_listen(8443, tls); + } return ioxd_run(0, 8080); } From 9bfeb3ea161b9e56d1f6c9a78be5d21e8ae1092f Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 11:41:03 +0100 Subject: [PATCH 40/49] tls: a header per file, like the other planes store.h is what the handshake needs from the store, handshake.h what the runner and the store need from the handshake; tls.h and internal.h are gone, and the hex digit helper only the keylog parser used is its own. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 2 +- lib/http/run.c | 2 +- lib/tls/handshake.c | 15 ++++++++++++--- lib/tls/{tls.h => handshake.h} | 11 +++++++++-- lib/tls/internal.h | 27 --------------------------- lib/tls/store.c | 4 ++-- lib/tls/store.h | 19 +++++++++++++++++++ 7 files changed, 44 insertions(+), 36 deletions(-) rename lib/tls/{tls.h => handshake.h} (56%) delete mode 100644 lib/tls/internal.h create mode 100644 lib/tls/store.h diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 0508854..2ee4e43 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -26,7 +26,7 @@ worker loop), with `proactor.h` as the interface the other planes use; `http/` i (handler helpers), `run.c` (`ioxd_run`, `ioxd_listen`, `ioxd_run_pipes`); and `tls/` is the TLS prologue - `store.c` (certificates, SNI, reload) and `handshake.c` (the OpenSSL handshake and the handoff to the kernel). `json/json.c` is the JSON writer, which depends on neither plane. Each -plane has an `internal.h` for what its files share. +`io/` and `http/` each have an `internal.h` for what their files share and no module owns; `tls/` has none - `store.h` and `handshake.h` are what its two files need from each other, and the runner includes the latter. --- diff --git a/lib/http/run.c b/lib/http/run.c index 0f90449..f9d78d1 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -5,7 +5,7 @@ #include "http/router.h" #include "io/pipe.h" #include "io/proactor.h" -#include "tls/tls.h" +#include "tls/handshake.h" #include #include diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index 58276f1..beacdd5 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -3,9 +3,9 @@ * traffic secrets caught by the keylog callback, HKDF-Expand-Label into key and IV, and the keys * into the socket, so the kernel does every record from then on. See TLS.md. */ -#include "tls/tls.h" +#include "tls/handshake.h" +#include "tls/store.h" #include "io/internal.h" -#include "tls/internal.h" #include #include @@ -50,11 +50,20 @@ static const char *ssl_error_text(void) return text; } +/* The value of a hex digit, or -1. */ +static int hexdigit(char c) +{ + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + /* 64 hex characters into 32 bytes. */ static bool unhex(const char *hex, unsigned char *out) { for (size_t i = 0; i < SECRET_LEN; i++) { - int hi = ioxd__hexdigit(hex[2 * i]), lo = ioxd__hexdigit(hex[2 * i + 1]); + int hi = hexdigit(hex[2 * i]), lo = hexdigit(hex[2 * i + 1]); if (hi < 0 || lo < 0) return false; out[i] = (unsigned char)((unsigned)hi << 4 | (unsigned)lo); diff --git a/lib/tls/tls.h b/lib/tls/handshake.h similarity index 56% rename from lib/tls/tls.h rename to lib/tls/handshake.h index 943ca72..44f94d6 100644 --- a/lib/tls/tls.h +++ b/lib/tls/handshake.h @@ -1,6 +1,7 @@ /* - * tls/tls.h - what the runner needs from the TLS plane: the prologue a TLS connection runs before - * its handler. The store itself is the public ioxd/tls.h. + * tls/handshake.h - the prologue a TLS connection runs before its handler, and the alert it sends + * when it ends; for the runner. The keylog callback is here too: the store installs it on every + * context it makes, and this is where the secrets it catches are wanted. */ #pragma once @@ -14,3 +15,9 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls); /* Tell the peer the connection is ending: a close_notify alert, sent as a TLS control record * through the kernel. Best effort, for a connection whose prologue succeeded. */ void ioxd__tls_close_notify(struct ioxd_pipe *pipe); + +#if IOXD_TLS +#include + +void ioxd__tls_keylog(const SSL *ssl, const char *line); /* catches the traffic secrets */ +#endif diff --git a/lib/tls/internal.h b/lib/tls/internal.h deleted file mode 100644 index 5aac404..0000000 --- a/lib/tls/internal.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * tls/internal.h - what the store and the handshake share: the table a handshake holds a - * reference to and hangs on its SSL, and the keylog callback the store installs on every context. - */ -#pragma once - -#include "ioxd/tls.h" - -/* The value of a hex digit, or -1. */ -static inline int ioxd__hexdigit(char c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - return -1; -} - -#if IOXD_TLS -#include - -struct table; -struct table *ioxd__tls_acquire (ioxd_tls *tls); /* store.c: the table serving now, referenced */ -void ioxd__tls_release (ioxd_tls *tls, struct table *t); -SSL_CTX *ioxd__tls_fallback(const struct table *t); /* the context a handshake starts on */ -void ioxd__tls_bind (SSL *ssl, struct table *t); /* the table its ClientHello picks a host from */ -void ioxd__tls_keylog (const SSL *ssl, const char *line); /* handshake.c: catches the traffic secrets */ -#endif diff --git a/lib/tls/store.c b/lib/tls/store.c index 823d4f2..188adde 100644 --- a/lib/tls/store.c +++ b/lib/tls/store.c @@ -8,9 +8,9 @@ * name one: the ClientHello callback is installed once, when the context is built, and finds the * table through the SSL its handshake holds a reference for. */ -#include "tls/tls.h" +#include "tls/store.h" +#include "tls/handshake.h" #include "io/internal.h" -#include "tls/internal.h" #include #include diff --git a/lib/tls/store.h b/lib/tls/store.h new file mode 100644 index 0000000..643a4dc --- /dev/null +++ b/lib/tls/store.h @@ -0,0 +1,19 @@ +/* + * tls/store.h - the certificate store's entries for the handshake: the table serving now, held + * by reference for as long as a handshake runs, the context a handshake starts on, and the + * binding that lets its ClientHello pick a host from that same table. The public side of the + * store - ioxd_tls_new, ioxd_tls_reload, ioxd_tls_free - is ioxd/tls.h. + */ +#pragma once + +#include "ioxd/tls.h" + +#if IOXD_TLS +#include + +struct table; +struct table *ioxd__tls_acquire (ioxd_tls *tls); /* the table serving now, referenced */ +void ioxd__tls_release (ioxd_tls *tls, struct table *t); +SSL_CTX *ioxd__tls_fallback(const struct table *t); /* the context a handshake starts on */ +void ioxd__tls_bind (SSL *ssl, struct table *t); /* the table its ClientHello picks a host from */ +#endif From ee593c0920bef8823c465dc4108d154fa688b901 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 11:54:54 +0100 Subject: [PATCH 41/49] ioxd_bind(port, tls) binds a port, plain or TLS; ioxd_run(workers) serves every bound port ioxd_listen and ioxd_run each took a port, a leftover from when the run was the only way to get a listener. Now a port is bound once, with its certificate store or none, and the run only takes the worker count and refuses to start with nothing bound. ioxd_run_pipes follows. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 2 +- README.md | 4 ++-- TLS.md | 11 ++++++----- include/ioxd.h | 3 ++- include/ioxd/http.h | 28 ++++++++++++++-------------- include/ioxd/pipe.h | 2 +- include/ioxd/tls.h | 2 +- lib/http/run.c | 32 ++++++++++++-------------------- playground/hello/main.c | 16 ++++++++-------- tests/pipe-server.c | 3 ++- tests/server.c | 7 ++++--- 11 files changed, 53 insertions(+), 57 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 2ee4e43..c36db73 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -23,7 +23,7 @@ own. Under `lib/` there are three planes, one concern per file: `io/` is the I/O `conn.c` (a connection and its awaits), `pipe.c` (the reader and the writer), `proactor.c` (the worker loop), with `proactor.h` as the interface the other planes use; `http/` is the HTTP plane - `engine.c` (parse, body, reply, the serve loop), `router.c` (routes and middleware), `api.c` -(handler helpers), `run.c` (`ioxd_run`, `ioxd_listen`, `ioxd_run_pipes`); and `tls/` is the TLS +(handler helpers), `run.c` (`ioxd_bind`, `ioxd_run`, `ioxd_run_pipes`); and `tls/` is the TLS prologue - `store.c` (certificates, SNI, reload) and `handshake.c` (the OpenSSL handshake and the handoff to the kernel). `json/json.c` is the JSON writer, which depends on neither plane. Each `io/` and `http/` each have an `internal.h` for what their files share and no module owns; `tls/` has none - `store.h` and `handshake.h` are what its two files need from each other, and the runner includes the latter. diff --git a/README.md b/README.md index 66a0a28..6e5d93c 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ body into its slab with `ioxd_write`, `ioxd_text` or `ioxd_printf`; the framewor in front of it, in one send when it fits and streamed when it does not. Endpoints live in groups: a group is a path prefix plus middleware, groups nest, and `ioxd_get(api, "/users/:id", user)` under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware of every group above it; the root is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it all once into a segment tree and flat -chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) and a port; more ports come -from `ioxd_listen` before it - plain with a `NULL`, or TLS with a certificate store from +chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) over every port +bound before it with `ioxd_bind(port, NULL)` - or `ioxd_bind(port, store)` for TLS, the store from `ioxd_tls_new("")`, a directory of `/cert.pem` and `key.pem` ([`TLS.md`](TLS.md)). Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with diff --git a/TLS.md b/TLS.md index 9404d61..d866d6e 100644 --- a/TLS.md +++ b/TLS.md @@ -1,7 +1,7 @@ # TLS: one way, in the kernel (design, branch `streams`) **Status.** Built: `lib/tls/store.c` (the store, SNI, `ioxd_tls_reload`, `ioxd_tls_free`) and -`lib/tls/handshake.c` (the prologue and the handoff); `ioxd_listen(port, ioxd_tls_new(dir))`. +`lib/tls/handshake.c` (the prologue and the handoff); `ioxd_bind(port, ioxd_tls_new(dir))`. Built by default; `make TLS=0` or `-DIOXD_TLS=OFF` leaves it out, and `ioxd_tls_new` then says so and returns NULL. Verified by the smoke suite through Python's `ssl` (default certificate, SNI, the `_.example.com` wildcard, an unknown name, a POST @@ -110,12 +110,13 @@ treats as end of input. Browsers do not send KeyUpdate; that is the accepted lim ## Where it plugs in -Listeners become explicit, one per port and per worker, so plain and TLS can coexist and more than -one port can be served (ioxide's multi-port): +Ports are bound one by one, each plain or with a store, and every worker opens all of them, so +plain and TLS coexist and more than one port can be served (ioxide's multi-port): ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree - ioxd_listen(8443, tls); // TLS, besides ioxd_run's plain port - ioxd_run(0, 8080); // workers over every listener + ioxd_bind(8080, NULL); // plain + ioxd_bind(8443, tls); // TLS + ioxd_run(0); // workers over every bound port Per connection, `ioxd__conn_main` runs the pipe's handler, and `run.c` puts the prologue in front of it when the listener has a TLS store; a close_notify goes out when the handler is done. The diff --git a/include/ioxd.h b/include/ioxd.h index cf8af2d..5e113a9 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -17,7 +17,8 @@ * } * int main(void) { * IOXD_GET("/users/:id", user); // or ioxd_route(NULL, "GET", "/users/:id", user) - * return ioxd_run(0, 8080); // one worker per core + * ioxd_bind(8080, NULL); // plain; ioxd_bind(8443, ioxd_tls_new("certs")) for TLS + * return ioxd_run(0); // one worker per core * } */ #pragma once diff --git a/include/ioxd/http.h b/include/ioxd/http.h index 80ebc09..a76686f 100644 --- a/include/ioxd/http.h +++ b/include/ioxd/http.h @@ -166,22 +166,22 @@ int ioxd_flush (ioxd_ctx *ctx); /* send what is in the /* ── run ───────────────────────────────────────────────────────────────────────────────── */ -/* Start `workers` proactor threads (<= 0: one per core) serving HTTP on `port` and on every - * listener added below, and block until SIGINT/SIGTERM. Returns 0 on clean shutdown, non-zero - * when a worker failed, when the port could not be bound, or when the limits above differ - * between this header and the library (the context would not match). May be called again - * after it returns. */ -int ioxd__run(int workers, int port, size_t ctx_size); -static inline int ioxd_run(int workers, int port) +/* Bind a port: plain HTTP when tls is NULL, TLS 1.3 terminated in the kernel otherwise, with the + * certificate store from ioxd_tls_new (TLS.md). Every bound port serves the same routes; bind as + * many as you need (at most 8), then run. -1 if refused: a bad port, or the table is full. */ +typedef struct ioxd_tls ioxd_tls; +int ioxd_bind(int port, ioxd_tls *tls); + +/* Start `workers` proactor threads (<= 0: one per core) serving HTTP on every bound port, and + * block until SIGINT/SIGTERM. Returns 0 on clean shutdown, non-zero when nothing was bound, when a + * port could not be opened, when a worker failed, or when the limits above differ between this + * header and the library (the context would not match). May be called again after it returns; + * the ports stay bound. */ +int ioxd__run(int workers, size_t ctx_size); +static inline int ioxd_run(int workers) { - return ioxd__run(workers, port, sizeof(ioxd_ctx)); + return ioxd__run(workers, sizeof(ioxd_ctx)); } -/* More ports: each ioxd_listen before the run adds one, plain when tls is NULL, TLS 1.3 terminated - * in the kernel otherwise (a certificate store from ioxd_tls_new; TLS.md). ioxd_run's own port - * joins them as a plain one; 0 there means only the listeners added. At most 8. -1 if refused. */ -typedef struct ioxd_tls ioxd_tls; -int ioxd_listen(int port, ioxd_tls *tls); - /* The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted. */ const char *ioxd_reason(int status); diff --git a/include/ioxd/pipe.h b/include/ioxd/pipe.h index e6e5b5e..5a4a830 100644 --- a/include/ioxd/pipe.h +++ b/include/ioxd/pipe.h @@ -16,7 +16,7 @@ * one such handler; ioxd_run_pipes runs one of yours on raw TCP connections instead. */ typedef struct ioxd_pipe ioxd_pipe; typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe); -int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn); /* like ioxd_run, without HTTP */ +int ioxd_run_pipes(int workers, ioxd_pipe_handler fn); /* like ioxd_run, over the ports ioxd_bind bound, without HTTP */ /* Reading. The live bytes are the ones received and not yet consumed, always handed out as one * contiguous span - in place in the kernel's buffer when they lie within one. read returns 1 diff --git a/include/ioxd/tls.h b/include/ioxd/tls.h index ec27455..17665f7 100644 --- a/include/ioxd/tls.h +++ b/include/ioxd/tls.h @@ -9,7 +9,7 @@ /* A store from a directory: //cert.pem (the chain) and key.pem for each hostname, * `default` for no SNI or no match, `_.example.com` for *.example.com. `default` is required - * without it nothing can answer a name we do not have. NULL, with the reason on stderr, when - * nothing loads or the build has no TLS. Then: ioxd_listen(port, store). */ + * nothing loads or the build has no TLS. Then: ioxd_bind(port, store). */ ioxd_tls *ioxd_tls_new(const char *dir); /* Read the directory again and switch to what it holds. A host that fails to load - unreadable, diff --git a/lib/http/run.c b/lib/http/run.c index f9d78d1..2ea5b99 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -58,35 +58,29 @@ static void raise_nofile(void) } } -/* Start the workers (workers <= 0: one per available core) and block until a stop signal. */ -/* Worker threads, one proactor each, serving `port` with `handler` on every connection until - * SIGINT/SIGTERM. What ioxd_run and ioxd_run_pipes share. */ -/* The listeners added before the run; ioxd_run's own port joins them. */ +/* The ports bound before the run, each with its store or none; every worker opens all of them. */ static struct listener g_listeners[IOXD_MAX_LISTENERS]; static int g_n_listeners; -int ioxd_listen(int port, ioxd_tls *tls) +int ioxd_bind(int port, ioxd_tls *tls) { if (port < 1 || port > 65535 || g_n_listeners == IOXD_MAX_LISTENERS) { - fprintf(stderr, "ioxd_listen: port %d refused (1..65535, at most %d listeners)\n", port, IOXD_MAX_LISTENERS); + fprintf(stderr, "ioxd_bind: port %d refused (1..65535, at most %d ports)\n", port, IOXD_MAX_LISTENERS); return -1; } g_listeners[g_n_listeners++] = (struct listener){ .port = (uint16_t)port, .tls = tls }; return 0; } -static int run_workers(int workers, int port, handler_fn handler) +/* Worker threads (workers <= 0: one per available core), one proactor each, running `handler` + * on every connection of every bound port until SIGINT/SIGTERM. What ioxd_run and ioxd_run_pipes + * share. */ +static int run_workers(int workers, handler_fn handler) { if (workers <= 0) workers = cpu_count(); - int added = 0; /* listeners this call added: taken out again before returning */ - if (port != 0) { - if (ioxd_listen(port, nullptr) < 0) - return 2; - added = 1; - } if (g_n_listeners == 0) { - fprintf(stderr, "ioxd_run: nothing to listen on\n"); + fprintf(stderr, "ioxd_run: nothing bound: ioxd_bind a port first\n"); return 2; } @@ -106,7 +100,6 @@ static int run_workers(int workers, int port, handler_fn handler) perror("calloc"); free(ws); free(th); - g_n_listeners -= added; return 1; } @@ -140,7 +133,6 @@ static int run_workers(int workers, int port, handler_fn handler) rc = 1; free(th); free(ws); - g_n_listeners -= added; /* so a second ioxd_run does not serve this port twice */ return rc; } @@ -163,7 +155,7 @@ static void serve_http(struct ioxd_pipe *pipe) /* ioxd_run, through the header's inline: the caller's sizeof(ioxd_ctx) must be ours, or the * limits that size it (IOXD_MAX_HEADERS and friends) were redefined on one side and every * handler would read the context at the wrong offsets. */ -int ioxd__run(int workers, int port, size_t ctx_size) +int ioxd__run(int workers, size_t ctx_size) { if (ctx_size != sizeof(ioxd_ctx)) { fprintf(stderr, "ioxd_run: the application's ioxd_ctx is %zu bytes, the library's %zu: " @@ -171,7 +163,7 @@ int ioxd__run(int workers, int port, size_t ctx_size) return 1; } ioxd__router_build(); /* the routes, resolved once, shared read-only */ - return run_workers(workers, port, serve_http); + return run_workers(workers, serve_http); } static ioxd_pipe_handler g_pipe_handler; @@ -185,8 +177,8 @@ static void serve_pipe(struct ioxd_pipe *pipe) ioxd__tls_close_notify(pipe); } -int ioxd_run_pipes(int workers, int port, ioxd_pipe_handler fn) +int ioxd_run_pipes(int workers, ioxd_pipe_handler fn) { g_pipe_handler = fn; - return run_workers(workers, port, serve_pipe); + return run_workers(workers, serve_pipe); } diff --git a/playground/hello/main.c b/playground/hello/main.c index 3866590..0aecce1 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -94,23 +94,23 @@ static void user_endpoint(ioxd_ctx *ctx) user_to_json(&j, &u); } -/* The routes, then the ports. ioxd_run serves plain HTTP on 8080; with a certificate directory - * on the command line a second listener serves the same routes on 8443 over TLS 1.3. The store - * holds one host per subdirectory - //cert.pem and key.pem - and the client's SNI - * picks the host, `default` answering for no name or an unknown one (TLS.md). The handshake is - * OpenSSL's; from then on the kernel encrypts and decrypts, and a handler cannot tell the two - * listeners apart. */ +/* The routes, then the ports, then the run. Plain HTTP on 8080; with a certificate directory on + * the command line the same routes on 8443 over TLS 1.3 as well. The store holds one host per + * subdirectory - //cert.pem and key.pem - and the client's SNI picks the host, + * `default` answering for no name or an unknown one (TLS.md). The handshake is OpenSSL's; from + * then on the kernel encrypts and decrypts, and a handler cannot tell the two ports apart. */ int main(int argc, char **argv) { IOXD_GET ("/hello/:name", hello); IOXD_GET ("/users/:id", user_endpoint); IOXD_POST("/repeat/:times", repeat); + ioxd_bind(8080, NULL); if (argc > 1) { ioxd_tls *tls = ioxd_tls_new(argv[1]); if (!tls) return 1; /* the reason is on stderr: no `default`, a bad key, a TLS=0 build */ - ioxd_listen(8443, tls); + ioxd_bind(8443, tls); } - return ioxd_run(0, 8080); + return ioxd_run(0); /* one worker per core, over both ports */ } diff --git a/tests/pipe-server.c b/tests/pipe-server.c index 528c59f..467f2c7 100644 --- a/tests/pipe-server.c +++ b/tests/pipe-server.c @@ -115,5 +115,6 @@ static void echo(ioxd_pipe *pipe) int main(int argc, char **argv) { int port = argc > 1 ? (int)strtol(argv[1], NULL, 10) : 8100; - return ioxd_run_pipes(2, port, echo); + ioxd_bind(port, NULL); + return ioxd_run_pipes(2, echo); } diff --git a/tests/server.c b/tests/server.c index b69b42b..4fd2b9c 100644 --- a/tests/server.c +++ b/tests/server.c @@ -522,14 +522,15 @@ int main(void) int workers = (int)env_number("IOXD_WORKERS", 0); /* 0: one per core */ int port = (int)env_number("IOXD_PORT", 8080); int p = port > 0 && port < 65536 ? port : 8080; - ioxd_listen(p + 1, NULL); /* a second plain port: the same routes */ + ioxd_bind(p, NULL); + ioxd_bind(p + 1, NULL); /* a second plain port: the same routes */ const char *certs = getenv("IOXD_CERTS"); /* NOLINT(concurrency-mt-unsafe): a TLS port, given a certificate directory */ if (certs && *certs) { g_tls = ioxd_tls_new(certs); if (g_tls) { - ioxd_listen(p + 2, g_tls); + ioxd_bind(p + 2, g_tls); IOXD_POST("/tls/reload", tls_reload); /* only a build with certificates has it */ } } - return ioxd_run(workers, p); + return ioxd_run(workers); } From 7b69381924afc9ade699d3cb924398f0e1f0e88c Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:07:38 +0100 Subject: [PATCH 42/49] ioxd_certs: the certificate store by its name ioxd_tls said nothing about what it was. ioxd_certs_load(dir) reads the directory, ioxd_bind(port, certs) serves it, ioxd_certs_reload and ioxd_certs_free do what they say; the listener's field is certs too. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- README.md | 4 +- TLS.md | 18 +++---- include/ioxd.h | 2 +- include/ioxd/http.h | 6 +-- include/ioxd/tls.h | 6 +-- lib/http/run.c | 12 ++--- lib/io/conn.c | 2 +- lib/io/proactor.c | 2 +- lib/io/proactor.h | 4 +- lib/tls/handshake.c | 12 ++--- lib/tls/handshake.h | 2 +- lib/tls/store.c | 104 ++++++++++++++++++++-------------------- lib/tls/store.h | 6 +-- playground/hello/main.c | 2 +- tests/server.c | 10 ++-- 15 files changed, 96 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index 6e5d93c..93b7ac3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run `make` in the repo root. It produces `libioxd.a`, `libioxd.so` and the demo and OpenSSL 3 with its headers, which the TLS handshake links against. On Ubuntu 24.04 `sudo apt install gcc-14 libssl-dev`; make and CMake pick the newest gcc they find unless told otherwise. TLS is built by default: `make TLS=0`, or CMake's `-DIOXD_TLS=OFF`, leaves it out and -with it the OpenSSL dependency, and `ioxd_tls_new` then returns NULL with a line saying so. +with it the OpenSSL dependency, and `ioxd_certs_load` then returns NULL with a line saying so. ## Run @@ -43,7 +43,7 @@ under a group at `/api` answers at `/api/users/:id`, wrapped by the middleware o is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it all once into a segment tree and flat chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) over every port bound before it with `ioxd_bind(port, NULL)` - or `ioxd_bind(port, store)` for TLS, the store from -`ioxd_tls_new("")`, a directory of `/cert.pem` and `key.pem` ([`TLS.md`](TLS.md)). +`ioxd_certs_load("")`, a directory of `/cert.pem` and `key.pem` ([`TLS.md`](TLS.md)). Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills; a struct diff --git a/TLS.md b/TLS.md index d866d6e..e40bc26 100644 --- a/TLS.md +++ b/TLS.md @@ -1,8 +1,8 @@ # TLS: one way, in the kernel (design, branch `streams`) -**Status.** Built: `lib/tls/store.c` (the store, SNI, `ioxd_tls_reload`, `ioxd_tls_free`) and -`lib/tls/handshake.c` (the prologue and the handoff); `ioxd_bind(port, ioxd_tls_new(dir))`. -Built by default; `make TLS=0` or `-DIOXD_TLS=OFF` leaves it out, and `ioxd_tls_new` then says so +**Status.** Built: `lib/tls/store.c` (the store, SNI, `ioxd_certs_reload`, `ioxd_certs_free`) and +`lib/tls/handshake.c` (the prologue and the handoff); `ioxd_bind(port, ioxd_certs_load(dir))`. +Built by default; `make TLS=0` or `-DIOXD_TLS=OFF` leaves it out, and `ioxd_certs_load` then says so and returns NULL. Verified by the smoke suite through Python's `ssl` (default certificate, SNI, the `_.example.com` wildcard, an unknown name, a POST body and a 1 MB upload through kernel RX, keep-alive, a 3000-object reply through kernel TX, a @@ -44,7 +44,7 @@ but not the handshake. So a TLS connection is a plain connection with a prologue 2. **Keys into the socket.** The keylog callback hands us the TLS 1.3 traffic secrets (server for TX, client for RX); RFC 8446 HKDF-Expand-Label makes the key and the IV; `setsockopt(TCP_ULP, "tls")` attaches the ULP and `setsockopt(SOL_TLS, TLS_TX / TLS_RX)` installs them. Secrets are - zeroed once programmed. This is ioxide.tls's handoff, in C. + zeroed once programmed. This is ioxide.certs's handoff, in C. 3. **Both directions in the kernel from then on.** The pipe's multishot recv delivers plaintext into the provided buffers; the writer's sends are encrypted by the kernel; `splice` from a file descriptor is encrypted too, which is what makes zero-copy file serving over TLS possible. @@ -87,7 +87,7 @@ treats as end of input. Browsers do not send KeyUpdate; that is the accepted lim - **Layout.** A directory per listener: `//cert.pem` (the chain) and `key.pem`, plus `/default/` for no SNI or no match. Matching is exact hostname, then one wildcard level (`*.example.com` as the directory name `_.example.com`). `default` is required: without it there - is nothing to answer a name we do not have, so `ioxd_tls_new` says so and returns NULL. Only a + is nothing to answer a name we do not have, so `ioxd_certs_load` says so and returns NULL. Only a reload may go without one, and only by carrying the host that was already answering forward. - **What a host must be to load.** The key has to match the certificate and the chain has to parse, and the certificate's validity dates are checked as well: one that has expired, or that does not @@ -98,14 +98,14 @@ treats as end of input. Browsers do not send KeyUpdate; that is the accepted lim callback goes on a context once, when it is built, and finds the table through the SSL that its handshake holds a reference to - not through the context - because a reload shares a carried-over context between two tables, and a published `SSL_CTX` is never written to again. -- **Reload.** `ioxd_tls_reload(tls)` reads the directory again and switches to what it holds. It is +- **Reload.** `ioxd_certs_reload(tls)` reads the directory again and switches to what it holds. It is manual: nothing watches the tree, and nothing sends it a signal. Reloads serialise against each other, and the table is reference-counted - every handshake takes a reference to the table it started with - so a handshake in flight finishes on the certificate it began with and the old table is freed when the last reference drops. A host that fails to load keeps the context it was serving, so an expired replacement changes nothing but a line on stderr; the host answering for unmatched SNI keeps answering. It returns -1 when nothing at all could be loaded, and what was - serving still is. `ioxd_tls_free(tls)` gives the store back once no handshake holds a table of + serving still is. `ioxd_certs_free(tls)` gives the store back once no handshake holds a table of it: for a store never listened on, or for after `ioxd_run` has returned. ## Where it plugs in @@ -113,7 +113,7 @@ treats as end of input. Browsers do not send KeyUpdate; that is the accepted lim Ports are bound one by one, each plain or with a store, and every worker opens all of them, so plain and TLS coexist and more than one port can be served (ioxide's multi-port): - ioxd_tls *tls = ioxd_tls_new("/etc/ioxd/certs"); // reads the tree + ioxd_certs *tls = ioxd_certs_load("/etc/ioxd/certs"); // reads the tree ioxd_bind(8080, NULL); // plain ioxd_bind(8443, tls); // TLS ioxd_run(0); // workers over every bound port @@ -136,5 +136,5 @@ ordinary ring read. Events would be debounced (500 ms: editors and certbot touch several times), then each changed host confirmed with `statx` (inode, size, mtime against what is loaded) before the reload the store already does. A `statx` sweep every 60 s is the safety net for filesystems where inotify is silent (NFS, some bind mounts), and a SIGHUP would force one for -deployments that prefer to say when. `ioxd_tls_reload` is what all of that would call; today it is +deployments that prefer to say when. `ioxd_certs_reload` is what all of that would call; today it is the whole of it, and the application decides when. FILES.md shares the same watch facility. diff --git a/include/ioxd.h b/include/ioxd.h index 5e113a9..aeb8a48 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -17,7 +17,7 @@ * } * int main(void) { * IOXD_GET("/users/:id", user); // or ioxd_route(NULL, "GET", "/users/:id", user) - * ioxd_bind(8080, NULL); // plain; ioxd_bind(8443, ioxd_tls_new("certs")) for TLS + * ioxd_bind(8080, NULL); // plain; ioxd_bind(8443, ioxd_certs_load("certs")) for TLS * return ioxd_run(0); // one worker per core * } */ diff --git a/include/ioxd/http.h b/include/ioxd/http.h index a76686f..4d03da8 100644 --- a/include/ioxd/http.h +++ b/include/ioxd/http.h @@ -167,10 +167,10 @@ int ioxd_flush (ioxd_ctx *ctx); /* send what is in the /* ── run ───────────────────────────────────────────────────────────────────────────────── */ /* Bind a port: plain HTTP when tls is NULL, TLS 1.3 terminated in the kernel otherwise, with the - * certificate store from ioxd_tls_new (TLS.md). Every bound port serves the same routes; bind as + * certificate store from ioxd_certs_load (TLS.md). Every bound port serves the same routes; bind as * many as you need (at most 8), then run. -1 if refused: a bad port, or the table is full. */ -typedef struct ioxd_tls ioxd_tls; -int ioxd_bind(int port, ioxd_tls *tls); +typedef struct ioxd_certs ioxd_certs; +int ioxd_bind(int port, ioxd_certs *certs); /* Start `workers` proactor threads (<= 0: one per core) serving HTTP on every bound port, and * block until SIGINT/SIGTERM. Returns 0 on clean shutdown, non-zero when nothing was bound, when a diff --git a/include/ioxd/tls.h b/include/ioxd/tls.h index 17665f7..674344b 100644 --- a/include/ioxd/tls.h +++ b/include/ioxd/tls.h @@ -10,17 +10,17 @@ * `default` for no SNI or no match, `_.example.com` for *.example.com. `default` is required - * without it nothing can answer a name we do not have. NULL, with the reason on stderr, when * nothing loads or the build has no TLS. Then: ioxd_bind(port, store). */ -ioxd_tls *ioxd_tls_new(const char *dir); +ioxd_certs *ioxd_certs_load(const char *dir); /* Read the directory again and switch to what it holds. A host that fails to load - unreadable, * mismatched, not valid yet, expired - keeps its old certificate, and the host answering for * unmatched SNI keeps answering. Safe while serving: handshakes in flight finish on the table * they started with, and reloads serialise against each other. 0, or -1 when nothing could be * loaded at all, in which case what was serving still is. */ -int ioxd_tls_reload(ioxd_tls *tls); +int ioxd_certs_reload(ioxd_certs *certs); /* Give the store back: its certificates and the store itself, once the last handshake holding a * table of it has finished. Not while a listener still uses it - every TLS connection takes a * reference through the store - so this is for a store that was never listened on, or for after * ioxd_run has returned. NULL is a no-op. */ -void ioxd_tls_free(ioxd_tls *tls); +void ioxd_certs_free(ioxd_certs *certs); diff --git a/lib/http/run.c b/lib/http/run.c index 2ea5b99..6c64704 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -62,13 +62,13 @@ static void raise_nofile(void) static struct listener g_listeners[IOXD_MAX_LISTENERS]; static int g_n_listeners; -int ioxd_bind(int port, ioxd_tls *tls) +int ioxd_bind(int port, ioxd_certs *certs) { if (port < 1 || port > 65535 || g_n_listeners == IOXD_MAX_LISTENERS) { fprintf(stderr, "ioxd_bind: port %d refused (1..65535, at most %d ports)\n", port, IOXD_MAX_LISTENERS); return -1; } - g_listeners[g_n_listeners++] = (struct listener){ .port = (uint16_t)port, .tls = tls }; + g_listeners[g_n_listeners++] = (struct listener){ .port = (uint16_t)port, .certs = certs }; return 0; } @@ -122,7 +122,7 @@ static int run_workers(int workers, handler_fn handler) if (started) { fprintf(stderr, "ioxd: %d workers on", started); for (int i = 0; i < g_n_listeners; i++) - fprintf(stderr, " :%u%s", g_listeners[i].port, g_listeners[i].tls ? "/tls" : ""); + fprintf(stderr, " :%u%s", g_listeners[i].port, g_listeners[i].certs ? "/tls" : ""); fputc('\n', stderr); } @@ -140,7 +140,7 @@ static int run_workers(int workers, handler_fn handler) static int prologue(struct ioxd_pipe *pipe) { struct listener *l = pipe->in.conn->listener; - return l->tls ? ioxd__tls_prologue(pipe, l->tls) : 0; + return l->certs ? ioxd__tls_prologue(pipe, l->certs) : 0; } static void serve_http(struct ioxd_pipe *pipe) @@ -148,7 +148,7 @@ static void serve_http(struct ioxd_pipe *pipe) if (prologue(pipe) != 0) return; ioxd__serve(pipe); - if (pipe->in.conn->listener->tls) + if (pipe->in.conn->listener->certs) ioxd__tls_close_notify(pipe); } @@ -173,7 +173,7 @@ static void serve_pipe(struct ioxd_pipe *pipe) if (prologue(pipe) != 0) return; g_pipe_handler(pipe); - if (pipe->in.conn->listener->tls) + if (pipe->in.conn->listener->certs) ioxd__tls_close_notify(pipe); } diff --git a/lib/io/conn.c b/lib/io/conn.c index e18b7d6..893f867 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -237,7 +237,7 @@ void ioxd__on_recv(proactor_t *p, conn_t *c, int result, unsigned flags) } /* Kernel TLS reports a control record - the peer's alert, a KeyUpdate it cannot honour - * as -EIO. TLS.md calls that the end of input, so a close_notify reads like a FIN. */ - end_input(c, result == -EIO && c->listener->tls ? 0 : result); + end_input(c, result == -EIO && c->listener->certs ? 0 : result); c->recv = RECV_DONE; wake_reader(c); /* a parked reader sees 0 / -errno */ conn_unref(c); /* the recv's ref; may recycle c */ diff --git a/lib/io/proactor.c b/lib/io/proactor.c index e668558..67fcc3e 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -375,7 +375,7 @@ void proactor_run(proactor_t *p) l->p = p; l->fd = listener_open(l->port); arm_accept(l); - int n = snprintf(ports + at, sizeof ports - at, "%s:%u%s", i ? " " : "", l->port, l->tls ? "/tls" : ""); + int n = snprintf(ports + at, sizeof ports - at, "%s:%u%s", i ? " " : "", l->port, l->certs ? "/tls" : ""); if (n < 0) break; at += (size_t)n < sizeof ports - at ? (size_t)n : sizeof ports - at - 1; /* truncated: stop growing */ diff --git a/lib/io/proactor.h b/lib/io/proactor.h index f81a088..91a0c75 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -51,7 +51,7 @@ struct listener { proactor_t *p; int fd; /* the socket, or its file slot under fixed files */ uint16_t port; - void *tls; /* the port's certificate store, or nullptr: plain */ + void *certs; /* the port's certificate store, or nullptr: plain */ /* accept back-pressure: out of descriptors, file slots or memory, re-arming at once would * spin, so the accept is left unarmed until there is room again (see rearm_stalled). */ @@ -66,7 +66,7 @@ struct proactor { /* set by the creator */ int id; int cpu; /* pin the thread here; -1 = don't */ - struct listener listeners[IOXD_MAX_LISTENERS]; /* port and tls set by the creator */ + struct listener listeners[IOXD_MAX_LISTENERS]; /* port and certs set by the creator */ int n_listeners; handler_fn handler; volatile sig_atomic_t *stop; diff --git a/lib/tls/handshake.c b/lib/tls/handshake.c index beacdd5..b480b85 100644 --- a/lib/tls/handshake.c +++ b/lib/tls/handshake.c @@ -255,11 +255,11 @@ static long drain_records(struct ioxd_pipe *pipe, SSL *ssl, BIO *rbio, BIO *wbio } } -int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_certs *certs) { pthread_once(&ex_once, make_ex_index); conn_t *c = pipe->in.conn; - struct table *t = ioxd__tls_acquire(tls); + struct table *t = ioxd__tls_acquire(certs); struct secrets s = {}; unsigned char *plain = nullptr; const char *why = nullptr; /* set on every failure: logged once */ @@ -332,14 +332,14 @@ int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) why = "input ended after the handshake"; /* or the worker is draining: nothing to serve */ out: if (why) - fprintf(stderr, "ioxd_tls: connection dropped: %s\n", why); + fprintf(stderr, "ioxd_certs: connection dropped: %s\n", why); explicit_bzero(&s, sizeof s); if (plain) { explicit_bzero(plain, PLAIN_MAX + RECORD_MAX); free(plain); } SSL_free(ssl); /* and its BIOs */ - ioxd__tls_release(tls, t); + ioxd__tls_release(certs, t); return why ? -1 : 0; } @@ -362,10 +362,10 @@ void ioxd__tls_close_notify(struct ioxd_pipe *pipe) #else /* built without TLS */ -int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls) +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_certs *certs) { (void)pipe; - (void)tls; + (void)certs; return -1; } diff --git a/lib/tls/handshake.h b/lib/tls/handshake.h index 44f94d6..b5ab44a 100644 --- a/lib/tls/handshake.h +++ b/lib/tls/handshake.h @@ -10,7 +10,7 @@ /* The handshake over the pipe, then the keys into the socket. 0, or -1: the connection is not * usable (the handshake failed, the peer left, kernel TLS is unavailable). */ -int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_tls *tls); +int ioxd__tls_prologue(struct ioxd_pipe *pipe, ioxd_certs *certs); /* Tell the peer the connection is ending: a close_notify alert, sent as a TLS control record * through the kernel. Best effort, for a connection whose prologue succeeded. */ diff --git a/lib/tls/store.c b/lib/tls/store.c index 188adde..aa0db2a 100644 --- a/lib/tls/store.c +++ b/lib/tls/store.c @@ -39,7 +39,7 @@ struct table { SSL_CTX *fallback; /* `default`: what answers when SNI matches nothing */ }; -struct ioxd_tls { +struct ioxd_certs { char *dir; struct table *table; pthread_mutex_t lock; /* around the table pointer and its refs */ @@ -204,12 +204,12 @@ static struct table *load(const char *dir, const struct table *old) { DIR *d = opendir(dir); if (!d) { - fprintf(stderr, "ioxd_tls: %s: %s\n", dir, ioxd__errstr(errno)); + fprintf(stderr, "ioxd_certs: %s: %s\n", dir, ioxd__errstr(errno)); return nullptr; } struct table *t = calloc(1, sizeof *t); if (!t) { - perror("ioxd_tls"); + perror("ioxd_certs"); closedir(d); return nullptr; } @@ -222,14 +222,14 @@ static struct table *load(const char *dir, const struct table *old) int cn = snprintf(cert, sizeof cert, "%s/%s/cert.pem", dir, e->d_name); int kn = snprintf(key, sizeof key, "%s/%s/key.pem", dir, e->d_name); if (cn < 0 || (size_t)cn >= sizeof cert || kn < 0 || (size_t)kn >= sizeof key) { - fprintf(stderr, "ioxd_tls: %s: the path to its certificate does not fit\n", e->d_name); + fprintf(stderr, "ioxd_certs: %s: the path to its certificate does not fit\n", e->d_name); continue; } struct stat cs, ks; if (stat(cert, &cs) != 0 || !S_ISREG(cs.st_mode) || stat(key, &ks) != 0 || !S_ISREG(ks.st_mode)) continue; /* not a host directory */ if (ks.st_mode & ((unsigned)S_IRGRP | (unsigned)S_IROTH)) /* once per host, on every load */ - fprintf(stderr, "ioxd_tls: %s: mode %03o, readable past its owner\n", key, + fprintf(stderr, "ioxd_certs: %s: mode %03o, readable past its owner\n", key, (unsigned)(ks.st_mode & 0777)); SSL_CTX *ctx = context_for(cert, key); const char *why = ctx ? not_current(ctx) : ssl_error(); @@ -238,7 +238,7 @@ static struct table *load(const char *dir, const struct table *old) ctx = nullptr; } if (!ctx) { - fprintf(stderr, "ioxd_tls: %s: %s (%s)\n", e->d_name, why, cert); + fprintf(stderr, "ioxd_certs: %s: %s (%s)\n", e->d_name, why, cert); if (old) { /* keep what was serving */ for (int i = 0; i < old->n; i++) if (strcmp(old->hosts[i].name, e->d_name) == 0) { @@ -252,7 +252,7 @@ static struct table *load(const char *dir, const struct table *old) struct host *grown = realloc(t->hosts, ((size_t)t->n + 1) * sizeof *grown); char *name = strdup(e->d_name); if (!grown || !name) { - perror("ioxd_tls"); + perror("ioxd_certs"); abort(); } t->hosts = grown; @@ -262,7 +262,7 @@ static struct table *load(const char *dir, const struct table *old) } closedir(d); if (t->n == 0) { - fprintf(stderr, "ioxd_tls: %s: no /cert.pem + key.pem loaded\n", dir); + fprintf(stderr, "ioxd_certs: %s: no /cert.pem + key.pem loaded\n", dir); table_free(t); return nullptr; } @@ -273,64 +273,64 @@ static struct table *load(const char *dir, const struct table *old) if (strcmp(t->hosts[i].name, prev) == 0) t->fallback = t->hosts[i].ctx; if (!t->fallback) { - fprintf(stderr, "ioxd_tls: %s: no `default` host (default/cert.pem + key.pem) to answer" + fprintf(stderr, "ioxd_certs: %s: no `default` host (default/cert.pem + key.pem) to answer" " when SNI matches nothing\n", dir); table_free(t); return nullptr; } - fprintf(stderr, "ioxd_tls: no `default` host; %s still answers when SNI matches nothing\n", prev); + fprintf(stderr, "ioxd_certs: no `default` host; %s still answers when SNI matches nothing\n", prev); } return t; } -ioxd_tls *ioxd_tls_new(const char *dir) +ioxd_certs *ioxd_certs_load(const char *dir) { struct table *t = load(dir, nullptr); if (!t) return nullptr; - ioxd_tls *tls = calloc(1, sizeof *tls); + ioxd_certs *certs = calloc(1, sizeof *certs); char *own = strdup(dir); - if (!tls || !own) { - perror("ioxd_tls"); + if (!certs || !own) { + perror("ioxd_certs"); table_free(t); free(own); - free(tls); + free(certs); return nullptr; } - tls->dir = own; - tls->table = t; - pthread_mutex_init(&tls->lock, nullptr); - pthread_mutex_init(&tls->reload, nullptr); - fprintf(stderr, "ioxd_tls: %d host%s from %s\n", t->n, t->n == 1 ? "" : "s", dir); - return tls; + certs->dir = own; + certs->table = t; + pthread_mutex_init(&certs->lock, nullptr); + pthread_mutex_init(&certs->reload, nullptr); + fprintf(stderr, "ioxd_certs: %d host%s from %s\n", t->n, t->n == 1 ? "" : "s", dir); + return certs; } -void ioxd_tls_free(ioxd_tls *tls) +void ioxd_certs_free(ioxd_certs *certs) { - if (!tls) + if (!certs) return; - ioxd__tls_release(tls, tls->table); /* the store's own reference; the last one frees */ - pthread_mutex_destroy(&tls->reload); - pthread_mutex_destroy(&tls->lock); - free(tls->dir); - free(tls); + ioxd__tls_release(certs, certs->table); /* the store's own reference; the last one frees */ + pthread_mutex_destroy(&certs->reload); + pthread_mutex_destroy(&certs->lock); + free(certs->dir); + free(certs); } /* A reference to the table serving now; released after the handshake. */ -struct table *ioxd__tls_acquire(ioxd_tls *tls) +struct table *ioxd__tls_acquire(ioxd_certs *certs) { - pthread_mutex_lock(&tls->lock); - struct table *t = tls->table; + pthread_mutex_lock(&certs->lock); + struct table *t = certs->table; t->refs++; - pthread_mutex_unlock(&tls->lock); + pthread_mutex_unlock(&certs->lock); return t; } -void ioxd__tls_release(ioxd_tls *tls, struct table *t) +void ioxd__tls_release(ioxd_certs *certs, struct table *t) { - pthread_mutex_lock(&tls->lock); + pthread_mutex_lock(&certs->lock); int left = --t->refs; - pthread_mutex_unlock(&tls->lock); + pthread_mutex_unlock(&certs->lock); if (left == 0) table_free(t); } @@ -340,39 +340,39 @@ SSL_CTX *ioxd__tls_fallback(const struct table *t) return t->fallback; } -int ioxd_tls_reload(ioxd_tls *tls) +int ioxd_certs_reload(ioxd_certs *certs) { - pthread_mutex_lock(&tls->reload); /* one at a time, so the table it reads stays put */ - struct table *old = ioxd__tls_acquire(tls); /* and cannot be freed while load() reads it */ - struct table *fresh = load(tls->dir, old); + pthread_mutex_lock(&certs->reload); /* one at a time, so the table it reads stays put */ + struct table *old = ioxd__tls_acquire(certs); /* and cannot be freed while load() reads it */ + struct table *fresh = load(certs->dir, old); if (fresh) { - pthread_mutex_lock(&tls->lock); - tls->table = fresh; - pthread_mutex_unlock(&tls->lock); - fprintf(stderr, "ioxd_tls: reloaded %d host%s from %s\n", fresh->n, fresh->n == 1 ? "" : "s", tls->dir); - ioxd__tls_release(tls, old); /* the store's own reference to the old table */ + pthread_mutex_lock(&certs->lock); + certs->table = fresh; + pthread_mutex_unlock(&certs->lock); + fprintf(stderr, "ioxd_certs: reloaded %d host%s from %s\n", fresh->n, fresh->n == 1 ? "" : "s", certs->dir); + ioxd__tls_release(certs, old); /* the store's own reference to the old table */ } - ioxd__tls_release(tls, old); /* the one this reload took */ - pthread_mutex_unlock(&tls->reload); + ioxd__tls_release(certs, old); /* the one this reload took */ + pthread_mutex_unlock(&certs->reload); return fresh ? 0 : -1; } #else /* built without TLS */ -ioxd_tls *ioxd_tls_new(const char *dir) +ioxd_certs *ioxd_certs_load(const char *dir) { - fprintf(stderr, "ioxd_tls: %s: this build has no TLS (make TLS=1 with libssl-dev)\n", dir); + fprintf(stderr, "ioxd_certs: %s: this build has no TLS (make TLS=1 with libssl-dev)\n", dir); return nullptr; } -void ioxd_tls_free(ioxd_tls *tls) +void ioxd_certs_free(ioxd_certs *certs) { - (void)tls; + (void)certs; } -int ioxd_tls_reload(ioxd_tls *tls) +int ioxd_certs_reload(ioxd_certs *certs) { - (void)tls; + (void)certs; return -1; } diff --git a/lib/tls/store.h b/lib/tls/store.h index 643a4dc..5c299af 100644 --- a/lib/tls/store.h +++ b/lib/tls/store.h @@ -2,7 +2,7 @@ * tls/store.h - the certificate store's entries for the handshake: the table serving now, held * by reference for as long as a handshake runs, the context a handshake starts on, and the * binding that lets its ClientHello pick a host from that same table. The public side of the - * store - ioxd_tls_new, ioxd_tls_reload, ioxd_tls_free - is ioxd/tls.h. + * store - ioxd_certs_load, ioxd_certs_reload, ioxd_certs_free - is ioxd/tls.h. */ #pragma once @@ -12,8 +12,8 @@ #include struct table; -struct table *ioxd__tls_acquire (ioxd_tls *tls); /* the table serving now, referenced */ -void ioxd__tls_release (ioxd_tls *tls, struct table *t); +struct table *ioxd__tls_acquire (ioxd_certs *certs); /* the table serving now, referenced */ +void ioxd__tls_release (ioxd_certs *certs, struct table *t); SSL_CTX *ioxd__tls_fallback(const struct table *t); /* the context a handshake starts on */ void ioxd__tls_bind (SSL *ssl, struct table *t); /* the table its ClientHello picks a host from */ #endif diff --git a/playground/hello/main.c b/playground/hello/main.c index 0aecce1..c291296 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -107,7 +107,7 @@ int main(int argc, char **argv) ioxd_bind(8080, NULL); if (argc > 1) { - ioxd_tls *tls = ioxd_tls_new(argv[1]); + ioxd_certs *tls = ioxd_certs_load(argv[1]); if (!tls) return 1; /* the reason is on stderr: no `default`, a bad key, a TLS=0 build */ ioxd_bind(8443, tls); diff --git a/tests/server.c b/tests/server.c index 4fd2b9c..a6ef6fa 100644 --- a/tests/server.c +++ b/tests/server.c @@ -385,11 +385,11 @@ static void add_server(ioxd_ctx *ctx, ioxd_next *next) /* POST /tls/reload - the certificate store read again, registered only when the fixture has one. * smoke.py rewrites a host's cert.pem and key.pem and calls this, then checks the new certificate * is what the handshake serves. */ -static ioxd_tls *g_tls; +static ioxd_certs *g_certs; static void tls_reload(ioxd_ctx *ctx) { - if (!g_tls || ioxd_tls_reload(g_tls) != 0) { + if (!g_certs || ioxd_certs_reload(g_certs) != 0) { ctx->res.status = 500; ioxd_text(ctx, "reload failed\n"); return; @@ -526,9 +526,9 @@ int main(void) ioxd_bind(p + 1, NULL); /* a second plain port: the same routes */ const char *certs = getenv("IOXD_CERTS"); /* NOLINT(concurrency-mt-unsafe): a TLS port, given a certificate directory */ if (certs && *certs) { - g_tls = ioxd_tls_new(certs); - if (g_tls) { - ioxd_bind(p + 2, g_tls); + g_certs = ioxd_certs_load(certs); + if (g_certs) { + ioxd_bind(p + 2, g_certs); IOXD_POST("/tls/reload", tls_reload); /* only a build with certificates has it */ } } From ff70fa7aabf64eefde9e8e068a39aaee420f8859 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:21:31 +0100 Subject: [PATCH 43/49] ioxd_configure: the ring, the receive buffers, the stacks and the pools, set at run time The build-time knobs were the only way to size a worker's ring, its provided buffers, its coroutine stacks and its pools. ioxd_config names them per worker and ioxd_configure applies it before the run, refusing a value the kernel or the engine would: the -D names are the defaults. The buffer ring carries its own count, size and mask; the coroutine pool its cap; a worker its configuration. The starved test build now starves through the environment rather than a second set of defines, which is the runtime path under test. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- ARCHITECTURE.md | 27 ++++++++++++++++--------- Makefile | 11 +++++----- PERF.md | 9 ++++++--- README.md | 7 +++++-- include/ioxd.h | 1 + include/ioxd/config.h | 24 ++++++++++++++++++++++ lib/http/run.c | 45 ++++++++++++++++++++++++++++++++++++++++- lib/io/bufring.c | 32 ++++++++++++++++------------- lib/io/bufring.h | 27 ++++++++++++++----------- lib/io/conn.c | 6 +++--- lib/io/conn.h | 2 +- lib/io/coro.c | 19 +++++++++-------- lib/io/coro.h | 7 +++++++ lib/io/proactor.c | 9 +++++---- lib/io/proactor.h | 4 +++- playground/hello/main.c | 1 + tests/server.c | 8 ++++++++ tests/unit.c | 17 ++++++++++++++++ 18 files changed, 192 insertions(+), 64 deletions(-) create mode 100644 include/ioxd/config.h diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index c36db73..bce54dd 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -71,7 +71,7 @@ the handler has consumed it, the worker hands it back by writing its id into the Returns are staged and the ring tail is published once per loop iteration, so a batch of returned buffers costs one atomic store. If the ring runs dry a recv ends with `-ENOBUFS`; the worker logs it -(once a second at most, with counts, so a starved ring is visible and `BUF_COUNT` can be raised) and the connection is +(once a second at most, with counts, so a starved ring is visible and `recv_buffers` can be raised) and the connection is parked and re-armed as soon as any buffer comes back. --- @@ -235,7 +235,7 @@ that buffer: it is not returned to the ring when the live bytes move on, but hel Only one buffer can be pinned, so a run that would need a second is copied into the gathering buffer instead, and `ioxd_pipereader_run` says where it ended up. At most two kernel buffers are held at a time, the pinned one and the live one, so a slow handler pins one 2 KB buffer per request -in flight; the starvation log says when `BUF_COUNT` should grow. The counts are clamped rather than +in flight; the starvation log says when `recv_buffers` should grow. The counts are clamped rather than trusted: `drop` consumes at most what is live, `keep` refuses an n past it (and refuses, as `IOXD_PIPE_FULL`, kept plus live bytes that would outgrow the gathering buffer). @@ -422,17 +422,24 @@ generated function is the code one would write by hand, with no table and nothin ## Tunables -| name | default | what | +The first six are set at run time, per worker, with `ioxd_configure(&(ioxd_config){ ... })` +before `ioxd_run` (`ioxd/config.h`; a zero field keeps its default, a bad value is refused with a +line on stderr); the build-time name is the default. The rest are build-time only. + +| `ioxd_config` field | default (`-D` name) | what | +|---|---|---| +| `ring_entries` | 4096 (`RING_ENTRIES`) | SQ depth (CQ is twice that); a power of two, at most 32768 | +| `recv_buffers` × `recv_buffer_size` | 4096 × 2 KB (`BUF_COUNT`, `BUF_SIZE`) | provided recv buffers per worker: a power of two at most 32768, and 64 B to 1 MB each | +| `stack_size` | 128 KB (`STACK_SIZE`) | per coroutine, above a 64 KB guard (`CORO_GUARD`); at least 64 KB | +| `idle_stacks`, `idle_connections` | 512, 1024 (`CORO_POOL_MAX`, `CONN_POOL_MAX`) | idle stacks / conns kept warm per worker (not connection limits) | + +| build-time only | default | what | |---|---|---| -| `RING_ENTRIES` | 4096 | SQ depth (CQ is twice that) | -| `BUF_COUNT` × `BUF_SIZE` | 4096 × 2 KB | provided recv buffers per worker | | `RX_QUEUE` | 64 | slices a connection may hold undelivered | -| `STACK_SIZE` | 128 KB | per coroutine, plus a 64 KB guard (`CORO_GUARD`) | -| `CORO_POOL_MAX`, `CONN_POOL_MAX` | 512, 1024 | idle stacks / conns kept warm per worker (not connection limits) | | `FIXED_FILES` | 16384 | registered file slots per worker, and so its connection ceiling; 0 disables the table | | `IOXD_PIPE_GATHER` | 16 KB | the reader's gathering buffer: a head must fit here (else 431) and so must a body read whole (else 413) | | `IOXD_PIPE_LEAD` / `IOXD_PIPE_CAP` / `IOXD_PIPE_SLACK` | 512 / 8 KB / 8 | the writer's slab and the room in front of and behind it | -Override any of them with `-D` at build time. The library's own limits - `IOXD_MAX_HEADERS` and the -rest of the `IOXD_MAX_*` in `ioxd/http.h` - are not among them: they lay out the context, so -`ioxd_run` checks that the application and the library agree and refuses to start otherwise. +The library's own limits - `IOXD_MAX_HEADERS` and the rest of the `IOXD_MAX_*` in `ioxd/http.h` - +are neither: they lay out the context, so `ioxd_run` checks that the application and the library +agree and refuses to start otherwise. diff --git a/Makefile b/Makefile index dc44803..86bf449 100644 --- a/Makefile +++ b/Makefile @@ -136,10 +136,11 @@ check: $(TESTSRV) $(UNIT) $(PIPESRV) $(ROUTER) --unit ./$(UNIT) --server ./$(TESTSRV) --pipe-server ./$(PIPESRV) --tls-python $(TLS_PYTHON) # --- the same stress suite, against a build starved on purpose --- -# 8 x 64 B receive buffers and a 4-deep per-connection queue: every request empties the buffer -# group, so recvs park on -ENOBUFS and are re-armed as handlers give buffers back, and the queue -# overflows at the first stall. The defines change every object, so it has its own directory. -TINY := -DBUF_COUNT=8 -DBUF_SIZE=64 -DRX_QUEUE=4 +# 8 x 64 B receive buffers (ioxd_configure, through the fixture's environment) and a 4-deep +# per-connection queue (a build-time constant, so a second object directory): every request +# empties the buffer group, so recvs park on -ENOBUFS and are re-armed as handlers give buffers +# back, and the queue overflows at the first stall. +TINY := -DRX_QUEUE=4 # the buffers come from the environment: ioxd_configure at run time TINYOBJ := $(addprefix obj-tiny/,$(addsuffix .o,$(UNITS))) obj-tiny/io/switch_x86_64.o obj-tiny/picohttpparser.o TINYSRV := tests/ioxd-test-server-tiny TINY_PORT ?= 8410 @@ -159,7 +160,7 @@ $(TINYSRV): tests/server.c libioxd-tiny.a $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(TINY) $(PTHREAD) $< libioxd-tiny.a -o $@ $(PTHREAD) $(LIBS) check-tiny: $(TINYSRV) - @sh tests/run-suites.sh --suite stress --port $(TINY_PORT) --server ./$(TINYSRV) --work obj-tiny/check + @IOXD_RECV_BUFFERS=8 IOXD_RECV_BUFFER_SIZE=64 sh tests/run-suites.sh --suite stress --port $(TINY_PORT) --server ./$(TINYSRV) --work obj-tiny/check # Everything: the default build's suites, then the starved build's. check-all: check check-tiny diff --git a/PERF.md b/PERF.md index de50655..33bf8cf 100644 --- a/PERF.md +++ b/PERF.md @@ -35,9 +35,12 @@ profiles score. The `-D` switches: `FIXED_FILES=0` disables the registered file table and `NO_REG_RING` the registered ring fd - both features fall back at runtime on kernels that lack them anyway. The rest -are the tunables, each defined where it is used: `BUF_SIZE` and `BUF_COUNT` in `lib/io/bufring.h`, -`RX_QUEUE` and `CONN_POOL_MAX` in `lib/io/conn.h`, `CORO_POOL_MAX` (and `CORO_GUARD`) in -`lib/io/coro.c`, `RING_ENTRIES`, `STACK_SIZE` and `FIXED_FILES` itself in `lib/io/proactor.h`. +are the tunables' defaults, each defined where it is used: `BUF_SIZE` and `BUF_COUNT` in +`lib/io/bufring.h`, `RX_QUEUE` and `CONN_POOL_MAX` in `lib/io/conn.h`, `CORO_POOL_MAX` and +`CORO_GUARD` in `lib/io/coro.h` and `lib/io/coro.c`, `RING_ENTRIES`, `STACK_SIZE` and +`FIXED_FILES` itself in `lib/io/proactor.h`. An application sets the ring, the buffers, the stack +and the pools per worker at run time instead, with `ioxd_configure` (`ioxd/config.h`), so a +deployment tunes them without rebuilding the library; `RX_QUEUE` and `FIXED_FILES` stay build-time. A recv that finds the ring empty is logged, at most once a second per worker, with counts: `ioxd: [w3] recv found no provided buffer N times (M in total, K connections parked): raise diff --git a/README.md b/README.md index 93b7ac3..ee791cc 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ is `NULL`, with `ioxd_use` for middleware on everything. `ioxd_run` resolves it chains, so a request costs one walk and no scan, then serves with a worker count (zero means one per core) over every port bound before it with `ioxd_bind(port, NULL)` - or `ioxd_bind(port, store)` for TLS, the store from `ioxd_certs_load("")`, a directory of `/cert.pem` and `key.pem` ([`TLS.md`](TLS.md)). +The runtime's knobs - the ring, the receive buffers, the coroutine stacks, the pools, per worker - are set +before the run with `ioxd_configure`; a zero field keeps the build's default. Underneath, a connection is a pipe: `ioxd_run_pipes` hands a handler of your own the reader and writer the HTTP engine uses, for raw TCP, with the same suspend-and-resume. A JSON reply is written as you go with the `ioxd_json` writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation, streamed as the slab fills; a struct @@ -57,8 +59,9 @@ nesting the routes below it; the hello example and `tests/server.c` are written test, then the smoke, conformance, stress and early-TLS suites against one HTTP fixture - one fixture for all four, since a port the suite before it left full of `TIME_WAIT` connections resets some of the next one's - then the pipe suite against the pipe fixture. `make check-tiny` runs the -stress suite alone against a second build starved on purpose (`-DBUF_COUNT=8 -DBUF_SIZE=64 --DRX_QUEUE=4`), so every request empties the buffer group; `make check-all` runs both. `make tidy` +stress suite alone against the fixture starved on purpose - eight 64-byte receive buffers through +`ioxd_configure`, and a build with `-DRX_QUEUE=4` - so every request empties the buffer group; +`make check-all` runs both. `make tidy` runs clang-tidy over the library, and `make check-tlsfuzzer TLSFUZZER=` runs six of tlsfuzzer's TLS 1.3 scripts against the fixture. The suites need python3 and the `openssl` command (`tests/mkcerts.sh` makes the certificates); `tests/tls_early.py` needs tlslite-ng and skips itself diff --git a/include/ioxd.h b/include/ioxd.h index aeb8a48..97958a3 100644 --- a/include/ioxd.h +++ b/include/ioxd.h @@ -24,6 +24,7 @@ #pragma once #include "ioxd/slice.h" /* slices, conversions, key/value parsing */ +#include "ioxd/config.h" /* the runtime's knobs, set before the run */ #include "ioxd/http.h" /* request, response, context, body, reply, ioxd_run */ #include "ioxd/router.h" /* groups, endpoints, middleware; the script macros */ #include "ioxd/json.h" /* JSON written as you go; structs described once */ diff --git a/include/ioxd/config.h b/include/ioxd/config.h new file mode 100644 index 0000000..2ae4299 --- /dev/null +++ b/include/ioxd/config.h @@ -0,0 +1,24 @@ +/* + * ioxd/config.h - the runtime's knobs: the ring, the receive buffers, the coroutine stacks and + * the pools, per worker. Set once before ioxd_run; the build's values are the defaults. + */ +#pragma once + +#include + +/* Every field is per worker, and a zero field keeps its default. The receive buffers are what + * the kernel delivers into, so their count bounds how much may be in flight before recvs park + * on -ENOBUFS (the log says "raise recv_buffers" when that happens) and their size bounds what + * one delivery holds; a worker's slab is count x size bytes. */ +typedef struct ioxd_config { + unsigned ring_entries; /* submission queue entries, the completion queue twice that; a power of two, at most 32768; 4096 */ + unsigned recv_buffers; /* provided receive buffers; a power of two, at most 32768; 4096 */ + unsigned recv_buffer_size; /* bytes in each, 64 to 1 MB; 2048 */ + size_t stack_size; /* a connection's coroutine stack, above a 64 KB guard; at least 64 KB; 128 KB */ + unsigned idle_stacks; /* stacks kept warm for the next connections; 512 */ + unsigned idle_connections; /* connection records kept warm; 1024 */ +} ioxd_config; + +/* Apply a configuration to the runs that follow. -1, with the reason on stderr, when a value is + * refused - nothing changes then. ioxd_configure(&(ioxd_config){ 0 }) is the defaults. */ +int ioxd_configure(const ioxd_config *config); diff --git a/lib/http/run.c b/lib/http/run.c index 6c64704..2ce396e 100644 --- a/lib/http/run.c +++ b/lib/http/run.c @@ -58,6 +58,47 @@ static void raise_nofile(void) } } +/* The configuration for the runs that follow: what ioxd_configure was given, zeros where the + * default is wanted. Validated on the way in, so the run never sees a bad value. */ +static ioxd_config g_config; + +static bool power_of_two(unsigned v) +{ + return v && (v & (v - 1)) == 0; +} + +int ioxd_configure(const ioxd_config *config) +{ + const char *why = nullptr; + if (config->ring_entries && (!power_of_two(config->ring_entries) || config->ring_entries > 32768)) + why = "ring_entries must be a power of two, at most 32768"; + else if (config->recv_buffers && (!power_of_two(config->recv_buffers) || config->recv_buffers > 32768)) + why = "recv_buffers must be a power of two, at most 32768 (the kernel refuses 65536)"; + else if (config->recv_buffer_size && (config->recv_buffer_size < 64 || config->recv_buffer_size > (1U << 20))) + why = "recv_buffer_size must be between 64 bytes and 1 MB"; + else if (config->stack_size && (config->stack_size < 64UL * 1024 || config->stack_size > 64UL * 1024 * 1024)) + why = "stack_size must be between 64 KB and 64 MB"; + if (why) { + fprintf(stderr, "ioxd_configure: %s\n", why); + return -1; + } + g_config = *config; + return 0; +} + +/* The configuration a worker gets: what was set, the build's defaults for the rest. */ +static ioxd_config effective_config(void) +{ + ioxd_config c = g_config; + if (!c.ring_entries) c.ring_entries = RING_ENTRIES; + if (!c.recv_buffers) c.recv_buffers = BUF_COUNT; + if (!c.recv_buffer_size) c.recv_buffer_size = BUF_SIZE; + if (!c.stack_size) c.stack_size = STACK_SIZE; + if (!c.idle_stacks) c.idle_stacks = CORO_POOL_MAX; + if (!c.idle_connections) c.idle_connections = CONN_POOL_MAX; + return c; +} + /* The ports bound before the run, each with its store or none; every worker opens all of them. */ static struct listener g_listeners[IOXD_MAX_LISTENERS]; static int g_n_listeners; @@ -103,10 +144,12 @@ static int run_workers(int workers, handler_fn handler) return 1; } - int rc = 0, started = 0; + int rc = 0, started = 0; + ioxd_config cfg = effective_config(); for (int i = 0; i < workers; i++) { ws[i].id = i; ws[i].cpu = i; + ws[i].cfg = cfg; ws[i].handler = handler; ws[i].n_listeners = g_n_listeners; memcpy(ws[i].listeners, g_listeners, sizeof g_listeners); diff --git a/lib/io/bufring.c b/lib/io/bufring.c index 5d240cb..336adb7 100644 --- a/lib/io/bufring.c +++ b/lib/io/bufring.c @@ -22,24 +22,28 @@ static void *map_pages(size_t bytes) /* The kernel named a buffer we never offered: the slab pointer it implies is outside the mapping, * so there is nothing safe to do with it. */ -[[noreturn]] void ioxd__bufring_bad_id(uint16_t buf_id) +[[noreturn]] void ioxd__bufring_bad_id(const struct bufring *b, uint16_t buf_id) { - fprintf(stderr, "ioxd: provided buffer id %u is outside the ring (BUF_COUNT %d)\n", buf_id, BUF_COUNT); + fprintf(stderr, "ioxd: provided buffer id %u is outside the ring (%u buffers)\n", buf_id, b->count); abort(); } -/* Map the slab and the ring, register the ring as buffer group BGID, and offer every buffer. */ -void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker) +/* Map the slab and the ring, register the ring as buffer group BGID, and offer every buffer. + * count is a power of two no larger than 32768: ioxd_configure checked it. */ +void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker, unsigned count, unsigned size) { - b->ring = map_pages((size_t)BUF_COUNT * sizeof(struct io_uring_buf)); - b->slab = map_pages((size_t)BUF_COUNT * BUF_SIZE); + b->count = count; + b->size = size; + b->mask = count - 1; + b->ring = map_pages((size_t)count * sizeof(struct io_uring_buf)); + b->slab = map_pages((size_t)count * size); b->dirty = false; b->returned = 0; struct io_uring_buf_reg reg; memset(®, 0, sizeof reg); reg.ring_addr = (uint64_t)(uintptr_t)b->ring; - reg.ring_entries = BUF_COUNT; + reg.ring_entries = count; reg.bgid = BGID; int rc = uring_register(ring, IORING_REGISTER_PBUF_RING, ®, 1); if (rc < 0) { @@ -49,13 +53,13 @@ void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker) /* Fill every slot, then publish the tail once. bufs[0] overlaps the ring header and the tail * sits in bufs[0].resv, so writing only addr/len/bid leaves it untouched. */ - for (unsigned i = 0; i < BUF_COUNT; i++) { + for (unsigned i = 0; i < count; i++) { struct io_uring_buf *slot = &b->ring->bufs[i]; slot->addr = (uint64_t)(uintptr_t)ioxd__bufring_at(b, (uint16_t)i); - slot->len = BUF_SIZE; + slot->len = size; slot->bid = (uint16_t)i; } - b->tail = BUF_COUNT; + b->tail = count; __atomic_store_n(&b->ring->tail, (uint16_t)b->tail, __ATOMIC_RELEASE); } @@ -63,9 +67,9 @@ void ioxd__bufring_init(struct bufring *b, struct uring *ring, int worker) * release for many returns, and the kernel is not re-reading a hot tail per request. */ void ioxd__bufring_return(struct bufring *b, uint16_t buf_id) { - struct io_uring_buf *slot = &b->ring->bufs[b->tail & BUF_MASK]; + struct io_uring_buf *slot = &b->ring->bufs[b->tail & b->mask]; slot->addr = (uint64_t)(uintptr_t)ioxd__bufring_at(b, buf_id); - slot->len = BUF_SIZE; + slot->len = b->size; slot->bid = buf_id; b->tail++; b->returned++; /* how many recvs the loop may re-arm */ @@ -94,6 +98,6 @@ void ioxd__bufring_unregister(struct bufring *b, struct uring *ring) /* Unmap the ring and the slab. Call after uring_exit, once no in-flight op can reference them. */ void ioxd__bufring_unmap(struct bufring *b) { - munmap(b->ring, (size_t)BUF_COUNT * sizeof(struct io_uring_buf)); - munmap(b->slab, (size_t)BUF_COUNT * BUF_SIZE); + munmap(b->ring, (size_t)b->count * sizeof(struct io_uring_buf)); + munmap(b->slab, (size_t)b->count * b->size); } diff --git a/lib/io/bufring.h b/lib/io/bufring.h index 9676cc6..7b0593c 100644 --- a/lib/io/bufring.h +++ b/lib/io/bufring.h @@ -1,8 +1,9 @@ /* - * bufring.h - the provided buffer ring: a slab of BUF_COUNT x BUF_SIZE bytes that the kernel - * picks from when a multishot recv delivers data, registered as one buffer group, and how - * buffers go back to it. One per worker, touched only by that worker's thread; returns are - * staged and published to the kernel once per loop iteration. + * bufring.h - the provided buffer ring: a slab of count x size bytes that the kernel picks from + * when a multishot recv delivers data, registered as one buffer group, and how buffers go back to + * it. One per worker, touched only by that worker's thread; returns are staged and published to + * the kernel once per loop iteration. The count and the size are the worker's configuration + * (ioxd_config); BUF_COUNT and BUF_SIZE are their defaults. */ #pragma once @@ -10,7 +11,7 @@ #include "io/uring.h" -/* tunables (override with -D) */ +/* defaults (override with -D, or at run time with ioxd_configure) */ #ifndef BUF_COUNT #define BUF_COUNT 4096 /* provided recv buffers per worker, power of two */ #endif @@ -19,30 +20,32 @@ static_assert(((unsigned)BUF_COUNT & ((unsigned)BUF_COUNT - 1U)) == 0 && BUF_COU #ifndef BUF_SIZE #define BUF_SIZE 2048 /* bytes per recv buffer (a request rarely needs more) */ #endif -#define BUF_MASK (BUF_COUNT - 1U) #define BGID 1 /* the one buffer group a worker registers */ struct bufring { struct io_uring_buf_ring *ring; /* kernel-shared ring of buffer descriptors */ - uint8_t *slab; /* BUF_COUNT x BUF_SIZE */ + uint8_t *slab; /* count x size bytes */ + unsigned count; /* buffers: a power of two */ + unsigned size; /* bytes in each */ + unsigned mask; /* count - 1: the ring index of a tail */ unsigned tail; /* local tail, published to ring->tail */ bool dirty; /* staged returns awaiting one publish */ unsigned returned; /* returns since the loop's last starved sweep */ }; -void ioxd__bufring_init (struct bufring *b, struct uring *ring, int worker); /* map, register, offer every buffer */ +void ioxd__bufring_init (struct bufring *b, struct uring *ring, int worker, unsigned count, unsigned size); /* map, register, offer every buffer */ void ioxd__bufring_return (struct bufring *b, uint16_t buf_id); /* stage a buffer's return */ void ioxd__bufring_publish (struct bufring *b); /* the staged returns, one release */ void ioxd__bufring_unregister(struct bufring *b, struct uring *ring); /* before uring_exit */ void ioxd__bufring_unmap (struct bufring *b); /* after uring_exit */ -[[noreturn]] void ioxd__bufring_bad_id(uint16_t buf_id); /* a buffer id outside the slab: abort */ +[[noreturn]] void ioxd__bufring_bad_id(const struct bufring *b, uint16_t buf_id); /* a buffer id outside the slab: abort */ /* Where a buffer's bytes are. The id comes from the kernel, so it is checked: a wrong one would * hand the reader a pointer past the slab. One predicted branch, twice per request. */ static inline uint8_t *ioxd__bufring_at(const struct bufring *b, uint16_t buf_id) { - if (buf_id >= BUF_COUNT) - ioxd__bufring_bad_id(buf_id); - return b->slab + (size_t)buf_id * BUF_SIZE; + if (buf_id >= b->count) + ioxd__bufring_bad_id(b, buf_id); + return b->slab + (size_t)buf_id * b->size; } diff --git a/lib/io/conn.c b/lib/io/conn.c index 893f867..d4e50db 100644 --- a/lib/io/conn.c +++ b/lib/io/conn.c @@ -96,7 +96,7 @@ static void conn_unref(conn_t *c) return; proactor_t *p = c->p; p->live--; - if (p->conn_free_count < CONN_POOL_MAX) { + if (p->conn_free_count < p->cfg.idle_connections) { c->pool_next = p->conn_free; p->conn_free = c; p->conn_free_count++; @@ -153,8 +153,8 @@ static void note_starved(proactor_t *p) if (now.tv_sec < p->starved_log_at) return; fprintf(stderr, "ioxd: [w%d] recv found no provided buffer %llu times (%llu in total, %u connections parked): " - "raise BUF_COUNT (-DBUF_COUNT=..., now %d)\n", - p->id, (unsigned long long)p->starved_since_log, (unsigned long long)p->starved_total, p->nstarved + 1, BUF_COUNT); + "raise recv_buffers (ioxd_configure; now %u)\n", + p->id, (unsigned long long)p->starved_since_log, (unsigned long long)p->starved_total, p->nstarved + 1, p->bufs.count); p->starved_since_log = 0; p->starved_log_at = now.tv_sec + 1; } diff --git a/lib/io/conn.h b/lib/io/conn.h index 2778f5a..538bd61 100644 --- a/lib/io/conn.h +++ b/lib/io/conn.h @@ -18,7 +18,7 @@ static_assert(((unsigned)RX_QUEUE & ((unsigned)RX_QUEUE - 1U)) == 0 && RX_QUEUE "RX_QUEUE: a power of two (RX_MASK is a bit mask over it)"); #define RX_MASK (RX_QUEUE - 1U) #ifndef CONN_POOL_MAX -#define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker */ +#define CONN_POOL_MAX 1024 /* idle conn_t kept warm per worker by default (ioxd_config.idle_connections) */ #endif typedef struct proactor proactor_t; diff --git a/lib/io/coro.c b/lib/io/coro.c index 0587291..e66722c 100644 --- a/lib/io/coro.c +++ b/lib/io/coro.c @@ -12,9 +12,6 @@ extern void swap_ctx(void **save_sp, void *load_sp); /* switch_x86_64.S */ static thread_local coro_t *cur; /* the running coroutine; nullptr on the loop stack */ static thread_local void *loop_sp; /* the loop's stack pointer while a coroutine runs */ -#ifndef CORO_POOL_MAX -#define CORO_POOL_MAX 512 /* warm stacks kept per worker, reused instead of munmap/mmap */ -#endif #ifndef CORO_GUARD #define CORO_GUARD (64UL * 1024) /* PROT_NONE below every stack. Big enough that a frame cannot * step over it into the neighbour below: ioxd__conn_main's is @@ -23,8 +20,14 @@ static thread_local void *loop_sp; /* the loop's stack pointer while a coro #endif /* Pooled stacks keep their pages: no madvise(MADV_DONTNEED) on the way in. The trade is deliberate, * a warm stack for the next connection against the RSS of an idle one, and the pool is capped. */ -static thread_local coro_t *pool_head; /* free list of whole stack blocks, linked via ->next */ -static thread_local int pool_count; +static thread_local coro_t *pool_head; /* free list of whole stack blocks, linked via ->next */ +static thread_local unsigned pool_count; +static thread_local unsigned pool_max = CORO_POOL_MAX; + +void coro_pool_limit(unsigned max_idle) +{ + pool_max = max_idle; +} /* The running coroutine, or nullptr on the loop stack. */ coro_t *coro_current(void) @@ -53,8 +56,8 @@ coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes) coro_t *c; if (pool_head) { - /* Every caller passes STACK_SIZE, so the pool holds one size. A mismatch would mean a - * second size is in play and this reuse would hand back the wrong stack. */ + /* Every caller passes the worker's configured size, so the pool holds one size. A mismatch + * would mean a second size is in play and this reuse would hand back the wrong stack. */ if (pool_head->size != total) { fprintf(stderr, "ioxd: coroutine stack size %zu does not match the pooled %zu\n", total, pool_head->size); @@ -106,7 +109,7 @@ coro_t *coro_create(void (*fn)(void *), void *arg, size_t stack_bytes) static void coro_destroy(coro_t *c) { c->sp = nullptr; /* the frame it named is gone; a stale sp must not be switched to */ - if (pool_count < CORO_POOL_MAX) { + if (pool_count < pool_max) { c->next = pool_head; pool_head = c; pool_count++; diff --git a/lib/io/coro.h b/lib/io/coro.h index 504334e..a849836 100644 --- a/lib/io/coro.h +++ b/lib/io/coro.h @@ -24,6 +24,10 @@ #include +#ifndef CORO_POOL_MAX +#define CORO_POOL_MAX 512 /* warm stacks kept per worker by default (ioxd_config.idle_stacks) */ +#endif + /* Private to libioxd: hidden symbols cannot be interposed, so nothing outside the library can * substitute a scheduler primitive (the .S hides swap_ctx the same way). */ #define CORO_API __attribute__((visibility("hidden"))) @@ -53,3 +57,6 @@ CORO_API coro_t *coro_current(void); /* Unmap the per-thread free list of pooled stacks. Call at worker teardown, on the worker thread. */ CORO_API void coro_pool_drain(void); + +/* How many idle stacks this thread keeps warm (CORO_POOL_MAX until told). Before the first create. */ +CORO_API void coro_pool_limit(unsigned max_idle); diff --git a/lib/io/proactor.c b/lib/io/proactor.c index 67fcc3e..8c8ab51 100644 --- a/lib/io/proactor.c +++ b/lib/io/proactor.c @@ -203,7 +203,7 @@ static void dispatch(proactor_t *p, struct io_uring_cqe *cqe) /* Queue a new coroutine; the loop starts it on its next iteration. */ void proactor_spawn(proactor_t *p, void (*fn)(void *), void *arg) { - coro_t *c = coro_create(fn, arg, STACK_SIZE); + coro_t *c = coro_create(fn, arg, p->cfg.stack_size); if (p->ready_tail) p->ready_tail->next = c; else @@ -354,7 +354,8 @@ void proactor_run(proactor_t *p) if (p->cpu >= 0) pin_to(p->cpu); - int rc = uring_init(&p->ring, RING_ENTRIES); /* on this thread: DEFER_TASKRUN ties it here */ + coro_pool_limit(p->cfg.idle_stacks); + int rc = uring_init(&p->ring, p->cfg.ring_entries); /* on this thread: DEFER_TASKRUN ties it here */ if (rc < 0) { fprintf(stderr, "[w%d] io_uring_setup: %s%s\n", p->id, ioxd__errstr(-rc), rc == -EPERM ? " (io_uring is disabled: see /proc/sys/kernel/io_uring_disabled)" : ""); @@ -367,7 +368,7 @@ void proactor_run(proactor_t *p) unsigned slots = fixed_slots(); /* optional: sockets live in a file table */ if (slots && uring_register_files_sparse(&p->ring, slots) == 0) p->file_slots = slots; /* the ceiling accept_room holds us to */ - ioxd__bufring_init(&p->bufs, &p->ring, p->id); + ioxd__bufring_init(&p->bufs, &p->ring, p->id, p->cfg.recv_buffers, p->cfg.recv_buffer_size); char ports[IOXD_MAX_LISTENERS * 12] = ""; size_t at = 0; for (int i = 0; i < p->n_listeners; i++) { @@ -381,7 +382,7 @@ void proactor_run(proactor_t *p) at += (size_t)n < sizeof ports - at ? (size_t)n : sizeof ports - at - 1; /* truncated: stop growing */ } fprintf(stderr, "[w%d] listening on %s (cpu %d, %u x %u B recv buffers, ring %u%s%s%s)\n", - p->id, ports, p->cpu, BUF_COUNT, BUF_SIZE, p->ring.sq_entries, + p->id, ports, p->cpu, p->bufs.count, p->bufs.size, p->ring.sq_entries, p->ring.has_sq_array ? "" : ", no sqarray", p->ring.enter_flags ? ", registered ring" : "", p->ring.fixed_files ? ", fixed files" : ""); diff --git a/lib/io/proactor.h b/lib/io/proactor.h index 91a0c75..0e2dd1a 100644 --- a/lib/io/proactor.h +++ b/lib/io/proactor.h @@ -21,12 +21,13 @@ #include #include +#include "ioxd/config.h" #include "io/bufring.h" #include "io/conn.h" #include "io/coro.h" #include "io/uring.h" -/* tunables (override with -D) */ +/* defaults (override with -D, or at run time with ioxd_configure) */ #ifndef RING_ENTRIES #define RING_ENTRIES 4096 /* SQ depth; the CQ is twice that */ #endif @@ -70,6 +71,7 @@ struct proactor { int n_listeners; handler_fn handler; volatile sig_atomic_t *stop; + ioxd_config cfg; /* every field filled in: the run resolved the defaults */ /* owned by the worker thread */ struct uring ring; diff --git a/playground/hello/main.c b/playground/hello/main.c index c291296..f0dbd56 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -105,6 +105,7 @@ int main(int argc, char **argv) IOXD_GET ("/users/:id", user_endpoint); IOXD_POST("/repeat/:times", repeat); + ioxd_configure(&(ioxd_config){ .recv_buffers = 8192 }); /* the runtime's knobs, per worker; a zero keeps its default */ ioxd_bind(8080, NULL); if (argc > 1) { ioxd_certs *tls = ioxd_certs_load(argv[1]); diff --git a/tests/server.c b/tests/server.c index a6ef6fa..79619cf 100644 --- a/tests/server.c +++ b/tests/server.c @@ -519,6 +519,14 @@ int main(void) IOXD_GET("/rooted", rooted); } + ioxd_config cfg = { /* the runtime's knobs, from the environment */ + .ring_entries = (unsigned)env_number("IOXD_RING_ENTRIES", 0), + .recv_buffers = (unsigned)env_number("IOXD_RECV_BUFFERS", 0), + .recv_buffer_size = (unsigned)env_number("IOXD_RECV_BUFFER_SIZE", 0), + .stack_size = (size_t)env_number("IOXD_STACK_SIZE", 0), + }; + if (ioxd_configure(&cfg) < 0) + return 1; int workers = (int)env_number("IOXD_WORKERS", 0); /* 0: one per core */ int port = (int)env_number("IOXD_PORT", 8080); int p = port > 0 && port < 65536 ? port : 8080; diff --git a/tests/unit.c b/tests/unit.c index 8457ebe..bfc612e 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -429,9 +429,26 @@ static void test_json(void) test_json_locale(); } +/* ioxd_configure: a zero keeps a default, a bad value is refused and changes nothing. */ +static void test_config(void) +{ + CHECK(ioxd_configure(&(ioxd_config){ 0 }) == 0); + CHECK(ioxd_configure(&(ioxd_config){ .ring_entries = 1024, .recv_buffers = 8192, .recv_buffer_size = 4096, + .stack_size = 256UL * 1024, .idle_stacks = 1, .idle_connections = 1 }) == 0); + CHECK(ioxd_configure(&(ioxd_config){ .ring_entries = 3000 }) == -1); /* not a power of two */ + CHECK(ioxd_configure(&(ioxd_config){ .ring_entries = 65536 }) == -1); + CHECK(ioxd_configure(&(ioxd_config){ .recv_buffers = 65536 }) == -1); /* the kernel refuses it */ + CHECK(ioxd_configure(&(ioxd_config){ .recv_buffers = 12 }) == -1); + CHECK(ioxd_configure(&(ioxd_config){ .recv_buffer_size = 16 }) == -1); + CHECK(ioxd_configure(&(ioxd_config){ .stack_size = 4096 }) == -1); /* the engine's frames alone are 44 KB */ + CHECK(ioxd_configure(&(ioxd_config){ .recv_buffers = 8, .recv_buffer_size = 64 }) == 0); /* the starved test build */ + CHECK(ioxd_configure(&(ioxd_config){ 0 }) == 0); /* back to the defaults */ +} + int main(void) { test_integers(); + test_config(); test_json(); test_doubles(); test_bools(); From 40db522bb407ef5f296b712c4d6ba4fd402b4ef4 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:24:39 +0100 Subject: [PATCH 44/49] hello: the runtime's knobs, every field shown Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- playground/hello/main.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/playground/hello/main.c b/playground/hello/main.c index f0dbd56..762ee97 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -94,24 +94,39 @@ static void user_endpoint(ioxd_ctx *ctx) user_to_json(&j, &u); } -/* The routes, then the ports, then the run. Plain HTTP on 8080; with a certificate directory on - * the command line the same routes on 8443 over TLS 1.3 as well. The store holds one host per - * subdirectory - //cert.pem and key.pem - and the client's SNI picks the host, - * `default` answering for no name or an unknown one (TLS.md). The handshake is OpenSSL's; from - * then on the kernel encrypts and decrypts, and a handler cannot tell the two ports apart. */ +/* The routes, the runtime's knobs, the ports, then the run. Plain HTTP on 8080; with a + * certificate directory on the command line the same routes on 8443 over TLS 1.3 as well. The + * store holds one host per subdirectory - //cert.pem and key.pem - and the client's + * SNI picks the host, `default` answering for no name or an unknown one (TLS.md). The handshake + * is OpenSSL's; from then on the kernel encrypts and decrypts, and a handler cannot tell the two + * ports apart. */ int main(int argc, char **argv) { IOXD_GET ("/hello/:name", hello); IOXD_GET ("/users/:id", user_endpoint); IOXD_POST("/repeat/:times", repeat); - ioxd_configure(&(ioxd_config){ .recv_buffers = 8192 }); /* the runtime's knobs, per worker; a zero keeps its default */ + /* Every field is per worker, and a zero keeps the build's default; a value the kernel or the + * engine would refuse is refused here, with the reason on stderr. The receive buffers are + * what the kernel delivers into: their count bounds how many deliveries may be in flight + * before recvs park (the log then says to raise it), their size what one delivery holds. */ + ioxd_config config = { + .ring_entries = 4096, /* submission queue depth; the completion queue is twice that */ + .recv_buffers = 8192, /* a power of two, at most 32768; 4096 by default */ + .recv_buffer_size = 2048, /* bytes in each: a request head rarely needs more */ + .stack_size = 128 * 1024, /* a connection's coroutine stack, above a 64 KB guard */ + .idle_stacks = 512, /* kept warm between connections, so churn pays no mmap */ + .idle_connections = 1024, /* connection records kept warm, the same way */ + }; + if (ioxd_configure(&config) < 0) + return 1; + ioxd_bind(8080, NULL); if (argc > 1) { - ioxd_certs *tls = ioxd_certs_load(argv[1]); - if (!tls) + ioxd_certs *certs = ioxd_certs_load(argv[1]); + if (!certs) return 1; /* the reason is on stderr: no `default`, a bad key, a TLS=0 build */ - ioxd_bind(8443, tls); + ioxd_bind(8443, certs); } return ioxd_run(0); /* one worker per core, over both ports */ } From 3991af1fff951aed7eb9923ef771d5a84b60a463 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:24:48 +0100 Subject: [PATCH 45/49] hello: the stack size as a size_t literal, for clang-tidy Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- playground/hello/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/hello/main.c b/playground/hello/main.c index 762ee97..95da15d 100644 --- a/playground/hello/main.c +++ b/playground/hello/main.c @@ -114,7 +114,7 @@ int main(int argc, char **argv) .ring_entries = 4096, /* submission queue depth; the completion queue is twice that */ .recv_buffers = 8192, /* a power of two, at most 32768; 4096 by default */ .recv_buffer_size = 2048, /* bytes in each: a request head rarely needs more */ - .stack_size = 128 * 1024, /* a connection's coroutine stack, above a 64 KB guard */ + .stack_size = 128UL * 1024, /* a connection's coroutine stack, above a 64 KB guard */ .idle_stacks = 512, /* kept warm between connections, so churn pays no mmap */ .idle_connections = 1024, /* connection records kept warm, the same way */ }; From 9964c742ca7f7e84e43d5a59edea0171d323fb6c Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:32:20 +0100 Subject: [PATCH 46/49] manual/: the API as man pages, generated from the headers One page per public header in section 3 - NAME and DESCRIPTION from the comments, SYNOPSIS from the declarations, EXAMPLES from build.py, SEE ALSO from the rest - an ioxd(7) overview, the front page and an index of every public name. Private names and macro expansions stay out; the script macros are shown as they are written. make manual refreshes it. Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- Makefile | 6 +- README.md | 6 + manual/__pycache__/build.cpython-312.pyc | Bin 0 -> 42268 bytes manual/build.py | 757 +++++++++++++++++++++++ manual/functions.html | 126 ++++ manual/index.html | 35 ++ manual/ioxd.7.html | 100 +++ manual/ioxd_config.html | 52 ++ manual/ioxd_http.html | 264 ++++++++ manual/ioxd_json.html | 170 +++++ manual/ioxd_pipe.html | 101 +++ manual/ioxd_router.html | 142 +++++ manual/ioxd_slice.html | 108 ++++ manual/ioxd_tls.html | 54 ++ manual/style.css | 46 ++ 15 files changed, 1966 insertions(+), 1 deletion(-) create mode 100644 manual/__pycache__/build.cpython-312.pyc create mode 100644 manual/build.py create mode 100644 manual/functions.html create mode 100644 manual/index.html create mode 100644 manual/ioxd.7.html create mode 100644 manual/ioxd_config.html create mode 100644 manual/ioxd_http.html create mode 100644 manual/ioxd_json.html create mode 100644 manual/ioxd_pipe.html create mode 100644 manual/ioxd_router.html create mode 100644 manual/ioxd_slice.html create mode 100644 manual/ioxd_tls.html create mode 100644 manual/style.css diff --git a/Makefile b/Makefile index 86bf449..d9ef087 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ MAP := cmake/ioxd.map # the recipe rewrites it only when it differs, so an unchanged build stays untouched. FLAGS := $(CC) $(CFLAGS) $(WARN) $(HARDEN) $(CPP) $(PTHREAD) $(LIBS) -.PHONY: all lib examples check check-tiny check-all tidy clean install uninstall force +.PHONY: all lib examples check check-tiny check-all tidy manual clean install uninstall force all: lib examples lib: libioxd.a libioxd.so @@ -174,6 +174,10 @@ TIDY_SRC := $(wildcard lib/*/*.c) tests/server.c tests/pipe-server.c tests/unit tidy: $(TIDY) $(TIDY_ARGS) $(TIDY_SRC) -- $(STD) $(CPP) $(PTHREAD) +# --- the manual: man-page style HTML for every public header, generated from the headers --- +manual: + python3 manual/build.py + # --- pkg-config --- ioxd.pc: ioxd.pc.in obj/flags sed -e 's|@PREFIX@|$(PREFIX)|g' -e 's|@VERSION@|$(VERSION)|g' -e 's|@LIBS@|$(LIBS)|g' $< > $@ diff --git a/README.md b/README.md index ee791cc..5e3e3cc 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ stackful coroutine per connection, so an endpoint is a plain function that takes returns a response. Modelled on [ioxide](https://github.com/MDA2AV/ioxide)'s TCP core. How the runtime works is in [`ARCHITECTURE.md`](ARCHITECTURE.md). +## Manual + +The API is documented as man pages under [`manual/`](manual/index.html): one page per public header +(`ioxd_http(3)`, `ioxd_router(3)`, ...), generated from the headers themselves by `make manual`, an +overview in `ioxd(7)`, and every public name in one list. Open `manual/index.html` in a browser. + ## Build Run `make` in the repo root. It produces `libioxd.a`, `libioxd.so` and the demo server diff --git a/manual/__pycache__/build.cpython-312.pyc b/manual/__pycache__/build.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d039aa2fbdfe000c9e3d522d3c014263b6c9672f GIT binary patch literal 42268 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 YqkSU$siEkh(fWHwF!M2PVrc&V0O3lVy8r+H literal 0 HcmV?d00001 diff --git a/manual/build.py b/manual/build.py new file mode 100644 index 0000000..6340842 --- /dev/null +++ b/manual/build.py @@ -0,0 +1,757 @@ +#!/usr/bin/env python3 +"""The manual: man-page style HTML for every public header, generated from the headers themselves. + + python3 manual/build.py # writes manual/*.html next to this script + +Each header under include/ioxd/ becomes one page in section 3 (ioxd_http(3), ioxd_json(3), ...): +NAME from the header's top comment, SYNOPSIS from its declarations, DESCRIPTION from the comment +above each declaration - in the header's own order and sections - EXAMPLES from the snippets in +this file, SEE ALSO from the rest. ioxd(7) is the overview, index.html the front page, and +functions.html every public name in one alphabetical list. Private names (ioxd__, IOXD__) are +left out, as are the macro internals that only serve a public one. +""" +import html +import os +import re +import sys +from datetime import date + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.dirname(HERE) +INCLUDE = os.path.join(ROOT, "include") + +PAGES = [ # (header, page name, one-line subject used on the index) + ("ioxd/config.h", "ioxd_config", "the runtime's knobs"), + ("ioxd/http.h", "ioxd_http", "request, response, context, body, reply, the run"), + ("ioxd/router.h", "ioxd_router", "groups, endpoints, middleware; the script macros"), + ("ioxd/slice.h", "ioxd_slice", "slices, conversions, key/value parsing"), + ("ioxd/json.h", "ioxd_json", "JSON written as you go; structs described once"), + ("ioxd/pipe.h", "ioxd_pipe", "a connection as a pipe, for other protocols"), + ("ioxd/tls.h", "ioxd_tls", "a certificate store, for a TLS port"), +] + + +def version(): + with open(os.path.join(ROOT, "Makefile")) as f: + m = re.search(r"^VERSION\s*:=\s*(\S+)", f.read(), re.M) + return m.group(1) if m else "0" + + +# ── parsing a header ─────────────────────────────────────────────────────────────────────── + +class Entry: + """One thing in a header: a section title, or a comment with the declarations under it.""" + def __init__(self, kind): + self.kind = kind # 'section' | 'entry' + self.title = "" # section + self.paras = [] # entry: the comment above, as paragraphs (text or ('pre', code)) + self.decls = [] # entry: [(code, trailing comment, [names], public)] + + +def comment_text(lines): + """The lines of a block comment, without their decoration, as paragraphs: plain text, or + indented code kept as it is.""" + body = [] + for ln in lines: + ln = re.sub(r"^\s*/\*\s?", "", ln) + ln = re.sub(r"\s*\*/\s*$", "", ln) + ln = re.sub(r"^\s*\*\s?", "", ln) if not ln.lstrip().startswith("*/") else "" + body.append(ln.rstrip()) + paras, text, code = [], [], [] + + def flush(): + nonlocal text, code + if code: + paras.append(("pre", "\n".join(code))) + code = [] + if text: + paras.append(" ".join(t.strip() for t in text)) + text = [] + + for ln in body: + if ln.startswith(" "): + if text: + paras.append(" ".join(t.strip() for t in text)); text = [] + code.append(ln[4:]) + elif ln.strip() == "": + flush() + else: + if code: + paras.append(("pre", "\n".join(code))); code = [] + text.append(ln) + flush() + return paras + + +def names_of(code): + """The public identifiers a declaration defines: a function, a macro, a type, a constant.""" + first = code.split("\n")[0].strip() + names = [] + m = re.match(r"#define\s+([A-Za-z_]\w*)", first) + if m: + return [m.group(1)] + m = re.match(r"typedef\s+.*\(\*\s*([A-Za-z_]\w*)\s*\)", first) + if m: + return [m.group(1)] + if first.startswith("typedef struct") or first.startswith("typedef union") or first.startswith("typedef enum"): + last = code.strip().split("\n")[-1] + m = re.search(r"}\s*([A-Za-z_]\w*)\s*;\s*$", last) or re.search(r"typedef\s+struct\s+\w+\s+([A-Za-z_]\w*)\s*;", first) + if m: + return [m.group(1)] + m = re.match(r"struct\s+([A-Za-z_]\w*)\s*\{", first) + if m: + return ["struct " + m.group(1)] + m = re.match(r"struct\s+([A-Za-z_]\w*)\s*;", first) + if m: + return ["struct " + m.group(1)] + m = re.search(r"([A-Za-z_]\w*)\s*\(", first) + if m and not first.startswith("#"): + return [m.group(1)] + return names + + +def is_public(names, code): + for n in names: + if n.startswith("ioxd__") or n.startswith("IOXD__") or n.endswith("_args"): + return False + if code.lstrip().startswith("#define IOXD__"): + return False + if re.match(r"struct\s+\w+\s*;", code.strip()): + return False # a forward declaration: the type is elsewhere + return True + + +MACRO_USAGE = { # the script macros, as they are written; the expansion is machinery + "IOXD_GROUP": "IOXD_GROUP(prefix, middleware...) { ... }", + "IOXD_USE": "IOXD_USE(middleware)", + "IOXD_ROUTE": "IOXD_ROUTE(method, path, handler, middleware...)", + "IOXD_GET": "IOXD_GET(path, handler, middleware...)", + "IOXD_POST": "IOXD_POST(path, handler, middleware...)", + "IOXD_PUT": "IOXD_PUT(path, handler, middleware...)", + "IOXD_PATCH": "IOXD_PATCH(path, handler, middleware...)", + "IOXD_DELETE": "IOXD_DELETE(path, handler, middleware...)", + "IOXD_DEFAULT": "IOXD_DEFAULT(handler)", + "IOXD_JSON_VALUE": "IOXD_JSON_VALUE(ioxd_json *j, x)", + "IOXD_JSON_FIELD": "IOXD_JSON_FIELD(ioxd_json *j, const char *name, x)", + "IOXD_JSON_STRUCT": "IOXD_JSON_STRUCT(name, FIELDS)", + "IOXD_JSON_WRITER": "IOXD_JSON_WRITER(name, FIELDS)", +} + + +def shown(code): + """A declaration as the manual shows it: an inline function by its signature alone, a + function-like macro by the way it is written rather than what it expands to.""" + if code.startswith("static inline") and "{" in code: + return code[:code.find("{")].rstrip() + ";" + m = re.match(r"#define\s+([A-Za-z_]\w*)\(", code) + if m: + name = m.group(1) + if name in MACRO_USAGE: + return MACRO_USAGE[name] + head = re.match(r"#define\s+[A-Za-z_]\w*\([^)]*\)", code) + return head.group(0) if head else code.split("\n")[0] + return code + + +def decl_ends(line): + core = strip_trailing_comment(line)[0].rstrip() + return core.endswith(";") or core.endswith("}") + + +def braces(line): + """The brace depth a line adds, comments and character literals not counted.""" + core = strip_trailing_comment(line)[0] + core = re.sub(r"'.'|\"[^\"]*\"", "", core) + return core.count("{") - core.count("}") + + +def strip_trailing_comment(line): + m = re.match(r"^(.*?)\s*/\*\s*(.*?)\s*\*/\s*$", line) + if m: + return m.group(1), m.group(2) + return line, "" + + +def parse_header(path): + with open(path) as f: + src = f.read().split("\n") + top = [] + i = 0 + if src and src[0].startswith("/*"): + while i < len(src): + top.append(src[i]) + if "*/" in src[i]: + i += 1 + break + i += 1 + top_paras = comment_text(top) + name_line = top_paras[0] if top_paras else "" + m = re.match(r"(\S+)\s+-\s+(.*)", name_line) + subject = m.group(2) if m else name_line + + entries = [] + pending = [] # comment paragraphs waiting for a declaration + skipping_else = False + while i < len(src): + line = src[i] + s = line.strip() + if skipping_else: + if s.startswith("#endif"): + skipping_else = False + i += 1 + continue + if s == "" or s.startswith("#pragma") or s.startswith("#include"): + if s == "" and pending and entries and entries[-1].kind == "entry" and not entries[-1].decls: + pass + i += 1 + continue + if s.startswith("#else"): + skipping_else = True + i += 1 + continue + if s.startswith("#endif") or s.startswith("#if") or s.startswith("#ifdef") or s.startswith("#ifndef"): + i += 1 + continue + if s.startswith("/*"): + block = [line] + while "*/" not in src[i]: + i += 1 + block.append(src[i]) + i += 1 + text = " ".join(b.strip(" /*") for b in block) + sec = re.match(r"\s*/\*\s*[─-]+\s*(.*?)\s*[─-]+\s*\*/\s*$", "".join(block)) + if sec: + e = Entry("section"); e.title = sec.group(1); entries.append(e) + pending = [] + continue + pending = comment_text(block) + e = Entry("entry"); e.paras = pending + entries.append(e) + continue + # a declaration: collect until it is whole - a ';' or a closing brace at depth zero, with + # any trailing comment out of the way; a macro continues while its lines end in '\\' + decl = [line] + depth = braces(line) + if s.startswith("#define"): + while src[i].rstrip().endswith("\\"): + i += 1 + decl.append(src[i]) + else: + while not (depth == 0 and decl_ends(decl[-1])): + i += 1 + decl.append(src[i]) + depth += braces(src[i]) + i += 1 + last, trailing = strip_trailing_comment(decl[-1]) + if trailing and not last.strip().startswith("}"): + decl[-1] = last # a prototype's trailing comment is its description + else: + trailing = "" # a struct's closing line: its members keep theirs + code = "\n".join(decl) + names = names_of(code) + public = is_public(names, code) + if entries and entries[-1].kind == "entry": + entries[-1].decls.append((code.rstrip(), trailing, names, public)) + else: + e = Entry("entry"); e.decls.append((code.rstrip(), trailing, names, public)); entries.append(e) + # a section title with nothing public under it is dropped later + return subject, top_paras, entries + + +# ── rendering ────────────────────────────────────────────────────────────────────────────── + +def esc(t): + return html.escape(t, quote=False) + + +def anchor_id(name): + return re.sub(r"[^A-Za-z0-9_]", "_", name) + + +def render_paras(paras, link): + out = [] + for p in paras: + if isinstance(p, tuple): + out.append('
' + link(esc(p[1])) + "
") + else: + out.append("

" + link(esc(p)) + "

") + return "\n".join(out) + + +def make_linker(index, self_page): + """Turn every public name mentioned in text into a link to its page and anchor.""" + names = sorted((n for n in index if not n.startswith("struct ")), key=len, reverse=True) + pat = re.compile(r"(?{n}' + return pat.sub(repl, text) + return link + + +def page_html(title, section, body, version_str, nav_extra=""): + today = date.today().isoformat() + upper = title.upper() + f"({section})" + return f""" + + + + +{esc(title)}({section}) - libioxd manual + + + +
+
+
{upper}libioxd Programmer's Manual{upper}
+{body} +
libioxd {esc(version_str)}{today}{upper}
+
+ + +""" + + +def synopsis_of(entries): + lines = [] + for e in entries: + if e.kind != "entry": + continue + for code, _t, names, public in e.decls: + if not public: + continue + first = code.split("\n")[0] + if code.startswith("typedef struct") and "\n" in code or code.startswith("struct") and "{" in code: + nm = names[0] if names else "..." + lines.append(f"typedef struct {{ ... }} {nm};" if code.startswith("typedef") else f"{nm} {{ ... }};") + elif code.startswith("#define"): + lines.append(shown(code) if "(" in first.split()[1] else strip_trailing_comment(first)[0].strip()) + elif code.startswith("static inline"): + body_at = code.find("{") + lines.append(code[:body_at].rstrip() + ";" if body_at > 0 else code) + else: + lines.append(re.sub(r"\s+", " ", code.replace("\n", " ")).strip() if "\n" in code else code.strip()) + return "\n".join(lines) + + +def render_page(header, page, subject, top_paras, entries, index, version_str, examples, see_also): + link = make_linker(index, page) + body = [] + body.append("

NAME

") + body.append(f"

{esc(header)} - {link(esc(subject))}

") + body.append("

SYNOPSIS

") + body.append("
#include <ioxd.h>\n\n" + link(esc(synopsis_of(entries))) + "
") + body.append("

DESCRIPTION

") + if len(top_paras) > 1: + body.append(render_paras(top_paras[1:], link)) + for e in entries: + if e.kind == "section": + body.append(f"

{esc(e.title)}

") + continue + pub = [d for d in e.decls if d[3]] + if not pub and not e.paras: + continue + if not pub and e.paras and e.decls: + continue # a comment on private machinery + body.append('
') + if pub: + ids = " ".join(anchor_id(n) for d in pub for n in d[2]) + first_id = anchor_id(pub[0][2][0]) if pub[0][2] else "" + body.append(f'
')
+            for code, trailing, names, _p in pub:
+                for n in names[1:]:
+                    body.append(f'')
+                body.append(esc(shown(code)))
+            body.append("
") + if e.paras: + body.append('
' + render_paras(e.paras, link) + "
") + trail = [(code, t) for code, t, _n, _p in pub if t] + if trail: + body.append('
') + for code, t in trail: + short = code.split("\n")[0].strip() + m = re.search(r"([A-Za-z_]\w*)\s*\(", short) + label = m.group(1) if m and not short.startswith("#") else (re.match(r"#define\s+(\S+)", short).group(1) if short.startswith("#define") else short) + body.append(f"
{esc(label)}
{link(esc(t))}
") + body.append("
") + body.append("
") + if examples: + body.append("

EXAMPLES

") + for title, code in examples: + body.append(f"

{link(esc(title))}

") + body.append('
' + link(esc(code)) + "
") + body.append("

SEE ALSO

") + body.append("

" + ", ".join(f'{p}({s})' for p, s in see_also) + "

") + return page_html(page, "3", "\n".join(body), version_str) + + +# ── the hand-written pages: the overview, the examples ───────────────────────────────────── + +OVERVIEW = """ +

NAME

+

ioxd - an HTTP/1.1 server library on io_uring, one worker per core, a stackful coroutine per connection

+ +

SYNOPSIS

+
#include <ioxd.h>
+
+cc main.c $(pkg-config --cflags --libs ioxd) -o server
+ +

DESCRIPTION

+

libioxd serves HTTP/1.1, plain or over TLS 1.3, from a thread per core. Each worker owns an io_uring +ring, a ring of receive buffers the kernel delivers into, and its own sockets on every bound port +(SO_REUSEPORT); nothing is shared between workers while serving. Every connection runs on its own +coroutine, so a handler reads the body and writes the reply in straight-line code: a call that has to +wait for the wire suspends the coroutine, and the worker's loop resumes it on the completion.

+ +

A program registers its routes, sets the runtime's knobs if it wants to, binds its ports, then runs:

+
static void hello(ioxd_ctx *ctx)
+{
+    ioxd_slice name = ctx->req.route_params[0].value;
+    ioxd_printf(ctx, "hello %.*s\\n", (int)name.len, name.p);
+}
+
+int main(void)
+{
+    IOXD_GET("/hello/:name", hello);
+    ioxd_bind(8080, NULL);                                  /* plain */
+    ioxd_bind(8443, ioxd_certs_load("certs"));              /* TLS 1.3, from a directory of certificates */
+    return ioxd_run(0);                                     /* one worker per core, until SIGINT or SIGTERM */
+}
+ +

The request and the reply

+

A handler receives an ioxd_ctx: the request as plain data - method, +path, query, headers, parameters, all slices into the connection's buffers - and the response being +shaped. The body stays on the wire until asked for: ioxd_body_all +reads it whole, ioxd_body_read_until streams it. The reply +is written into a slab with ioxd_write, ioxd_printf +or the JSON writer; when everything fits it goes out in one send with its head in +front, and when it does not it streams, chunked. What goes on the wire follows the protocol whatever the handler +did: a reply to HEAD carries no body, a declared length is held to, a request whose framing cannot be trusted is +refused before a handler sees it.

+ +

Routes

+

Endpoints live in groups: a prefix plus middleware, nesting. Everything is +resolved once, when the run starts, into a segment tree and one flat middleware chain per endpoint, so a request +costs one walk and no scan. The script macros (IOXD_GROUP, IOXD_GET, IOXD_USE) are the same registrations +written as a block.

+ +

Threads and lifetimes

+

Register routes, configure and bind from the main thread, before the run. Handlers run on worker threads, +one at a time per worker; a request's slices are valid until the handler returns, and anything a handler hands +the reply (a header, a content type) is copied. Nothing in the library is shared between workers except the +read-only route tree and a TLS store's certificate table, which is reference counted.

+ +

Limits

+

A request head, and a body read whole, must fit the reader's 16 KB; streamed bodies have no limit. At most +64 request headers, 32 query parameters, 8 route captures, 16 added reply headers within 3 KB. These size the +context, so ioxd_run refuses an application built with different values. +The runtime's own sizes - the ring, the receive buffers, the coroutine stacks, the pools - are the +configuration, per worker.

+ +

Building

+

Linux 6.x on x86-64, gcc 14 or newer (the library is C23; the headers are usable from C11), OpenSSL 3 for +the TLS handshake (built by default; make TLS=0 or -DIOXD_TLS=OFF leaves it out). +make produces libioxd.a and libioxd.so; make install the headers and a pkg-config file; +CMake exports ioxd::ioxd. Kernel TLS needs a kernel with SOCKET_URING_OP_SETSOCKOPT (6.7 or newer) +when the registered file table is on, which is the default.

+ +

FILES

+
+
<ioxd.h>
the whole API: an umbrella over the headers below
+
<ioxd/config.h>
the runtime's knobs: ring, buffers, stacks, pools
+
<ioxd/http.h>
request, response, context, body, reply, bind and run
+
<ioxd/router.h>
groups, endpoints, middleware, the script macros
+
<ioxd/slice.h>
slices, conversions, key/value parsing
+
<ioxd/json.h>
the JSON writer and IOXD_JSON_STRUCT
+
<ioxd/pipe.h>
a connection as a pipe, for protocols other than HTTP
+
<ioxd/tls.h>
a certificate store, for a TLS port
+
+ +

SEE ALSO

+

every public name, and in the repository: README.md, ARCHITECTURE.md (how the +runtime works), TLS.md, PERF.md, REVIEW.md.

+""" + +EXAMPLES = { + "ioxd_config": [ + ("Twice the receive buffers, before the run; every other field keeps its default:", + """ioxd_config config = { .recv_buffers = 8192 }; +if (ioxd_configure(&config) < 0) + return 1; /* the reason is on stderr */ +ioxd_bind(8080, NULL); +return ioxd_run(0);"""), + ], + "ioxd_http": [ + ("A route parameter, a query parameter converted, and a formatted reply:", + """static void user(ioxd_ctx *ctx) +{ + int64_t id; + if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) { + ctx->res.status = 400; + ioxd_text(ctx, "the id must be an integer\\n"); + return; + } + for (size_t i = 0; i < ctx->req.n_params; i++) + if (ioxd_slice_eq(ctx->req.params[i].key, "fields")) + ioxd_printf(ctx, "fields=%.*s\\n", (int)ctx->req.params[i].value.len, ctx->req.params[i].value.p); + ioxd_header(ctx, "x-user", "42"); /* copied: a temporary is fine */ + ioxd_printf(ctx, "user %lld\\n", (long long)id); +}"""), + ("A body read whole, then a reply streamed with a flush every ten lines:", + """static void repeat(ioxd_ctx *ctx) +{ + ioxd_slice body = ioxd_body_all(ctx); /* over 16 KB: empty, and res.status is 413 */ + if (ctx->res.status != 200) + return; + for (int i = 1; i <= 25; i++) { + if (ioxd_printf(ctx, "%d: %.*s\\n", i, (int)body.len, body.p) < 0) + return; /* the peer is gone */ + if (i % 10 == 0 && ioxd_flush(ctx) < 0) + return; + } +}"""), + ("A large upload streamed through a fixed buffer:", + """static void upload(ioxd_ctx *ctx) +{ + char buf[4096]; + size_t total = 0; + for (;;) { + int n = ioxd_body_read_until(ctx, buf, sizeof buf); + if (n < 0) return; /* malformed or gone: the engine answers */ + if (n == 0) break; + total += (size_t)n; + } + ioxd_printf(ctx, "%zu bytes\\n", total); +}"""), + ("Middleware around the handler, the onion way:", + """static void timing(ioxd_ctx *ctx, ioxd_next *next) +{ + struct timespec t0, t1; + clock_gettime(CLOCK_MONOTONIC, &t0); + ioxd_next_run(ctx, next); /* the rest of the chain, then the endpoint */ + clock_gettime(CLOCK_MONOTONIC, &t1); + /* the head may already be out (a streamed reply): ioxd_header then returns false */ +}"""), + ], + "ioxd_router": [ + ("The same registrations as calls and as a script:", + """ioxd_group *api = ioxd_group_new(NULL, "/api"); +ioxd_group_use(api, auth); +ioxd_get(api, "/users/:id", user); /* GET /api/users/:id, behind auth */ +ioxd_endpoint_use(ioxd_post(api, "/users", create), audit); + +IOXD_USE(log); /* root middleware: every request */ +IOXD_GROUP("/api", auth) { + IOXD_GET ("/users/:id", user); + IOXD_POST("/users", create, audit); + IOXD_GROUP("/admin", require_token) { + IOXD_GET("/stats", stats); + } +} +IOXD_DEFAULT(not_found);"""), + ], + "ioxd_slice": [ + ("Strict conversions: the whole slice is the value, or the call fails and *out is untouched:", + """int64_t id; +double price; +bool on; +if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) /* "42", "-7"; not "42x", not " 42" */ + ... +if (ioxd_to_double(v, &price) && ioxd_to_bool(w, &on)) /* "2.5", "1e-3"; "yes", "off" */ + ..."""), + ("A form body parsed like a query string:", + """ioxd_slice body = ioxd_body_all(ctx); +ioxd_kv form[8]; +char arena[512]; +bool truncated; +size_t n = ioxd_kv_parse(body.p, body.len, form, 8, arena, sizeof arena, &truncated); +if (truncated) { ctx->res.status = 400; return; } /* never act on part of it */ +for (size_t i = 0; i < n; i++) + if (ioxd_slice_eq(form[i].key, "name")) + ioxd_printf(ctx, "hello %.*s\\n", (int)form[i].value.len, form[i].value.p);"""), + ], + "ioxd_json": [ + ("Written as you go, straight into the reply:", + """ioxd_json j = ioxd_json_reply(ctx); +ioxd_json_object(&j); + IOXD_JSON_FIELD(&j, "id", id); + IOXD_JSON_FIELD(&j, "name", name); + ioxd_json_key(&j, "tags"); ioxd_json_array(&j); + ioxd_json_cstr(&j, "new"); + ioxd_json_end(&j); +ioxd_json_end(&j);"""), + ("A struct described once, nested objects and arrays included:", + """#define ORDER_FIELDS(X) \\ + X(VALUE, int, number) \\ + X(VALUE, double, total) +IOXD_JSON_STRUCT(order, ORDER_FIELDS) + +#define USER_FIELDS(X) \\ + X(VALUE, int64_t, id) \\ + X(VALUE, const char *, name) /* NULL comes out as null */ \\ + X(ARRAY, const char *, tags, n_tags) \\ + X(OBJECTS, order, orders, n_orders) +IOXD_JSON_STRUCT(user, USER_FIELDS) + +struct user u = { .id = 42, .name = "Zoe", .tags = tags, .n_tags = 2, .orders = orders, .n_orders = 1 }; +ioxd_json j = ioxd_json_reply(ctx); +user_to_json(&j, &u); /* {"id":42,"name":"Zoe","tags":[...],"orders":[{...}]} */"""), + ], + "ioxd_pipe": [ + ("A line echo server on raw TCP: read until a newline, answer, repeat:", + """static void echo(ioxd_pipe *pipe) +{ + for (;;) { + ioxd_slice live; + int rc = ioxd_pipe_read(pipe, &live); /* one contiguous span, or waits */ + if (rc <= 0) + return; /* 0: the peer is done; <0: gone or FULL */ + const char *nl = memchr(live.p, '\\n', live.len); + if (!nl) { + ioxd_pipe_examine(pipe, live.len); /* seen it all: the next read waits for more */ + continue; + } + size_t n = (size_t)(nl - live.p) + 1; + if (ioxd_pipe_send(pipe, live.p, n) < 0) + return; + ioxd_pipe_drop(pipe, n); + } +} + +int main(void) +{ + ioxd_bind(8100, NULL); + return ioxd_run_pipes(0, echo); +}"""), + ], + "ioxd_tls": [ + ("A TLS port beside a plain one; the files rotated, then reloaded:", + """ioxd_certs *certs = ioxd_certs_load("/etc/ioxd/certs"); /* //cert.pem and key.pem; `default` required */ +if (!certs) + return 1; +ioxd_bind(8080, NULL); +ioxd_bind(8443, certs); +/* ... later, after new files were written: */ +ioxd_certs_reload(certs); /* a host that fails keeps its old certificate */"""), + ], +} + +STYLE = """/* The manual's look: a man page, as man7.org renders one - monospace, sections in capitals at the + * margin, the text indented under them - with links, anchors and a light nav bar on top. */ +:root { + --paper: #ffffff; --ink: #111111; --dim: #555555; --rule: #d8d8d8; --link: #1a3fbf; --code: #f4f4f4; +} +@media (prefers-color-scheme: dark) { + :root { --paper: #111213; --ink: #e6e6e6; --dim: #a0a0a0; --rule: #333; --link: #7da2ff; --code: #1c1e21; } +} +html { background: var(--paper); } +body { + margin: 0; color: var(--ink); background: var(--paper); + font: 14px/1.5 "DejaVu Sans Mono", "Liberation Mono", Menlo, Consolas, ui-monospace, monospace; +} +a { color: var(--link); text-decoration: none; } +a:hover { text-decoration: underline; } +.crumbs { padding: .5em 1.5em; border-bottom: 1px solid var(--rule); color: var(--dim); } +main { max-width: 100ch; margin: 0 auto; padding: 1em 1.5em 4em; } +.hdr, .ftr { display: flex; justify-content: space-between; font-weight: bold; } +.ftr { margin-top: 3em; font-weight: normal; color: var(--dim); } +h1 { font-size: 1em; font-weight: bold; margin: 1.4em 0 .5em; } +h2 { font-size: 1em; font-weight: bold; margin: 1.8em 0 .5em; letter-spacing: .02em; } +h3 { font-size: 1em; font-weight: bold; margin: 1.4em 0 .4em 3ch; } +h3::before { content: ""; } +main > p, .entry, dl, pre, .text { margin-left: 7ch; } +main > pre.ex, main > pre.syn { margin-left: 7ch; } +p { margin: .5em 0; } +pre { margin: .5em 0; white-space: pre-wrap; word-break: break-word; } +pre.syn { padding: .6em 1em; background: var(--code); border-left: 3px solid var(--rule); } +pre.decl { font-weight: bold; margin: 1.2em 0 .3em; } +pre.ex { padding: .6em 1em; background: var(--code); border-left: 3px solid var(--rule); } +.entry { margin-top: .4em; } +.entry .text { margin-left: 4ch; } +.entry .text pre.ex, .text pre.ex { margin-left: 0; } +dl.trail { margin: .3em 0 0 4ch; } +dl.trail dt { font-weight: bold; margin-top: .4em; } +dl.trail dd { margin: 0 0 0 4ch; color: var(--ink); } +dl.files dt { font-weight: bold; margin-top: .6em; } +dl.files dd { margin: 0 0 0 4ch; } +table { border-collapse: collapse; margin-left: 7ch; } +td, th { text-align: left; padding: .25em 1.5em .25em 0; vertical-align: top; } +th { font-weight: bold; } +.dim { color: var(--dim); } +@media (max-width: 700px) { + main > p, .entry, dl, pre, .text, table, h3 { margin-left: 1ch; } + .hdr span:nth-child(2), .ftr span:nth-child(2) { display: none; } +} +""" + + +def build(): + version_str = version() + parsed = [] + index = {} # name -> (page, anchor) + for header, page, subject_hint in PAGES: + subject, top_paras, entries = parse_header(os.path.join(INCLUDE, header)) + parsed.append((header, page, subject or subject_hint, top_paras, entries)) + for e in entries: + if e.kind != "entry": + continue + for _code, _t, names, public in e.decls: + if public: + for n in names: + index.setdefault(n, (page, anchor_id(n))) + index.setdefault("ioxd_run", ("ioxd_http", "ioxd_run")) + for header, page, subject, top_paras, entries in parsed: + see = [(p, "3") for _h, p, _s in PAGES if p != page] + [("ioxd", "7")] + out = render_page(header, page, subject, top_paras, entries, index, version_str, EXAMPLES.get(page, []), see) + with open(os.path.join(HERE, page + ".html"), "w") as f: + f.write(out) + + # ioxd(7) + with open(os.path.join(HERE, "ioxd.7.html"), "w") as f: + f.write(page_html("ioxd", "7", OVERVIEW, version_str)) + + # every name + rows = [] + for n in sorted(index, key=lambda s: s.lower()): + page, aid = index[n] + rows.append(f'{esc(n)}{page}(3)') + names_body = ("

NAME

functions - every public name of libioxd, alphabetically, with the page that describes it

" + "

DESCRIPTION

" + "\n".join(rows) + "
") + with open(os.path.join(HERE, "functions.html"), "w") as f: + f.write(page_html("functions", "3", names_body, version_str)) + + # the front page + rows = "\n".join(f'{p}(3)<{esc(h)}>{esc(s)}' + for h, p, s in PAGES) + front = f"""

libioxd manual

+

The manual of libioxd, an HTTP/1.1 server library on io_uring for Linux, in the shape of man pages: +one page per public header, generated from the headers themselves, so what a page says is what the +header declares. Start with the overview.

+

SECTION 7: OVERVIEW

+
ioxd(7)the library, its model and its limits
+

SECTION 3: HEADERS

+{rows} +
functions(3)every public name, alphabetically
+

SEE ALSO

+

The repository's README.md, ARCHITECTURE.md (how the runtime works, for those who change it), TLS.md, +PERF.md and REVIEW.md. This manual is built by manual/build.py; make manual refreshes it.

+""" + with open(os.path.join(HERE, "index.html"), "w") as f: + f.write(page_html("index", "", front, version_str).replace("index() - libioxd manual", "libioxd manual") + .replace('
INDEX()libioxd Programmer\'s ManualINDEX()
', + '
LIBIOXDlibioxd Programmer\'s ManualLIBIOXD
') + .replace("INDEX()\n", "LIBIOXD\n")) + with open(os.path.join(HERE, "style.css"), "w") as f: + f.write(STYLE) + print(f"manual: {len(PAGES)} pages, {len(index)} names, version {version_str}") + + +if __name__ == "__main__": + build() diff --git a/manual/functions.html b/manual/functions.html new file mode 100644 index 0000000..bc0d975 --- /dev/null +++ b/manual/functions.html @@ -0,0 +1,126 @@ + + + + + +functions(3) - libioxd manual + + + + +
+
FUNCTIONS(3)libioxd Programmer's ManualFUNCTIONS(3)
+

NAME

functions - every public name of libioxd, alphabetically, with the page that describes it

DESCRIPTION

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ioxd_advanceioxd_http(3)
ioxd_bindioxd_http(3)
ioxd_body_allioxd_http(3)
ioxd_body_read_next_chunkioxd_http(3)
ioxd_body_read_untilioxd_http(3)
ioxd_certsioxd_http(3)
ioxd_certs_freeioxd_tls(3)
ioxd_certs_loadioxd_tls(3)
ioxd_certs_reloadioxd_tls(3)
ioxd_configioxd_config(3)
ioxd_configureioxd_config(3)
ioxd_content_lengthioxd_http(3)
ioxd_content_typeioxd_http(3)
ioxd_cstrioxd_slice(3)
ioxd_ctxioxd_http(3)
ioxd_defaultioxd_router(3)
IOXD_DEFAULTioxd_router(3)
ioxd_deleteioxd_router(3)
IOXD_DELETEioxd_router(3)
ioxd_endpointioxd_router(3)
ioxd_endpoint_useioxd_router(3)
ioxd_flushioxd_http(3)
ioxd_getioxd_router(3)
IOXD_GETioxd_router(3)
ioxd_groupioxd_router(3)
IOXD_GROUPioxd_router(3)
ioxd_group_newioxd_router(3)
ioxd_group_useioxd_router(3)
ioxd_handlerioxd_http(3)
ioxd_headerioxd_http(3)
ioxd_jsonioxd_json(3)
ioxd_json_arrayioxd_json(3)
ioxd_json_boolioxd_json(3)
ioxd_json_cstrioxd_json(3)
IOXD_JSON_DEPTHioxd_json(3)
ioxd_json_doneioxd_json(3)
ioxd_json_doubleioxd_json(3)
ioxd_json_endioxd_json(3)
IOXD_JSON_FIELDioxd_json(3)
ioxd_json_floatioxd_json(3)
ioxd_json_intioxd_json(3)
ioxd_json_keyioxd_json(3)
ioxd_json_memioxd_json(3)
ioxd_json_nullioxd_json(3)
ioxd_json_objectioxd_json(3)
ioxd_json_pipeioxd_json(3)
ioxd_json_rawioxd_json(3)
ioxd_json_replyioxd_json(3)
ioxd_json_stringioxd_json(3)
IOXD_JSON_STRUCTioxd_json(3)
ioxd_json_uintioxd_json(3)
IOXD_JSON_VALUEioxd_json(3)
IOXD_JSON_WRITERioxd_json(3)
ioxd_kvioxd_slice(3)
ioxd_kv_parseioxd_slice(3)
IOXD_MAX_HEADERSioxd_http(3)
IOXD_MAX_MWioxd_router(3)
IOXD_MAX_PARAMSioxd_http(3)
IOXD_MAX_RESP_HEADERSioxd_http(3)
IOXD_MAX_ROUTE_PARAMSioxd_http(3)
ioxd_mwioxd_http(3)
ioxd_nextioxd_http(3)
ioxd_next_runioxd_http(3)
ioxd_patchioxd_router(3)
IOXD_PATCHioxd_router(3)
ioxd_pipeioxd_pipe(3)
ioxd_pipe_advanceioxd_pipe(3)
ioxd_pipe_copyioxd_pipe(3)
ioxd_pipe_dropioxd_pipe(3)
ioxd_pipe_examineioxd_pipe(3)
ioxd_pipe_flushioxd_pipe(3)
IOXD_PIPE_FULLioxd_pipe(3)
IOXD_PIPE_GONEioxd_pipe(3)
ioxd_pipe_handlerioxd_pipe(3)
ioxd_pipe_keepioxd_pipe(3)
ioxd_pipe_readioxd_pipe(3)
ioxd_pipe_releaseioxd_pipe(3)
ioxd_pipe_reserveioxd_pipe(3)
ioxd_pipe_sendioxd_pipe(3)
ioxd_pipe_writeioxd_pipe(3)
ioxd_postioxd_router(3)
IOXD_POSTioxd_router(3)
ioxd_printfioxd_http(3)
ioxd_putioxd_router(3)
IOXD_PUTioxd_router(3)
ioxd_reasonioxd_http(3)
ioxd_requestioxd_http(3)
ioxd_reserveioxd_http(3)
IOXD_RESP_HEAD_CAPioxd_http(3)
ioxd_responseioxd_http(3)
ioxd_routeioxd_router(3)
IOXD_ROUTEioxd_router(3)
IOXD_ROUTE_ARENAioxd_http(3)
ioxd_runioxd_http(3)
ioxd_run_pipesioxd_pipe(3)
ioxd_sliceioxd_slice(3)
ioxd_slice_ends_withioxd_slice(3)
ioxd_slice_eqioxd_slice(3)
ioxd_slice_eq_ciioxd_slice(3)
ioxd_slice_starts_withioxd_slice(3)
ioxd_slice_trimioxd_slice(3)
ioxd_textioxd_http(3)
ioxd_to_boolioxd_slice(3)
ioxd_to_doubleioxd_slice(3)
ioxd_to_i64ioxd_slice(3)
ioxd_to_intioxd_slice(3)
ioxd_to_u64ioxd_slice(3)
ioxd_useioxd_router(3)
IOXD_USEioxd_router(3)
ioxd_writeioxd_http(3)
+
libioxd 0.1.02026-09-09FUNCTIONS(3)
+
+ + diff --git a/manual/index.html b/manual/index.html new file mode 100644 index 0000000..77273db --- /dev/null +++ b/manual/index.html @@ -0,0 +1,35 @@ + + + + + +libioxd manual + + + + +
+
LIBIOXDlibioxd Programmer's ManualLIBIOXD
+

libioxd manual

+

The manual of libioxd, an HTTP/1.1 server library on io_uring for Linux, in the shape of man pages: +one page per public header, generated from the headers themselves, so what a page says is what the +header declares. Start with the overview.

+

SECTION 7: OVERVIEW

+
ioxd(7)the library, its model and its limits
+

SECTION 3: HEADERS

+ + + + + + + +
ioxd_config(3)<ioxd/config.h>the runtime's knobs
ioxd_http(3)<ioxd/http.h>request, response, context, body, reply, the run
ioxd_router(3)<ioxd/router.h>groups, endpoints, middleware; the script macros
ioxd_slice(3)<ioxd/slice.h>slices, conversions, key/value parsing
ioxd_json(3)<ioxd/json.h>JSON written as you go; structs described once
ioxd_pipe(3)<ioxd/pipe.h>a connection as a pipe, for other protocols
ioxd_tls(3)<ioxd/tls.h>a certificate store, for a TLS port
functions(3)every public name, alphabetically
+

SEE ALSO

+

The repository's README.md, ARCHITECTURE.md (how the runtime works, for those who change it), TLS.md, +PERF.md and REVIEW.md. This manual is built by manual/build.py; make manual refreshes it.

+ +
libioxd 0.1.02026-09-09LIBIOXD
+
+ + diff --git a/manual/ioxd.7.html b/manual/ioxd.7.html new file mode 100644 index 0000000..c60fefd --- /dev/null +++ b/manual/ioxd.7.html @@ -0,0 +1,100 @@ + + + + + +ioxd(7) - libioxd manual + + + + +
+
IOXD(7)libioxd Programmer's ManualIOXD(7)
+ +

NAME

+

ioxd - an HTTP/1.1 server library on io_uring, one worker per core, a stackful coroutine per connection

+ +

SYNOPSIS

+
#include <ioxd.h>
+
+cc main.c $(pkg-config --cflags --libs ioxd) -o server
+ +

DESCRIPTION

+

libioxd serves HTTP/1.1, plain or over TLS 1.3, from a thread per core. Each worker owns an io_uring +ring, a ring of receive buffers the kernel delivers into, and its own sockets on every bound port +(SO_REUSEPORT); nothing is shared between workers while serving. Every connection runs on its own +coroutine, so a handler reads the body and writes the reply in straight-line code: a call that has to +wait for the wire suspends the coroutine, and the worker's loop resumes it on the completion.

+ +

A program registers its routes, sets the runtime's knobs if it wants to, binds its ports, then runs:

+
static void hello(ioxd_ctx *ctx)
+{
+    ioxd_slice name = ctx->req.route_params[0].value;
+    ioxd_printf(ctx, "hello %.*s\n", (int)name.len, name.p);
+}
+
+int main(void)
+{
+    IOXD_GET("/hello/:name", hello);
+    ioxd_bind(8080, NULL);                                  /* plain */
+    ioxd_bind(8443, ioxd_certs_load("certs"));              /* TLS 1.3, from a directory of certificates */
+    return ioxd_run(0);                                     /* one worker per core, until SIGINT or SIGTERM */
+}
+ +

The request and the reply

+

A handler receives an ioxd_ctx: the request as plain data - method, +path, query, headers, parameters, all slices into the connection's buffers - and the response being +shaped. The body stays on the wire until asked for: ioxd_body_all +reads it whole, ioxd_body_read_until streams it. The reply +is written into a slab with ioxd_write, ioxd_printf +or the JSON writer; when everything fits it goes out in one send with its head in +front, and when it does not it streams, chunked. What goes on the wire follows the protocol whatever the handler +did: a reply to HEAD carries no body, a declared length is held to, a request whose framing cannot be trusted is +refused before a handler sees it.

+ +

Routes

+

Endpoints live in groups: a prefix plus middleware, nesting. Everything is +resolved once, when the run starts, into a segment tree and one flat middleware chain per endpoint, so a request +costs one walk and no scan. The script macros (IOXD_GROUP, IOXD_GET, IOXD_USE) are the same registrations +written as a block.

+ +

Threads and lifetimes

+

Register routes, configure and bind from the main thread, before the run. Handlers run on worker threads, +one at a time per worker; a request's slices are valid until the handler returns, and anything a handler hands +the reply (a header, a content type) is copied. Nothing in the library is shared between workers except the +read-only route tree and a TLS store's certificate table, which is reference counted.

+ +

Limits

+

A request head, and a body read whole, must fit the reader's 16 KB; streamed bodies have no limit. At most +64 request headers, 32 query parameters, 8 route captures, 16 added reply headers within 3 KB. These size the +context, so ioxd_run refuses an application built with different values. +The runtime's own sizes - the ring, the receive buffers, the coroutine stacks, the pools - are the +configuration, per worker.

+ +

Building

+

Linux 6.x on x86-64, gcc 14 or newer (the library is C23; the headers are usable from C11), OpenSSL 3 for +the TLS handshake (built by default; make TLS=0 or -DIOXD_TLS=OFF leaves it out). +make produces libioxd.a and libioxd.so; make install the headers and a pkg-config file; +CMake exports ioxd::ioxd. Kernel TLS needs a kernel with SOCKET_URING_OP_SETSOCKOPT (6.7 or newer) +when the registered file table is on, which is the default.

+ +

FILES

+
+
<ioxd.h>
the whole API: an umbrella over the headers below
+
<ioxd/config.h>
the runtime's knobs: ring, buffers, stacks, pools
+
<ioxd/http.h>
request, response, context, body, reply, bind and run
+
<ioxd/router.h>
groups, endpoints, middleware, the script macros
+
<ioxd/slice.h>
slices, conversions, key/value parsing
+
<ioxd/json.h>
the JSON writer and IOXD_JSON_STRUCT
+
<ioxd/pipe.h>
a connection as a pipe, for protocols other than HTTP
+
<ioxd/tls.h>
a certificate store, for a TLS port
+
+ +

SEE ALSO

+

every public name, and in the repository: README.md, ARCHITECTURE.md (how the +runtime works), TLS.md, PERF.md, REVIEW.md.

+ +
libioxd 0.1.02026-09-09IOXD(7)
+
+ + diff --git a/manual/ioxd_config.html b/manual/ioxd_config.html new file mode 100644 index 0000000..8038342 --- /dev/null +++ b/manual/ioxd_config.html @@ -0,0 +1,52 @@ + + + + + +ioxd_config(3) - libioxd manual + + + + +
+
IOXD_CONFIG(3)libioxd Programmer's ManualIOXD_CONFIG(3)
+

NAME

+

ioxd/config.h - the runtime's knobs: the ring, the receive buffers, the coroutine stacks and the pools, per worker. Set once before ioxd_run; the build's values are the defaults.

+

SYNOPSIS

+
#include <ioxd.h>
+
+typedef struct { ... } ioxd_config;
+int ioxd_configure(const ioxd_config *config);
+

DESCRIPTION

+
+
+typedef struct ioxd_config {
+    unsigned ring_entries;      /* submission queue entries, the completion queue twice that; a power of two, at most 32768; 4096 */
+    unsigned recv_buffers;      /* provided receive buffers; a power of two, at most 32768; 4096 */
+    unsigned recv_buffer_size;  /* bytes in each, 64 to 1 MB; 2048 */
+    size_t   stack_size;        /* a connection's coroutine stack, above a 64 KB guard; at least 64 KB; 128 KB */
+    unsigned idle_stacks;       /* stacks kept warm for the next connections; 512 */
+    unsigned idle_connections;  /* connection records kept warm; 1024 */
+} ioxd_config;
+
+

Every field is per worker, and a zero field keeps its default. The receive buffers are what the kernel delivers into, so their count bounds how much may be in flight before recvs park on -ENOBUFS (the log says "raise recv_buffers" when that happens) and their size bounds what one delivery holds; a worker's slab is count x size bytes.

+
+
+
+int ioxd_configure(const ioxd_config *config);
+
+

Apply a configuration to the runs that follow. -1, with the reason on stderr, when a value is refused - nothing changes then. ioxd_configure(&(ioxd_config){ 0 }) is the defaults.

+
+

EXAMPLES

+

Twice the receive buffers, before the run; every other field keeps its default:

+
ioxd_config config = { .recv_buffers = 8192 };
+if (ioxd_configure(&config) < 0)
+    return 1;                                   /* the reason is on stderr */
+ioxd_bind(8080, NULL);
+return ioxd_run(0);
+

SEE ALSO

+

ioxd_http(3), ioxd_router(3), ioxd_slice(3), ioxd_json(3), ioxd_pipe(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_CONFIG(3)
+
+ + diff --git a/manual/ioxd_http.html b/manual/ioxd_http.html new file mode 100644 index 0000000..3bf14f3 --- /dev/null +++ b/manual/ioxd_http.html @@ -0,0 +1,264 @@ + + + + + +ioxd_http(3) - libioxd manual + + + + +
+
IOXD_HTTP(3)libioxd Programmer's ManualIOXD_HTTP(3)
+

NAME

+

ioxd/http.h - the request, the response, the context a handler receives, the body read on demand, the reply written as you go, and the run.

+

SYNOPSIS

+
#include <ioxd.h>
+
+#define IOXD_MAX_HEADERS      64
+#define IOXD_MAX_PARAMS       32
+#define IOXD_MAX_ROUTE_PARAMS 8
+#define IOXD_MAX_RESP_HEADERS 16
+#define IOXD_RESP_HEAD_CAP    3072
+#define IOXD_ROUTE_ARENA      256
+typedef struct { ... } ioxd_request;
+typedef struct { ... } ioxd_response;
+typedef struct { ... } ioxd_ctx;
+typedef void (*ioxd_handler)(ioxd_ctx *ctx);
+typedef struct ioxd_next ioxd_next;
+typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next);
+void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next);
+ioxd_slice ioxd_body_all(ioxd_ctx *ctx);
+int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n);
+int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap);
+int  ioxd_write (ioxd_ctx *ctx, const void *data, size_t len);
+void *ioxd_reserve(ioxd_ctx *ctx, size_t n);
+void  ioxd_advance(ioxd_ctx *ctx, size_t n);
+int  ioxd_text  (ioxd_ctx *ctx, const char *s);
+int  ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+bool ioxd_header        (ioxd_ctx *ctx, const char *name, const char *value);
+bool ioxd_content_type  (ioxd_ctx *ctx, const char *type);
+bool ioxd_content_length(ioxd_ctx *ctx, size_t n);
+int  ioxd_flush         (ioxd_ctx *ctx);
+typedef struct ioxd_certs ioxd_certs;
+int ioxd_bind(int port, ioxd_certs *certs);
+static inline int ioxd_run(int workers);
+const char *ioxd_reason(int status);
+

DESCRIPTION

+
+
+#define IOXD_MAX_HEADERS      64
+#define IOXD_MAX_PARAMS       32
+#define IOXD_MAX_ROUTE_PARAMS 8
+#define IOXD_MAX_RESP_HEADERS 16
+#define IOXD_RESP_HEAD_CAP    3072
+#define IOXD_ROUTE_ARENA      256
+
+

The limits that size a request and a reply. They are build-time constants of the LIBRARY: an application may not redefine them, since they lay out the context the library allocates - ioxd_run checks that the two sides agree and refuses to start otherwise. A request past a limit is answered 400 (more headers than fit, more query parameters than fit) or 414 (more decoded query than fits its arena); a reply past one is refused by the call that adds to it.

+
+
IOXD_MAX_HEADERS
request headers; more is a 400
+
IOXD_MAX_PARAMS
query parameters; more is a 400
+
IOXD_MAX_ROUTE_PARAMS
:name captures a route pattern may have
+
IOXD_MAX_RESP_HEADERS
headers a reply may add
+
IOXD_RESP_HEAD_CAP
bytes the added headers may serialize to
+
IOXD_ROUTE_ARENA
per-request bytes the router decodes into
+
+
+

the request

+
+
+typedef struct ioxd_request {
+    ioxd_slice  method;                         /* "GET", "POST", ...                        */
+    ioxd_slice  target;                         /* raw request target: path plus any query   */
+    ioxd_slice  path;                           /* the path, query stripped                  */
+    ioxd_slice  query;                          /* raw text after '?', undecoded             */
+    int         minor_version;                  /* 0 or 1 for HTTP/1.0 or 1.1                */
+
+    ioxd_kv     headers[IOXD_MAX_HEADERS];      /* names lower-cased, values as received     */
+    size_t      n_headers;
+    ioxd_kv     params[IOXD_MAX_PARAMS];        /* query parameters, percent-decoded         */
+    size_t      n_params;
+    ioxd_kv     route_params[IOXD_MAX_ROUTE_PARAMS];   /* the :name captures, percent-decoded       */
+    size_t      n_route_params;
+
+    size_t      content_length;                 /* what the head declared; 0 if nothing      */
+    bool        chunked;                        /* the body is chunked: length unknown       */
+    ioxd_slice  body;                           /* the whole body, once ioxd_body_all read it */
+    bool        keep_alive;                     /* computed from version + Connection         */
+    bool        expect_continue;                /* "Expect: 100-continue": the body waits for the interim reply the first body read sends */
+    char        route_arena[IOXD_ROUTE_ARENA];  /* private: the router's per-request scratch */
+} ioxd_request;
+
+

All the data of a request, as slices into the connection's read buffer (decoded parameters into a per-request arena), valid only until the handler returns. Read the arrays directly; header names are lower-cased, so compare them with lowercase literals. The body is not here until you ask for it: ioxd_body_all reads it whole, ioxd_body_read_until streams it. The engine has already checked the framing (RFC 9112): a Content-Length that is not a plain number, conflicting duplicates, a Transfer-Encoding with anything but a final "chunked", both fields together, a folded header line, or an HTTP/1.1 request without exactly one Host never reach a handler - they are answered 400 (501 for a transfer coding we do not implement) and the connection closes.

+
+

the response

+
+
+typedef struct ioxd_response {
+    int         status;                         /* 200 by default                            */
+    ioxd_slice  content_type;                   /* "text/plain" by default; assign a slice that outlives the handler (a literal), or ioxd_content_type copies one */
+    ioxd_kv     headers[IOXD_MAX_RESP_HEADERS]; /* added with ioxd_header: copies, names lower-cased */
+    size_t      n_headers;
+    bool        close;                          /* close the connection after this reply     */
+    bool        head_sent;
+    size_t      content_length;                 /* declared with ioxd_content_length         */
+    bool        has_length;
+
+    bool        chunked, failed;                /* private: how a stream is framed; peer gone */
+    size_t      body_sent;                      /* private: body bytes sent so far           */
+    size_t      head_len;                       /* private: the added headers, serialized    */
+    char        head[IOXD_RESP_HEAD_CAP];
+} ioxd_response;
+
+

The reply being shaped. Body bytes wait in the connection's write slab (ioxd_write, ioxd_printf, ioxd_reserve); a full slab is sent and emptied, and the head (status, content type, headers) goes out in front of the first send - after the chain when everything fit, earlier when the body streams - and is frozen from then on (head_sent). What goes on the wire follows the request and the status, not only the handler: a reply to HEAD, a 1xx, 204 or 304 carries no body whatever was written (HEAD keeps the Content-Length the GET would have had; 1xx and 204 carry no framing header at all), a status outside 100-999 goes out as 500, and a declared Content-Length that the writes do not match is corrected when the reply was buffered whole and closes the connection when it streamed.

+
+

the context

+
+
+typedef struct ioxd_ctx {
+    ioxd_request  req;
+    ioxd_response res;
+    void         *user;                         /* free slot: middleware hands data to the handler */
+    void         *priv;                         /* the engine's own state                    */
+} ioxd_ctx;
+typedef void (*ioxd_handler)(ioxd_ctx *ctx);
+
+
+
+
+typedef struct ioxd_next ioxd_next;
+typedef void (*ioxd_mw)(ioxd_ctx *ctx, ioxd_next *next);
+void ioxd_next_run(ioxd_ctx *ctx, ioxd_next *next);
+
+

Middleware runs around the handler (the onion model): shape the context, call ioxd_next_run to run the rest of the chain and then the endpoint, then act on the result - or write a reply and return WITHOUT calling ioxd_next_run to short-circuit (auth failure, cache hit).

+
+

the body

+
+
+ioxd_slice ioxd_body_all(ioxd_ctx *ctx);
+
+

The whole body, read into the request buffer once and returned as a slice (also req.body). It must fit the buffer (16 KB by default): otherwise the slice is empty and res.status is 413, which becomes the reply - a handler that streams its reply should check and stop. Not after one of the reads below. A malformed chunked body is a 400 the same way. With "Expect: 100-continue" the first of these reads answers "100 Continue" before waiting; a handler that never reads such a body gets its reply sent and the connection closed.

+
+
+
+int ioxd_body_read_until(ioxd_ctx *ctx, void *dst, size_t n);
+
+

The next bytes of the body into dst, reading until n are there or the body ends. Returns the count (less than n only at the end), 0 once it is all consumed (or for n == 0), -1 on error (the connection then closes after the reply). Any size of body, nothing kept in the engine.

+
+
+
+int ioxd_body_read_next_chunk(ioxd_ctx *ctx, void *dst, size_t cap);
+
+

The next chunk of a chunked body, exactly as the sender framed it, into dst: the rest of the current chunk when a read stopped inside one, else the next whole one. Returns its length, 0 at the last chunk, -1 on error - a chunk larger than cap is a 413 - or when the body is not chunked.

+
+

the reply

+
+
+int  ioxd_write (ioxd_ctx *ctx, const void *data, size_t len);
+
+

Body writes into the slab. When it fills, it is sent - head first - and the body streams from then on: chunked on HTTP/1.1, until close on HTTP/1.0, or with the length declared below. Return 0, or -1 once the reply failed: the peer is gone, or a format could not be written (further writes are ignored either way).

+
+
+
+void *ioxd_reserve(ioxd_ctx *ctx, size_t n);
+void  ioxd_advance(ioxd_ctx *ctx, size_t n);
+int  ioxd_text  (ioxd_ctx *ctx, const char *s);
+int  ioxd_printf(ioxd_ctx *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+

Or write into the slab directly: reserve n bytes (flushing first when they do not fit; nullptr once the peer is gone or n exceeds the slab) and advance by what was written - never more than reserved; advance clamps to the room that was there.

+
+
ioxd_text
a C string
+
ioxd_printf
formatted, into the slab
+
+
+
+
+bool ioxd_header        (ioxd_ctx *ctx, const char *name, const char *value);
+bool ioxd_content_type  (ioxd_ctx *ctx, const char *type);
+bool ioxd_content_length(ioxd_ctx *ctx, size_t n);
+int  ioxd_flush         (ioxd_ctx *ctx);
+
+

Shape the head, only before it is sent: each returns false afterwards. ioxd_header copies the name (sent lower-cased) and the value, so temporaries are fine; it also returns false for a name that is not an HTTP token, a value with a control byte (CR, LF, NUL: no response splitting), a header the engine owns (content-length, transfer-encoding, connection), when the table or its IOXD_RESP_HEAD_CAP bytes are full. "content-type" through it sets the content type.

+
+
ioxd_content_type
copied
+
ioxd_content_length
stream a large body with a known length
+
ioxd_flush
send what is in the slab now (starts streaming)
+
+
+

run

+
+
+typedef struct ioxd_certs ioxd_certs;
+int ioxd_bind(int port, ioxd_certs *certs);
+
+

Bind a port: plain HTTP when tls is NULL, TLS 1.3 terminated in the kernel otherwise, with the certificate store from ioxd_certs_load (TLS.md). Every bound port serves the same routes; bind as many as you need (at most 8), then run. -1 if refused: a bad port, or the table is full.

+
+
+
+static inline int ioxd_run(int workers);
+
+

Start `workers` proactor threads (<= 0: one per core) serving HTTP on every bound port, and block until SIGINT/SIGTERM. Returns 0 on clean shutdown, non-zero when nothing was bound, when a port could not be opened, when a worker failed, or when the limits above differ between this header and the library (the context would not match). May be called again after it returns; the ports stay bound.

+
+
+
+const char *ioxd_reason(int status);
+
+

The reason phrase for a status code ("OK", "Not Found", ...); "Unknown" if unlisted.

+
+

EXAMPLES

+

A route parameter, a query parameter converted, and a formatted reply:

+
static void user(ioxd_ctx *ctx)
+{
+    int64_t id;
+    if (!ioxd_to_i64(ctx->req.route_params[0].value, &id)) {
+        ctx->res.status = 400;
+        ioxd_text(ctx, "the id must be an integer\n");
+        return;
+    }
+    for (size_t i = 0; i < ctx->req.n_params; i++)
+        if (ioxd_slice_eq(ctx->req.params[i].key, "fields"))
+            ioxd_printf(ctx, "fields=%.*s\n", (int)ctx->req.params[i].value.len, ctx->req.params[i].value.p);
+    ioxd_header(ctx, "x-user", "42");                 /* copied: a temporary is fine */
+    ioxd_printf(ctx, "user %lld\n", (long long)id);
+}
+

A body read whole, then a reply streamed with a flush every ten lines:

+
static void repeat(ioxd_ctx *ctx)
+{
+    ioxd_slice body = ioxd_body_all(ctx);             /* over 16 KB: empty, and res.status is 413 */
+    if (ctx->res.status != 200)
+        return;
+    for (int i = 1; i <= 25; i++) {
+        if (ioxd_printf(ctx, "%d: %.*s\n", i, (int)body.len, body.p) < 0)
+            return;                                   /* the peer is gone */
+        if (i % 10 == 0 && ioxd_flush(ctx) < 0)
+            return;
+    }
+}
+

A large upload streamed through a fixed buffer:

+
static void upload(ioxd_ctx *ctx)
+{
+    char   buf[4096];
+    size_t total = 0;
+    for (;;) {
+        int n = ioxd_body_read_until(ctx, buf, sizeof buf);
+        if (n < 0) return;                            /* malformed or gone: the engine answers */
+        if (n == 0) break;
+        total += (size_t)n;
+    }
+    ioxd_printf(ctx, "%zu bytes\n", total);
+}
+

Middleware around the handler, the onion way:

+
static void timing(ioxd_ctx *ctx, ioxd_next *next)
+{
+    struct timespec t0, t1;
+    clock_gettime(CLOCK_MONOTONIC, &t0);
+    ioxd_next_run(ctx, next);                         /* the rest of the chain, then the endpoint */
+    clock_gettime(CLOCK_MONOTONIC, &t1);
+    /* the head may already be out (a streamed reply): ioxd_header then returns false */
+}
+

SEE ALSO

+

ioxd_config(3), ioxd_router(3), ioxd_slice(3), ioxd_json(3), ioxd_pipe(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_HTTP(3)
+
+ + diff --git a/manual/ioxd_json.html b/manual/ioxd_json.html new file mode 100644 index 0000000..5d60bb6 --- /dev/null +++ b/manual/ioxd_json.html @@ -0,0 +1,170 @@ + + + + + +ioxd_json(3) - libioxd manual + + + + +
+
IOXD_JSON(3)libioxd Programmer's ManualIOXD_JSON(3)
+

NAME

+

ioxd/json.h - JSON written as you go, and a struct described once, serialized with one call.

+

SYNOPSIS

+
#include <ioxd.h>
+
+#define IOXD_JSON_DEPTH 63
+typedef struct { ... } ioxd_json;
+ioxd_json ioxd_json_reply(ioxd_ctx *ctx);
+ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe);
+ioxd_json ioxd_json_mem  (char *buf, size_t cap, size_t *len);
+bool ioxd_json_object(ioxd_json *j);
+bool ioxd_json_array (ioxd_json *j);
+bool ioxd_json_end   (ioxd_json *j);
+bool ioxd_json_done  (ioxd_json *j);
+bool ioxd_json_key   (ioxd_json *j, const char *name);
+bool ioxd_json_string(ioxd_json *j, ioxd_slice s);
+bool ioxd_json_cstr  (ioxd_json *j, const char *s);
+bool ioxd_json_int   (ioxd_json *j, int64_t v);
+bool ioxd_json_uint  (ioxd_json *j, uint64_t v);
+bool ioxd_json_double(ioxd_json *j, double v);
+bool ioxd_json_float (ioxd_json *j, float v);
+bool ioxd_json_bool  (ioxd_json *j, bool v);
+bool ioxd_json_null  (ioxd_json *j);
+bool ioxd_json_raw   (ioxd_json *j, ioxd_slice json);
+IOXD_JSON_VALUE(ioxd_json *j, x)
+IOXD_JSON_FIELD(ioxd_json *j, const char *name, x)
+IOXD_JSON_STRUCT(name, FIELDS)
+IOXD_JSON_WRITER(name, FIELDS)
+

DESCRIPTION

+

JSON, written as you go

+
+
+#define IOXD_JSON_DEPTH 63
+typedef struct ioxd_json {
+    enum {
+        IOXD_JSON_TO_REPLY,
+        IOXD_JSON_TO_PIPE,
+        IOXD_JSON_TO_MEM,
+    } kind;
+
+    union {
+        ioxd_ctx         *ctx;
+        struct ioxd_pipe *pipe;
+        struct { char *p; size_t cap, *len; } mem;
+    } to;
+
+    uint64_t has_value;                         /* per level: a value is there, so a comma is due */
+    uint64_t is_object;                         /* per level: it closes with '}' rather than ']'  */
+    unsigned depth;
+    bool     after_key;                         /* the next value follows a key: no comma        */
+    bool     failed;
+} ioxd_json;
+ioxd_json ioxd_json_reply(ioxd_ctx *ctx);
+ioxd_json ioxd_json_pipe (struct ioxd_pipe *pipe);
+ioxd_json ioxd_json_mem  (char *buf, size_t cap, size_t *len);
+bool ioxd_json_object(ioxd_json *j);
+bool ioxd_json_array (ioxd_json *j);
+bool ioxd_json_end   (ioxd_json *j);
+bool ioxd_json_done  (ioxd_json *j);
+bool ioxd_json_key   (ioxd_json *j, const char *name);
+bool ioxd_json_string(ioxd_json *j, ioxd_slice s);
+bool ioxd_json_cstr  (ioxd_json *j, const char *s);
+bool ioxd_json_int   (ioxd_json *j, int64_t v);
+bool ioxd_json_uint  (ioxd_json *j, uint64_t v);
+bool ioxd_json_double(ioxd_json *j, double v);
+bool ioxd_json_float (ioxd_json *j, float v);
+bool ioxd_json_bool  (ioxd_json *j, bool v);
+bool ioxd_json_null  (ioxd_json *j);
+bool ioxd_json_raw   (ioxd_json *j, ioxd_slice json);
+
+

A forward-only JSON writer, the shape of .NET's Utf8JsonWriter: no tree, no allocation. The bytes go straight into the reply - or a raw pipe, or a buffer - escaped as they are written, and stream out as the slab fills. Nesting and commas are tracked, so a handler just says what it means:

+
ioxd_json j = ioxd_json_reply(ctx);                  // content-type: application/json
+ioxd_json_object(&j);
+    ioxd_json_key(&j, "id");    ioxd_json_int(&j, id);
+    ioxd_json_key(&j, "name");  ioxd_json_string(&j, name);
+    ioxd_json_key(&j, "tags");  ioxd_json_array(&j);
+        ioxd_json_cstr(&j, "new");
+    ioxd_json_end(&j);
+ioxd_json_end(&j);
+if (!ioxd_json_done(&j)) { ... }                     // whole: nothing failed, nothing open
+

Strings are emitted byte for byte, with only '"', '\' and the control characters escaped: invalid UTF-8 goes out exactly as it came in, so untrusted input has to be validated first. Every call returns false once the sink is gone (the peer left; the buffer is full), the nesting passed IOXD_JSON_DEPTH, or the call had no place in the document - a key outside an object, a value where a key was due, an end with nothing open. The rest is then dropped, so checking the last call is enough; check done() after it to catch an end that was never written.

+
+
IOXD_JSON_DEPTH
levels: one bit of each mask below apiece
+
ioxd_json_reply
into the reply; sets its content type
+
ioxd_json_pipe
into a raw pipe's slab
+
ioxd_json_mem
into memory; *len is what was written
+
ioxd_json_object
{
+
ioxd_json_array
[
+
ioxd_json_end
} or ], whichever is open
+
ioxd_json_done
nothing failed, all closed
+
ioxd_json_key
"name":
+
ioxd_json_string
"...", escaped
+
ioxd_json_cstr
NULL is null
+
ioxd_json_double
the shortest that reads back the same; nan and inf become null
+
ioxd_json_float
the same, read back as a float: 0.1f is 0.1
+
ioxd_json_raw
already JSON: copied as is
+
+
+
+
+IOXD_JSON_VALUE(ioxd_json *j, x)
+
+

A value by its C type, and a key with one: the _Generic picks ioxd_json_int for the integer types, _uint for the unsigned ones, _float and _double for those two, _bool, _cstr for a char pointer, _string for a slice.

+
+
+
+IOXD_JSON_FIELD(ioxd_json *j, const char *name, x)
+
+

A key and its value in one line. The answer goes through a function so that a field written for its effect - `IOXD_JSON_FIELD(j, "n", n);` - is a plain statement and not a value the compiler sees discarded, while `if (IOXD_JSON_FIELD(j, "n", n))` still reads it.

+
+
+
+IOXD_JSON_STRUCT(name, FIELDS)
+IOXD_JSON_WRITER(name, FIELDS)
+
+

A struct described once, serialized with one call. The description is a list of fields, each line its kind, its C type (or, for a nested struct, that struct's name) and its name:

+
#define USER_FIELDS(X)                       \
+    X(VALUE,    int64_t,      id)            \
+    X(VALUE,    const char *, name)          \
+    X(OBJECT,   address,      address)       \
+    X(OPTIONAL, address,      billing)       \
+    X(ARRAY,    const char *, tags,   n_tags)    \
+    X(OBJECTS,  order,        orders, n_orders)
+IOXD_JSON_STRUCT(user, USER_FIELDS)
+

VALUE is a scalar, written by its C type; OBJECT a nested struct held by value; OPTIONAL a pointer to one, null where the pointer is NULL; ARRAY scalars and the field holding their count; OBJECTS the same for nested structs. IOXD_JSON_STRUCT defines the struct and the function - struct user, and user_to_json(ioxd_json *, const struct user *); IOXD_JSON_WRITER only the function, for a struct declared elsewhere with the same fields. A nested struct's own IOXD_JSON_STRUCT comes first. Counts are size_t; arrays are pointers to their first element. A note beside a field is written as a block comment, the way playground/hello/main.c writes them: a // one would run on through the backslash and swallow the lines after it.

+
+

EXAMPLES

+

Written as you go, straight into the reply:

+
ioxd_json j = ioxd_json_reply(ctx);
+ioxd_json_object(&j);
+    IOXD_JSON_FIELD(&j, "id", id);
+    IOXD_JSON_FIELD(&j, "name", name);
+    ioxd_json_key(&j, "tags"); ioxd_json_array(&j);
+        ioxd_json_cstr(&j, "new");
+    ioxd_json_end(&j);
+ioxd_json_end(&j);
+

A struct described once, nested objects and arrays included:

+
#define ORDER_FIELDS(X)        \
+    X(VALUE,   int,    number)  \
+    X(VALUE,   double, total)
+IOXD_JSON_STRUCT(order, ORDER_FIELDS)
+
+#define USER_FIELDS(X)                         \
+    X(VALUE,   int64_t,      id)               \
+    X(VALUE,   const char *, name)             /* NULL comes out as null */ \
+    X(ARRAY,   const char *, tags,   n_tags)   \
+    X(OBJECTS, order,        orders, n_orders)
+IOXD_JSON_STRUCT(user, USER_FIELDS)
+
+struct user u = { .id = 42, .name = "Zoe", .tags = tags, .n_tags = 2, .orders = orders, .n_orders = 1 };
+ioxd_json j = ioxd_json_reply(ctx);
+user_to_json(&j, &u);                                 /* {"id":42,"name":"Zoe","tags":[...],"orders":[{...}]} */
+

SEE ALSO

+

ioxd_config(3), ioxd_http(3), ioxd_router(3), ioxd_slice(3), ioxd_pipe(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_JSON(3)
+
+ + diff --git a/manual/ioxd_pipe.html b/manual/ioxd_pipe.html new file mode 100644 index 0000000..40795fd --- /dev/null +++ b/manual/ioxd_pipe.html @@ -0,0 +1,101 @@ + + + + + +ioxd_pipe(3) - libioxd manual + + + + +
+
IOXD_PIPE(3)libioxd Programmer's ManualIOXD_PIPE(3)
+

NAME

+

ioxd/pipe.h - a connection as a pipe: a reader over the bytes the kernel received and a writer over a slab, for handlers of protocols other than HTTP.

+

SYNOPSIS

+
#include <ioxd.h>
+
+typedef struct ioxd_pipe ioxd_pipe;
+typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe);
+int ioxd_run_pipes(int workers, ioxd_pipe_handler fn);
+#define IOXD_PIPE_GONE (-1)
+#define IOXD_PIPE_FULL (-2)
+int         ioxd_pipe_read   (ioxd_pipe *pipe, ioxd_slice *live);
+void        ioxd_pipe_examine(ioxd_pipe *pipe, size_t n);
+void        ioxd_pipe_drop   (ioxd_pipe *pipe, size_t n);
+const char *ioxd_pipe_keep   (ioxd_pipe *pipe, size_t n);
+void        ioxd_pipe_release(ioxd_pipe *pipe);
+int         ioxd_pipe_copy   (ioxd_pipe *pipe, void *dst, size_t n);
+void  *ioxd_pipe_reserve(ioxd_pipe *pipe, size_t n);
+void   ioxd_pipe_advance(ioxd_pipe *pipe, size_t n);
+int    ioxd_pipe_write  (ioxd_pipe *pipe, const void *data, size_t n);
+int    ioxd_pipe_flush  (ioxd_pipe *pipe);
+int    ioxd_pipe_send   (ioxd_pipe *pipe, const void *data, size_t n);
+

DESCRIPTION

+

pipes

+
+
+typedef struct ioxd_pipe ioxd_pipe;
+typedef void (*ioxd_pipe_handler)(ioxd_pipe *pipe);
+int ioxd_run_pipes(int workers, ioxd_pipe_handler fn);
+
+

A connection as a pipe: a reader over the bytes the kernel received and a writer over a slab. Every call that must wait suspends the connection's coroutine, and the worker's loop resumes it on the completion, so a handler reads and writes in straight-line code. The HTTP engine is one such handler; ioxd_run_pipes runs one of yours on raw TCP connections instead.

+
+
ioxd_run_pipes
like ioxd_run, over the ports ioxd_bind bound, without HTTP
+
+
+
+
+#define IOXD_PIPE_GONE (-1)
+#define IOXD_PIPE_FULL (-2)
+int         ioxd_pipe_read   (ioxd_pipe *pipe, ioxd_slice *live);
+void        ioxd_pipe_examine(ioxd_pipe *pipe, size_t n);
+void        ioxd_pipe_drop   (ioxd_pipe *pipe, size_t n);
+const char *ioxd_pipe_keep   (ioxd_pipe *pipe, size_t n);
+void        ioxd_pipe_release(ioxd_pipe *pipe);
+int         ioxd_pipe_copy   (ioxd_pipe *pipe, void *dst, size_t n);
+
+

Reading. The live bytes are the ones received and not yet consumed, always handed out as one contiguous span - in place in the kernel's buffer when they lie within one. read returns 1 with them once some are unexamined, otherwise it waits for more; examine says how many were looked at without being consumed, so the next read waits for more rather than returning the same bytes; drop consumes (never more than is live); keep consumes but leaves the bytes where they are, contiguous with earlier kept bytes and valid until release - it returns where they are, or NULL when they would not fit the pipe's buffer (the pipe is then FULL) or n is more than is live; copy is the plain read into your own buffer. read and copy return 0 at the end of input, IOXD_PIPE_GONE on a dead peer, IOXD_PIPE_FULL when kept plus live bytes would exceed the pipe's buffer (16 KB). A handler that returns with bytes still in the writer's slab has them sent before the connection closes.

+
+
+
+void  *ioxd_pipe_reserve(ioxd_pipe *pipe, size_t n);
+void   ioxd_pipe_advance(ioxd_pipe *pipe, size_t n);
+int    ioxd_pipe_write  (ioxd_pipe *pipe, const void *data, size_t n);
+int    ioxd_pipe_flush  (ioxd_pipe *pipe);
+int    ioxd_pipe_send   (ioxd_pipe *pipe, const void *data, size_t n);
+
+

Writing: a slab, sent on flush. reserve n bytes to write into directly and advance by what was written, or write to copy in; send is write then flush. -1 once the peer is gone.

+
+

EXAMPLES

+

A line echo server on raw TCP: read until a newline, answer, repeat:

+
static void echo(ioxd_pipe *pipe)
+{
+    for (;;) {
+        ioxd_slice live;
+        int rc = ioxd_pipe_read(pipe, &live);         /* one contiguous span, or waits */
+        if (rc <= 0)
+            return;                                   /* 0: the peer is done; <0: gone or FULL */
+        const char *nl = memchr(live.p, '\n', live.len);
+        if (!nl) {
+            ioxd_pipe_examine(pipe, live.len);        /* seen it all: the next read waits for more */
+            continue;
+        }
+        size_t n = (size_t)(nl - live.p) + 1;
+        if (ioxd_pipe_send(pipe, live.p, n) < 0)
+            return;
+        ioxd_pipe_drop(pipe, n);
+    }
+}
+
+int main(void)
+{
+    ioxd_bind(8100, NULL);
+    return ioxd_run_pipes(0, echo);
+}
+

SEE ALSO

+

ioxd_config(3), ioxd_http(3), ioxd_router(3), ioxd_slice(3), ioxd_json(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_PIPE(3)
+
+ + diff --git a/manual/ioxd_router.html b/manual/ioxd_router.html new file mode 100644 index 0000000..48a8d45 --- /dev/null +++ b/manual/ioxd_router.html @@ -0,0 +1,142 @@ + + + + + +ioxd_router(3) - libioxd manual + + + + +
+
IOXD_ROUTER(3)libioxd Programmer's ManualIOXD_ROUTER(3)
+

NAME

+

ioxd/router.h - groups, endpoints and middleware, and the same as a script.

+

SYNOPSIS

+
#include <ioxd.h>
+
+typedef struct ioxd_group    ioxd_group;
+typedef struct ioxd_endpoint ioxd_endpoint;
+ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix);
+void        ioxd_group_use(ioxd_group *group, ioxd_mw mw);
+ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn);
+void           ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw);
+static inline ioxd_endpoint *ioxd_get   (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_post  (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_put   (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn);
+void ioxd_use(ioxd_mw mw);
+void ioxd_default(ioxd_handler fn);
+#define IOXD_MAX_MW 16
+IOXD_GROUP(prefix, middleware...) { ... }
+IOXD_USE(middleware)
+IOXD_ROUTE(method, path, handler, middleware...)
+IOXD_GET(path, handler, middleware...)
+IOXD_POST(path, handler, middleware...)
+IOXD_PUT(path, handler, middleware...)
+IOXD_PATCH(path, handler, middleware...)
+IOXD_DELETE(path, handler, middleware...)
+IOXD_DEFAULT(handler)
+

DESCRIPTION

+

routing

+
+
+typedef struct ioxd_group    ioxd_group;
+typedef struct ioxd_endpoint ioxd_endpoint;
+ioxd_group *ioxd_group_new(ioxd_group *parent, const char *prefix);
+void        ioxd_group_use(ioxd_group *group, ioxd_mw mw);
+
+

Endpoints live in groups, and groups nest. A group is a path prefix plus middleware: an endpoint "/users" in a group "/api" under a group "/v1" answers at "/v1/api/users", wrapped by the middleware of every group above it, outermost first, then its own. NULL as the group is the root: no prefix, and the middleware given to ioxd_use. A prefix and what follows it are joined by a '/' when neither side brings one ("/api" and "users" is "/api/users"), and a repeated slash counts once.

+

Register everything before ioxd_run, from the main thread; methods, paths and prefixes are copied, so temporaries are fine, and anything registered once ioxd_run has started is ignored with a line on stderr. ioxd_run resolves it once: every endpoint's full path into a segment tree and its middleware into one flat chain, which the workers then share read-only. A request costs one walk down the tree - no scan, no regex - and one call through its chain.

+
+
ioxd_group_new
"/api"; "" for middleware only
+
ioxd_group_use
wraps everything below it
+
+
+
+
+ioxd_endpoint *ioxd_route(ioxd_group *group, const char *method, const char *path, ioxd_handler fn);
+void           ioxd_endpoint_use(ioxd_endpoint *endpoint, ioxd_mw mw);
+
+

An endpoint: method matched exactly, except that HEAD is answered by the GET of a path that has no HEAD of its own; path matched by segment below the group's prefix, with :name captures ("/users/:id") landing in req.route_params. A static segment beats a capture at any depth, and a static path that lacks the method falls through to a capture route that has it. A trailing slash is tolerated. Segments are matched as they arrive on the wire, so an escape in a static segment does not match it, but a captured value is handed over percent-decoded ("/users/a%2Fb" captures "a/b") - raw in the rare case that it does not fit IOXD_ROUTE_ARENA.

+
+
ioxd_endpoint_use
wraps this one only
+
+
+
+
+static inline ioxd_endpoint *ioxd_get   (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_post  (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_put   (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_patch (ioxd_group *g, const char *path, ioxd_handler fn);
+static inline ioxd_endpoint *ioxd_delete(ioxd_group *g, const char *path, ioxd_handler fn);
+
+

The verbs, for short: ioxd_get(api, "/users/:id", user).

+
+
+
+void ioxd_use(ioxd_mw mw);
+
+

Root middleware: every request, the fallbacks included.

+
+
+
+void ioxd_default(ioxd_handler fn);
+
+

The fallback when no path matches (a built-in 404 by default). A path that matches without the method gets a built-in 405 whose allow header lists every method that path has, on a capture route too. Both run behind the root's middleware only, so that allow header names methods a group's own middleware would otherwise have gated.

+
+

the same, as a script

+
+
+#define IOXD_MAX_MW 16
+
+

Registration as a block-structured script: a current group, which the block after IOXD_GROUP sets (the root outside any block), endpoints registered into it, with their own middleware listed after the handler, and IOXD_USE adding middleware to it - so a group's middleware is either listed after its prefix or added with IOXD_USE inside its block. Plain functions underneath, so everything is type-checked; a group's block runs exactly once, and leaving it early - break, return, goto - still closes the group.

+
IOXD_USE(log);
+IOXD_GET("/", home);
+IOXD_GROUP("/api", api_header) {
+    IOXD_GET("/ping", ping);
+    IOXD_GROUP("/admin", require_token) {
+        IOXD_GET("/stats", stats, timing);
+    }
+}
+
+
IOXD_MAX_MW
middleware per group and per endpoint
+
+
+
+
+IOXD_GROUP(prefix, middleware...) { ... }
+IOXD_USE(middleware)
+IOXD_ROUTE(method, path, handler, middleware...)
+IOXD_GET(path, handler, middleware...)
+IOXD_POST(path, handler, middleware...)
+IOXD_PUT(path, handler, middleware...)
+IOXD_PATCH(path, handler, middleware...)
+IOXD_DELETE(path, handler, middleware...)
+IOXD_DEFAULT(handler)
+
+

A break, a return or a goto out of the block skips the loop's increment, so where the compiler has __attribute__((cleanup)) the pop is hung on the block's variable and runs on every way out; a block that ended on its own has already popped and nulled it. Elsewhere the plain form stands, and a group still open at ioxd_run is reported.

+
+

EXAMPLES

+

The same registrations as calls and as a script:

+
ioxd_group *api = ioxd_group_new(NULL, "/api");
+ioxd_group_use(api, auth);
+ioxd_get(api, "/users/:id", user);                    /* GET /api/users/:id, behind auth */
+ioxd_endpoint_use(ioxd_post(api, "/users", create), audit);
+
+IOXD_USE(log);                                        /* root middleware: every request */
+IOXD_GROUP("/api", auth) {
+    IOXD_GET ("/users/:id", user);
+    IOXD_POST("/users",     create, audit);
+    IOXD_GROUP("/admin", require_token) {
+        IOXD_GET("/stats", stats);
+    }
+}
+IOXD_DEFAULT(not_found);
+

SEE ALSO

+

ioxd_config(3), ioxd_http(3), ioxd_slice(3), ioxd_json(3), ioxd_pipe(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_ROUTER(3)
+
+ + diff --git a/manual/ioxd_slice.html b/manual/ioxd_slice.html new file mode 100644 index 0000000..31aecfc --- /dev/null +++ b/manual/ioxd_slice.html @@ -0,0 +1,108 @@ + + + + + +ioxd_slice(3) - libioxd manual + + + + +
+
IOXD_SLICE(3)libioxd Programmer's ManualIOXD_SLICE(3)
+

NAME

+

ioxd/slice.h - a slice, bytes with a length, and a key/value pair of them: what every request carries. Compare and convert them without copying; parse a query string or a form body.

+

SYNOPSIS

+
#include <ioxd.h>
+
+typedef struct { const char *p; size_t len; } ioxd_slice;
+typedef struct { ioxd_slice key, value; } ioxd_kv;
+bool       ioxd_slice_eq         (ioxd_slice s, const char *cstr);
+bool       ioxd_slice_eq_ci      (ioxd_slice s, const char *cstr);
+bool       ioxd_slice_starts_with(ioxd_slice s, const char *prefix);
+bool       ioxd_slice_ends_with  (ioxd_slice s, const char *suffix);
+ioxd_slice ioxd_slice_trim       (ioxd_slice s);
+bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap);
+bool ioxd_to_int   (ioxd_slice s, int      *out);
+bool ioxd_to_i64   (ioxd_slice s, int64_t  *out);
+bool ioxd_to_u64   (ioxd_slice s, uint64_t *out);
+bool ioxd_to_double(ioxd_slice s, double   *out);
+bool ioxd_to_bool  (ioxd_slice s, bool     *out);
+size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap, bool *truncated);
+

DESCRIPTION

+
+
+typedef struct { const char *p; size_t len; } ioxd_slice;
+
+

A slice: pointer + length, the C span. Not NUL-terminated.

+
+
+
+typedef struct { ioxd_slice key, value; } ioxd_kv;
+
+

One key/value pair of slices: a header, a query parameter, a route parameter.

+
+

slices

+
+
+bool       ioxd_slice_eq         (ioxd_slice s, const char *cstr);
+bool       ioxd_slice_eq_ci      (ioxd_slice s, const char *cstr);
+bool       ioxd_slice_starts_with(ioxd_slice s, const char *prefix);
+bool       ioxd_slice_ends_with  (ioxd_slice s, const char *suffix);
+ioxd_slice ioxd_slice_trim       (ioxd_slice s);
+
+

Everything a request carries is a slice: bytes with a length, not NUL-terminated, valid until the handler returns. These compare and convert one without copying it.

+
+
ioxd_slice_eq
exact
+
ioxd_slice_eq_ci
ASCII case-insensitive
+
ioxd_slice_trim
no leading/trailing space, tab, CR, LF
+
+
+
+
+bool ioxd_cstr(ioxd_slice s, char *buf, size_t cap);
+
+

A NUL-terminated copy in buf, for whatever wants a C string. False when it did not fit: buf then holds what fit, still terminated (cap 0 writes nothing) - and false when the slice holds a NUL of its own, which would end the C string early ("secret.txt%00.png" is not a PNG).

+
+
+
+bool ioxd_to_int   (ioxd_slice s, int      *out);
+bool ioxd_to_i64   (ioxd_slice s, int64_t  *out);
+bool ioxd_to_u64   (ioxd_slice s, uint64_t *out);
+bool ioxd_to_double(ioxd_slice s, double   *out);
+bool ioxd_to_bool  (ioxd_slice s, bool     *out);
+
+

Conversions. The whole slice must be the value - nothing around it, nothing after it - and a number that does not fit the type fails. On failure *out is left alone and false comes back, so "0" and "not a number" cannot be confused. Integers: an optional '-' and decimal digits. Doubles: also a fraction and an exponent ("2.5", ".5", "1e-3"); never inf, nan or hex; too large fails, too small rounds towards zero. Booleans: true/false, 1/0, yes/no, on/off, any case.

+
+
+
+size_t ioxd_kv_parse(const char *text, size_t len, ioxd_kv *out, size_t cap, char *arena, size_t arena_cap,
+                     bool *truncated);
+
+

Parse "k=v&k2=v2" - a query string, a form body - into out, up to cap pairs. Keys and values that need it ('+', %XX) are decoded into arena and point there; the rest are views of s. A malformed %XX and %00 stay as written. Returns the pair count; *truncated (may be NULL) is set when a pair was left out - past cap, or not fitting the arena - so the caller can refuse the request rather than act on part of it. Every pair is returned, duplicates included, in order: pick a policy (first or last) and keep to it.

+
+

EXAMPLES

+

Strict conversions: the whole slice is the value, or the call fails and *out is untouched:

+
int64_t id;
+double  price;
+bool    on;
+if (!ioxd_to_i64(ctx->req.route_params[0].value, &id))     /* "42", "-7"; not "42x", not " 42" */
+    ...
+if (ioxd_to_double(v, &price) && ioxd_to_bool(w, &on))      /* "2.5", "1e-3"; "yes", "off" */
+    ...
+

A form body parsed like a query string:

+
ioxd_slice body = ioxd_body_all(ctx);
+ioxd_kv    form[8];
+char       arena[512];
+bool       truncated;
+size_t n = ioxd_kv_parse(body.p, body.len, form, 8, arena, sizeof arena, &truncated);
+if (truncated) { ctx->res.status = 400; return; }        /* never act on part of it */
+for (size_t i = 0; i < n; i++)
+    if (ioxd_slice_eq(form[i].key, "name"))
+        ioxd_printf(ctx, "hello %.*s\n", (int)form[i].value.len, form[i].value.p);
+

SEE ALSO

+

ioxd_config(3), ioxd_http(3), ioxd_router(3), ioxd_json(3), ioxd_pipe(3), ioxd_tls(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_SLICE(3)
+
+ + diff --git a/manual/ioxd_tls.html b/manual/ioxd_tls.html new file mode 100644 index 0000000..e2e4d00 --- /dev/null +++ b/manual/ioxd_tls.html @@ -0,0 +1,54 @@ + + + + + +ioxd_tls(3) - libioxd manual + + + + +
+
IOXD_TLS(3)libioxd Programmer's ManualIOXD_TLS(3)
+

NAME

+

ioxd/tls.h - TLS 1.3, terminated in the kernel after an OpenSSL handshake (TLS.md): a store of certificates to listen with.

+

SYNOPSIS

+
#include <ioxd.h>
+
+ioxd_certs *ioxd_certs_load(const char *dir);
+int ioxd_certs_reload(ioxd_certs *certs);
+void ioxd_certs_free(ioxd_certs *certs);
+

DESCRIPTION

+
+
+ioxd_certs *ioxd_certs_load(const char *dir);
+
+

A store from a directory: <dir>/<host>/cert.pem (the chain) and key.pem for each hostname, `default` for no SNI or no match, `_.example.com` for *.example.com. `default` is required - without it nothing can answer a name we do not have. NULL, with the reason on stderr, when nothing loads or the build has no TLS. Then: ioxd_bind(port, store).

+
+
+
+int ioxd_certs_reload(ioxd_certs *certs);
+
+

Read the directory again and switch to what it holds. A host that fails to load - unreadable, mismatched, not valid yet, expired - keeps its old certificate, and the host answering for unmatched SNI keeps answering. Safe while serving: handshakes in flight finish on the table they started with, and reloads serialise against each other. 0, or -1 when nothing could be loaded at all, in which case what was serving still is.

+
+
+
+void ioxd_certs_free(ioxd_certs *certs);
+
+

Give the store back: its certificates and the store itself, once the last handshake holding a table of it has finished. Not while a listener still uses it - every TLS connection takes a reference through the store - so this is for a store that was never listened on, or for after ioxd_run has returned. NULL is a no-op.

+
+

EXAMPLES

+

A TLS port beside a plain one; the files rotated, then reloaded:

+
ioxd_certs *certs = ioxd_certs_load("/etc/ioxd/certs");   /* <dir>/<host>/cert.pem and key.pem; `default` required */
+if (!certs)
+    return 1;
+ioxd_bind(8080, NULL);
+ioxd_bind(8443, certs);
+/* ... later, after new files were written: */
+ioxd_certs_reload(certs);                               /* a host that fails keeps its old certificate */
+

SEE ALSO

+

ioxd_config(3), ioxd_http(3), ioxd_router(3), ioxd_slice(3), ioxd_json(3), ioxd_pipe(3), ioxd(7)

+
libioxd 0.1.02026-09-09IOXD_TLS(3)
+
+ + diff --git a/manual/style.css b/manual/style.css new file mode 100644 index 0000000..7691c67 --- /dev/null +++ b/manual/style.css @@ -0,0 +1,46 @@ +/* The manual's look: a man page, as man7.org renders one - monospace, sections in capitals at the + * margin, the text indented under them - with links, anchors and a light nav bar on top. */ +:root { + --paper: #ffffff; --ink: #111111; --dim: #555555; --rule: #d8d8d8; --link: #1a3fbf; --code: #f4f4f4; +} +@media (prefers-color-scheme: dark) { + :root { --paper: #111213; --ink: #e6e6e6; --dim: #a0a0a0; --rule: #333; --link: #7da2ff; --code: #1c1e21; } +} +html { background: var(--paper); } +body { + margin: 0; color: var(--ink); background: var(--paper); + font: 14px/1.5 "DejaVu Sans Mono", "Liberation Mono", Menlo, Consolas, ui-monospace, monospace; +} +a { color: var(--link); text-decoration: none; } +a:hover { text-decoration: underline; } +.crumbs { padding: .5em 1.5em; border-bottom: 1px solid var(--rule); color: var(--dim); } +main { max-width: 100ch; margin: 0 auto; padding: 1em 1.5em 4em; } +.hdr, .ftr { display: flex; justify-content: space-between; font-weight: bold; } +.ftr { margin-top: 3em; font-weight: normal; color: var(--dim); } +h1 { font-size: 1em; font-weight: bold; margin: 1.4em 0 .5em; } +h2 { font-size: 1em; font-weight: bold; margin: 1.8em 0 .5em; letter-spacing: .02em; } +h3 { font-size: 1em; font-weight: bold; margin: 1.4em 0 .4em 3ch; } +h3::before { content: ""; } +main > p, .entry, dl, pre, .text { margin-left: 7ch; } +main > pre.ex, main > pre.syn { margin-left: 7ch; } +p { margin: .5em 0; } +pre { margin: .5em 0; white-space: pre-wrap; word-break: break-word; } +pre.syn { padding: .6em 1em; background: var(--code); border-left: 3px solid var(--rule); } +pre.decl { font-weight: bold; margin: 1.2em 0 .3em; } +pre.ex { padding: .6em 1em; background: var(--code); border-left: 3px solid var(--rule); } +.entry { margin-top: .4em; } +.entry .text { margin-left: 4ch; } +.entry .text pre.ex, .text pre.ex { margin-left: 0; } +dl.trail { margin: .3em 0 0 4ch; } +dl.trail dt { font-weight: bold; margin-top: .4em; } +dl.trail dd { margin: 0 0 0 4ch; color: var(--ink); } +dl.files dt { font-weight: bold; margin-top: .6em; } +dl.files dd { margin: 0 0 0 4ch; } +table { border-collapse: collapse; margin-left: 7ch; } +td, th { text-align: left; padding: .25em 1.5em .25em 0; vertical-align: top; } +th { font-weight: bold; } +.dim { color: var(--dim); } +@media (max-width: 700px) { + main > p, .entry, dl, pre, .text, table, h3 { margin-left: 1ch; } + .hdr span:nth-child(2), .ftr span:nth-child(2) { display: none; } +} From ce598e9e6aa42900d58c32d466a349704fc7459b Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:32:29 +0100 Subject: [PATCH 47/49] manual: no bytecode cache in the tree Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .gitignore | 1 + manual/__pycache__/build.cpython-312.pyc | Bin 42268 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 manual/__pycache__/build.cpython-312.pyc diff --git a/.gitignore b/.gitignore index cdb2a32..f0fe0e2 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ tests/ioxd-unit tests/ioxd-pipe-server tests/ioxd-router-test tests/certs/ +__pycache__/ diff --git a/manual/__pycache__/build.cpython-312.pyc b/manual/__pycache__/build.cpython-312.pyc deleted file mode 100644 index d039aa2fbdfe000c9e3d522d3c014263b6c9672f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42268 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 YqkSU$siEkh(fWHwF!M2PVrc&V0O3lVy8r+H From 117f54668fafa2d2fe0e09e1051f97740961add2 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:35:24 +0100 Subject: [PATCH 48/49] GitHub Pages: the manual deployed by a workflow on every push Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- .github/workflows/pages.yml | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..eaa24ef --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,39 @@ +# The manual, on GitHub Pages: built from the headers by manual/build.py on every push, and +# deployed with the Pages actions (the repository's Pages source is "GitHub Actions"). +name: manual + +on: + push: + branches: [main, streams] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/configure-pages@v5 + - name: build the manual from the headers + run: python3 manual/build.py + - uses: actions/upload-pages-artifact@v3 + with: + path: manual + + deploy: + needs: build + runs-on: ubuntu-24.04 + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 From 5cb99e193b103861169aa73f462c19eb412fe3a2 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Wed, 9 Sep 2026 12:37:22 +0100 Subject: [PATCH 49/49] README: the manual's address Claude-Session: https://claude.ai/code/session_013wYnJvEFUjKEpGLkyTLt9P --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e3e3cc..30988a9 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ runtime works is in [`ARCHITECTURE.md`](ARCHITECTURE.md). ## Manual -The API is documented as man pages under [`manual/`](manual/index.html): one page per public header +The API is documented as man pages at [mda2av.github.io/libioxd](https://mda2av.github.io/libioxd/) (the `manual/` directory, deployed by a workflow on every push): one page per public header (`ioxd_http(3)`, `ioxd_router(3)`, ...), generated from the headers themselves by `make manual`, an -overview in `ioxd(7)`, and every public name in one list. Open `manual/index.html` in a browser. +overview in `ioxd(7)`, and every public name in one list; `manual/index.html` is the same site, offline. ## Build

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%0DYqa=$P^2b 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