Pause control¶
The proxy can pause a subscriber's traffic at runtime. A broadcast NATS command closes that subscriber's live proxy sessions and, optionally, rejects new matching sessions until a short expiry. This lets you cut a subscriber off quickly without a restart or a config change.
Pause state is in memory and is cleared on restart. Only identified sessions can be paused: the proxy must already know the subscriber's username from the simulator's decision. A session whose username is not yet known cannot be matched.
What pausing does¶
- Close. Every live session matching the username (and profile, if selected) is closed promptly.
- Reject. If the command sets a future expiry, new matching sessions are refused until that time. The rejection window is capped to 60 seconds; any longer value is silently reduced. Without a future expiry the command only closes current sessions and opens no rejection window.
A policy block always wins over a pause: if the simulator blocks a connection, it is logged and refused as a policy block even when a pause also matches.
NATS subjects¶
Pause and unpause are broadcast on the proxy's NATS service, under the prefix
from nats.itsy.prefix (default pdnspf):
- Pause:
pdnspf.proxy-tcp.pause-internet.all - Unpause:
pdnspf.proxy-tcp.unpause-internet.all
The .any and .id.<instance_id> target forms are also available for
addressing a single instance instead of every instance.
A response is sent only when the request carries a reply subject. Fire-and-forget broadcasts get no reply.
Pause request¶
The expiry can instead be given as an absolute timestamp:
{
"username": "alice@example.test",
"match_profile": true,
"profile": 2,
"expires_at": "2026-05-29T04:15:00Z"
}
Profile selector¶
The match_profile and profile fields decide which of the subscriber's
profiles the command applies to.
match_profile |
profile |
Selects |
|---|---|---|
false or omitted |
omitted, null, or 0 |
All profiles for the username. |
true |
a specific number | Only that profile. |
true |
omitted | Profile 0. |
A non-zero profile without match_profile: true is ambiguous and is rejected.
Expiry rules¶
| Fields present | Effect |
|---|---|
No ttl_seconds and no future expires_at |
Close current matching sessions only; no rejection window. |
ttl_seconds > 0 |
Reject new matching sessions for that many seconds, capped to 60. |
Future expires_at |
Reject until that timestamp, capped to 60 seconds from now. |
Both ttl_seconds and a future expires_at |
Use whichever expiry is earlier, capped to 60 seconds. |
A ttl_seconds of 0 is the unset value. An expires_at in the past behaves
like no future expiry.
The proxy rejects malformed JSON, a missing or empty username, a negative
profile, an ambiguous non-zero profile without match_profile: true, and an
invalid expires_at.
Unpause request¶
Unpause uses the same profile-selector rules as pause. It removes any future rejection window for the matching subscriber and profile. Already-closed sessions are not reopened — clients reconnect on their own.
Response¶
When a reply subject is set, the handler returns a summary:
{
"instance_id": "VFAOuXPQKaJFU9SlETBVZ8",
"action": "pause",
"username": "alice@example.test",
"match_profile": false,
"profile": 0,
"ttl_seconds": 60,
"expires_at": "2026-05-29T04:15:00Z",
"connections": 3
}
The response always includes a scalar profile; use match_profile to decide
whether it is meaningful. The connections count is best-effort — it reports the
matching identified sessions selected for closure, not a guarantee that every
socket has finished closing. The unpause response carries the same fields and may
include pauses_removed.