Skip to main content

Overview

A Configuration defines how peer-to-peer communication via PeerConnection is established or re-established. Configurations may be set up once and reused across multiple connections.
Source: configuration.go:9-59
Configurations are treated as readonly. As long as they are unmodified, they are safe for concurrent use.

Type Definition

type Configuration struct {
    ICEServers                  []ICEServer
    ICETransportPolicy          ICETransportPolicy
    BundlePolicy                BundlePolicy
    RTCPMuxPolicy               RTCPMuxPolicy
    PeerIdentity                string
    Certificates                []Certificate
    ICECandidatePoolSize        uint8
    SDPSemantics                SDPSemantics
    AlwaysNegotiateDataChannels bool
}

Fields

ICEServers

ICEServers
[]ICEServer
Defines a slice describing servers available to be used by ICE, such as STUN and TURN servers.
Source: configuration.go:15-17
ICE servers help with NAT traversal and relay traffic when direct peer-to-peer connections aren’t possible.
config := webrtc.Configuration{
    ICEServers: []webrtc.ICEServer{
        {
            URLs: []string{"stun:stun.l.google.com:19302"},
        },
        {
            URLs:       []string{"turn:turn.example.com:3478"},
            Username:   "user",
            Credential: "pass",
        },
    },
}
STUN servers help discover your public IP address, while TURN servers relay traffic when direct connections fail.

ICETransportPolicy

ICETransportPolicy
ICETransportPolicy
Indicates which candidates the ICEAgent is allowed to use.
Source: configuration.go:19-21
Possible values:
  • ICETransportPolicyAll (default) - All candidates may be used
  • ICETransportPolicyRelay - Only relay candidates (TURN) may be used
config := webrtc.Configuration{
    ICETransportPolicy: webrtc.ICETransportPolicyRelay,
}
Using ICETransportPolicyRelay requires a TURN server and prevents direct peer-to-peer connections.

BundlePolicy

BundlePolicy
BundlePolicy
Indicates which media-bundling policy to use when gathering ICE candidates.
Source: configuration.go:23-25
Possible values:
  • BundlePolicyBalanced (default)
  • BundlePolicyMaxBundle - Bundle all media on a single transport
  • BundlePolicyMaxCompat - Use separate transports for each media type
config := webrtc.Configuration{
    BundlePolicy: webrtc.BundlePolicyMaxBundle,
}

RTCPMuxPolicy

RTCPMuxPolicy
RTCPMuxPolicy
Indicates which RTCP-mux policy to use when gathering ICE candidates.
Source: configuration.go:27-29
Possible values:
  • RTCPMuxPolicyRequire (default) - Only gather RTCP candidates for multiplexed RTCP
  • RTCPMuxPolicyNegotiate - Gather ICE candidates for both RTP and RTCP
config := webrtc.Configuration{
    RTCPMuxPolicy: webrtc.RTCPMuxPolicyRequire,
}
Modern WebRTC implementations typically use RTCPMuxPolicyRequire to multiplex RTP and RTCP on the same port.

PeerIdentity

PeerIdentity
string
Sets the target peer identity for the PeerConnection. The PeerConnection will not establish a connection to a remote peer unless it can be successfully authenticated with the provided name.
Source: configuration.go:31-34
config := webrtc.Configuration{
    PeerIdentity: "[email protected]",
}

Certificates

Certificates
[]Certificate
Describes a set of certificates that the PeerConnection uses to authenticate.
Source: configuration.go:36-47
Valid values are created through calls to the GenerateCertificate function. If this value is absent, a default set of certificates is generated for each PeerConnection instance.
// Generate a custom certificate
cert, err := webrtc.GenerateCertificate(privateKey)
if err != nil {
    return err
}

config := webrtc.Configuration{
    Certificates: []webrtc.Certificate{*cert},
}
// Certificates are auto-generated if not provided
config := webrtc.Configuration{}
pc, err := webrtc.NewPeerConnection(config)
Although any given DTLS connection will use only one certificate, this attribute allows multiple certificates that support different algorithms. Certificates cannot be modified after the PeerConnection is created.

ICECandidatePoolSize

ICECandidatePoolSize
uint8
Describes the size of the prefetched ICE pool.
Source: configuration.go:49-50
Setting this to a non-zero value allows ICE candidates to be gathered before calling CreateOffer() or CreateAnswer().
config := webrtc.Configuration{
    ICECandidatePoolSize: 1,
}
Currently, pool sizes greater than 1 are not supported and will result in an error.

SDPSemantics

SDPSemantics
SDPSemantics
Controls the type of SDP offers accepted by and SDP answers generated by the PeerConnection.
Source: configuration.go:52-54
Possible values:
  • SDPSemanticsUnifiedPlan (default) - Modern standard
  • SDPSemanticsPlanB - Legacy Google Plan B
  • SDPSemanticsUnifiedPlanWithFallback - Try Unified Plan, fall back to Plan B
