aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/quic_server.py66
1 files changed, 14 insertions, 52 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/quic_server.py b/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
index e34153c..7b9d094 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
@@ -235,8 +235,14 @@ class _MNPServerProtocol(QuicConnectionProtocol):
self._do_index_sync_sync(stream_id)
elif mtype == MNP.FILE_REQUEST:
self._do_file_request_sync(stream_id, msg)
- elif mtype == MNP.CHAT_MESSAGE:
- self._do_chat_message_sync(stream_id, msg)
+ # No chat here. A message is sealed under a per-device subkey and
+ # signed by the device the *connection* proved it is, and this
+ # transport implements neither `device_hello` nor the envelope
+ # checks that go with it. Relaying one unchecked would put a
+ # plaintext row in the group's archive, which is the one thing chat
+ # encryption is for; an unimplemented type is logged and dropped
+ # instead, which is what every other unimplemented message here
+ # does.
elif mtype == MNP.PING:
# Liveness is transport-agnostic, and a native client over QUIC
# has the same half-open problem a DataChannel does.
@@ -389,12 +395,12 @@ class _MNPServerProtocol(QuicConnectionProtocol):
task.add_done_callback(self._tasks.discard)
def _peer_registry(self) -> dict:
- """QUIC peers for THIS connection's group, keyed per group so a message
- never crosses into another group on a multi-group node (findings M2b /
- H1). Deliberately separate from the WebRTC registry that also lives in
- the group context: the two transports' session objects have different
- `_send` signatures, and cross-transport chat fan-out is not wired (no
- QUIC client ships yet)."""
+ """QUIC peers for THIS connection's group, keyed per group so nothing a
+ node pushes can cross into another group on a multi-group node.
+
+ Deliberately separate from the WebRTC registry that also lives in the
+ group context: the two transports' session objects have different
+ `_send` signatures, so nothing may iterate both as one set."""
return self._group_ctx().setdefault("_quic_peers", {})
def _do_index_sync_sync(self, stream_id: int) -> None:
@@ -421,50 +427,6 @@ class _MNPServerProtocol(QuicConnectionProtocol):
ctx["gek"], file_path, chunk_index, file_hash, entry.id)
self._send(stream_id, chunk_data)
- def _do_chat_message_sync(self, stream_id: int, msg: dict) -> None:
- """
- Store a chat message and broadcast it to the rest of THIS group.
-
- `sender_id` is the authenticated session's, never the wire's — a peer
- must not be able to post as someone else (NS6 / finding M2a). The store
- and the peer set come from the group context, not a connection-global
- one, so a message never crosses into another group on a multi-group node
- (findings M2b / H1). The WebRTC path has done both since Phase 11.5.
- """
- gctx = self._group_ctx()
- payload = msg.get("payload", b"")
- if isinstance(payload, str):
- payload = payload.encode()
-
- chat_store = gctx.get("chat_store")
- if chat_store:
- self._spawn(chat_store.save_message(
- sender_id=self._user_id,
- iteration=msg.get("iteration", 0),
- payload=payload,
- thread_id=msg.get("thread_id"),
- ))
-
- broadcast = {
- "type": MNP.CHAT_MESSAGE,
- "v": MNP_VERSION,
- "sender_id": self._user_id,
- "iteration": msg.get("iteration", 0),
- "payload": msg.get("payload", ""),
- "thread_id": msg.get("thread_id"),
- "group_id": self._group_id or "",
- }
- # Per connection, not per account — see the WebRTC path and
- # docs/chat-sender-keys.md F7. A person's other devices are recipients.
- for proto in list(self._peer_registry().values()):
- if proto is not self:
- try:
- proto._send(0, broadcast)
- except Exception:
- pass
-
- self._send(stream_id, {"type": "ack", "v": MNP_VERSION})
-
def connection_lost(self, exc) -> None:
if self._user_id:
self._peer_registry().pop(self._registry_key, None)