I seek to implement the following connection logic:
In order to get through their routers/NAT and connect via WebRTC, web browser clients first connect to a server to have holes punched in their firewalls.
That server keeps a list of the public IPs and open ports of all connected browsers.
Every connected browser can request that list and directly connect to others without the server knowing who connected with whom.
The core part is the requirement that (for the sake of privacy) the server must not be able to determine which pairs of browsers are connected.
Can this be achieved with the JavaScript WebRTC API provided in modern web browsers?
I am certain that this is possible with any client that provides direct access to the UDP protocol, but I assume web browsers won't allow that, in the same way that they enable HTTP and WebSocket connections but don't allow forming raw TCP connections.
In case the given logic can indeed be implemented in the browser, a secondary question would be if multiple connections can be handled using the same hole, or if any new browser-browser connection requires a new roundtrip to the server for hole punching.
Short answer: Yes, this indeed can be achieved.
Short answer for secondary question: It depends...
WebRTC requires:
A signaling server - that is used to pass the RTC candidates between the browsers.
A STUN server to make these "hole punches"
Usually - to work and bypass complicated NAT - a TURN server to proxy data as a fallback.
The standard way is after one browser asks to initiate a call with a different browser - each browser generates candidates with the help of the STUN server, shares them through the signaling server to the destination browser. The WebRTC ICE implementation tests and measures the best candidate pairs and then a connection is initiated. If the NAT is too complicated - it falls back to a TURN server.
In case a TURN server must be used - the server has to know the candidate pair because all the data gets through the server.
In other cases, where ICE can find candidates with direct access or with the help of STUN - you can find some workarounds to obfuscate the talking pairs from the servers.
You didn't mention how many browsers should participate and what the actual WebRTC usage is. But as an example - you can generate a mesh so every browser connects to every browser, then the signaling and STUN servers cannot guess who actually talks to whom. Now each browser can talk to the one it wants without any additional data sent to the servers.
P.S. webtorrent use webrtc to download torrents. It is very similar to your request.