Project 3: SIP User Agent Signaling Lab

Build a minimal SIP user agent that can REGISTER, INVITE, ACK, and BYE while logging transaction and dialog state transitions deterministically.

Quick Reference

Attribute Value
Difficulty Level 3: Advanced
Time Estimate 14-24 hours
Main Programming Language Python (Alternatives: Go, JavaScript)
Alternative Programming Languages Go, JavaScript
Coolness Level Level 3: Genuinely Clever
Business Potential 2. The “Micro-SaaS / Pro Tool”
Prerequisites P02 completion, HTTP-like protocol parsing mindset
Key Topics SIP state, digest auth, SDP offer/answer, error handling

1. Learning Objectives

By completing this project, you will:

  1. Construct syntactically valid SIP requests and parse responses.
  2. Implement digest authentication challenge-response flow.
  3. Track transaction and dialog state reliably.
  4. Produce deterministic signaling transcripts for success and failure scenarios.
  5. Bridge signaling understanding into PBX operations in P04.

2. All Theory Needed (Per-Concept Breakdown)

2.1 SIP Transaction and Dialog State

Fundamentals

SIP signaling is a protocol-state system, not free-form text exchange. Each request/response transaction must be correlated correctly, and longer-lived dialogs must maintain identity across multiple transactions. Core identifiers include Via branch, CSeq, Call-ID, and From/To tags.

Deep Dive into the concept

A robust SIP implementation separates transaction handling from dialog handling. Transaction state addresses request reliability (especially on UDP), while dialog state models the established relationship between endpoints. Confusing these layers causes subtle bugs: incorrect ACK behavior, mishandled re-INVITE flows, or leaked call state.

For INVITE, provisional responses (1xx) indicate progress, final responses determine outcome, and ACK behavior differs for 2xx versus non-2xx classes. REGISTER flows may succeed while INVITE fails due to policy, route, or media constraints. Therefore, per-method state handlers are preferable to monolithic response logic.

Retries and timers matter. Under UDP, missing responses trigger retransmission logic. Even in a lab, implement at least minimal timeout/retry structure so behavior resembles real deployments.

Deterministic logging is a major design requirement. Each message should log method/status, timestamp, CSeq, Call-ID, and dialog state transition. This provides postmortem-grade observability and prepares you for PBX troubleshooting.

How this fit on projects

  • Core for this project.
  • Directly reused in P04.

Definitions & key terms

  • Transaction -> Request plus related responses.
  • Dialog -> Peer relationship across transactions.
  • CSeq -> Command sequence number per dialog role.
  • Call-ID -> Global identifier for call context.

Mental model diagram

REGISTER transaction(s) -> INVITE transaction -> dialog established -> BYE transaction

How it works

  1. Create request with required headers.
  2. Send and wait for responses.
  3. Handle challenge or success branch.
  4. Update state machine and log transition.

Invariants: consistent identifiers and valid CSeq progression.

Failure modes: incorrect ACK semantics, mixed transaction/dialog state.

Minimal concrete example

INVITE CSeq=1 Call-ID=call-abc
180 Ringing
200 OK
ACK CSeq=1
BYE CSeq=2
200 OK

Common misconceptions

  • “SIP success means media success.” -> Media may still fail due to SDP/NAT.
  • “REGISTER and INVITE auth behave identically.” -> policy and routing differences matter.

Check-your-understanding questions

  1. Which identifiers define a dialog?
  2. Why does CSeq evolve across requests?

Check-your-understanding answers

  1. Call-ID + local tag + remote tag.
  2. To preserve ordered transaction semantics.

Real-world applications

  • Softphone implementation.
  • SIP trunk troubleshooting.

Where you’ll apply it

References

  • RFC 3261

Key insights

SIP reliability depends on disciplined state tracking more than raw message formatting.

Summary

Correct state modeling turns SIP from “string parsing” into reliable call control.

Homework/Exercises

  1. Annotate a full INVITE flow and identify state transitions.
  2. Add one failure branch and expected state outcome.

Solutions

  1. Track provisional -> final -> established -> terminated states.
  2. For timeout branch, transition to failed and release resources.

2.2 SDP Offer/Answer and Media Reachability

Fundamentals

SDP communicates media capabilities and endpoints within SIP messages. Even perfect SIP signaling fails operationally if SDP advertises unreachable IP/port or incompatible codecs.

Deep Dive into the concept

Offer/answer semantics determine codec intersection, transport profile, and endpoint ports. A practical user agent must generate minimal but coherent SDP and validate responses before declaring call readiness.

