Skip to content

Commit

Permalink
Annotate SIP validation errors with Twirp codes.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennwc committed Nov 7, 2024
1 parent 5bd7e73 commit e8d8912
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions sip/sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/twitchtv/twirp"
"maps"
"math"
"net/netip"
Expand Down Expand Up @@ -151,7 +152,7 @@ func ValidateDispatchRules(rules []*livekit.SIPDispatchRuleInfo) error {
key := ruleKey{Pin: pin, Trunk: trunk, Number: normalizeNumber(number)}
r2 := byRuleKey[key]
if r2 != nil {
return fmt.Errorf("Conflicting SIP Dispatch Rules: same Trunk+Number+PIN combination for for %q and %q",
return twirp.NewErrorf(twirp.InvalidArgument, "Conflicting SIP Dispatch Rules: same Trunk+Number+PIN combination for for %q and %q",
printID(r.SipDispatchRuleId), printID(r2.SipDispatchRuleId))
}
byRuleKey[key] = r
Expand Down Expand Up @@ -217,7 +218,7 @@ func normalizeNumber(num string) string {
func validateTrunkInbound(byInbound map[string]*livekit.SIPInboundTrunkInfo, t *livekit.SIPInboundTrunkInfo) error {
if len(t.AllowedNumbers) == 0 {
if t2 := byInbound[""]; t2 != nil {
return fmt.Errorf("Conflicting inbound SIP Trunks: %q and %q, using the same number(s) %s without AllowedNumbers set",
return twirp.NewErrorf(twirp.InvalidArgument, "Conflicting inbound SIP Trunks: %q and %q, using the same number(s) %s without AllowedNumbers set",
printID(t.SipTrunkId), printID(t2.SipTrunkId), printNumbers(t.Numbers))
}
byInbound[""] = t
Expand All @@ -226,7 +227,7 @@ func validateTrunkInbound(byInbound map[string]*livekit.SIPInboundTrunkInfo, t *
inboundKey := normalizeNumber(num)
t2 := byInbound[inboundKey]
if t2 != nil {
return fmt.Errorf("Conflicting inbound SIP Trunks: %q and %q, using the same number(s) %s and AllowedNumber %q",
return twirp.NewErrorf(twirp.InvalidArgument, "Conflicting inbound SIP Trunks: %q and %q, using the same number(s) %s and AllowedNumber %q",
printID(t.SipTrunkId), printID(t2.SipTrunkId), printNumbers(t.Numbers), num)
}
byInbound[inboundKey] = t
Expand Down Expand Up @@ -333,7 +334,7 @@ func MatchTrunk(trunks []*livekit.SIPInboundTrunkInfo, srcIP netip.Addr, calling
if normalizeNumber(num) == calledNorm {
// Trunk specific to the number.
if selectedTrunk != nil {
return nil, fmt.Errorf("Multiple SIP Trunks matched for %q", called)
return nil, twirp.NewErrorf(twirp.FailedPrecondition, "Multiple SIP Trunks matched for %q", called)
}
selectedTrunk = tr
// Keep searching! We want to know if there are any conflicting Trunk definitions.
Expand All @@ -345,7 +346,7 @@ func MatchTrunk(trunks []*livekit.SIPInboundTrunkInfo, srcIP netip.Addr, calling
return selectedTrunk, nil
}
if defaultTrunkCnt > 1 {
return nil, fmt.Errorf("Multiple default SIP Trunks matched for %q", called)
return nil, twirp.NewErrorf(twirp.FailedPrecondition, "Multiple default SIP Trunks matched for %q", called)
}
// Could still be nil here.
return defaultTrunk, nil
Expand All @@ -357,7 +358,8 @@ func MatchDispatchRule(trunk *livekit.SIPInboundTrunkInfo, rules []*livekit.SIPD
// Trunk can still be nil here in case none matched or were defined.
// This is still fine, but only in case we'll match exactly one wildcard dispatch rule.
if len(rules) == 0 {
return nil, &ErrNoDispatchMatched{NoRules: true, NoTrunks: trunk == nil, CalledNumber: req.CalledNumber}
err := &ErrNoDispatchMatched{NoRules: true, NoTrunks: trunk == nil, CalledNumber: req.CalledNumber}
return nil, twirp.WrapError(twirp.NewErrorf(twirp.FailedPrecondition, err.Error()), err)
}
// We split the matched dispatch rules into two sets in relation to Trunks: specific and default (aka wildcard).
// First, attempt to match any of the specific rules, where we did match the Trunk ID.
Expand Down Expand Up @@ -420,7 +422,8 @@ func MatchDispatchRule(trunk *livekit.SIPInboundTrunkInfo, rules []*livekit.SIPD
} else if best != nil {
return best, nil
}
return nil, &ErrNoDispatchMatched{NoRules: false, NoTrunks: trunk == nil, CalledNumber: req.CalledNumber}
err = &ErrNoDispatchMatched{NoRules: false, NoTrunks: trunk == nil, CalledNumber: req.CalledNumber}
return nil, twirp.WrapError(twirp.NewErrorf(twirp.FailedPrecondition, err.Error()), err)
}

// EvaluateDispatchRule checks a selected Dispatch Rule against the provided request.
Expand Down Expand Up @@ -477,7 +480,7 @@ func EvaluateDispatchRule(projectID string, trunk *livekit.SIPInboundTrunkInfo,
}
if rulePin != sentPin {
// This should never happen in practice, because matchSIPDispatchRule should remove rules with the wrong pin.
return nil, fmt.Errorf("Incorrect PIN for SIP room")
return nil, twirp.NewError(twirp.PermissionDenied, "Incorrect PIN for SIP room")
}
} else {
// Pin was sent, but room doesn't require one. Assume user accidentally pressed phone button.
Expand Down

0 comments on commit e8d8912

Please sign in to comment.