ICE is the answer to a hard question: given two browsers, neither of which has a public IP address, how do you get a packet from one to the other? It works by having both peers collect every plausible network address they can reach themselves on — local interfaces, public IPs discovered via STUN, relayed addresses obtained from TURN — and then trying every pair in priority order until one combination connects.
The candidates exchanged during ICE are part of the SDP offer/answer flow, which is why you can't run WebRTC without a signaling server even though the eventual connection is peer-to-peer. The signaling channel is purely the introduction; ICE is the handshake that follows.
When ICE succeeds, you get a direct peer connection most of the time and a TURN-relayed fallback when both peers are stuck behind symmetric NATs. When ICE fails, the post-mortem usually finds a misconfigured TURN server, a candidate that was filtered by a corporate firewall, or a network where UDP is blocked entirely.