v0.5.0
SIP conformance overhaul and a major feature batch: this release makes
aiosipua hold its own against real-world SIP servers and adds the
signaling features a voice-AI backend needs.
Breaking changes
SipUAC.send_cancel(call)replacessend_cancel(dialog, remote_addr)—
the CANCEL is built from the original INVITE (same branch and CSeq,
RFC 3261 §9.1), which is what proxies require to match it.SipMessage.bodyis nowbytes(SIP bodies are octet streams). Read or
write text bodies through the newmessage.textproperty;parse_sdp
raises aTypeErrorpointing at.textif handed bytes.
Conformance fixes
- Digest authentication rewritten per RFC 7616:
qop="auth"(cnonce/nc),
SHA-256 (RFC 8760) alongside MD5,opaqueechoed — challenges from
Asterisk/FreeSWITCH/Kamailio now succeed. - re-INVITE 200s are ACKed with their own CSeq;
on_answerno longer replays. - In-dialog requests are validated against the dialog (wrong tags → 481,
non-increasing CSeq → 500); CANCEL matches the INVITE transaction by branch. - SDP answers mirror every offered m-line in order, port 0 for rejected
streams (RFC 3264 §6). received/rportstamped on incoming Vias (RFC 3581);advertised_addr
on UAC/UAS for NATed signaling.
New features
- Reliability: 200 OK retransmitted until ACK over UDP, reliable
provisionals with PRACK/100rel (RFC 3262), automatic transaction expiry. - REGISTER client with auto-refresh, 423 handling, and expiry watchdog.
- UPDATE (RFC 3311) and blind transfer via REFER (RFC 3515) with
transfer-progress NOTIFYs. - Session timers (RFC 4028): UPDATE refreshes and dead-call watchdogs.
- IPv6 end to end: bracketed literals in Via/Contact/URIs,
IN IP6SDP.
Hardening
- Header-injection guards on all header setters; size caps on header count,
TCP header bytes, and declared body length; required-header validation. - Parser survives the RFC 4475 torture suite and holds two hypothesis-checked
invariants: onlyValueErroron arbitrary input, and a stable wire format
after one normalization pass.
344 → 524 tests; every module under strict mypy.