Skip to main content

Overview

The CandidateType enum represents the type of ICE candidate as defined in RFC 5245. Each type indicates how the candidate address was obtained and affects its priority in the connection establishment process.

Type Definition

type CandidateType byte

Types

CandidateTypeHost

const CandidateTypeHost CandidateType = iota + 1
A host candidate represents a local network address obtained directly from a network interface. Characteristics:
  • Highest priority (preference: 126)
  • No STUN/TURN servers required
  • Direct peer-to-peer connection
  • Best latency and bandwidth

CandidateTypeServerReflexive

const CandidateTypeServerReflexive
A server reflexive (srflx) candidate is discovered by sending a STUN Binding Request to a STUN server, which returns the public address as seen from the Internet. Characteristics:
  • Medium-high priority (preference: 100)
  • Requires STUN server
  • Reveals public NAT address
  • Good for NAT traversal
Short form: "srflx"

CandidateTypePeerReflexive

const CandidateTypePeerReflexive
A peer reflexive (prflx) candidate is discovered from the source address of a STUN Binding Request received from the peer. Characteristics:
  • Medium priority (preference: 110)
  • Discovered during connectivity checks
  • Created automatically by the ICE agent
  • Not gathered explicitly
Short form: "prflx"

CandidateTypeRelay

const CandidateTypeRelay
A relay candidate is obtained by allocating an address on a TURN relay server. All media flows through the relay. Characteristics:
  • Lowest priority (preference: 0)
  • Requires TURN server
  • Guaranteed connectivity
  • Higher latency and bandwidth cost
  • Most reliable for restrictive NATs

CandidateTypeUnspecified

const CandidateTypeUnspecified CandidateType = 0
Represents an unspecified or unknown candidate type.

Methods

String

func (c CandidateType) String() string
Returns the string representation of the candidate type. Returns:
  • "host" for CandidateTypeHost
  • "srflx" for CandidateTypeServerReflexive
  • "prflx" for CandidateTypePeerReflexive
  • "relay" for CandidateTypeRelay
  • "Unknown candidate type" for CandidateTypeUnspecified or invalid values

Preference

func (c CandidateType) Preference() uint16
Returns the RFC 5245 recommended preference weight for the candidate type. Higher values indicate higher priority. Returns:
  • 126 for CandidateTypeHost
  • 110 for CandidateTypePeerReflexive
  • 100 for CandidateTypeServerReflexive
  • 0 for CandidateTypeRelay and CandidateTypeUnspecified

Priority Order

1. Host (126)            ← Highest priority
2. Peer Reflexive (110)
3. Server Reflexive (100)
4. Relay (0)             ← Lowest priority

Usage Examples

// Only gather host candidates (no STUN/TURN)
agent, _ := ice.NewAgentWithOptions(
    ice.WithCandidateTypes([]ice.CandidateType{
        ice.CandidateTypeHost,
    }),
)

Default Behavior

When no candidate types are specified, all three gatherable types are enabled:
// Default configuration
agent, _ := ice.NewAgentWithOptions()
// Equivalent to:
agent, _ := ice.NewAgentWithOptions(
    ice.WithCandidateTypes([]ice.CandidateType{
        ice.CandidateTypeHost,
        ice.CandidateTypeServerReflexive,
        ice.CandidateTypeRelay,
    }),
)
Peer reflexive candidates are never explicitly gathered. They are discovered automatically during connectivity checks and don’t need to be specified in the candidate types list.

Server Requirements

Candidate TypeRequired Servers
HostNone
Server ReflexiveSTUN server
Peer ReflexiveNone (discovered)
RelayTURN server

NAT Traversal

Best case (Direct connection):
Host ←→ Host
Good case (NAT traversal with STUN):
Host/Srflx ←→ Host/Srflx
Fallback case (TURN relay):
Host/Srflx ←→ Relay ←→ Host/Srflx

Address Rewrite Rules

You can specify which candidate type to use for address rewriting:
import "github.com/pion/ice/v4"

agent, _ := ice.NewAgentWithOptions(
    ice.WithAddressRewriteRules(
        ice.AddressRewriteRule{
            External:        []string{"203.0.113.10"},
            AsCandidateType: ice.CandidateTypeServerReflexive,
        },
    ),
)

Acceptance Timing

You can configure minimum wait times before accepting each candidate type:
agent, _ := ice.NewAgentWithOptions(
    ice.WithHostAcceptanceMinWait(0),                  // Immediate
    ice.WithSrflxAcceptanceMinWait(500 * time.Millisecond),
    ice.WithPrflxAcceptanceMinWait(1 * time.Second),
    ice.WithRelayAcceptanceMinWait(2 * time.Second),
)
This allows the agent to wait for potentially better candidates before settling on a relay connection.

Build docs developers (and LLMs) love