* fix: expire FS/RTP roster members on shared last-seen, not one SBC's local view
The active-fs, fs-service-url and active-rtp redis sets are shared by every
SBC in the cluster, but the expiry sweep in lib/options.js removed members
based solely on when THIS sidecar last received an OPTIONS ping from them.
An SBC that was taken out of active-sip (so FS/RTP servers stopped pinging
it) therefore deleted every feature server and rtpengine from the shared
rosters 60s later, rejecting all inbound calls until the other SBC re-added
them on its next ping cycle.
Each SBC now records the last ping it received per member in a shared redis
hash (<setName>:lastseen, member -> epoch ms) and the sweep removes a member
only when that shared timestamp is older than EXPIRES_INTERVAL. Members with
no shared timestamp are never expired by the sweep, so a parked or
mixed-version SBC cannot remove members the others are still hearing from.
Adds a unit test that reproduces the failure against the old code.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: make sbc_addresses keepalive recurring instead of a single setTimeout
addSbcAddress() refreshes the row's last_updated and cleanSbcAddresses()
deletes rows older than DEAD_SBC_IN_SECOND (default 3600s), but app.js only
re-called addSbcAddress once, 15 minutes after connecting. The row then
went stale, and the next sidecar to start anywhere in the cluster deleted
the healthy SBC's row, so new sip realms were provisioned with one SBC IP
instead of two.
Run one recurring timer (SBC_PUBLIC_ADDRESS_KEEP_ALIVE_IN_MILISECOND, default
15 min) that refreshes this SBC's rows and only then reaps stale ones, so the
cleaner never runs ahead of this process's own keepalive. The timer is
unref'd and replaced (not stacked) on drachtio reconnect.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
- jambonzVersion is read from the schema_version table via the existing
db-helpers pool (now exposed on srf.locals); a DB error yields null
rather than failing discovery
- drachtioVersion is captured from the drachtio connect handshake and
stored on srf.locals
- README example updated
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* support draining feature server manually
* support draining feature server manually
* support CLI to add or remove feature server
* wip
* wip
* wip
* add redis key for feature server and integration test
* wip
* add support for registration trunks which result in a set of ephemeral sip gateways to be stored in redis
* wip
* refactor createEphemeralGateways into realtime dbhelpers
* minor
* update eslint
* disable options ping on defined errors
* correct sid
* disable reg on error
* fix path
* fixes from testing
* fixes from testing
* lint
* update dbhelpers dep
* remove whitespace in CONFIG strings
* lint
* this seems like a better way of convering and matching status codes