Repository navigation
Honor interface/IP filters for srflx and relay STUN requests - #899
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes srflx candidate gathering so STUN requests honor InterfaceFilter / IPFilter by binding srflx sockets to the filtered local interface addresses (instead of wildcard binds that allow kernel routing to choose disallowed interfaces).
Changes:
- Refactors
gatherCandidatesSrflxto use per-interface/per-IP binds when interface/IP filters are configured, while preserving wildcard bind behavior when no filters are set. - Adds a regression test that captures
ListenUDPbind addresses and verifies only the allowed interface IP is used for srflx gathering.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
gather.go |
Applies interface/IP filtering to srflx STUN socket binding to prevent leaking candidates from disallowed interfaces. |
gather_test.go |
Adds a test net shim to capture srflx bind addresses and a regression test for InterfaceFilter behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #899 +/- ##
==========================================
- Coverage 88.37% 88.35% -0.02%
==========================================
Files 44 44
Lines 5591 5626 +35
==========================================
+ Hits 4941 4971 +30
- Misses 451 452 +1
- Partials 199 203 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
2be2a19 to
b4bda32
Compare
b4bda32 to
0c217ac
Compare
JoTurk
left a comment
There was a problem hiding this comment.
Thank you, I wanted to do this for a while now, thank you for picking it.
|
This change caused an unexpected change in behavior for us in Snowflake. We had been using if !keepLocalAddresses {
s.SetIPFilter(func(ip net.IP) (keep bool) {
keep = !util.IsLocal(ip) && !ip.IsLoopback() && !ip.IsUnspecified()
return
})
s.SetICEMulticastDNSMode(ice.MulticastDNSModeDisabled)
}After upgrading pion/ice beyond v4.2.2, peers that are behind NAT (which is most of them) stopped sending STUN requests. We traced the cause: the peer want to know its own external IP address outside the NAT, which it can do by means of a STUN server; but in order to send the STUN request, it needs to bind to a LAN IP address from inside the NAT, which is now prohibited by a This isn't asking for any action from you, just FYI that this change had a side effect we did not expect. As a workaround, we've gone back to editing the text of SDP to filter out LAN and localhost candidates. This is the change where we originally migrated to |
|
@uumaro we're so sorry about this, in v5 we'll try to make it possible to filter by allocation type |
Change WithIPFilter to accept IPFilterInfo containing local IP and candidate type. context for this change: #899 (comment)
|
@uumaro thank you again for reporting this, we're currently working on releasing v5 with some changes, and it's a good time to report this because we can change the API, if #1017 got merged, you can bring back the IP filter and it will look like: ice.WithIPFilter(func(info ice.IPFilterInfo) bool {
if info.CandidateType != ice.CandidateTypeHost {
return true // allow local addresses for STUN/TURN.
}
return HostFilter(info.IP)
}) |
Change WithIPFilter to accept IPFilterInfo containing local IP and candidate type. context for this change: #899 (comment)
Summary
This PR fixes a bug where server-reflexive (srflx) STUN requests and TURN relay UDP sockets could be sent from interfaces that were filtered out by
InterfaceFilter/IPFilter.Previously:
0.0.0.0/::)0.0.0.0:0)That allowed kernel routing to choose source interfaces outside configured filters, which could expose public IPs from non-allowed adapters.
With this change, when interface/IP filters are configured:
Root cause
localInterfaces(...)filtering was applied to host gathering but not consistently to srflx and relay local bind paths.What changed
gather.gogatherCandidatesSrflxto support two modes:interfaceFilteroripFilterset):localInterfaces(...).gatherCandidatesRelay(TURN/UDP path) with the same two-mode behavior:0.0.0.0:0bind behavior.gather_test.gosrflxListenCaptureNetandTestGatherCandidatesSrflxRespectsInterfaceFilter.relayListenCaptureNetandTestGatherCandidatesRelayRespectsInterfaceFilter.TestGatherCandidatesRelayCallsAddRelayCandidates.Backward compatibility
InterfaceFilter/IPFilter.Reference issue
Fixes #727