Skip to content

Commit eb8fbe3

Browse files
committed
self-review
1 parent 907c826 commit eb8fbe3

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

pkg/sip/inbound.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137,21 +137,22 @@ func (s *Server) getCallInfo(id string) *inboundCallInfo {
137137
return c
138138
}
139139

140-
func (s *Server) getInvite(sipCallID string) *inProgressInvite {
140+
func (s *Server) getInvite(sipCallID, toTag, fromTag string) *inProgressInvite {
141+
key := fmt.Sprintf("%s:%s:%s", sipCallID, toTag, fromTag)
141142
s.imu.Lock()
142143
defer s.imu.Unlock()
143-
is, ok := s.inProgressInvites[sipCallID]
144+
is, ok := s.inProgressInvites[key]
144145
if ok {
145146
return is
146147
}
147148
is = &inProgressInvite{sipCallID: sipCallID}
148-
s.inProgressInvites[sipCallID] = is
149+
s.inProgressInvites[key] = is
149150

150151
go func() {
151152
time.Sleep(inviteCredentialValidity)
152153
s.imu.Lock()
153154
defer s.imu.Unlock()
154-
delete(s.inProgressInvites, sipCallID)
155+
delete(s.inProgressInvites, key)
155156
}()
156157
return is
157158
}
@@ -309,7 +310,7 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
309310
)
310311

311312
var call *inboundCall
312-
cc := s.newInbound(log, "unassigned", s.ContactURI(legTr), req, tx, func(headers map[string]string) map[string]string {
313+
cc := s.newInbound(log, s.ContactURI(legTr), req, tx, func(headers map[string]string) map[string]string {
313314
c := call
314315
if c == nil || len(c.attrsToHdr) == 0 {
315316
return headers
@@ -333,21 +334,22 @@ func (s *Server) processInvite(req *sip.Request, tx sip.ServerTransaction) (retE
333334
}
334335

335336
// Establish ID
336-
if _, ok := req.To().Params.Get("tag"); !ok {
337+
fromTag, _ := req.From().Params.Get("tag") // always exists, via ValidateInvite() check
338+
toTag, ok := req.To().Params.Get("tag") // To() always exists, via ValidateInvite() check
339+
if !ok {
337340
// No to-tag on the invite means we need to generate one per RFC 3261 section 12.
338-
if !inviteHasAuth(req) {
339-
// No auth = a 407 response and another INVITE+auth.
340-
// Generate a new to-tag early, to make sure both INVITES have the same ID.
341-
uuid, _ := uuid.NewV4() // Same as NewResponseFromRequest in sipgo
342-
req.To().Params.Add("tag", uuid.String())
343-
}
341+
// Generate a new to-tag early, to make sure both INVITES have the same ID.
342+
uuid, _ := uuid.NewV4() // Same as NewResponseFromRequest in sipgo
343+
toTag = uuid.String()
344+
req.To().Params.Add("tag", toTag)
344345
}
345-
inviteProgress := s.getInvite(req.CallID().Value())
346+
inviteProgress := s.getInvite(sipCallID, toTag, fromTag)
346347
callID := inviteProgress.lkCallID
347348
if callID == "" {
348349
callID = lksip.NewCallID()
349350
inviteProgress.lkCallID = callID
350351
}
352+
cc.id = LocalTag(callID)
351353

352354
log = log.WithValues("callID", callID)
353355
cc.log = log
@@ -1310,11 +1312,11 @@ func (c *inboundCall) transferCall(ctx context.Context, transferTo string, heade
13101312

13111313
}
13121314

1313-
func (s *Server) newInbound(log logger.Logger, id LocalTag, contact URI, invite *sip.Request, inviteTx sip.ServerTransaction, getHeaders setHeadersFunc) *sipInbound {
1315+
func (s *Server) newInbound(log logger.Logger, contact URI, invite *sip.Request, inviteTx sip.ServerTransaction, getHeaders setHeadersFunc) *sipInbound {
13141316
c := &sipInbound{
13151317
log: log,
13161318
s: s,
1317-
id: id,
1319+
id: "unassigned",
13181320
invite: invite,
13191321
inviteTx: inviteTx,
13201322
legTr: legTransportFromReq(invite),

pkg/sip/service_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ func TestSameCallIDForAuthFlow(t *testing.T) {
633633
username = "testuser"
634634
password = "testpass"
635635
callID = "same-call-id@test.com"
636+
fromTag = "fixed-from-tag-12345"
636637
)
637638

638639
var capturedCallIDs []string
@@ -701,13 +702,20 @@ func TestSameCallIDForAuthFlow(t *testing.T) {
701702
offerData, err := offer.SDP.Marshal()
702703
require.NoError(t, err)
703704

705+
inviteFromHeader := sip.FromHeader{
706+
DisplayName: fromUser,
707+
Address: sip.Uri{User: fromUser, Host: sipServerAddress},
708+
Params: sip.NewParams().Add("tag", fromTag), // Key bit here
709+
}
710+
704711
// Create first INVITE request (without auth)
705712
inviteRecipient := sip.Uri{User: toUser, Host: sipServerAddress}
706713
inviteRequest1 := sip.NewRequest(sip.INVITE, inviteRecipient)
707714
inviteRequest1.SetDestination(sipServerAddress)
708715
inviteRequest1.SetBody(offerData)
709716
inviteRequest1.AppendHeader(sip.NewHeader("Content-Type", "application/sdp"))
710717
inviteRequest1.AppendHeader(sip.NewHeader("Call-ID", callID))
718+
inviteRequest1.AppendHeader(&inviteFromHeader)
711719

712720
tx1, err := sipClient.TransactionRequest(inviteRequest1)
713721
require.NoError(t, err)
@@ -719,6 +727,12 @@ func TestSameCallIDForAuthFlow(t *testing.T) {
719727
res1 = getResponseOrFail(t, tx1)
720728
require.Equal(t, sip.StatusCode(407), res1.StatusCode, "First request should receive 407 Unauthorized")
721729

730+
// Get the To tag from the 407 response
731+
toHeader := res1.To()
732+
require.NotNil(t, toHeader, "407 response should have To header")
733+
_, ok := toHeader.Params.Get("tag")
734+
require.True(t, ok, "407 response To header should have tag parameter")
735+
722736
// Get the challenge from first response
723737
authHeader1 := res1.GetHeader("Proxy-Authenticate")
724738
require.NotNil(t, authHeader1, "First response should have Proxy-Authenticate header")
@@ -737,13 +751,15 @@ func TestSameCallIDForAuthFlow(t *testing.T) {
737751
})
738752
require.NoError(t, err, "Should be able to compute digest response")
739753

740-
// Create second INVITE request (with auth) using the SAME Call-ID
754+
// Create second INVITE request (with auth) using the SAME Call-ID, From tag, and To tag
741755
inviteRequest2 := sip.NewRequest(sip.INVITE, inviteRecipient)
742756
inviteRequest2.SetDestination(sipServerAddress)
743757
inviteRequest2.SetBody(offerData)
744758
inviteRequest2.AppendHeader(sip.NewHeader("Content-Type", "application/sdp"))
745759
inviteRequest2.AppendHeader(sip.NewHeader("Call-ID", callID))
746760
inviteRequest2.AppendHeader(sip.NewHeader("Proxy-Authorization", cred.String()))
761+
inviteRequest2.AppendHeader(&inviteFromHeader)
762+
inviteRequest2.AppendHeader(toHeader)
747763

748764
tx2, err := sipClient.TransactionRequest(inviteRequest2)
749765
require.NoError(t, err)

0 commit comments

Comments
 (0)