Include explicit codec preferences and ensure media addresses are reachable in your test topology. In NAT scenarios, private addresses can silently break one-way audio. Your lab should detect and log suspicious SDP values rather than assuming success.

Track SDP versioning for session updates if you extend to re-INVITE later. For this project, simple single-offer call setup is enough, but establish clear parsing structure now.

How this fit on projects

  • Supports media success in this project.
  • Essential for P04.

Definitions & key terms

  • Offer/Answer -> Negotiation model for media parameters.
  • m-line -> Declares media type, port, transport, and payload IDs.
  • rtpmap -> Maps payload type to codec name/rate.

Mental model diagram

Caller SDP offer -> Callee SDP answer -> codec intersection + media endpoint agreement

How it works

  1. Build SDP offer with supported codec(s) and receive port.
  2. Parse answer and verify codec overlap.
  3. Validate endpoint reachability assumptions.

Failure modes: codec mismatch, unreachable media address.

Minimal concrete example

Offer m=audio 40000 RTP/AVP 0
Answer m=audio 50020 RTP/AVP 0
Result: PCMU/8000 media path expected

Common misconceptions

  • “200 OK means media is guaranteed.” -> Not without SDP validation.

Check-your-understanding questions

  1. What minimal SDP fields are required for basic audio offer?
  2. Why is codec overlap mandatory?

Check-your-understanding answers

  1. Session/version basics, connection address, media line, codec mapping.
  2. Without overlap no mutually intelligible payload format exists.

Real-world applications

  • SIP endpoint interoperability testing.

Where you’ll apply it

References

  • RFC 4566
  • RFC 3264

Key insights

SDP correctness is the bridge between signaling success and audible media success.

Summary

Treat SDP parsing/validation as a first-class requirement, not optional parsing detail.

Homework/Exercises

  1. Write one valid and one intentionally broken SDP offer.
  2. Predict resulting signaling/media outcomes.

Solutions

  1. Broken media port/address should trigger one-way/no-audio behavior.
  2. Signaling may succeed while media fails.

3. Project Specification

3.1 What You Will Build

A CLI user agent that supports registration, call initiation, call teardown, and deterministic signaling logs.

3.2 Functional Requirements

  1. REGISTER with digest challenge support.
  2. INVITE flow with provisional/final response handling.
  3. ACK after successful INVITE final response.
  4. BYE-based clean call termination.
  5. Structured logs per transaction.

3.3 Non-Functional Requirements

  • Performance: Response handling within practical timeout windows.
  • Reliability: No state leak across failed calls.
  • Usability: Human-readable logs and explicit errors.

3.4 Example Usage / Output

sip_lab register --user 100 --server 192.168.1.50
sip_lab call --from 100 --to 101@lab.local
sip_lab hangup --call-id call-100-101-001

3.5 Data Formats / Schemas / Protocols

  • SIP text messages over UDP/TCP.
  • SDP payload in INVITE/200 OK as needed.

3.6 Edge Cases

  • 401/407 auth challenges.
  • Timeout/no response.
  • 4xx/5xx failure responses.

3.7 Real World Outcome

3.7.1 How to Run (Copy/Paste)

$ sip_lab register --user 100 --server 192.168.1.50 --domain lab.local --password '***'
$ sip_lab call --from 100 --to 101@lab.local
$ sip_lab hangup --call-id call-100-101-001

3.7.2 Golden Path Demo (Deterministic)

  • REGISTER receives 401 then 200.
  • INVITE receives 100/180/200 then ACK.
  • BYE receives 200.

3.7.3 If CLI: exact terminal transcript

$ sip_lab call --from 100 --to 101@lab.local
[TX] INVITE cseq=1 call_id=call-100-101-001
[RX] 100 Trying
[RX] 180 Ringing
[RX] 200 OK
[TX] ACK cseq=1
[STATE] established
[EXIT] code=0

4. Solution Architecture

4.1 High-Level Design

CLI -> Message Builder -> Transport -> Response Parser -> State Machine -> Logger

4.2 Key Components

Component Responsibility Key Decisions
Message Builder Construct SIP requests strict header templates
Response Parser Parse status/header/body tolerant but validated parser
State Machine Track transaction/dialog lifecycle explicit transitions
Auth Module Digest challenge handling nonce-aware retry path

4.4 Data Structures (No Full Code)

DialogState: call_id, local_tag, remote_tag, cseq
TransactionState: method, branch_id, status
SdpOffer: media_ip, media_port, codecs[]

