aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py26
1 files changed, 24 insertions, 2 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
index 20636fa..0ca4b3d 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -70,7 +70,15 @@ log = logging.getLogger(__name__)
# so the cost to an operator grew with the number of people in their groups.
# Sized to be unreachable in ordinary use: a browser holds one connection per
# open group, and a handshake unfinished after a minute is not going to finish.
-MAX_PEER_SESSIONS = 64
+MAX_PEER_SESSIONS = 128
+# One account's share of them: half. A member of twenty groups hosted here,
+# with three devices and a spare tab, holds up to 52 (each device keeps up to
+# twelve connections for search and music, plus the open group page), so the
+# share never refuses real use — and no single member can hold more than half
+# of what the node will take. The node's own account is not counted against it:
+# it is the operator's machine. Measured, an idle connected session costs about
+# 0.15 MiB and one file descriptor.
+MAX_PEER_SESSIONS_PER_ACCOUNT = MAX_PEER_SESSIONS // 2
UNAUTHENTICATED_SESSION_TIMEOUT = 60 # seconds
@@ -238,8 +246,13 @@ class WebRTCTransport:
pass
return
+ def _sessions_of(self, user_id: str) -> int:
+ return sum(1 for s in self._sessions.values()
+ if (getattr(s, "_offer_user", "") or getattr(s, "_user_id", "") or "")
+ == user_id)
+
async def handle_offer(
- self, offer_sdp: str, peer_id: str,
+ self, offer_sdp: str, peer_id: str, user_id: str = "",
) -> tuple[str, list[dict]]:
"""
Process a WebRTC SDP offer from a browser client.
@@ -267,9 +280,18 @@ class WebRTCTransport:
log.warning("Refusing WebRTC offer: %d peer sessions already open",
len(self._sessions))
raise RuntimeError("Node is at its peer-connection limit")
+ # The account the hub authenticated for this offer. A hub that lied
+ # could only move the count between accounts; it can refuse offers
+ # outright already.
+ if (user_id and user_id != self._ctx.get("node_user_id")
+ and self._sessions_of(user_id) >= MAX_PEER_SESSIONS_PER_ACCOUNT):
+ log.warning("Refusing WebRTC offer: account %s already holds %d sessions",
+ user_id[:8], MAX_PEER_SESSIONS_PER_ACCOUNT)
+ raise RuntimeError("Account is at its peer-connection share")
pc = RTCPeerConnection(configuration=config)
session = WebRTCPeerSession(pc, self._ctx, peer_id=peer_id)
+ session._offer_user = user_id
self._sessions[peer_id] = session
self._reap_if_unauthenticated(peer_id)