Documentation
¶
Overview ¶
Package call provides authenticated direct 1:1 WebRTC calls.
Media is protected end to end by DTLS-SRTP. The complete SDP, including the ephemeral DTLS certificate fingerprint and ICE candidates, is hybrid-signed by the caller's or callee's existing device identity before it is sent over the messaging channel. This prevents a signaling service or storage node from substituting a media endpoint.
This package deliberately does not implement SFU/group-call encryption. Such calls require an audited RFC 9605 SFrame implementation and an audited forward-secure group key manager such as RFC 9420 MLS.
Index ¶
- Constants
- Variables
- type Config
- type Endpoint
- func (e *Endpoint) Accept(ctx context.Context, remote protocol.NodePublicIdentity, offer Signal) (*Session, Signal, error)
- func (e *Endpoint) Identity() protocol.NodePublicIdentity
- func (e *Endpoint) Start(ctx context.Context, remote protocol.NodePublicIdentity, media Media) (*Session, Signal, error)
- type Media
- type Session
- func (s *Session) ApplyAnswer(answer Signal) error
- func (s *Session) CallID() string
- func (s *Session) Close() error
- func (s *Session) ConnectionState() webrtc.PeerConnectionState
- func (s *Session) OnConnectionStateChange(handler func(webrtc.PeerConnectionState))
- func (s *Session) OnTrack(handler func(*webrtc.TrackRemote, *webrtc.RTPReceiver))
- func (s *Session) ReplaceAudioTrack(track webrtc.TrackLocal) error
- func (s *Session) ReplaceVideoTrack(track webrtc.TrackLocal) error
- type Signal
- type SignalType
Constants ¶
const ( ProtocolVersion = 1 MaxSignalBytes = 96 * 1024 MaxSDPBytes = 64 * 1024 MaxICECandidates = 64 MaxICEServers = 8 MaxICEURLs = 16 MaxConcurrentCalls = 64 MaxRememberedCallIDs = 4096 DefaultSignalLifetime = 2 * time.Minute MaxSignalLifetime = 5 * time.Minute DefaultCallDuration = time.Hour MaxCallDuration = 24 * time.Hour )
Variables ¶
var ( ErrInvalidSignal = errors.New("invalid direct-call signal") ErrExpiredSignal = errors.New("expired direct-call signal") ErrSignalReplay = errors.New("direct-call signal replay") ErrCallLimit = errors.New("concurrent direct-call limit reached") ErrAnswerAlreadyUsed = errors.New("call answer was already applied") )
Functions ¶
This section is empty.
Types ¶
type Endpoint ¶
type Endpoint struct {
// contains filtered or unexported fields
}
Endpoint owns the bounded replay cache and WebRTC configuration for one device. A new ephemeral ECDSA certificate is generated for every call.
func NewEndpoint ¶
func (*Endpoint) Accept ¶
func (e *Endpoint) Accept(ctx context.Context, remote protocol.NodePublicIdentity, offer Signal) (*Session, Signal, error)
Accept verifies an offer before parsing SDP or allocating a PeerConnection, reserves its call ID against replay, and returns the signed answer.
func (*Endpoint) Identity ¶
func (e *Endpoint) Identity() protocol.NodePublicIdentity
type Media ¶
Media describes the only media sections accepted by direct-call protocol v1. At least one of Audio or Video must be set.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session wraps the media-facing part of a direct PeerConnection. Frontends can provide platform-specific Pion tracks, but never handle key material.
func (*Session) ApplyAnswer ¶
ApplyAnswer authenticates the callee and the DTLS fingerprint before Pion processes the remote SDP. A session accepts exactly one answer.
func (*Session) ConnectionState ¶
func (s *Session) ConnectionState() webrtc.PeerConnectionState
func (*Session) OnConnectionStateChange ¶
func (s *Session) OnConnectionStateChange(handler func(webrtc.PeerConnectionState))
func (*Session) OnTrack ¶
func (s *Session) OnTrack(handler func(*webrtc.TrackRemote, *webrtc.RTPReceiver))
func (*Session) ReplaceAudioTrack ¶
func (s *Session) ReplaceAudioTrack(track webrtc.TrackLocal) error
func (*Session) ReplaceVideoTrack ¶
func (s *Session) ReplaceVideoTrack(track webrtc.TrackLocal) error
type Signal ¶
type Signal struct {
Version uint8 `json:"version"`
CallID string `json:"call_id"`
Type SignalType `json:"type"`
InitiatorID string `json:"initiator_id"`
ResponderID string `json:"responder_id"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
Media Media `json:"media"`
SDP string `json:"sdp"`
Signature protocol.HybridSignature `json:"signature"`
}
Signal is safe to serialize inside an end-to-end encrypted chat message. The signature authenticates every field, including all ICE candidates and the ephemeral DTLS certificate fingerprint contained in SDP.
type SignalType ¶
type SignalType string
const ( SignalOffer SignalType = "offer" SignalAnswer SignalType = "answer" )