diff options
| -rw-r--r-- | Makefile | 32 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | docs/research/093-connectionless-link.md | 2 | ||||
| -rw-r--r-- | docs/research/096-per-delivery-cpu.md | 2 | ||||
| -rw-r--r-- | link/crypto-openssl.c (renamed from serve/crypto-openssl.c) | 2 | ||||
| -rw-r--r-- | link/crypto.c (renamed from serve/crypto.c) | 4 | ||||
| -rw-r--r-- | link/crypto.h (renamed from serve/crypto.h) | 8 | ||||
| -rw-r--r-- | link/link.c (renamed from serve/link.c) | 2 | ||||
| -rw-r--r-- | link/link.h (renamed from serve/link.h) | 0 | ||||
| -rw-r--r-- | link/seal.h (renamed from serve/seal.h) | 4 | ||||
| -rw-r--r-- | link/tls.h (renamed from serve/tls.h) | 2 | ||||
| -rw-r--r-- | research/experiments/019-idle-links/links.c | 4 | ||||
| -rw-r--r-- | research/experiments/019-idle-links/run.py | 11 | ||||
| -rw-r--r-- | serve/deliver.c | 2 | ||||
| -rw-r--r-- | serve/deliver.h | 2 | ||||
| -rw-r--r-- | serve/serve.c | 2 |
16 files changed, 47 insertions, 35 deletions
@@ -10,24 +10,29 @@ BUILD ?= build # states as drafts; state.h and store.h are what it asks of storage. # store/ the tree store (one file; commits are one contiguous write and one # sync; formats PURETRE3 and PUREREC1). -# serve/ pure-serve: the HTTP host, outbound delivery, JSON in place; with -# pure-crypto.so beside it, OpenSSL's part (TLS to https receivers, -# sealed sends), mapped only by a server that uses one. +# link/ links without connections (UDP, sealed, no handshake) and the +# crypto they and sealed sends use; with pure-crypto.so beside it, +# OpenSSL's part (TLS to https receivers, sealing), mapped only by a +# process that uses one. +# serve/ pure-serve: the HTTP host, outbound delivery, JSON in place. # cli/ command-line hosts. # libpure.a is the app model with the tree store: what a host embeds (Vega's -# surfaces link it). prototypes/ keeps the earlier document runtime (000-077). +# surfaces link it); libpure-link.a is the links with the crypto loader. +# prototypes/ keeps the earlier document runtime (000-077). # Unit tests sit by their part (core/test-module.c, store/test-tree-store.c, # store/test-log.c, serve/test-message-json.c); # tests/check.py checks the hosts end to end. INCLUDES = -Icore MODEL = core/module.c core/module-list.c core/module-save.c core/module-text.c core/module-store.c core/flow.c STORE = store/store-tree.c store/store-log.c -SERVE = serve/serve.c serve/deliver.c serve/link.c serve/message-json.c serve/crypto.c -HEADERS = $(wildcard core/*.h) $(wildcard serve/*.h) $(wildcard store/*.h) +LINK = link/link.c link/crypto.c +SERVE = serve/serve.c serve/deliver.c serve/message-json.c +HEADERS = $(wildcard core/*.h) $(wildcard link/*.h) $(wildcard serve/*.h) $(wildcard store/*.h) OBJECTS = $(patsubst %.c,$(BUILD)/obj/%.o,$(MODEL) $(STORE)) +LINK_OBJECTS = $(patsubst %.c,$(BUILD)/obj/%.o,$(LINK)) .PHONY: all check -all: $(BUILD)/libpure.a $(BUILD)/pure-serve $(BUILD)/pure-crypto.so $(BUILD)/pure-run $(BUILD)/pure-edit-module +all: $(BUILD)/libpure.a $(BUILD)/libpure-link.a $(BUILD)/pure-serve $(BUILD)/pure-crypto.so $(BUILD)/pure-run $(BUILD)/pure-edit-module $(BUILD)/obj/%.o: %.c $(HEADERS) @mkdir -p $(dir $@) @@ -37,15 +42,20 @@ $(BUILD)/libpure.a: $(OBJECTS) rm -f $@ $(AR) rcs $@ $^ +$(BUILD)/libpure-link.a: $(LINK_OBJECTS) + rm -f $@ + $(AR) rcs $@ $^ + # The runtime's tickets and budgets, with effects completed off the owner thread. # It links after the library, last as it always was, so code keeps its place. # The app model's functions are exported for a surface it maps (serve/surface.h). -$(BUILD)/pure-serve: $(SERVE) core/runtime.c $(BUILD)/libpure.a $(HEADERS) - $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -Iserve -DPURE_ASYNC_EFFECTS $(SERVE) $(BUILD)/libpure.a core/runtime.c \ +$(BUILD)/pure-serve: $(SERVE) core/runtime.c $(BUILD)/libpure.a $(BUILD)/libpure-link.a $(HEADERS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -Ilink -Iserve -DPURE_ASYNC_EFFECTS $(SERVE) $(BUILD)/libpure-link.a \ + $(BUILD)/libpure.a core/runtime.c \ $(LDFLAGS) -Wl,--export-dynamic-symbol='pure_*' -lm -pthread $(LDLIBS) -o $@ -$(BUILD)/pure-crypto.so: serve/crypto-openssl.c $(HEADERS) - $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -Iserve -fPIC -shared serve/crypto-openssl.c $(LDFLAGS) -lssl -lcrypto \ +$(BUILD)/pure-crypto.so: link/crypto-openssl.c $(HEADERS) + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -shared link/crypto-openssl.c $(LDFLAGS) -lssl -lcrypto \ $(LDLIBS) -o $@ $(BUILD)/pure-run: cli/pure-run.c $(BUILD)/libpure.a $(HEADERS) @@ -36,7 +36,8 @@ The source follows the principle below, a small core with the rest selected arou |---|---|---| | `core/` | execution, ownership, limits and completion (`runtime.c`); the app model: modules verified before they run, events as transactions, states as drafts (`module*.c`); what the core asks of storage (`state.h`, `store.h`) | `build/libpure.a` (with the store) | | `store/` | the tree store: one file, a commit is one contiguous write and one sync (formats `PURETRE3`, `PUREREC1`) | in `libpure.a` | -| `serve/` | `pure-serve`: the HTTP host, outbound delivery, JSON read in place, surfaces for people run in the node ([010](docs/design/010-surfaces.md)); OpenSSL's part (TLS to https receivers, sealed sends) apart, mapped only by a server that uses one | `build/pure-serve`, `build/pure-crypto.so` | +| `link/` | links without connections: saved sends over UDP, sealed with the two nodes' keys, no handshake ([011](docs/design/011-pure-transport.md)); the crypto they and sealed sends use, OpenSSL's part apart, mapped only by a process that uses one | `build/libpure-link.a`, `build/pure-crypto.so` | +| `serve/` | `pure-serve`: the HTTP host, outbound delivery, JSON read in place, surfaces for people run in the node ([010](docs/design/010-surfaces.md)) | `build/pure-serve` | | `cli/` | command-line hosts | `build/pure-run`, `build/pure-edit-module` | | `prototypes/` | the earlier document runtime (000-077), built against `core/` and `store/` | `make -C prototypes/connections` | | `tests/` | the hosts checked end to end, with apps built by aup (the sibling checkout) | `make check` | diff --git a/docs/research/093-connectionless-link.md b/docs/research/093-connectionless-link.md index ad36e47..da2a979 100644 --- a/docs/research/093-connectionless-link.md +++ b/docs/research/093-connectionless-link.md @@ -34,7 +34,7 @@ - 새로 저장하는 전송 상태는 없다. 011이 적은 "링크의 행(약 100 B)"도 필요 없었다. 첫 에폭에서 링크가 저장소에 더하는 것은 0 바이트다. -**보내는 쪽([serve/link.c](../../serve/link.c)의 `PureLink`).** +**보내는 쪽([link/link.c](../../link/link.c)의 `PureLink`).** - 전달선과 같은 자리에 붙는다. `--send OUTPUT=pure://host:port/INPUT`로 열고, 받는 노드의 키는 `--seal`로 준다. - outbox의 기록을 패킷에 채워 보낸다. 한 패킷에 여러 기록이 들고, 큰 기록은 1000 B 조각으로 나눈다. diff --git a/docs/research/096-per-delivery-cpu.md b/docs/research/096-per-delivery-cpu.md index e038a7c..df2718c 100644 --- a/docs/research/096-per-delivery-cpu.md +++ b/docs/research/096-per-delivery-cpu.md @@ -38,7 +38,7 @@ pure-serve 두 대를 잇고, 보내는 앱에 주문 2만 건을 쌓은 뒤 받 | 커밋 | 무엇 | 기록당 CPU | |---|---|---:| | 처음(pure-serve, 2만 건) | | 3.5 µs | -| [0f365f0](../../serve/link.c) | 쌓인 것을 훑지 않는다. GSO 묶음과 recvmmsg | 1.0 µs(pure-serve) | +| [0f365f0](../../link/link.c) | 쌓인 것을 훑지 않는다. GSO 묶음과 recvmmsg | 1.0 µs(pure-serve) | | e19aa30 | 링크 스레드를 잠들었을 때만 한 번 깨운다 | 0.49 µs | | 54035fe | 작은 기록을 RECORDS 프레임에 담는다(머리 19 B → 1–2 B) | 0.447 µs | | 803626a | 받을 때 UDP GRO, 리스너의 AES 키는 run이 바뀔 때만 넣는다 | 0.394 µs | diff --git a/serve/crypto-openssl.c b/link/crypto-openssl.c index 67ce5fd..6bdf6fb 100644 --- a/serve/crypto-openssl.c +++ b/link/crypto-openssl.c @@ -1,5 +1,5 @@ #define _GNU_SOURCE -/* pure-crypto.so: what pure-serve asks of OpenSSL (serve/crypto.h), mapped +/* pure-crypto.so: what pure-serve asks of OpenSSL (link/crypto.h), mapped * only when a server seals, opens a seal or reaches an https receiver. It * exports one table, pure_crypto. */ #include "crypto.h" diff --git a/serve/crypto.c b/link/crypto.c index da63b37..2fa7d44 100644 --- a/serve/crypto.c +++ b/link/crypto.c @@ -1,6 +1,6 @@ #define _GNU_SOURCE -/* Sealing and TLS for pure-serve (serve/seal.h, serve/tls.h), by way of - * pure-crypto.so (serve/crypto.h): mapped, and OpenSSL with it, the first +/* Sealing and TLS for pure-serve (link/seal.h, link/tls.h), by way of + * pure-crypto.so (link/crypto.h): mapped, and OpenSSL with it, the first * time a server needs it. What needs no OpenSSL (a key's hex, the suite * this machine seals with) is here. */ #include "crypto.h" diff --git a/serve/crypto.h b/link/crypto.h index 53e9c2c..53ac785 100644 --- a/serve/crypto.h +++ b/link/crypto.h @@ -4,9 +4,9 @@ #include "tls.h" /* What pure-serve asks of OpenSSL, as the table pure-crypto.so exports - * (serve/crypto-openssl.c). pure-serve maps it, and OpenSSL with it, the + * (link/crypto-openssl.c). pure-serve maps it, and OpenSSL with it, the * first time a server seals, opens a seal or connects to an https receiver - * (serve/crypto.c): one that does none of these maps no OpenSSL, 2.3 MiB + * (link/crypto.c): one that does none of these maps no OpenSSL, 2.3 MiB * less resident and 0.6 MiB less of its own. */ enum { PURE_CRYPTO_VERSION = 4 }; @@ -20,7 +20,7 @@ typedef struct { int (*tls_read)(PureTls *, void *bytes, int size); int (*tls_write)(PureTls *, const void *bytes, int size); void (*tls_close)(PureTls *); - /* Sealing, as serve/seal.h says; a sender's sessions in the suite named. */ + /* Sealing, as link/seal.h says; a sender's sessions in the suite named. */ PureSealKey *(*seal_key)(const char *path, char public_hex[2 * PURE_SEAL_KEY + 1], char *error, size_t size); void (*seal_key_free)(PureSealKey *); PureSealer *(*sealer)(const char *suite, const unsigned char peer[PURE_SEAL_KEY], const PureSealKey *own, @@ -33,7 +33,7 @@ typedef struct { bool (*unseal)(PureOpener *, uint64_t n, const char *aad, const unsigned char *sealed, size_t size, unsigned char *plain); void (*opener_free)(PureOpener *); - /* Links, as serve/seal.h says. */ + /* Links, as link/seal.h says. */ bool (*link_secret)(const PureSealKey *, const unsigned char peer[PURE_SEAL_KEY], unsigned char out[32]); bool (*link_derive)(const unsigned char secret[32], const unsigned char *info, size_t info_size, unsigned char *out, size_t out_size); diff --git a/serve/link.c b/link/link.c index e2da052..9c6794b 100644 --- a/serve/link.c +++ b/link/link.c @@ -1,5 +1,5 @@ #define _GNU_SOURCE -/* Links without connections (serve/link.h, docs/design/011-pure-transport.md). */ +/* Links without connections (link/link.h, docs/design/011-pure-transport.md). */ #include "link.h" #include <arpa/inet.h> #include <errno.h> diff --git a/serve/link.h b/link/link.h index 83cc645..83cc645 100644 --- a/serve/link.h +++ b/link/link.h diff --git a/serve/seal.h b/link/seal.h index 18e3e5f..9245f25 100644 --- a/serve/seal.h +++ b/link/seal.h @@ -13,7 +13,7 @@ * (one encapsulation) and numbers its seals in it; a receiver opens a * session once and then each seal by its number. A private key lives in * OpenSSL's secure heap: locked in memory, out of core dumps, cleared when - * freed. OpenSSL comes with pure-crypto.so (serve/crypto.c), mapped the + * freed. OpenSSL comes with pure-crypto.so (link/crypto.c), mapped the * first time a key is read or a session made. */ enum { PURE_SEAL_KEY = 32, PURE_SEAL_OVERHEAD = 16 }; /* a public key; a seal's tag */ @@ -54,7 +54,7 @@ bool pure_unseal(PureOpener *, uint64_t n, const char *aad, const unsigned char unsigned char *plain); void pure_opener_free(PureOpener *); -/* Links (serve/link.h): the secret two nodes share (X25519 of this node's +/* Links (link/link.h): the secret two nodes share (X25519 of this node's * private key and the other's public key: the same on both sides, and * never all zeros), keys from it (HKDF-SHA256 with the info given), and * AES-128-GCM under such a key with the nonce the caller gives (sealing may @@ -3,7 +3,7 @@ #include <stdbool.h> #include <stddef.h> -/* TLS to https receivers (serve/crypto.c): one client context, verifying a +/* TLS to https receivers (link/crypto.c): one client context, verifying a * receiver's certificate against the system's CAs or ca_file, and its name. */ typedef struct PureTls PureTls; /* The context, made once; false with why in error when it cannot be. */ diff --git a/research/experiments/019-idle-links/links.c b/research/experiments/019-idle-links/links.c index 732429a..666ac29 100644 --- a/research/experiments/019-idle-links/links.c +++ b/research/experiments/019-idle-links/links.c @@ -1,7 +1,7 @@ #define _GNU_SOURCE /* Many senders to one Pure node over links without connections * (docs/design/011-pure-transport.md, M1). Written from the packet format in - * serve/link.h alone, with OpenSSL: a second implementation of it. + * link/link.h alone, with OpenSSL: a second implementation of it. * * links keys N FILE * N X25519 keys into FILE (each a private then a public half, 32 bytes @@ -111,7 +111,7 @@ static int keys(size_t n, const char *path) { return 0; } -/* ---- Keys of a link (serve/link.h): X25519, HKDF-SHA256, AES-128-GCM */ +/* ---- Keys of a link (link/link.h): X25519, HKDF-SHA256, AES-128-GCM */ static bool secret_of(const unsigned char own[2 * KEY], const unsigned char peer[KEY], unsigned char out[32]) { EVP_PKEY *mine = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, own, KEY); diff --git a/research/experiments/019-idle-links/run.py b/research/experiments/019-idle-links/run.py index 96a0cbc..d10cb3f 100644 --- a/research/experiments/019-idle-links/run.py +++ b/research/experiments/019-idle-links/run.py @@ -552,11 +552,12 @@ def main(): args = parser.parse_args() counts = [int(c) for c in args.counts.split(',')] if args.transport: - subprocess.run(['make', '-s', '-C', str(ROOT), 'build/libpure.a', 'build/pure-crypto.so'], check=True) - subprocess.run(['cc', '-O2', '-g', '-std=c17', '-Wall', '-Wextra', '-Werror', f'-I{ROOT}/core', f'-I{ROOT}/serve', - '-DPURE_ASYNC_EFFECTS', str(Path(__file__).parent / 'transport.c'), str(ROOT / 'serve/link.c'), - str(ROOT / 'serve/crypto.c'), str(ROOT / 'build/libpure.a'), '-lm', '-pthread', '-ldl', '-o', - str(ROOT / 'build/link-transport')], check=True) + subprocess.run(['make', '-s', '-C', str(ROOT), 'build/libpure.a', 'build/libpure-link.a', 'build/pure-crypto.so'], + check=True) + subprocess.run(['cc', '-O2', '-g', '-std=c17', '-Wall', '-Wextra', '-Werror', f'-I{ROOT}/core', f'-I{ROOT}/link', + str(Path(__file__).parent / 'transport.c'), str(ROOT / 'build/libpure-link.a'), + str(ROOT / 'build/libpure.a'), '-lm', '-pthread', '-ldl', '-o', str(ROOT / 'build/link-transport')], + check=True) subprocess.run(['cargo', 'build', '--release', '--offline', '--quiet'], cwd=Path(__file__).parent / 'quic', check=True) with tempfile.TemporaryDirectory(prefix='pure-m5-', dir=args.store) as directory: work = Path(directory) diff --git a/serve/deliver.c b/serve/deliver.c index 05e7f21..b4d9e57 100644 --- a/serve/deliver.c +++ b/serve/deliver.c @@ -59,7 +59,7 @@ struct PureWire { }; /* TLS verifies a receiver's certificate against the system's CAs or the - * file pure_wire_trust named (serve/tls.h). */ + * file pure_wire_trust named (link/tls.h). */ static const char *tls_ca; void pure_wire_trust(const char *ca_file) { tls_ca = ca_file; } diff --git a/serve/deliver.h b/serve/deliver.h index f7427c5..71cc38e 100644 --- a/serve/deliver.h +++ b/serve/deliver.h @@ -24,7 +24,7 @@ void pure_wire_trust(const char *ca_file); PureWire *pure_wire_open(const PureModule *m, const char *output, const char *url, const char *source, char *error, size_t size); uint32_t pure_wire_output(const PureWire *); -/* Seal the wire's sends to the receiver's public key (serve/seal.h), +/* Seal the wire's sends to the receiver's public key (link/seal.h), * authenticated by own (whose public half is from) when given: each * request's body, bound to its source, first number and count, goes with * X-Pure-Seal naming the suite, the session, the seal's number and the diff --git a/serve/serve.c b/serve/serve.c index 93406fd..d89fb13 100644 --- a/serve/serve.c +++ b/serve/serve.c @@ -162,7 +162,7 @@ typedef struct { RouteKind route; PureFault fault; /* a failed event's */ const char *type; /* a view's content type */ - struct LinkJob *link; /* records a link delivered (serve/link.h) */ + struct LinkJob *link; /* records a link delivered (link/link.h) */ uint64_t heard; /* then the source's last number heard after them */ bool gap; /* and whether they stopped at a gap */ } Applied; |
