Files
cunicu/docs/dev/signaling.md
Steffen Vogel 3bee839348 fix: Update copyright years
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
2025-01-01 22:45:39 +01:00

3.5 KiB

Session Signaling

Lets assume two peers P_a & P_b are seeking to establish a ICE session.

The smaller public key (PK) of the two peers takes the role of the controlling agent. In this example PA has the role of the controlling agent as: PK(P_a) < PK(P_b).

sequenceDiagram
    autonumber

    actor Pa as Peer A
    actor Pb as Peer B
    participant b as Backend

    Pa ->> b: SessionDescription(Pa -> Pb)
    b ->> Pb: SessionDescription(Pa -> Pb)

    Pb ->> b: SessionDescription(Pb -> Pa)
    b ->> Pa: SessionDescription(Pb -> Pa)
stateDiagram-v2 
    [*] --> Unknown
    
    note right of Unknown
        No agent exists
    end note

    Unknown --> Idle: 1. Create new agent<br>2. Send local credentials

    Idle --> New: On remote credentials<br>1. Start gathering local candidates
    Idle --> Idle: Repeatedly send local credentials with back-off

    New --> Connecting: On remote candidate<br>1. Connect
    Connecting --> Checking
    Checking --> Connected
    Checking --> Failed
    Completed --> Disconnected
    Connected --> Disconnected
    Connected --> Completed
    Completed --> Closed
    Disconnected --> Closed
    Closed --> Idle: 1. Create new agent<br>2. Send local credentials
    Failed --> Closed

Session Description

Session descriptions are exchanged by one or more the signaling backends via signaling envelopes which contain signaling messages. The envelopes are containers which encrypt the carried message via asymmetric cryptography using the public key of the recipient.

Both the envelope and the message are serialized using Protobuf.

Checkout the pkg/pb/signaling.proto for details.

Backends

cunīcu can support multiple backends for signaling session information such as session IDs, ICE candidates, public keys and STUN credentials.

Available backends

  • gRPC
  • Kubernetes API server

For the use within a Kubernetes cluster also a dedicated backend using the Kubernetes api-server is available. Checkout the Backend interface for implementing your own backend.

Semantics

A backend must:

  • Must facilitate a reliable delivery envelopes between peers using their public keys as addresses.
  • Must support delivery of envelopes to a group of recipients (e.g. multicast).
  • May deliver the envelopes out-of-order.
  • May discard envelopes if the recipient is not yet known or reachable.
  • Shall be stateless. It shall not buffer or record any envelopes.

Interface

All signaling backends implement the rather simple signaling.Backend interface:

type Message = pb.SignalingMessage

type MessageHandler interface {
	OnSignalingMessage(*crypto.PublicKeyPair, *Message)
}

type Backend interface {
	io.Closer

	// Publish a signaling message to a specific peer
	Publish(ctx context.Context, kp *crypto.KeyPair, msg *Message) error

	// Subscribe to messages send by a specific peer
	Subscribe(ctx context.Context, kp *crypto.KeyPair, h MessageHandler) (bool, error)

	// Unsubscribe from messages send by a specific peer
	Unsubscribe(ctx context.Context, kp *crypto.KeyPair, h MessageHandler) (bool, error)

	// Returns the backends type identifier
	Type() signalingproto.BackendType
}