Skip to content

fix(olcrtc): validate profile inputs - #153

Closed
hawkff wants to merge 2 commits into
mainfrom
fix/olcrtc-profile-validation
Closed

fix(olcrtc): validate profile inputs#153
hawkff wants to merge 2 commits into
mainfrom
fix/olcrtc-profile-validation

Conversation

@hawkff

@hawkff hawkff commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • validate olcRTC carrier, transport, DNS, and VP8 settings before save or startup
  • parse bracketed IPv6 carrier hosts without truncating the address
  • keep validation errors in the editor and add focused regression coverage

Validation

  • Namespace CI: Repo Guards, Unit Tests, Instrumented tests, Android Lint and Spotless, native artifacts, and APK assembly passed
  • CodeRabbit CLI review completed; its context-lifetime suggestion was applied
  • Android verification is pending

Greptile Summary

This PR tightens olcRTC profile handling and validation. The main changes are:

  • Shared validation for carrier, transport, key, DNS, and VP8 settings.
  • VP8 checks limited to VP8 transport profiles.
  • Safer Jitsi host parsing, including bracketed IPv6 rooms.
  • Editor-side validation that keeps failed saves in the settings screen.
  • Tests for parsing, validation, DNS endpoints, and host extraction.

Confidence Score: 4/5

This is close, but the IPv6 host path should be fixed before merging.

  • Datachannel profiles no longer depend on VP8 fields for save, export, or startup.
  • The new Jitsi IPv6 extraction can feed an IP literal into a domain-only DNS rule path.
  • That can produce an incorrect DNS direct-force entry for bracketed IPv6 room URLs.

app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt

Important Files Changed

Filename Overview
app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt Adds shared olcRTC validation, DNS endpoint parsing, transport-specific VP8 handling, and updated Jitsi host extraction.
app/src/main/java/io/nekohasekai/sagernet/ui/profile/OlcrtcSettingsActivity.kt Validates olcRTC settings before saving and reports validation failures in the editor.
app/src/test/java/io/nekohasekai/sagernet/fmt/OlcrtcFmtTest.kt Adds tests for olcRTC validation, URI parsing, DNS endpoint handling, and carrier host extraction.

Reviews (2): Last reviewed commit: "fix(olcrtc): address profile review feed..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OLCRTC validation is centralized across URI parsing, serialization, CLI argument generation, and profile saving. Transport compatibility, VP8 values, encryption keys, DNS endpoints, payload syntax, client IDs, and carrier host extraction now have stricter handling with expanded tests.

Changes

OLCRTC validation and codec

Layer / File(s) Summary
Validation contract and IP helpers
app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
Adds shared profile validation, carrier/transport rules, VP8 bounds, encryption-key checks, resolver validation, payload syntax checks, and IPv4/IPv6 literal helpers.
URI parsing and serialization
app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
Tightens payload parsing, applies defaults and validation, preserves client IDs, enforces round-trip-safe delimiters, and improves carrier host extraction.
CLI argument validation
app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
Normalizes fields and requires valid client IDs, supported transports, and IP-literal DNS endpoints with ports when building arguments.
Save handling and coverage
app/src/main/java/io/nekohasekai/sagernet/ui/profile/OlcrtcSettingsActivity.kt, app/src/test/java/io/nekohasekai/sagernet/fmt/OlcrtcFmtTest.kt
Uses shared validation during save, displays validation errors with a toast, and expands codec, argument, DNS, and carrier-host tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Poem

A rabbit checks each key and port,
While URIs hop through stricter court.
VP8 bounds stand neat in line,
And hosts resolve by rule and sign.
A toast appears when fields go astray—
Safe little links now lead the way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding olcRTC profile input validation.
Description check ✅ Passed The description is directly related to the changeset and describes the validation, parsing, and test updates.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

Comment thread app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
Comment thread app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt`:
- Around line 146-148: Update the cid handling in the parser’s `"cid",
"client-id", "clientid"` branch to apply the same URI delimiter validation used
for other parsed values, rejecting payloads containing reserved delimiters such
as `=`. Ensure invalid cid input is rejected during import while valid client
IDs continue assigning to clientId and remain serializable through toUri().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 45d00970-9cf0-443b-9885-4eba040f83ea

📥 Commits

Reviewing files that changed from the base of the PR and between 890c492 and 7816193.

📒 Files selected for processing (3)
  • app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
  • app/src/main/java/io/nekohasekai/sagernet/ui/profile/OlcrtcSettingsActivity.kt
  • app/src/test/java/io/nekohasekai/sagernet/fmt/OlcrtcFmtTest.kt

Comment thread app/src/main/java/io/nekohasekai/sagernet/fmt/olcrtc/OlcrtcFmt.kt
@hawkff

hawkff commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

Applied the current review fixes in 3dc68cb9:

  • reject imported client IDs that cannot round-trip
  • ignore unused VP8 values for datachannel profiles
  • preserve permissive Jitsi host parsing while handling bracketed IPv6

Namespace validation is running on the updated branch.

Comment on lines +275 to +276
authority.startsWith('[') -> {
val closingBracket = authority.indexOf(']')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 IPv6 hosts become domains

When a Jitsi room uses a bracketed IPv6 signaling host, this branch returns the bare literal, such as 2001:db8::1. The DNS direct-force caller only skips values that isIpAddress() recognizes, and that check handles IPv4-style octets, so this IPv6 literal is treated as a domain and emitted as full:2001:db8::1. That can leave the config with an invalid or non-matching DNS rule instead of cleanly skipping IP signaling targets. The IPv6 host path should either return no domain here or be filtered by an IP check that recognizes IPv6 before adding full:.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

No change is needed here. ConfigBuilder filters this value through String.isIpAddress(), which explicitly checks both NGUtil.isIpv4Address() and NGUtil.isIpv6Address(). The bare compressed IPv6 literal is recognized and skipped, so it is not emitted as a full: domain rule.

@hawkff

hawkff commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #157, which carries this validation with the matching runtime pin and recovery changes at the tested combined SHA.

@hawkff hawkff closed this Jul 14, 2026
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