Skip to content

SIP types

Small value objects that flow through the scripting API: parsed URIs, contact bindings, the captured inbound flow, and the action record the test harness uses to report what a handler did.

SipUri

A parsed SIP / SIPS / tel URI. Reachable via request.ruri, request.from_uri, request.to_uri, and Contact.uri parsing.

A parsed SIP or SIPS URI (e.g. sip:alice@example.com:5060).

At runtime this is backed by the Rust PySipUri class. The mock version is a plain dataclass with the same properties.

Examples::

uri = SipUri(user="alice", host="example.com")
assert str(uri) == "sip:alice@example.com"

uri = SipUri(scheme="sips", host="proxy.example.com", port=5061)
assert str(uri) == "sips:proxy.example.com:5061"

scheme class-attribute instance-attribute

scheme: str = 'sip'

URI scheme — "sip" or "sips".

user class-attribute instance-attribute

user: Optional[str] = None

User part of the URI (e.g. "alice"). None for server URIs.

host class-attribute instance-attribute

host: str = 'localhost'

Host or domain (e.g. "example.com", "10.0.0.1").

port class-attribute instance-attribute

port: Optional[int] = None

Port number. None means default (5060 for SIP, 5061 for SIPS).

is_local property

is_local: bool

True if the host matches one of the locally configured domains.

In the mock, set via SipUri._is_local = True or via the test harness local_domains parameter.

is_tel property

is_tel: bool

True if the scheme is tel:.

Contact

A registered contact binding returned by registrar.lookup(...).

A registered contact binding returned by registrar.lookup().

Attributes:

Name Type Description
uri str

The contact URI string (e.g. "sip:alice@192.168.1.5:5060").

q float

Quality value between 0.0 and 1.0 (higher = preferred).

expires int

Seconds remaining until this binding expires.

uri instance-attribute

uri: str

Contact URI as a string.

q class-attribute instance-attribute

q: float = 1.0

Quality value (0.0–1.0). Higher values are preferred. Default is 1.0 per RFC 3261.

expires class-attribute instance-attribute

expires: int = 3600

Seconds remaining until this contact binding expires.

path class-attribute instance-attribute

path: list = field(default_factory=list)

RFC 3327 Path headers stored with this binding. Use as Route headers when routing terminating requests to this contact.

instance_id class-attribute instance-attribute

instance_id: Optional[str] = None

Stable identity of the siphon instance that originally accepted the REGISTER (typically the StatefulSet pod name). None for legacy bindings or deployments that do not configure server.instance_id.

instance_epoch class-attribute instance-attribute

instance_epoch: Optional[str] = None

Boot-time epoch UUID of the process that accepted the REGISTER. Combined with :attr:instance_id, distinguishes successive runs of the same logical replica.

is_local class-attribute instance-attribute

is_local: bool = False

True when the binding's (instance_id, instance_epoch) matches the current siphon process — i.e. this process accepted the REGISTER. Useful for graceful-shutdown deregister and NAT keepalive ownership.

flow_token class-attribute instance-attribute

flow_token: Optional[str] = None

Opaque proxy-side token attached at REGISTER time via registrar.save(flow_token=...). None for non-P-CSCF bindings.

flow class-attribute instance-attribute

flow: Optional[Flow] = None

Captured inbound flow (Flow view). Pass to request.relay(flow=...) / request.fork(contacts) / call.dial(flow=...) for RFC 5626 §5.3 connection reuse — the only way to reach a WebSocket UE (RFC 7118 §5). Populated for any binding this process accepted (no flow_token= required); None only for a binding restored cross-instance whose local listener / connection id aren't available here. Guard on :attr:is_local before routing over it.

params class-attribute instance-attribute

params: list = field(default_factory=list)

Contact-header parameters preserved from the originating REGISTER (or 3PR 200 OK), excluding tag, q, expires, +sip.instance, and reg-id which are broken out into other fields. Each entry is a (name, value) tuple — value is None for flag parameters (e.g. +g.3gpp.smsip) and a string for valued parameters (e.g. +g.3gpp.icsi-ref="urn:...").

