diff --git a/go.mod b/go.mod index 591c453a6..49f802464 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jxskiss/base62 v1.1.0 github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598 - github.com/livekit/protocol v1.27.1-0.20241022061022-caa595ed3292 + github.com/livekit/protocol v1.27.2-0.20241107143334-083fcac1318d github.com/livekit/psrpc v0.6.1-0.20240924010758-9f0a4268a3b9 github.com/mackerelio/go-osstat v0.2.5 github.com/magefile/mage v1.15.0 @@ -128,7 +128,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.uber.org/zap/exp v0.2.0 // indirect + go.uber.org/zap/exp v0.3.0 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect diff --git a/go.sum b/go.sum index b1ea92974..3fd464cd0 100644 --- a/go.sum +++ b/go.sum @@ -165,8 +165,8 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598 h1:yLlkHk2feSLHstD9n4VKg7YEBR4rLODTI4WE8gNBEnQ= github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598/go.mod h1:jwKUCmObuiEDH0iiuJHaGMXwRs3RjrB4G6qqgkr/5oE= -github.com/livekit/protocol v1.27.1-0.20241022061022-caa595ed3292 h1:wVzOLGSjJpCsdKHKKpPxYhXW/JL90l0XYFQbeINSdP4= -github.com/livekit/protocol v1.27.1-0.20241022061022-caa595ed3292/go.mod h1:nxRzmQBKSYK64gqr7ABWwt78hvrgiO2wYuCojRYb7Gs= +github.com/livekit/protocol v1.27.2-0.20241107143334-083fcac1318d h1:UW4fSs0v1wqaiLDKvhyCVZzEqv3jXBfayALMcTal1c8= +github.com/livekit/protocol v1.27.2-0.20241107143334-083fcac1318d/go.mod h1:BrACGxSTlbAe+T9uXLOiiWyYrJ2gNc0mTYmZJPq/4aA= github.com/livekit/psrpc v0.6.1-0.20240924010758-9f0a4268a3b9 h1:33oBjGpVD9tYkDXQU42tnHl8eCX9G6PVUToBVuCUyOs= github.com/livekit/psrpc v0.6.1-0.20240924010758-9f0a4268a3b9/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0= github.com/mackerelio/go-osstat v0.2.5 h1:+MqTbZUhoIt4m8qzkVoXUJg1EuifwlAJSk4Yl2GXh+o= @@ -350,8 +350,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.uber.org/zap/exp v0.2.0 h1:FtGenNNeCATRB3CmB/yEUnjEFeJWpB/pMcy7e2bKPYs= -go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ= +go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= +go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/pkg/service/ioservice_sip.go b/pkg/service/ioservice_sip.go index 093a184f8..8c4204828 100644 --- a/pkg/service/ioservice_sip.go +++ b/pkg/service/ioservice_sip.go @@ -19,6 +19,8 @@ import ( "errors" "net/netip" + "github.com/twitchtv/twirp" + "github.com/livekit/protocol/livekit" "github.com/livekit/protocol/logger" "github.com/livekit/protocol/rpc" @@ -57,7 +59,7 @@ func (s *IOInfoService) EvaluateSIPDispatchRules(ctx context.Context, req *rpc.E srcIP, err := netip.ParseAddr(req.SrcAddress) if req.SrcAddress != "" && err != nil { log.Errorw("cannot parse source IP", err) - return nil, err + return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err) } trunk, err := s.matchSIPTrunk(ctx, req.SipTrunkId, req.CallingNumber, req.CalledNumber, srcIP) if err != nil { @@ -102,7 +104,7 @@ func (s *IOInfoService) GetSIPTrunkAuthentication(ctx context.Context, req *rpc. srcIP, err := netip.ParseAddr(req.SrcAddress) if req.SrcAddress != "" && err != nil { log.Errorw("cannot parse source IP", err) - return nil, err + return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err) } trunk, err := s.matchSIPTrunk(ctx, "", req.From, req.To, srcIP) if err != nil { diff --git a/pkg/service/sip.go b/pkg/service/sip.go index 38d45245a..c73284e6d 100644 --- a/pkg/service/sip.go +++ b/pkg/service/sip.go @@ -16,10 +16,9 @@ package service import ( "context" - "errors" - "fmt" "time" + "github.com/twitchtv/twirp" "google.golang.org/protobuf/types/known/emptypb" "github.com/livekit/protocol/livekit" @@ -70,7 +69,7 @@ func (s *SIPService) CreateSIPTrunk(ctx context.Context, req *livekit.CreateSIPT return nil, ErrSIPNotConnected } if len(req.InboundNumbersRegex) != 0 { - return nil, fmt.Errorf("Trunks with InboundNumbersRegex are deprecated. Use InboundNumbers instead.") + return nil, twirp.NewError(twirp.InvalidArgument, "Trunks with InboundNumbersRegex are deprecated. Use InboundNumbers instead.") } // Keep ID empty, so that validation can print "" instead of a non-existent ID in the error. @@ -112,12 +111,13 @@ func (s *SIPService) CreateSIPInboundTrunk(ctx context.Context, req *livekit.Cre if s.store == nil { return nil, ErrSIPNotConnected } + if err := req.Validate(); err != nil { + return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err) + } info := req.Trunk - if info == nil { - return nil, errors.New("trunk info is required") - } else if info.SipTrunkId != "" { - return nil, errors.New("trunk ID must be empty") + if info.SipTrunkId != "" { + return nil, twirp.NewError(twirp.InvalidArgument, "trunk ID must be empty") } AppendLogFields(ctx, "trunk", logger.Proto(req.Trunk)) @@ -148,11 +148,13 @@ func (s *SIPService) CreateSIPOutboundTrunk(ctx context.Context, req *livekit.Cr if s.store == nil { return nil, ErrSIPNotConnected } + if err := req.Validate(); err != nil { + return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err) + } + info := req.Trunk - if info == nil { - return nil, errors.New("trunk info is required") - } else if info.SipTrunkId != "" { - return nil, errors.New("trunk ID must be empty") + if info.SipTrunkId != "" { + return nil, twirp.NewError(twirp.InvalidArgument, "trunk ID must be empty") } AppendLogFields(ctx, "trunk", logger.Proto(req.Trunk)) @@ -171,6 +173,10 @@ func (s *SIPService) GetSIPInboundTrunk(ctx context.Context, req *livekit.GetSIP if s.store == nil { return nil, ErrSIPNotConnected } + if req.SipTrunkId == "" { + return nil, twirp.NewError(twirp.InvalidArgument, "trunk ID is required") + } + AppendLogFields(ctx, "trunkID", req.SipTrunkId) trunk, err := s.store.LoadSIPInboundTrunk(ctx, req.SipTrunkId) if err != nil { @@ -187,6 +193,9 @@ func (s *SIPService) GetSIPOutboundTrunk(ctx context.Context, req *livekit.GetSI if s.store == nil { return nil, ErrSIPNotConnected } + if req.SipTrunkId == "" { + return nil, twirp.NewError(twirp.InvalidArgument, "trunk ID is required") + } AppendLogFields(ctx, "trunkID", req.SipTrunkId) trunk, err := s.store.LoadSIPOutboundTrunk(ctx, req.SipTrunkId) @@ -253,6 +262,9 @@ func (s *SIPService) DeleteSIPTrunk(ctx context.Context, req *livekit.DeleteSIPT if s.store == nil { return nil, ErrSIPNotConnected } + if req.SipTrunkId == "" { + return nil, twirp.NewError(twirp.InvalidArgument, "trunk ID is required") + } AppendLogFields(ctx, "trunkID", req.SipTrunkId) if err := s.store.DeleteSIPTrunk(ctx, req.SipTrunkId); err != nil { @@ -269,6 +281,9 @@ func (s *SIPService) CreateSIPDispatchRule(ctx context.Context, req *livekit.Cre if s.store == nil { return nil, ErrSIPNotConnected } + if err := req.Validate(); err != nil { + return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err) + } AppendLogFields(ctx, "request", logger.Proto(req), @@ -326,6 +341,9 @@ func (s *SIPService) DeleteSIPDispatchRule(ctx context.Context, req *livekit.Del if s.store == nil { return nil, ErrSIPNotConnected } + if req.SipDispatchRuleId == "" { + return nil, twirp.NewError(twirp.InvalidArgument, "dispatch rule ID is required") + } info, err := s.store.LoadSIPDispatchRule(ctx, req.SipDispatchRuleId) if err != nil {