github.com/pion/webrtc/v4@v4.0.1/dtlsrole.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package webrtc
     5  
     6  import (
     7  	"github.com/pion/sdp/v3"
     8  )
     9  
    10  // DTLSRole indicates the role of the DTLS transport.
    11  type DTLSRole byte
    12  
    13  const (
    14  	// DTLSRoleUnknown is the enum's zero-value
    15  	DTLSRoleUnknown DTLSRole = iota
    16  
    17  	// DTLSRoleAuto defines the DTLS role is determined based on
    18  	// the resolved ICE role: the ICE controlled role acts as the DTLS
    19  	// client and the ICE controlling role acts as the DTLS server.
    20  	DTLSRoleAuto
    21  
    22  	// DTLSRoleClient defines the DTLS client role.
    23  	DTLSRoleClient
    24  
    25  	// DTLSRoleServer defines the DTLS server role.
    26  	DTLSRoleServer
    27  )
    28  
    29  const (
    30  	// https://tools.ietf.org/html/rfc5763
    31  	/*
    32  		The answerer MUST use either a
    33  		setup attribute value of setup:active or setup:passive.  Note that
    34  		if the answerer uses setup:passive, then the DTLS handshake will
    35  		not begin until the answerer is received, which adds additional
    36  		latency. setup:active allows the answer and the DTLS handshake to
    37  		occur in parallel.  Thus, setup:active is RECOMMENDED.
    38  	*/
    39  	defaultDtlsRoleAnswer = DTLSRoleClient
    40  	/*
    41  		The endpoint that is the offerer MUST use the setup attribute
    42  		value of setup:actpass and be prepared to receive a client_hello
    43  		before it receives the answer.
    44  	*/
    45  	defaultDtlsRoleOffer = DTLSRoleAuto
    46  )
    47  
    48  func (r DTLSRole) String() string {
    49  	switch r {
    50  	case DTLSRoleAuto:
    51  		return "auto"
    52  	case DTLSRoleClient:
    53  		return "client"
    54  	case DTLSRoleServer:
    55  		return "server"
    56  	default:
    57  		return ErrUnknownType.Error()
    58  	}
    59  }
    60  
    61  // Iterate a SessionDescription from a remote to determine if an explicit
    62  // role can been determined from it. The decision is made from the first role we we parse.
    63  // If no role can be found we return DTLSRoleAuto
    64  func dtlsRoleFromRemoteSDP(sessionDescription *sdp.SessionDescription) DTLSRole {
    65  	if sessionDescription == nil {
    66  		return DTLSRoleAuto
    67  	}
    68  
    69  	for _, mediaSection := range sessionDescription.MediaDescriptions {
    70  		for _, attribute := range mediaSection.Attributes {
    71  			if attribute.Key == "setup" {
    72  				switch attribute.Value {
    73  				case sdp.ConnectionRoleActive.String():
    74  					return DTLSRoleClient
    75  				case sdp.ConnectionRolePassive.String():
    76  					return DTLSRoleServer
    77  				default:
    78  					return DTLSRoleAuto
    79  				}
    80  			}
    81  		}
    82  	}
    83  
    84  	return DTLSRoleAuto
    85  }
    86  
    87  func connectionRoleFromDtlsRole(d DTLSRole) sdp.ConnectionRole {
    88  	switch d {
    89  	case DTLSRoleClient:
    90  		return sdp.ConnectionRoleActive
    91  	case DTLSRoleServer:
    92  		return sdp.ConnectionRolePassive
    93  	case DTLSRoleAuto:
    94  		return sdp.ConnectionRoleActpass
    95  	default:
    96  		return sdp.ConnectionRole(0)
    97  	}
    98  }