webrtc
webrtc copied to clipboard
Port Mapping Support
Feature Request: Support for Port Mapping in Docker Deployments
Description: When deploying Pion-based WebRTC applications in Docker containers, there's often a mismatch between the port that the application listens on internally and the port that's exposed/forwarded to the outside world through Docker's port mapping. This creates issues during SDP negotiation, where the peer expects to connect to the mapped port (e.g., 3478 on the host) but the SDP offers/answers contain the internal container port (e.g., 3478 inside the container).
Current Behavior: Pion currently binds to and advertises the port it listens on internally within the container. When Docker maps this internal port to a different host port (e.g., -p 3478:3478), the SDP still contains the internal port, causing connection failures since peers attempt to connect to the wrong port.
Requested Feature: Add support for port mapping awareness in Pion, where:
1.The library can be configured with a port mapping (internal vs. external ports) during initialization or when creating transports. 2.The SDP offers/answers are automatically adjusted to advertise the externally mapped port instead of the internal port. 3.This should work seamlessly for both UDP and TCP-based transports (ICE candidates). Use Case Example: A Docker container running a Pion-based SFU (Selective Forwarding Unit) listens on port 3478 internally. Docker maps this to host port 5000 (-p 5000:3478). When generating SDP, Pion should advertise port 5000 instead of 3478 so that peers connect to the correct host port.
Implementation Suggestions:
Add a SetPortMapping(internalPort, externalPort) method to the API or transport interfaces. Modify ICE candidate generation to use the mapped port when appropriate. Ensure backward compatibility (default to internal port if no mapping is configured). Impact: This feature would greatly simplify WebRTC deployments in containerized environments, making Pion more production-friendly for cloud-native setups.
~~We have SetNAT1To1IPs in the settings engine. It should work for your use case, https://github.com/pion/webrtc/blob/f5d98ceac9537df6293b258ae99074125699b7a9/settingengine.go#L265C25-L265C38~~
Let me know if you have any issue using it!
Edit: never mind I miss read the issue.
It just map the IPs not ports
It just map the IPs not ports
Yeah, I misread your issue at first. I think supporting port mapping like this is definitely possible without breaking changes. We'd probably just need to introduce a callback like mapPort(port uint16) uint16 Because normally ICE doesn't use a single static port, So not sure if this would be helpful for UDP ICE.
For now you can just edit the ICE candidates manually before sending them to the clients, And map them to your docker ports, It should work. Or just use the same port mapping.
you are right,thank you
Should I modify ICE candidates in OnICECandidate callback function?
@langhuihui this is a great idea!
I would implement it in @langhuihui
What do you think of implementing it as a callback? Users may want to modify ports depending on
- Candidate Type
- Interface
- Port
Maybe we start with a callback that does func(Candidate, Interface) int and a user can define it and replaces the port? We have a private member in ice.Candidate that is mappedPort (or something like that) that when the candidates gets serialized is used?
We can be pretty scrappy about it. If you want to a start a PR I would love to help :)
Hello, @xinze-zheng is working on implementing this 🙏