Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/khaki-stamps-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"github.com/livekit/protocol": minor
---

Adding ability to specify media timeout per CreateSIPParticipant request and per Dispatch Rule.

278 changes: 145 additions & 133 deletions livekit/livekit_sip.pb.go

Large diffs are not rendered by default.

700 changes: 351 additions & 349 deletions livekit/livekit_sip.twirp.go

Large diffs are not rendered by default.

46 changes: 35 additions & 11 deletions livekit/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"slices"
"strconv"
"strings"
"time"

"golang.org/x/text/language"
"google.golang.org/grpc/codes"
Expand All @@ -16,6 +17,10 @@ import (
"github.com/livekit/protocol/utils/xtwirp"
)

// MaxSIPMediaTimeout is the maximum allowed trunk / API value for media_timeout
// (no incoming RTP before the RTP path is torn down)
const MaxSIPMediaTimeout = 10 * time.Minute

var (
_ xtwirp.ErrorMeta = (*SIPStatus)(nil)
_ error = (*SIPStatus)(nil)
Expand Down Expand Up @@ -686,13 +691,19 @@ func (p *SIPDispatchRuleInfo) Validate() error {
if p.Rule == nil {
return errors.New("missing rule")
}
if err := p.Media.Validate(); err != nil {
return err
}
return nil
}

func (p *SIPDispatchRuleUpdate) Validate() error {
if err := p.TrunkIds.Validate(); err != nil {
return err
}
if err := p.Media.Validate(); err != nil {
return err
}
return nil
}

Expand All @@ -702,7 +713,7 @@ func (p *SIPDispatchRuleUpdate) Apply(info *SIPDispatchRuleInfo) error {
}
applyListUpdate(&info.TrunkIds, p.TrunkIds)
applyUpdatePtr(&info.Rule, p.Rule)
applyUpdatePtr(&info.Media, p.Media)
applyUpdatePtr(&info.Media, p.Media) // TODO: Consider applying partial updates
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dennwc , we might need to revisit this to avoid it being a pain long term

applyUpdate(&info.Name, p.Name)
applyUpdate(&info.Metadata, p.Metadata)
applyUpdate(&info.MediaEncryption, p.MediaEncryption)
Expand Down Expand Up @@ -777,16 +788,16 @@ func (p *CreateSIPParticipantRequest) Validate() error {
return fmt.Errorf("DisplayName must be a valid quoted string: %w", err)
}
}

// Validate destination if provided
if err := p.Destination.Validate(); err != nil {
return err
}

if err := validateHeaders(p.Headers); err != nil {
return err
}

if err := p.Media.Validate(); err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -1061,20 +1072,33 @@ func (p *CreateSIPParticipantRequest) Upgrade() {
p.Media = p.Media.UpgradeWith(p.MediaEncryption)
}

func (p *SIPMediaEncryption) Deref() SIPMediaEncryption {
if p == nil {
return SIPMediaEncryption_SIP_MEDIA_ENCRYPT_DISABLE
}
return *p
}
Comment on lines +1075 to +1080
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved as-is.


func (p *SIPMediaConfig) Validate() error {
if p == nil { // When optional, p can be nil
return nil
}
for _, c := range p.Codecs {
if err := c.Validate(); err != nil {
return err
}
}
return nil
}

func (p *SIPMediaEncryption) Deref() SIPMediaEncryption {
if p == nil {
return SIPMediaEncryption_SIP_MEDIA_ENCRYPT_DISABLE
if p.MediaTimeout != nil {
dur := p.MediaTimeout.AsDuration()
if dur < 0 {
return errors.New("media_timeout must not be negative")
}
// Zero means use default
if dur > MaxSIPMediaTimeout {
return fmt.Errorf("media_timeout must not exceed %v", MaxSIPMediaTimeout)
}
}
return *p
return nil
}

func (p *SIPMediaConfig) UpgradeWith(enc SIPMediaEncryption) *SIPMediaConfig {
Expand Down
Loading
Loading