config := webrtc.Configuration{
    SDPSemantics: webrtc.SDPSemanticsUnifiedPlan,
}
Use SDPSemanticsUnifiedPlan for new applications. Plan B is deprecated but may be needed for compatibility with older implementations.

AlwaysNegotiateDataChannels

AlwaysNegotiateDataChannels
bool
Specifies whether the application prefers to always negotiate data channels in the initial SDP offer.
Source: configuration.go:56-58
config := webrtc.Configuration{
    AlwaysNegotiateDataChannels: true,
}
When set to true, a data channel section will be included in the SDP even if no data channels have been created yet.

Usage Examples

Minimal configuration with a public STUN server:
config := webrtc.Configuration{
    ICEServers: []webrtc.ICEServer{
        {
            URLs: []string{"stun:stun.l.google.com:19302"},
        },
    },
}

pc, err := webrtc.NewPeerConnection(config)
if err != nil {
    panic(err)
}
defer pc.Close()
Configuration including TURN for relay:
config := webrtc.Configuration{
    ICEServers: []webrtc.ICEServer{
        {
            URLs: []string{"stun:stun.l.google.com:19302"},
        },
        {
            URLs:       []string{"turn:turn.example.com:3478"},
            Username:   "username",
            Credential: "password",
        },
    },
}

pc, err := webrtc.NewPeerConnection(config)
if err != nil {
    panic(err)
}
defer pc.Close()
Force all traffic through TURN (no direct connections):
config := webrtc.Configuration{
    ICEServers: []webrtc.ICEServer{
        {
            URLs:       []string{"turn:turn.example.com:3478"},
            Username:   "username",
            Credential: "password",
        },
    },
    ICETransportPolicy: webrtc.ICETransportPolicyRelay,
}

pc, err := webrtc.NewPeerConnection(config)
if err != nil {
    panic(err)
}
defer pc.Close()
Full configuration with all options:
import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
)

// Generate certificate
sk, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
cert, _ := webrtc.GenerateCertificate(sk)

config := webrtc.Configuration{
    ICEServers: []webrtc.ICEServer{
        {
            URLs: []string{"stun:stun.l.google.com:19302"},
        },
        {
            URLs:       []string{"turn:turn.example.com:3478"},
            Username:   "user",
            Credential: "pass",
        },
    },
    ICETransportPolicy:          webrtc.ICETransportPolicyAll,
    BundlePolicy:                webrtc.BundlePolicyMaxBundle,
    RTCPMuxPolicy:               webrtc.RTCPMuxPolicyRequire,
    PeerIdentity:                "",
    Certificates:                []webrtc.Certificate{*cert},
    ICECandidatePoolSize:        1,
    SDPSemantics:                webrtc.SDPSemanticsUnifiedPlan,
    AlwaysNegotiateDataChannels: false,
}

pc, err := webrtc.NewPeerConnection(config)
if err != nil {
    panic(err)
}
defer pc.Close()

Modifying Configuration

After creating a PeerConnection, you can update certain configuration properties:
// Get current configuration
currentConfig := pc.GetConfiguration()

// Modify ICE servers
currentConfig.ICEServers = []webrtc.ICEServer{
    {
        URLs: []string{"stun:new-stun.example.com:19302"},
    },
}

// Apply updated configuration
err := pc.SetConfiguration(currentConfig)
if err != nil {
    // Handle error - some properties cannot be changed
}
Immutable Properties: The following cannot be modified after creation:
  • Certificates
  • BundlePolicy
  • RTCPMuxPolicy
  • ICECandidatePoolSize (after SetLocalDescription)
  • PeerIdentity

Best Practices

Use STUN for Discovery

Always include at least one STUN server to discover your public IP address for NAT traversal.

Include TURN for Reliability

Add a TURN server for scenarios where direct connections fail (strict firewalls, symmetric NATs).

Reuse Configurations

Create one configuration and reuse it across multiple PeerConnections to save resources.

Test Relay-Only

Test with ICETransportPolicyRelay to verify your TURN server works before production.

Common Patterns

Environment-Based Configuration

func getConfig(env string) webrtc.Configuration {
    config := webrtc.Configuration{
        ICEServers: []webrtc.ICEServer{
            {
                URLs: []string{"stun:stun.l.google.com:19302"},
            },
        },
    }

    if env == "production" {
        config.ICEServers = append(config.ICEServers, webrtc.ICEServer{
            URLs:       []string{"turn:turn.prod.example.com:3478"},
            Username:   os.Getenv("TURN_USERNAME"),
            Credential: os.Getenv("TURN_PASSWORD"),
        })
    }

    return config
}

Configuration Validation

func validateConfig(config webrtc.Configuration) error {
    if len(config.ICEServers) == 0 {
        return errors.New("at least one ICE server required")
    }

    for _, server := range config.ICEServers {
        if len(server.URLs) == 0 {
            return errors.New("ICE server must have at least one URL")
        }
    }

    return nil
}

See Also

Build docs developers (and LLMs) love