refactor(client): migrate PacketProxy to network/packetrelay#2777
Conversation
…v0.0.23) Replaces the callback-based PacketProxy API with the flow-based PacketRelay API introduced in SDK v0.0.23, eliminating boilerplate goroutines and adopting the SDK's built-in DNS intercept and timeout decorators. - Bump SDK to v0.0.23 - Delete client/go/outline/dnsintercept package (replaced by SDK) - Replace network.PacketProxy with packetrelay.PacketRelay throughout - Replace lwip2transport.ConfigureDevice with ConfigureDeviceWithRelay - Use sdk network/dnsintercept.InterceptDNSPacketRelay for UDP DNS routing - Use sdk network/packetrelay.TimeoutPacketRelay (30s base, 5s DNS) - Inline TCP DNS redirect into outline_dns_intercept.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@greptile review |
Greptile SummaryThis PR replaces the callback-based
Confidence Score: 5/5Safe to merge; the refactor is a clean API migration with no functional regressions and one opportunistic correctness fix. All changed call-sites consistently adopt the new PacketRelay API. The DNS interception logic — truncate-first, switch to forward on UDP health confirmation — is faithfully preserved. The shared baseListener between both relay paths is intentional and correct (PacketListenerRelay is stateless; each NewAssociation creates an independent socket). The dnsListener carries the required 5 s write-idle timeout, satisfying the SDK's documented MUST constraint for the dnsRelay parameter. The only comment is on the incidental log-level inversion fix in relay.go. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
OS["OS (UDP traffic)"] --> relayMain
check["UDP connectivity check\n(onNetworkChanged)"] -->|"UDP healthy → SetRelay(relayForward)"| relayMain
check -->|"UDP blocked → SetRelay(relayTrunc)"| relayMain
relayMain{{"DelegatePacketRelay\n(relayMain)\nstarts with relayTrunc"}}
relayMain -->|"UDP available"| relayForward["InterceptDNSPacketRelay\n(relayForward)"]
relayMain -->|"UDP blocked"| relayTrunc["InterceptDNSPacketRelay\n(relayTrunc)"]
relayForward -->|"DNS → linkLocalDNS"| dnsListener["PacketListenerRelay\n(dnsListener, 5s timeout)\n→ remoteDNS resolver"]
relayForward -->|"non-DNS"| baseListener["PacketListenerRelay\n(baseListener)\n→ proxy transport"]
relayTrunc -->|"DNS → linkLocalDNS"| dnsTruncRelay["dnstruncate.PacketRelay\n(returns TC=1 immediately)"]
relayTrunc -->|"non-DNS"| baseListener
OS2["OS (TCP traffic)"] --> sdForward["sdForward closure\n(TCP DNS: linkLocalDNS → remoteDNS)"]
sdForward --> sdDial["sd.Dial (proxy transport)"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
OS["OS (UDP traffic)"] --> relayMain
check["UDP connectivity check\n(onNetworkChanged)"] -->|"UDP healthy → SetRelay(relayForward)"| relayMain
check -->|"UDP blocked → SetRelay(relayTrunc)"| relayMain
relayMain{{"DelegatePacketRelay\n(relayMain)\nstarts with relayTrunc"}}
relayMain -->|"UDP available"| relayForward["InterceptDNSPacketRelay\n(relayForward)"]
relayMain -->|"UDP blocked"| relayTrunc["InterceptDNSPacketRelay\n(relayTrunc)"]
relayForward -->|"DNS → linkLocalDNS"| dnsListener["PacketListenerRelay\n(dnsListener, 5s timeout)\n→ remoteDNS resolver"]
relayForward -->|"non-DNS"| baseListener["PacketListenerRelay\n(baseListener)\n→ proxy transport"]
relayTrunc -->|"DNS → linkLocalDNS"| dnsTruncRelay["dnstruncate.PacketRelay\n(returns TC=1 immediately)"]
relayTrunc -->|"non-DNS"| baseListener
OS2["OS (TCP traffic)"] --> sdForward["sdForward closure\n(TCP DNS: linkLocalDNS → remoteDNS)"]
sdForward --> sdDial["sd.Dial (proxy transport)"]
Reviews (3): Last reviewed commit: "chore: update outline-sdk to dnsintercep..." | Re-trigger Greptile |
Give each TimeoutPacketRelay its own PacketListenerRelay so their independent idle timeouts cannot close each other's underlying listener. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SetRelay only fails for nil relay; both relays are provably non-nil. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ohnorobo
left a comment
There was a problem hiding this comment.
thanks, very nice simplification
Replaces the callback-based PacketProxy API with the flow-based PacketRelay API introduced in SDK v0.0.23, eliminating boilerplate goroutines and adopting the SDK's built-in DNS intercept and timeout decorators.
Depends on OutlineFoundation/outline-sdk#625