Skip to content

Add IPv6 support and add stronger SIP types#54

Merged
codingjoe merged 4 commits intomainfrom
ipv6
Mar 18, 2026
Merged

Add IPv6 support and add stronger SIP types#54
codingjoe merged 4 commits intomainfrom
ipv6

Conversation

@codingjoe
Copy link
Copy Markdown
Owner

No description provided.

@codingjoe codingjoe self-assigned this Mar 18, 2026
Copilot AI review requested due to automatic review settings March 18, 2026 22:45
@codingjoe codingjoe linked an issue Mar 18, 2026 that may be closed by this pull request
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 99.15612% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.79%. Comparing base (187448d) to head (daa1944).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
voip/__main__.py 91.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #54      +/-   ##
==========================================
+ Coverage   92.51%   93.79%   +1.28%     
==========================================
  Files          24       24              
  Lines        1790     1966     +176     
==========================================
+ Hits         1656     1844     +188     
+ Misses        134      122      -12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class IPv6 support across STUN/SIP/RTP and introduces stronger SIP typing primitives (URI/method/status) to make signaling and serialization more robust and explicit.

Changes:

  • Decode STUN MAPPED-ADDRESS / XOR-MAPPED-ADDRESS for both IPv4 and IPv6 and propagate typed ipaddress objects through STUN/RTP/SIP.
  • Introduce SipUri, SIPStatus, and SIPMethod, and update SIP message/protocol code to use phrase + enum-based status/methods.
  • Update CLI parsing and docs/tests to reflect IPv6 bracket rules and the new types.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
voip/stun.py Adds shared address decoding helper and returns typed IPv4/IPv6 addresses.
voip/sip/types.py Adds SipUri, SIPStatus, SIPMethod and expands SIP typing surface.
voip/sip/protocol.py Uses typed addresses, formats IPv6 hosts with brackets, and migrates to SIPStatus/phrase.
voip/sip/messages.py Strengthens request/response types and renames reasonphrase.
voip/sip/init.py Re-exports new SIP types (SipUri, SIPStatus, SIPMethod).
voip/rtp.py Propagates typed public address future result from STUN.
voip/ai.py Avoids appending/speaking empty assistant replies.
voip/main.py Switches AOR parsing to SipUri and adds bracketed IPv6 host:port parsing.
tests/test_stun.py Adds IPv6 STUN attribute builders and coverage for IPv6 parsing paths.
tests/test_rtp.py Updates expectations to typed ipaddress results.
tests/test_main.py Adjusts CLI tests for new parsing flow and transport mocking.
tests/sip/test_types.py Adds coverage for SipUri.parse() and SipUri.__str__() including IPv6.
tests/sip/test_protocol.py Updates protocol tests for typed addresses, phrase, IPv6 SDP addrtype, and header formatting.
tests/sip/test_messages.py Updates message tests for phrase rename.
docs/feature_roadmap.md Documents IPv6 support in STUN/SIP/SDP.
README.md Adds lint suppression for example password literal.
Comments suppressed due to low confidence (1)

voip/main.py:78

  • _parse_hostport() will mis-parse an unbracketed IPv6 literal like 2001:db8::1 as host='2001:db8::' and port=1 because it falls through to rpartition(':'). Since the docstring requires brackets for IPv6, consider explicitly detecting unbracketed IPv6 (e.g., multiple ':' characters) and raising click.BadParameter with guidance to use [addr] syntax.
    host, _, port_str = value.rpartition(":")
    if not host:
        return value, default_port
    try:
        return host, int(port_str)
    except ValueError:
        raise click.BadParameter(f"Invalid port in {value!r}.", param=param) from None

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 18, 2026

@codingjoe I've opened a new pull request, #55, to work on those changes. Once the pull request is ready, I'll request review from you.

codingjoe and others added 3 commits March 18, 2026 23:58
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
… IPv6 tests (#55)

`_parse_hostport()` had manual bracket-parsing logic with no tests,
silently mishandled unbracketed IPv6 literals, and returned a plain
`str` host regardless of whether the value was a numeric IP address.

## Changes

- **`voip/__main__.py`**:
- Replaced manual bracket/partition logic with a single
`HOSTPORT_PATTERN` regex that handles `[IPv6HOST][:PORT]`, `HOST:PORT`,
and bare `HOST` forms.
- Return type changed from `tuple[str, int]` to `tuple[IPv4Address |
IPv6Address | str, int]` — numeric IP literals are parsed into typed
address objects; hostnames remain `str`.
- Unbracketed IPv6 literals (e.g. `::1`) raise `click.BadParameter`
directing the user to bracket notation.
- `_parse_stun_server` converts the typed host to `str` for
socket/asyncio compatibility.
- `_connect_sip` uses `str(proxy_addr[0])` when calling
`asyncio.create_connection`.
- **`voip/sip/protocol.py`**: `outbound_proxy` type updated to
`tuple[IPv4Address | IPv6Address | str, int] | None`.
- **`tests/test_main.py`**: New `TestParseHostport` class covering the
three key paths:
  - `[::1]` → `(IPv6Address("::1"), 5061)` (default port)
  - `[::1]:5061` → `(IPv6Address("::1"), 5061)` (explicit port)
  - `::1` → `BadParameter("...enclosed in brackets...")`

```python
# Before: silently wrong, plain str host
_parse_hostport(None, None, "::1")   # → ("::", 1)
_parse_hostport(None, None, "[::1]") # → ("::1", 5061)

# After: explicit error for unbracketed IPv6, typed address objects
_parse_hostport(None, None, "::1")
# click.BadParameter: IPv6 address must be enclosed in brackets, e.g. [::1].
_parse_hostport(None, None, "[::1]")  # → (IPv6Address('::1'), 5061)
_parse_hostport(None, None, "1.2.3.4:5060")  # → (IPv4Address('1.2.3.4'), 5060)
```

<!-- START COPILOT CODING AGENT TIPS -->
---

📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs),
[Azure Boards](https://gh.io/cca-azure-boards-docs) or
[Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in
one click without leaving your project management tool.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: codingjoe <[email protected]>
Co-authored-by: Johannes Maron <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
@codingjoe codingjoe merged commit 0e3d9f7 into main Mar 18, 2026
24 checks passed
@codingjoe codingjoe deleted the ipv6 branch March 18, 2026 23:41
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.

IPv6 support

3 participants