Skip to content

Commit

Permalink
fix: dialog handle Record Route and Route headers
Browse files Browse the repository at this point in the history
  • Loading branch information
emiago committed Mar 16, 2024
1 parent 9392fa6 commit 9a076d6
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ func ClientRequestAddRecordRoute(c *Client, r *sip.Request) error {
"transport": sip.NetworkToLower(r.Transport()),
"lr": "",
},
Headers: sip.NewParams(),
},
}

Expand Down
10 changes: 10 additions & 0 deletions dialog_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ func (s *DialogClientSession) Ack(ctx context.Context) error {
}

func (s *DialogClientSession) WriteAck(ctx context.Context, ack *sip.Request) error {
// Check Record-Route Header
if rr := s.InviteResponse.RecordRoute(); rr != nil {
ack.SetDestination(rr.Address.HostPort())
}

if err := s.dc.c.WriteRequest(ack); err != nil {
// Make sure we close our error
// s.Close()
Expand Down Expand Up @@ -273,6 +278,11 @@ func (s *DialogClientSession) WriteBye(ctx context.Context, bye *sip.Request) er
return fmt.Errorf("Dialog not confirmed. ACK not send?")
}

// Check Record-Route Header
if rr := s.InviteResponse.RecordRoute(); rr != nil {
bye.SetDestination(rr.Address.HostPort())
}

tx, err := dc.c.TransactionRequest(ctx, bye)
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions dialog_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ func (s *DialogServerSession) Bye(ctx context.Context) error {
return fmt.Errorf("non matching ID %q %q", s.ID, byeID)
}

// Check Route Header
if rr := bye.Route(); rr != nil {
bye.SetDestination(rr.Address.HostPort())
}

tx, err := cli.TransactionRequest(ctx, bye)
if err != nil {
return err
Expand Down
137 changes: 137 additions & 0 deletions sip/parse_uri_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package sip

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestParseUri(t *testing.T) {
// This are all good accepted URIs test.

/*
https://datatracker.ietf.org/doc/html/rfc3261#section-19.1.3
sip:[email protected]
sip:alice:[email protected];transport=tcp
sips:[email protected]?subject=project%20x&priority=urgent
sip:+1-212-555-1212:[email protected];user=phone
sips:[email protected]
sip:[email protected]
sip:atlanta.com;method=REGISTER?to=alice%40atlanta.com
sip:alice;[email protected]
*/

var uri Uri
var err error
var str string

t.Run("basic", func(t *testing.T) {
uri = Uri{}
str = "sip:alice@localhost:5060"
err = ParseUri(str, &uri)
require.NoError(t, err)
assert.Equal(t, "alice", uri.User)
assert.Equal(t, "localhost", uri.Host)
assert.Equal(t, 5060, uri.Port)
assert.Equal(t, "localhost:5060", uri.HostPort())
assert.Equal(t, "alice@localhost:5060", uri.Endpoint())
})

t.Run("sip case insensitive", func(t *testing.T) {
testCases := []string{
"sip:[email protected]",
"SIP:[email protected]",
"sIp:[email protected]",
}
for _, testCase := range testCases {
err = ParseUri(testCase, &uri)
require.NoError(t, err)
assert.Equal(t, "alice", uri.User)
assert.Equal(t, "atlanta.com", uri.Host)
assert.False(t, uri.Encrypted)
}

testCases = []string{
"sips:[email protected]",
"SIPS:[email protected]",
"sIpS:[email protected]",
}
for _, testCase := range testCases {
err = ParseUri(testCase, &uri)
require.NoError(t, err)
assert.Equal(t, "alice", uri.User)
assert.Equal(t, "atlanta.com", uri.Host)
assert.True(t, uri.Encrypted)
}

})

t.Run("no sip scheme", func(t *testing.T) {
// No scheme we currently allow
uri = Uri{}
str = "alice@localhost:5060"
err = ParseUri(str, &uri)
require.NoError(t, err)
assert.Equal(t, "sip:alice@localhost:5060", uri.String())
})

t.Run("uri params parsed", func(t *testing.T) {
uri = Uri{}
str = "sips:[email protected]?subject=project%20x&priority=urgent"
err = ParseUri(str, &uri)
require.NoError(t, err)

assert.Equal(t, "alice", uri.User)
assert.Equal(t, "atlanta.com", uri.Host)
subject, _ := uri.Headers.Get("subject")
priority, _ := uri.Headers.Get("priority")
assert.Equal(t, "project%20x", subject)
assert.Equal(t, "urgent", priority)
})

t.Run("header params parsed", func(t *testing.T) {
uri = Uri{}
str = "sip:bob:[email protected]:9999;rport;transport=tcp;method=REGISTER?to=sip:bob%40biloxi.com"
err = ParseUri(str, &uri)
require.NoError(t, err)

assert.Equal(t, "bob", uri.User)
assert.Equal(t, "secret", uri.Password)
assert.Equal(t, "atlanta.com", uri.Host)
assert.Equal(t, 9999, uri.Port)

assert.Equal(t, 3, uri.UriParams.Length())
transport, _ := uri.UriParams.Get("transport")
method, _ := uri.UriParams.Get("method")
assert.Equal(t, "tcp", transport)
assert.Equal(t, "REGISTER", method)

assert.Equal(t, 1, uri.Headers.Length())
to, _ := uri.Headers.Get("to")
assert.Equal(t, "sip:bob%40biloxi.com", to)

})

t.Run("params no value", func(t *testing.T) {
uri = Uri{}
str = "127.0.0.2:5060;rport;branch=z9hG4bKPj6c65c5d9-b6d0-4a30-9383-1f9b42f97de9"
err = ParseUri(str, &uri)
require.NoError(t, err)

rport, _ := uri.UriParams.Get("rport")
branch, _ := uri.UriParams.Get("branch")
assert.Equal(t, "", rport)
assert.Equal(t, "z9hG4bKPj6c65c5d9-b6d0-4a30-9383-1f9b42f97de9", branch)

})
}

func TestParseUriBad(t *testing.T) {
t.Run("double ports", func(t *testing.T) {
str := "sip:127.0.0.1:5060:5060;lr;transport=udp"
uri := Uri{}
err := ParseUri(str, &uri)
require.Error(t, err)
})
}

0 comments on commit 9a076d6

Please sign in to comment.