meshsocket 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshsocket-0.4.0 → meshsocket-0.4.1}/PKG-INFO +1 -1
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket/__init__.py +1 -1
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket.egg-info/PKG-INFO +1 -1
- {meshsocket-0.4.0 → meshsocket-0.4.1}/pyproject.toml +1 -1
- {meshsocket-0.4.0 → meshsocket-0.4.1}/socket_server.py +33 -7
- {meshsocket-0.4.0 → meshsocket-0.4.1}/LICENSE +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/README.md +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket.egg-info/SOURCES.txt +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket.egg-info/dependency_links.txt +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket.egg-info/requires.txt +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/meshsocket.egg-info/top_level.txt +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/setup.cfg +0 -0
- {meshsocket-0.4.0 → meshsocket-0.4.1}/socketCore.py +0 -0
|
@@ -7,4 +7,4 @@ so existing code keeps running while it migrates to the package name.
|
|
|
7
7
|
from socketCore import MeshSocket, LogColors, sanitize_identity, valid_ident, IDENT_RE, NAMESPACED_RE
|
|
8
8
|
|
|
9
9
|
__all__ = ["MeshSocket", "LogColors", "sanitize_identity", "valid_ident", "IDENT_RE", "NAMESPACED_RE"]
|
|
10
|
-
__version__ = "0.4.
|
|
10
|
+
__version__ = "0.4.1"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meshsocket"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.1"
|
|
8
8
|
description = "Lightweight WebSocket mesh networking — broadcast, direct routing, and request/response over a simple JSON wire protocol."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -22,23 +22,45 @@ class MeshServerConfigError(RuntimeError):
|
|
|
22
22
|
# The key the relay writes on every routed payload (0.4.0): the sender's
|
|
23
23
|
# authenticated name, as this relay registered it at identify (through the
|
|
24
24
|
# carter-relay gateway that is the namespaced `<account>.<principal>_<name>`).
|
|
25
|
+
# Peers write `_from` too (on broadcasts, where it is left alone), so a receiver
|
|
26
|
+
# cannot tell this stamp from a peer's claim by the key alone: see RELAY_SENDER_KEY.
|
|
25
27
|
SENDER_KEY = "_from"
|
|
26
28
|
|
|
29
|
+
# The relay-only sender key (0.4.1). Set beside `_from` on every routed payload,
|
|
30
|
+
# and removed from every payload the relay forwards (routed, routed replies and
|
|
31
|
+
# broadcasts), so a receiver that finds it knows this relay wrote it: no peer can
|
|
32
|
+
# get its own copy through. Broadcasts never carry it (they are not stamped).
|
|
33
|
+
RELAY_SENDER_KEY = "_relayFrom"
|
|
34
|
+
|
|
27
35
|
|
|
28
36
|
def stamp_sender(payload: Any, sender_name: str) -> Any:
|
|
29
|
-
"""`payload` with `SENDER_KEY` set to `sender_name`,
|
|
30
|
-
sender wrote. Only a dict payload is stamped. On an
|
|
31
|
-
(`{"e2ee": 2, "s", "n", "ct"}`) the
|
|
32
|
-
beside the ciphertext, which is where receivers read the
|
|
33
|
-
sealed body is never touched. Other payloads (lists,
|
|
34
|
-
unchanged. Returns a copy; the caller's dict is not
|
|
37
|
+
"""`payload` with `SENDER_KEY` and `RELAY_SENDER_KEY` set to `sender_name`,
|
|
38
|
+
overwriting any value the sender wrote. Only a dict payload is stamped. On an
|
|
39
|
+
E2EE envelope (`{"e2ee": 2, "s", "n", "ct"}`) the keys land on the outer,
|
|
40
|
+
unsealed object beside the ciphertext, which is where receivers read the
|
|
41
|
+
relay's stamp; the sealed body is never touched. Other payloads (lists,
|
|
42
|
+
strings, null) pass unchanged. Returns a copy; the caller's dict is not
|
|
43
|
+
modified."""
|
|
35
44
|
if not isinstance(payload, dict):
|
|
36
45
|
return payload
|
|
37
46
|
stamped = dict(payload)
|
|
38
47
|
stamped[SENDER_KEY] = sender_name
|
|
48
|
+
stamped[RELAY_SENDER_KEY] = sender_name
|
|
39
49
|
return stamped
|
|
40
50
|
|
|
41
51
|
|
|
52
|
+
def strip_relay_sender(payload: Any) -> Any:
|
|
53
|
+
"""`payload` without a peer-written `RELAY_SENDER_KEY` on its outer object.
|
|
54
|
+
Only a dict payload changes (a copy; the caller's dict is not modified);
|
|
55
|
+
nested values and an E2EE envelope's sealed body are not touched, and
|
|
56
|
+
everything else, `_from` included, is delivered as sent."""
|
|
57
|
+
if not isinstance(payload, dict) or RELAY_SENDER_KEY not in payload:
|
|
58
|
+
return payload
|
|
59
|
+
stripped = dict(payload)
|
|
60
|
+
del stripped[RELAY_SENDER_KEY]
|
|
61
|
+
return stripped
|
|
62
|
+
|
|
63
|
+
|
|
42
64
|
def _env_int(name: str, default: int) -> int:
|
|
43
65
|
raw = os.getenv(name)
|
|
44
66
|
if raw is None or not raw.strip():
|
|
@@ -503,7 +525,8 @@ class MeshServer:
|
|
|
503
525
|
# The target never answered: say so instead of leaving the
|
|
504
526
|
# requester to wait out its own timeout with no signal.
|
|
505
527
|
return {"error": "target timeout", "status": "failed"}
|
|
506
|
-
|
|
528
|
+
# The target wrote this reply: it may not carry the relay-only key.
|
|
529
|
+
return strip_relay_sender(response)
|
|
507
530
|
|
|
508
531
|
@client.on("get_nodes")
|
|
509
532
|
async def on_get_nodes(payload):
|
|
@@ -635,8 +658,11 @@ class MeshServer:
|
|
|
635
658
|
# `command_ack` whose `to` differs, and carterkit acks to the outer `_from`
|
|
636
659
|
# of a sealed frame when there is one. Behind the gateway the relay name is
|
|
637
660
|
# namespaced, so stamping broadcasts would break those acks.
|
|
661
|
+
# A peer-written RELAY_SENDER_KEY is removed (0.4.1): on a broadcast the
|
|
662
|
+
# receiver finds none, so it never mistakes a peer's claim for the relay's.
|
|
638
663
|
if not self.clients:
|
|
639
664
|
return
|
|
665
|
+
payload = strip_relay_sender(payload)
|
|
640
666
|
sends, targets = [], []
|
|
641
667
|
for peer in list(self.clients.values()):
|
|
642
668
|
if sender and not self._can_receive_broadcast(sender, peer):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|