diff --git a/go.mod b/go.mod index 8dcb6e37..dda109d8 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/livekit/protocol v1.45.1 github.com/livekit/psrpc v0.7.1 github.com/livekit/server-sdk-go/v2 v2.16.1 - github.com/livekit/sipgo v0.13.2-0.20260325054441-8dee0d1c8190 + github.com/livekit/sipgo v0.13.2-0.20260405181755-35e98b69cf07 github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12 github.com/ory/dockertest/v3 v3.12.0 github.com/pion/rtp v1.10.1 diff --git a/go.sum b/go.sum index af7bd89d..6ef8e985 100644 --- a/go.sum +++ b/go.sum @@ -142,8 +142,8 @@ github.com/livekit/psrpc v0.7.1 h1:ms37az0QTD3UXIWuUC5D/SkmKOlRMVRsI261eBWu/Vw= github.com/livekit/psrpc v0.7.1/go.mod h1:bZ4iHFQptTkbPnB0LasvRNu/OBYXEu1NA6O5BMFo9kk= github.com/livekit/server-sdk-go/v2 v2.16.1 h1:ZkIA9OdVvQ6Up1uW/RtQ0YJUgYMJ6+ywOmDg0jX7bTg= github.com/livekit/server-sdk-go/v2 v2.16.1/go.mod h1:oQbYijcbPzfjBAOzoq7tz9Ktqur8JNRCd923VP8xOQQ= -github.com/livekit/sipgo v0.13.2-0.20260325054441-8dee0d1c8190 h1:faSHy5wbIRo9RXYtc4cV7M89GsXbbv69TIdkyVnMH2E= -github.com/livekit/sipgo v0.13.2-0.20260325054441-8dee0d1c8190/go.mod h1:aDa6mbFktNzA1D917RhFlIB5IOfNBTmrwt+/lX960j0= +github.com/livekit/sipgo v0.13.2-0.20260405181755-35e98b69cf07 h1:BW7XseN+9RhH14gQm7EFxqal61XRUvg6xlE/jROwiD0= +github.com/livekit/sipgo v0.13.2-0.20260405181755-35e98b69cf07/go.mod h1:aDa6mbFktNzA1D917RhFlIB5IOfNBTmrwt+/lX960j0= github.com/mackerelio/go-osstat v0.2.5 h1:+MqTbZUhoIt4m8qzkVoXUJg1EuifwlAJSk4Yl2GXh+o= github.com/mackerelio/go-osstat v0.2.5/go.mod h1:atxwWF+POUZcdtR1wnsUcQxTytoHG4uhl2AKKzrOajY= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= diff --git a/pkg/config/config.go b/pkg/config/config.go index e59c9d29..e1dd76fd 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -74,21 +74,22 @@ type Config struct { ApiSecret string `yaml:"api_secret"` // required (env LIVEKIT_API_SECRET) WsUrl string `yaml:"ws_url"` // required (env LIVEKIT_WS_URL) - HealthPort int `yaml:"health_port"` - PrometheusPort int `yaml:"prometheus_port"` - PProfPort int `yaml:"pprof_port"` - SIPPort int `yaml:"sip_port"` // announced SIP signaling port - SIPPortListen int `yaml:"sip_port_listen"` // SIP signaling port to listen on - SIPHostname string `yaml:"sip_hostname"` - SIPRingingInterval time.Duration `yaml:"sip_ringing_interval"` // from 1 sec up to 60 (default '1s') - TCP *TCPConfig `yaml:"tcp"` - TLS *TLSConfig `yaml:"tls"` - RTPPort rtcconfig.PortRange `yaml:"rtp_port"` - Logging logger.Config `yaml:"logging"` - ClusterID string `yaml:"cluster_id"` // cluster this instance belongs to - MaxCpuUtilization float64 `yaml:"max_cpu_utilization"` - MaxActiveCalls int `yaml:"max_active_calls"` // if set, used for affinity-based routing - SIPTrunkIds []string `yaml:"sip_trunk_ids"` // if set, only accept calls for these trunk IDs + HealthPort int `yaml:"health_port"` + PrometheusPort int `yaml:"prometheus_port"` + PProfPort int `yaml:"pprof_port"` + SIPPort int `yaml:"sip_port"` // announced SIP signaling port + SIPPortListen int `yaml:"sip_port_listen"` // SIP signaling port to listen on + SIPHostname string `yaml:"sip_hostname"` + OutboundRouteHeaders []string `yaml:"outbound_route_headers"` // Route headers prepended to outbound requests, e.g. "" + SIPRingingInterval time.Duration `yaml:"sip_ringing_interval"` // from 1 sec up to 60 (default '1s') + TCP *TCPConfig `yaml:"tcp"` + TLS *TLSConfig `yaml:"tls"` + RTPPort rtcconfig.PortRange `yaml:"rtp_port"` + Logging logger.Config `yaml:"logging"` + ClusterID string `yaml:"cluster_id"` // cluster this instance belongs to + MaxCpuUtilization float64 `yaml:"max_cpu_utilization"` + MaxActiveCalls int `yaml:"max_active_calls"` // if set, used for affinity-based routing + SIPTrunkIds []string `yaml:"sip_trunk_ids"` // if set, only accept calls for these trunk IDs UseExternalIP bool `yaml:"use_external_ip"` LocalNet string `yaml:"local_net"` // local IP net to use, e.g. 192.168.0.0/24 diff --git a/pkg/sip/features.go b/pkg/sip/features.go index 7b3bf4d3..e27299c9 100644 --- a/pkg/sip/features.go +++ b/pkg/sip/features.go @@ -1,3 +1,6 @@ package sip -const signalLoggingFeatureFlag = "sip.signal_logging" +const ( + signalLoggingFeatureFlag = "sip.signal_logging" + outboundRouteHeadersFeatureFlag = "sip.outbound_route_headers" +) diff --git a/pkg/sip/inbound.go b/pkg/sip/inbound.go index 2409ba32..51ea02c9 100644 --- a/pkg/sip/inbound.go +++ b/pkg/sip/inbound.go @@ -1008,7 +1008,7 @@ func (c *inboundCall) runMediaConn(tid traceid.ID, offerData []byte, enc livekit c.mon.SDPSize(len(answerData), false) c.log().Debugw("SDP answer", "sdp", string(answerData)) - mconf.Processor = c.s.handler.GetMediaProcessor(features, featureFlags, c.call.LkCallId) + mconf.Processor = c.s.handler.GetMediaProcessor(features, featureFlags, string(c.cc.ID())) if err = c.media.SetConfig(mconf); err != nil { return nil, err } diff --git a/pkg/sip/outbound.go b/pkg/sip/outbound.go index e3f65a5c..25847d63 100644 --- a/pkg/sip/outbound.go +++ b/pkg/sip/outbound.go @@ -135,6 +135,9 @@ func (c *Client) newCall(ctx context.Context, tid traceid.ID, conf *config.Confi } return AttrsToHeaders(r.LocalParticipant.Attributes(), c.sipConf.attrsToHeaders, headers) }) + if sipConf.featureFlags[outboundRouteHeadersFeatureFlag] == "true" { + call.cc.routeHeaders = conf.OutboundRouteHeaders + } call.mon = c.mon.NewCall(stats.Outbound, sipConf.host, sipConf.address) var err error @@ -769,11 +772,12 @@ func (c *Client) newOutbound(log logger.Logger, id LocalTag, from, contact URI, } type sipOutbound struct { - log logger.Logger - c *Client - id LocalTag - from *sip.FromHeader - contact *sip.ContactHeader + log logger.Logger + c *Client + id LocalTag + from *sip.FromHeader + contact *sip.ContactHeader + routeHeaders []string mu sync.RWMutex tag RemoteTag @@ -1038,6 +1042,10 @@ func (c *sipOutbound) attemptInvite(ctx context.Context, callID sip.CallIDHeader req.AppendHeader(h) } + for _, route := range c.routeHeaders { + req.PrependHeader(sip.NewHeader("Route", route)) + } + tx, err := c.c.sipCli.TransactionRequest(req) if err != nil { return nil, nil, err