4.4 Algorithm Overview

  1. Construct and send request.
  2. Parse responses and branch by status class.
  3. Update state and emit logs.
  4. Retry on challenge where applicable.

5. Implementation Guide

5.1 Development Environment Setup

$ mkdir -p logs captures
$ toolchain --check-sip

5.2 Project Structure

sip-lab/
├── src/
├── logs/
└── fixtures/

5.3 The Core Question You’re Answering

“Can I make call setup behavior deterministic and explainable from raw protocol events?”

5.4 Concepts You Must Understand First

  • SIP transaction/dialog distinction.
  • Digest auth flow.
  • SDP offer/answer basics.

5.5 Questions to Guide Your Design

  1. How will you represent state transitions?
  2. Which log fields are mandatory for postmortems?
  3. Which failures are retryable?

5.6 Thinking Exercise

Manually trace a challenged REGISTER and an INVITE success flow before implementation.

5.7 The Interview Questions They’ll Ask

  1. Explain 401 challenge flow.
  2. Why does ACK handling matter?
  3. What causes one-way audio after 200 OK?
  4. How do you correlate SIP messages in logs?

5.8 Hints in Layers

Hint 1: Start with parser and logging, then add methods.

Hint 2: Implement REGISTER first, INVITE second.

Hint 3 (pseudocode):

if response.status in 200-range:
  advance_state()
elif response.status in challenge-range:
  build_auth_retry()
else:
  fail_with_context()

5.9 Books That Will Help

Topic Book Chapter
SIP core RFC 3261 8-13
SIP transactions RFC 3261 17
SDP format RFC 4566 Full

5.10 Implementation Phases

Phase 1: Foundation (4-6 hours)

  • Parser, logger, and message templating.

Phase 2: Core Functionality (6-10 hours)

  • REGISTER + INVITE + ACK + BYE flows.

Phase 3: Polish & Edge Cases (4-8 hours)

  • Timeout handling, malformed responses, transcript exports.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Transport UDP/TCP UDP first aligns with common SIP lab behavior
Parser strictness lenient/strict strict core fields prevents silent bugs

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Unit Header parse/build Via/CSeq checks
Integration End-to-end call flow INVITE success path
Edge Auth/timeouts 401 retry, no-response timeout

6.2 Critical Test Cases

  1. REGISTER with challenge then success.
  2. INVITE/ACK/BYE full lifecycle.
  3. Malformed response is rejected with actionable log.

6.3 Test Data

fixtures/sip/register_challenge.txt
fixtures/sip/invite_success.txt
fixtures/sip/malformed_response.txt

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Bad CSeq handling unexpected server rejection method-aware CSeq progression
Missing ACK behavior call teardown immediately implement correct ACK branch
Weak logs impossible diagnosis structured message correlation

7.2 Debugging Strategies

  • Replay captured messages against parser.
  • Compare with known-good softphone trace.
  • Validate every state transition explicitly.

7.3 Performance Traps

  • Blocking waits without timeouts cause hung sessions.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add CANCEL flow for unanswered calls.
  • Add transcript export in markdown.

8.2 Intermediate Extensions

  • Add basic re-INVITE support.
  • Add OPTIONS keepalive behavior.

8.3 Advanced Extensions

  • Add proxy-route support.
  • Add TLS transport mode.

9. Real-World Connections

9.1 Industry Applications

  • SIP softphone stacks.
  • Carrier interconnect QA.
  • SIP testing tools (SIPp ecosystem).
  • PBX signaling modules.

9.3 Interview Relevance

  • Demonstrates protocol-state reasoning and deterministic debugging discipline.

10. Resources

10.1 Essential Reading

  • RFC 3261
  • RFC 4566
  • RFC 3264

10.2 Video Resources

  • SIP call-flow deep dives.

10.3 Tools & Documentation

  • Wireshark SIP dissector docs.

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain SIP dialog identity fields.
  • I can explain why signaling and media failures differ.

11.2 Implementation

  • REGISTER and INVITE flows are deterministic.
  • Logs allow full message correlation.

11.3 Growth

  • I can explain this project in an interview with concrete examples.

12. Submission / Completion Criteria

Minimum Viable Completion

  • REGISTER + INVITE + BYE flow works in lab.
  • Basic auth challenge handling implemented.

Full Completion

  • Deterministic success/failure transcripts.
  • Structured logs and state transitions documented.

Excellence

  • Adds controlled retry logic and richer diagnostics beyond baseline.