Merge pull request #6 from kc1awv/protocol_alignment

align protocol constants and update handling of HELLO/WELCOME messages
This commit is contained in:
Steve Miller
2025-12-31 16:05:30 -05:00
committed by GitHub
6 changed files with 535 additions and 150 deletions

View File

@@ -80,15 +80,22 @@ too large for the current Reticulum link MTU.
Mitigations: Mitigations:
- Keep `greeting` reasonably short if you want it to appear inside `WELCOME`. - `WELCOME` sent by `rrcd` is intentionally minimal (hub name/version/caps).
- If `WELCOME` would exceed MTU, `rrcd` automatically sends a minimal `WELCOME` - The hub `greeting` is delivered after `WELCOME` via one or more `NOTICE`
and then delivers the full greeting as one or more `NOTICE` messages sized to messages chunked to fit the link MTU.
fit the link MTU.
## Compatibility ## Compatibility
`rrcd` implements the core RRC protocol as described in the RRC docs. `rrcd` implements the core RRC protocol as described in the RRC docs.
Protocol alignment notes (for implementers):
- `HELLO` and `WELCOME` bodies are CBOR maps with unsigned integer keys.
- Capabilities are carried in body key `2` as a CBOR map (not a bitmask). Keys
inside the capabilities map are unsigned integers; values are advisory.
- `WELCOME` is intentionally minimal (hub name/version/caps only). Any hub
greeting text is delivered after `WELCOME` via one or more `NOTICE` messages.
Extensions beyond core RRC will be documented in the Extensions section of this Extensions beyond core RRC will be documented in the Extensions section of this
README as they are added. README as they are added.
@@ -120,10 +127,10 @@ Wire-level extensions (backwards-compatible):
hint associated with `K_SRC` so clients can display a human-friendly hint associated with `K_SRC` so clients can display a human-friendly
nickname instead of only the sender identity hash. nickname instead of only the sender identity hash.
The hub learns this value from the client's `HELLO` body key The hub learns this value from the client's optional envelope nickname field
`B_HELLO_NICK = 0` and treats it as the authoritative nickname for that `K_NICK = 7` on inbound messages, and treats it as the authoritative nickname
link. Clients should treat `K_NICK` as optional and fall back to `K_SRC` for that link. Clients should treat `K_NICK` as optional and fall back to
when it is missing. `K_SRC` when it is missing.
Nicknames are advisory only; clients should treat them as display hints. Nicknames are advisory only; clients should treat them as display hints.
The hub may ignore, sanitize, replace, or omit them. The hub may ignore, sanitize, replace, or omit them.

View File

@@ -117,14 +117,12 @@ dest_name = "rrc.hub"
announce_on_start = true announce_on_start = true
announce_period_s = 0.0 announce_period_s = 0.0
# WELCOME message fields. # Hub identity fields.
hub_name = "rrc" hub_name = "rrc"
greeting = "" greeting = ""
# Note: Some Reticulum links have low MTU. If `greeting` is very long, the hub # Note: The hub greeting is delivered after WELCOME via one or more NOTICE
# may be unable to include it inside the initial WELCOME. In that case, rrcd # messages. NOTICE payloads are chunked as needed to fit the Link MTU.
# will send a minimal WELCOME and then deliver the greeting afterward via NOTICE
# messages.
# Operator / moderation # Operator / moderation
# #
@@ -296,7 +294,11 @@ def _build_arg_parser() -> argparse.ArgumentParser:
) )
p.add_argument("--hub-name", default=None, help="Hub name in WELCOME") p.add_argument("--hub-name", default=None, help="Hub name in WELCOME")
p.add_argument("--greeting", default=None, help="Greeting in WELCOME") p.add_argument(
"--greeting",
default=None,
help="Greeting delivered via NOTICE after WELCOME",
)
p.add_argument( p.add_argument(
"--include-joined-member-list", "--include-joined-member-list",
action="store_true", action="store_true",

View File

@@ -30,12 +30,19 @@ T_PONG = 31
T_ERROR = 40 T_ERROR = 40
# HELLO body keys # HELLO body keys
B_HELLO_NICK = 0 # Per spec: key assignments are fixed.
B_HELLO_NAME = 1 B_HELLO_NAME = 0
B_HELLO_VER = 2 B_HELLO_VER = 1
B_HELLO_CAPS = 3 B_HELLO_CAPS = 2
# Legacy / pre-spec implementations may have sent nick in HELLO body.
# Prefer the envelope-level nickname field (K_NICK=7) going forward.
B_HELLO_NICK_LEGACY = 64
# WELCOME body keys # WELCOME body keys
B_WELCOME_HUB = 0 B_WELCOME_HUB = 0
B_WELCOME_GREETING = 1 B_WELCOME_VER = 1
B_WELCOME_CAPS = 2 B_WELCOME_CAPS = 2
# Capabilities map keys (values are advisory). Keep these small and numeric.
CAP_RESOURCE_ENVELOPE = 0

View File

@@ -63,7 +63,9 @@ def configure_logging(
if bool(cfg.log_console): if bool(cfg.log_console):
handlers.append(logging.StreamHandler()) handlers.append(logging.StreamHandler())
log_file = _clean_optional_path(override_file) if override_file is not None else None log_file = (
_clean_optional_path(override_file) if override_file is not None else None
)
if log_file is None: if log_file is None:
log_file = _clean_optional_path(cfg.log_file) log_file = _clean_optional_path(cfg.log_file)

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import pytest import pytest
from rrcd.constants import ( from rrcd.constants import (
B_HELLO_NICK, B_HELLO_NICK_LEGACY,
K_BODY, K_BODY,
K_ID, K_ID,
K_NICK, K_NICK,
@@ -16,7 +16,7 @@ from rrcd.envelope import make_envelope, validate_envelope
def test_validate_accepts_make_envelope() -> None: def test_validate_accepts_make_envelope() -> None:
env = make_envelope(T_HELLO, src=b"peer", body={B_HELLO_NICK: "alice"}) env = make_envelope(T_HELLO, src=b"peer", body={B_HELLO_NICK_LEGACY: "alice"})
validate_envelope(env) validate_envelope(env)