Skip to content

feat(cdr): capture caller/callee SIP peer addresses on call records - #276

Open
ftong2010 wants to merge 1 commit into
restsend:mainfrom
ftong2010:cdr-peer-capture
Open

feat(cdr): capture caller/callee SIP peer addresses on call records#276
ftong2010 wants to merge 1 commit into
restsend:mainfrom
ftong2010:cdr-peer-capture

Conversation

@ftong2010

Copy link
Copy Markdown

What

Adds two signaling-plane fields to call records (CDRs), serialized as callerPeer and calleePeer:

  • callerPeer — A-leg (caller side) SIP peer ip:port: the transport source of the inbound INVITE (connection remote address, top-Via fallback when the connection is unavailable).
  • calleePeer — B-leg (callee side) SIP destination ip:port: where the outbound INVITE was sent (dial-target destination; URI-routed legs fall back to the request-URI host — exact for IP-literal trunk hosts). Not populated for PBX-originated (RWI) calls that have no inbound-leg pairing at report time.

Why

Consumers (dashboards, top-N source analysis, IP filtering) currently need a join against the signaling capture table to answer "which IP did this call come from / go to". With the peers on the record itself, CDR queries are self-contained.

How

  • The A-leg peer is captured in handle_invite and rides the transaction cookie (CallerPeerContext extension), so early-failure CDRs — reported before any SipSession exists — keep it.
  • The B-leg peer is stashed into CallMeta at dial time, because cleanup() clears the leg dialogs before CDR reporting; last dial wins on re-dials.
  • The reporter surfaces both onto CallDetails via the cookie extension + CallSessionRecordSnapshot; the SQL model is unchanged (peers live in the JSON saver payloads only).

Semantics

These are signaling addresses (INVITE transport source/destination), never media endpoints: for WebRTC callers the value is the WebSocket connection's public NAT address, which deliberately does not reflect ICE/STUN-selected media candidates. IP-granular grouping is valid; ports are not media ports.

Testing

  • cargo test --lib cdr_capture — 3/3 pass
  • cargo test --test common_selftest cdr_capture — 3/3 pass
  • cargo check clean on default features

- callerPeer: transport source of the inbound INVITE (connection remote
  addr, top-Via fallback), riding the transaction cookie
  (CallerPeerContext) so early-failure CDRs — reported before any
  SipSession exists — keep it
- calleePeer: outbound INVITE destination stashed into CallMeta at dial
  time (cleanup() clears the leg dialogs before CDR reporting; last dial
  wins; URI-routed legs fall back to the request-URI host — exact for
  IP-literal trunk hosts)
- surfaced onto CallDetails by the reporter via cookie extension +
  CallSessionRecordSnapshot, serialized as callerPeer/calleePeer, so
  consumers (Grafana plugin top-N, IP filtering) need no join against
  the signaling table
- signaling-plane addresses only: never the ICE/STUN-selected media
  path — IP-granular grouping is valid, ports are not media ports
- also init trace_id (field from 1c127eed) in the common_selftest CDR
  fixture, which that commit missed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant