@@ -42,7 +42,6 @@ import (
4242 "github.com/livekit/protocol/rpc"
4343 lksip "github.com/livekit/protocol/sip"
4444 "github.com/livekit/protocol/tracer"
45- "github.com/livekit/protocol/utils"
4645 "github.com/livekit/protocol/utils/traceid"
4746 "github.com/livekit/psrpc"
4847 lksdk "github.com/livekit/server-sdk-go/v2"
@@ -65,8 +64,6 @@ const (
6564 inviteOKRetryAttempts = 5
6665 inviteOKRetryAttemptsNoACK = 2
6766 inviteOkAckLateTimeout = inviteOkRetryIntervalMax
68-
69- inviteCredentialValidity = 60 * time .Minute // Allow reuse of credentials for 1h
7067)
7168
7269var errNoACK = errors .New ("no ACK received for 200 OK" )
@@ -137,50 +134,23 @@ func (s *Server) getCallInfo(id string) *inboundCallInfo {
137134 return c
138135}
139136
140- func (s * Server ) cleanupInvites () {
141- ticker := time .NewTicker (5 * time .Minute ) // Periodic cleanup every 5 minutes
142- defer ticker .Stop ()
143- for {
144- select {
145- case <- s .closing .Watch ():
146- return
147- case <- ticker .C :
148- s .imu .Lock ()
149- for it := s .inviteTimeoutQueue .IterateRemoveAfter (inviteCredentialValidity ); it .Next (); {
150- key := it .Item ().Value
151- delete (s .inProgressInvites , key )
152- }
153- s .imu .Unlock ()
137+ func (s * Server ) getInvite (sipCallID string ) * inProgressInvite {
138+ s .imu .Lock ()
139+ defer s .imu .Unlock ()
140+ for i := range s .inProgressInvites {
141+ if s .inProgressInvites [i ].sipCallID == sipCallID {
142+ return s .inProgressInvites [i ]
154143 }
155144 }
156- }
157-
158- func (s * Server ) getInvite (sipCallID , toTag , fromTag string ) * inProgressInvite {
159- key := dialogKey {
160- sipCallID : sipCallID ,
161- toTag : toTag ,
162- fromTag : fromTag ,
163- }
164-
165- s .imu .RLock ()
166- is , exists := s .inProgressInvites [key ]
167- s .imu .RUnlock ()
168- if ! exists {
169- s .imu .Lock ()
170- is , exists = s .inProgressInvites [key ]
171- if ! exists {
172- is = & inProgressInvite {sipCallID : sipCallID , timeoutLink : utils.TimeoutQueueItem [dialogKey ]{Value : key }}
173- s .inProgressInvites [key ] = is
174- }
175- s .imu .Unlock ()
145+ if len (s .inProgressInvites ) >= digestLimit {
146+ s .inProgressInvites = s .inProgressInvites [1 :]
176147 }
177-
178- // Always reset the timeout link, whether just created or not
179- s .inviteTimeoutQueue .Reset (& is .timeoutLink )
148+ is := & inProgressInvite {sipCallID : sipCallID }
149+ s .inProgressInvites = append (s .inProgressInvites , is )
180150 return is
181151}
182152
183- func (s * Server ) handleInviteAuth (tid traceid.ID , log logger.Logger , req * sip.Request , tx sip.ServerTransaction , from , username , password string , inviteState * inProgressInvite ) (ok bool ) {
153+ func (s * Server ) handleInviteAuth (tid traceid.ID , log logger.Logger , req * sip.Request , tx sip.ServerTransaction , from , username , password string ) (ok bool ) {
184154 log = log .WithValues (
185155 "username" , username ,
186156 "passwordHash" , hashPassword (password ),
@@ -201,6 +171,14 @@ func (s *Server) handleInviteAuth(tid traceid.ID, log logger.Logger, req *sip.Re
201171 _ = tx .Respond (sip .NewResponseFromRequest (req , 100 , "Processing" , nil ))
202172 }
203173
174+ // Extract SIP Call ID for tracking in-progress invites
175+ sipCallID := ""
176+ if h := req .CallID (); h != nil {
177+ sipCallID = h .Value ()
178+ }
179+ inviteState := s .getInvite (sipCallID )
180+ log = log .WithValues ("inviteStateSipCallID" , sipCallID )
181+
204182 h := req .GetHeader ("Proxy-Authorization" )
205183 if h == nil {
206184 inviteState .challenge = digest.Challenge {
@@ -252,6 +230,7 @@ func (s *Server) handleInviteAuth(tid traceid.ID, log logger.Logger, req *sip.Re
252230 // Check if we have a valid challenge state
253231 if inviteState .challenge .Realm == "" {
254232 log .Warnw ("No challenge state found for authentication attempt" , errors .New ("missing challenge state" ),
233+ "sipCallID" , sipCallID ,
255234 "expectedRealm" , UserAgent ,
256235 )
257236 _ = tx .Respond (sip .NewResponseFromRequest (req , 401 , "Bad credentials" , nil ))
@@ -326,18 +305,20 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
326305 s .log .Errorw ("cannot parse source IP" , err , "fromIP" , src )
327306 return psrpc .NewError (psrpc .MalformedRequest , errors .Wrap (err , "cannot parse source IP" ))
328307 }
329- sipCallID := legCallIDFromReq (req )
308+ callID := lksip .NewCallID ()
309+ tid := traceid .FromGUID (callID )
330310 tr := callTransportFromReq (req )
331311 legTr := legTransportFromReq (req )
332312 log := s .log .WithValues (
333- "sipCallID" , sipCallID ,
313+ "callID" , callID ,
314+ "traceID" , tid .String (),
334315 "fromIP" , src .Addr (),
335316 "toIP" , req .Destination (),
336317 "transport" , tr ,
337318 )
338319
339320 var call * inboundCall
340- cc := s .newInbound (log , s .ContactURI (legTr ), req , tx , func (headers map [string ]string ) map [string ]string {
321+ cc := s .newInbound (log , LocalTag ( callID ), s .ContactURI (legTr ), req , tx , func (headers map [string ]string ) map [string ]string {
341322 c := call
342323 if c == nil || len (c .attrsToHdr ) == 0 {
343324 return headers
@@ -350,53 +331,25 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
350331 })
351332 log = LoggerWithParams (log , cc )
352333 log = LoggerWithHeaders (log , cc )
334+ cc .log = log
335+ log .Infow ("processing invite" )
353336
354337 if err := cc .ValidateInvite (); err != nil {
355- log .Errorw ("invalid invite" , err )
356338 if s .conf .HideInboundPort {
357339 cc .Drop ()
358340 } else {
359341 cc .RespondAndDrop (sip .StatusBadRequest , "Bad request" )
360342 }
361343 return psrpc .NewError (psrpc .InvalidArgument , errors .Wrap (err , "invite validation failed" ))
362344 }
363-
364- // Establish ID
365- fromTag , _ := req .From ().Params .Get ("tag" ) // always exists, via ValidateInvite() check
366- toParams := req .To ().Params // To() always exists, via ValidateInvite() check
367- if toParams == nil {
368- toParams = sip .NewParams ()
369- req .To ().Params = toParams
370- }
371- toTag , ok := toParams .Get ("tag" )
372- if ! ok {
373- // No to-tag on the invite means we need to generate one per RFC 3261 section 12.
374- // Generate a new to-tag early, to make sure both INVITES have the same ID.
375- toTag = utils .NewGuid ("" )
376- toParams .Add ("tag" , toTag )
377- }
378- inviteProgress := s .getInvite (sipCallID , toTag , fromTag )
379- callID := inviteProgress .lkCallID
380- if callID == "" {
381- callID = lksip .NewCallID ()
382- inviteProgress .lkCallID = callID
383- }
384- cc .id = LocalTag (callID )
385- tid := traceid .FromGUID (sipCallID )
386-
387- log = log .WithValues ("callID" , callID )
388- log = log .WithValues ("traceID" , tid .String ())
389- cc .log = log
390- log .Infow ("processing invite" )
391-
392345 ctx , span := tracer .Start (ctx , "Server.onInvite" )
393346 defer span .End ()
394347
395348 s .cmu .RLock ()
396- existing := s .byCallID [sipCallID ]
349+ existing := s .byCallID [cc . SIPCallID () ]
397350 s .cmu .RUnlock ()
398351 if existing != nil && existing .cc .InviteCSeq () < cc .InviteCSeq () {
399- log .Infow ("accepting reinvite" , "content-type" , req .ContentType (), "content-length" , req .ContentLength ())
352+ log .Infow ("accepting reinvite" , "sipCallID" , existing . cc . ID (), " content-type" , req .ContentType (), "content-length" , req .ContentLength ())
400353 existing .log ().Infow ("reinvite" , "content-type" , req .ContentType (), "content-length" , req .ContentLength (), "cseq" , cc .InviteCSeq ())
401354 cc .AcceptAsKeepAlive (existing .cc .OwnSDP ())
402355 return nil
@@ -423,7 +376,7 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
423376
424377 callInfo := & rpc.SIPCall {
425378 LkCallId : callID ,
426- SipCallId : sipCallID ,
379+ SipCallId : cc . SIPCallID () ,
427380 SourceIp : src .Addr ().String (),
428381 Address : ToSIPUri ("" , cc .Address ()),
429382 From : ToSIPUri ("" , from ),
@@ -494,15 +447,15 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
494447 // We will send password request anyway, so might as well signal that the progress is made.
495448 cc .Processing ()
496449 }
497- s .getCallInfo (sipCallID ).countInvite (log , req )
498- if ! s .handleInviteAuth (tid , log , req , tx , from .User , r .Username , r .Password , inviteProgress ) {
450+ s .getCallInfo (cc . SIPCallID () ).countInvite (log , req )
451+ if ! s .handleInviteAuth (tid , log , req , tx , from .User , r .Username , r .Password ) {
499452 cmon .InviteErrorShort ("unauthorized" )
500453 // handleInviteAuth will generate the SIP Response as needed
501454 return psrpc .NewErrorf (psrpc .PermissionDenied , "invalid credentials were provided" )
502455 }
503456 // ok
504457 case AuthAccept :
505- s .getCallInfo (sipCallID ).countInvite (log , req )
458+ s .getCallInfo (cc . SIPCallID () ).countInvite (log , req )
506459 // ok
507460 }
508461
@@ -1422,10 +1375,11 @@ func (c *inboundCall) transferCall(ctx context.Context, transferTo string, heade
14221375
14231376}
14241377
1425- func (s * Server ) newInbound (log logger.Logger , contact URI , invite * sip.Request , inviteTx sip.ServerTransaction , getHeaders setHeadersFunc ) * sipInbound {
1378+ func (s * Server ) newInbound (log logger.Logger , id LocalTag , contact URI , invite * sip.Request , inviteTx sip.ServerTransaction , getHeaders setHeadersFunc ) * sipInbound {
14261379 c := & sipInbound {
14271380 log : log ,
14281381 s : s ,
1382+ id : id ,
14291383 invite : invite ,
14301384 inviteTx : inviteTx ,
14311385 legTr : legTransportFromReq (invite ),
0 commit comments