mirror of
https://github.com/logos-storage/nim-libplum.git
synced 2026-06-07 01:29:27 +00:00
42 lines
1.9 KiB
Markdown
42 lines
1.9 KiB
Markdown
# nim-libplum
|
|
|
|
Nim binding for libplum (PCP / NAT-PMP / UPnP-IGD port mapping), with a
|
|
chronos-based async wrapper.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
git submodule update --init # vendor/libplum is required for everything
|
|
nimble test # builds vendor/libplum.a via cmake, then runs unit tests
|
|
nimble testIntegration # miniupnpd integration tests in Docker/Podman (NET_ADMIN)
|
|
nimble format # nph on libplum/ and tests/
|
|
```
|
|
|
|
Debug env vars: `LIBPLUM_VERBOSE=1`, `TEST_VERBOSE=1`, `MINIUPNPD_VERBOSE=1`.
|
|
|
|
## Architecture
|
|
|
|
- `libplum/libplum.nim` — raw C bindings (importc), no logic
|
|
- `libplum/plum.nim` — public API: bridges libplum's C callback thread to chronos
|
|
- `tests/test_plum.nim` — unit suite + integration suites gated by `-d:miniupnp_protocol`
|
|
- `api.md` — user-facing API doc, keep in sync with plum.nim
|
|
- `vendor/libplum` — git submodule, built statically by nimble tasks
|
|
|
|
## Threading invariants (critical)
|
|
|
|
- `mappingCallback` runs on libplum's internal C thread, wrapped in
|
|
`foreignThreadGc`; it must stay `raises: []` and only touch thread-safe state
|
|
- The mapping signal fires exactly once (first of SUCCESS/FAILURE/DESTROYED
|
|
via `resolved.exchange`); `createMapping` owns it and closes it on the
|
|
chronos loop thread after consuming that fire. Never call
|
|
`ThreadSignalPtr.close()` from the C thread: close() unregisters the fd
|
|
from the *calling* thread's dispatcher
|
|
- `MappingHandle` is pinned with `GC_ref` while libplum holds `user_ptr`;
|
|
unpinned only in the DESTROYED callback
|
|
- `activeMappings` is an `Atomic[int]` counting pinned handles; libplum is the source of truth for mapping state
|
|
(`hasMapping`)
|
|
- The wrapper relies on a libplum guarantee: DESTROYED fires exactly once for
|
|
every created mapping (explicit destroy, or `destroy_all_mappings` during
|
|
`plum_cleanup`, synchronously before it returns), verified in
|
|
`vendor/libplum/src/client.c`. Re-verify this when bumping the submodule
|