Surfaced verbatim by :func:registrar.reginfo_xml as <unknown-param> children per RFC 3680 §5.3.2 so watchers see the same capability advertisement the registrar received.

kind class-attribute instance-attribute

kind: str = 'ue'

"ue" (UE-side binding from a REGISTER — the default and the only contacts returned by :func:registrar.lookup) or "as" (application-server capability record captured from a 3PR 200 OK via :func:registrar.save_as_contact). AS contacts surface in reg-event NOTIFY bodies (TS 24.229 §5.4.2.1.2) but are excluded from routing lookups.

Flow

An opaque view of the inbound flow captured at REGISTER time, used for Path-token MT routing.

Opaque view of an inbound flow captured at REGISTER time.

Returned by :attr:Contact.flow and :attr:Request.flow. Pass back to :meth:Request.relay (flow= kwarg) to send a request over the same listener that received the REGISTER — bypassing DNS resolution of the Request-URI. Used by P-CSCF MT routing (RFC 3327 §5 / TS 24.229 §5.2.7.2) where the UE's Contact URI is unreachable (NAT, IPSec) and the only path back is the captured flow.

Treat as opaque: scripts read :attr:is_alive for defensive checks but should not depend on the internal field shapes.

transport class-attribute instance-attribute

transport: str = 'udp'

Lowercase transport name: "udp", "tcp", "tls", "ws", or "wss".

remote_addr class-attribute instance-attribute

remote_addr: str = '0.0.0.0:0'

String form of the captured UE source address ("ip:port").

local_addr class-attribute instance-attribute

local_addr: str = '0.0.0.0:0'

String form of the captured listener local address — load-bearing for IPSec sec-agree where the protected port pair must be preserved (3GPP TS 33.203 §7.4).

is_alive property

is_alive: bool

Whether the flow is still usable.

For UDP, always True: the listener socket survives any individual exchange. For stream transports (TCP/TLS/WS/WSS), the real implementation returns True only while the exact accepted connection that delivered the REGISTER is still open on this process — a real lookup against the unified stream-connection registry (see PyFlow.is_alive in src/script/api/registrar.rs). A UE that reconnected, or whose socket closed, reports False.

The mock always returns True (no live connections to track).

Action

The record the test harness captures for each action a handler takes (reply, relay, fork, reject, …). Scripts do not create these; assertions read them.

Records a single action taken by a handler (reply, relay, fork, etc.).

Used by the test harness to capture what a script did in response to a SIP message, so you can assert on it.

kind instance-attribute

kind: str

Action type: "reply", "relay", "fork", "reject", "dial", "terminate", "record_route", "silent_drop".

status_code class-attribute instance-attribute

status_code: Optional[int] = None

For reply / reject — the SIP status code (e.g. 200, 404).

reason class-attribute instance-attribute

reason: Optional[str] = None

For reply / reject — the reason phrase (e.g. "OK").

next_hop class-attribute instance-attribute

next_hop: Optional[str] = None

For relay — the explicit next-hop URI, or None for default.

targets class-attribute instance-attribute

targets: Optional[list[str]] = None

For fork — list of target URIs.

strategy class-attribute instance-attribute

strategy: Optional[str] = None

For fork"parallel" or "sequential".

timeout class-attribute instance-attribute

timeout: Optional[int] = None

For dial / fork — timeout in seconds.

headers_set class-attribute instance-attribute

headers_set: dict[str, str] = field(default_factory=dict)

Headers that were set/modified before this action.

headers_removed class-attribute instance-attribute

headers_removed: list[str] = field(default_factory=list)

Headers that were removed before this action.

extras class-attribute instance-attribute

extras: Optional[dict] = None

Additional action-specific data (e.g. session timer params, SRS URI).

reliable class-attribute instance-attribute

reliable: bool = False

For reply — RFC 3262 reliable provisional flag (Require: 100rel).