Repository navigation
FreeSBC v0.6.0
FreeSBC v0.6.0 cuts about 30% of the allocations per call on the signaling path, raises the UDP SIP receive buffer request to 8 MiB, adds per-socket UDP drop metrics, and counts reads from banned sources. It is built with Go 1.27.3 for GO-2026-6809. Configuration is unchanged: a v0.5.1 file loads as is.
curl -fsSL https://github.com/rasonyang/freesbc/releases/latest/download/install.sh | shBreaking changes
None. No configuration key, CLI command, admin API field, metric name or label changed. Two things look different after the upgrade:
freesbc_shield_drops_total{reason="banned"}now rises during a ban (#250, closes #249). Before, reads from a banned source were dropped before parsing and not counted, so the series stayed nearly flat while a ban was in force. It now counts one per dropped UDP datagram or WS/WSS frame (on tcp/tls, usually one chunk before the connection closes). Expect much higher values from scanners that keep sending, and adjust alerts that assumed a low rate.freesbc_edge_stream_refused_total{reason="banned"}is unchanged.- A host with
net.core.rmem_maxbelow 8 MiB now logs a startup WARN (udp socket receive buffer below request), once per UDP SIP socket, and keeps the smaller buffer. This includes hosts set to the 4 MiB that earlier docs asked for. Raisermem_maxto 8388608 to clear it (see "UDP buffer" below).
Performance
- Fewer allocations per call (#247, closes #173). A new benchmark runs a whole client call (INVITE, 180, 200, ACK, BYE, 200) through a real edge over loopback.
BenchmarkEdgeCall: 1125 to 777 allocations per call (-31%), 66.3 KB to 58.9 KB (-11%).BenchmarkEdgeCallParallelon Linux, 8 vCPU: about 12.2k to 15.8k calls/s, CPU per call 464 to 389 µs, GC CPU per call down about a fifth, stack growth (runtime.newstack) 8.2% to 4.6% of CPU.- How: case-insensitive header matching without lower-casing every header, the read filter reads addresses without a string round trip, cached topology hosts, one stored 2xx instead of a second clone, each handler goroutine's stack grown once while shallow, and
sdp.Build/Negotiaterewritten without maps (Buildoutput is byte-identical to the previous marshaller, checked over randomized inputs and the fuzz targets). Forwarding an RTP packet no longer allocates. - Trust and latching behave as before. The rest of the allocations and stack growth are inside sipgo.
- UDP buffer: the SIP receive request goes from 4 MiB to 8 MiB (#248, closes #235). It applies to the public
edge.listen.udpsocket and the privateprivate.ip:5060socket. The kernel grants it in full only withnet.core.rmem_maxof at least 8 MiB (Linux then allocates 16 MiB). This is a stopgap: it rides out longer waits but does not remove them, and it is not yet measured on the three hosts. - Why carrier-in drops above 3500 CPS (#235). A local re-run on 4 CPUs found that both UDP SIP sockets drop, the private one slightly more. GC mark phases (0.5 to 1.6 s each) hold most of the CPUs, and each socket's single read loop waits behind them, up to 164 ms without a read. Average CPU had headroom.
GOGC=200delays the onset but costs 7.8 GB RSS. The real fix is less GC work (#170 in v0.5.1, #173 in this release). 3500 CPS stays the loss-free carrier-in figure on 4 vCPU until the next three-host run.
Metrics
freesbc_udp_socket_drops_total{socket="public|private"}(counter) andfreesbc_udp_socket_rx_queue_bytes{socket}(gauge) (#248). They name which UDP SIP socket the kernel dropped datagrams on, and how full its receive queue is at the scrape. They come from/proc/self/net/udpandudp6at scrape time, Linux only. A socket that is not bound (noedge.listen.udp) has no series. The namespace-widefreesbc_udp_receive_buffer_errors_totalandfreesbc_udp_in_errors_totalare unchanged.freesbc_shield_drops_total{reason="banned"}counts reads the read filter drops from banned sources (#250); see Breaking changes.
Build
- Go 1.27.3 (in #250). govulncheck flagged GO-2026-6809 in Go 1.27.2's
crypto/x509, reachable from TLS reads on stream connections. Release binaries are built with 1.27.3; building from source now needs Go 1.27.3 or later.
Docs
- README (#251, #252, closes #240, #241, #242). It now leads with what FreeSBC is, a WebUI screenshot (light and dark), install, and five headline performance numbers. The Features, Status & limitations and Layout sections are gone; their details moved to
docs/. docs/edge.mdgains a "Scope rule" section (the two questions a feature must pass), and SDES-SRTP is listed under Known limitations.docs/config.mdgains an admin Endpoints table (every route, its purpose and auth), thetls_cert_*health conditions, and the Config tab's read-only view, Validate and line diff.docs/performance.mdadds the full-call benchmark, updated micro-benchmarks and the #235 analysis.docs/edge.md,docs/install.mdanddocs/troubleshooting.mdnow say 8 MiB forrmem_max.
Test rig and CI
- The perf kit records per-socket kernel drops and receive-queue peaks for each step (
udp_pub_drops,udp_priv_drops,udp_*_rxq_peak_bytesinsteps.csv) (#248). PROFILE_AT=<rate>saves a CPU profile, an execution trace, a goroutine dump and a heap profile at that step (#248).- The rig images build on the Go version in
go.mod, and a CI step fails when agolang:<version>tag in the repo differs from it (#256, closes #253).
Known limitations and follow-ups
- #257: the next monthly three-host run re-measures the carrier-in ceiling with the 8 MiB buffer, and the GC cuts of #170 and #173. Until then 3500 CPS is the loss-free carrier-in figure on 4 vCPU.
- #254: the WebUI header shows
vv0.6.0on release builds. - #255: some WebUI buttons and the theme icon keep the old colours when the colour scheme changes.
- #246: no release signing yet.
SHA256SUMSguards against corruption only.