Skip to content

Commit

Permalink
Parse DTLS setup in SetRemoteDescription
Browse files Browse the repository at this point in the history
Take into consideration if remote is running DTLS as a
client/server. Before we ignored this value and we could
enter cases where DTLS would never connect.

Resolves #494
  • Loading branch information
Sean-Der committed Aug 13, 2019
1 parent 94f07ff commit 7f3000d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 4 deletions.
30 changes: 30 additions & 0 deletions dtlsrole.go
@@ -1,5 +1,9 @@
package webrtc

import (
"github.com/pion/sdp/v2"
)

// DTLSRole indicates the role of the DTLS transport.
type DTLSRole byte

Expand Down Expand Up @@ -28,3 +32,29 @@ func (r DTLSRole) String() string {
return unknownStr
}
}

// Iterate a SessionDescription from a remote to determine if an explicit
// role can been determined for local connection. The decision is made from the first role we we parse.
// If no role can be found we return DTLSRoleAuto
func dtlsRoleFromRemoteSDP(sessionDescription *sdp.SessionDescription) DTLSRole {
if sessionDescription == nil {
return DTLSRoleAuto
}

for _, mediaSection := range sessionDescription.MediaDescriptions {
for _, attribute := range mediaSection.Attributes {
if attribute.Key == "setup" {
switch attribute.Value {
case "active":
return DTLSRoleServer
case "passive":
return DTLSRoleClient
default:
return DTLSRoleAuto
}
}
}
}

return DTLSRoleAuto
}
55 changes: 55 additions & 0 deletions dtlsrole_test.go
@@ -1,8 +1,10 @@
package webrtc

import (
"fmt"
"testing"

"github.com/pion/sdp/v2"
"github.com/stretchr/testify/assert"
)

Expand All @@ -25,3 +27,56 @@ func TestDTLSRole_String(t *testing.T) {
)
}
}

func TestDTLSRoleFromRemoteSDP(t *testing.T) {
parseSDP := func(raw string) *sdp.SessionDescription {
parsed := &sdp.SessionDescription{}
if err := parsed.Unmarshal([]byte(raw)); err != nil {
panic(err)
}
return parsed
}

const noMedia = `v=0
o=- 4596489990601351948 2 IN IP4 127.0.0.1
s=-
t=0 0
`

const mediaNoSetup = `v=0
o=- 4596489990601351948 2 IN IP4 127.0.0.1
s=-
t=0 0
m=application 47299 DTLS/SCTP 5000
c=IN IP4 192.168.20.129
`

const mediaSetupDeclared = `v=0
o=- 4596489990601351948 2 IN IP4 127.0.0.1
s=-
t=0 0
m=application 47299 DTLS/SCTP 5000
c=IN IP4 192.168.20.129
a=setup:%s
`

testCases := []struct {
test string
sessionDescription *sdp.SessionDescription
expectedRole DTLSRole
}{
{"nil SessionDescription", nil, DTLSRoleAuto},
{"No MediaDescriptions", parseSDP(noMedia), DTLSRoleAuto},
{"MediaDescription, no setup", parseSDP(mediaNoSetup), DTLSRoleAuto},
{"MediaDescription, setup:actpass", parseSDP(fmt.Sprintf(mediaSetupDeclared, "actpass")), DTLSRoleAuto},
{"MediaDescription, setup:passive", parseSDP(fmt.Sprintf(mediaSetupDeclared, "passive")), DTLSRoleClient},
{"MediaDescription, setup:active", parseSDP(fmt.Sprintf(mediaSetupDeclared, "active")), DTLSRoleServer},
}
for _, testCase := range testCases {
assert.Equal(t,
testCase.expectedRole,
dtlsRoleFromRemoteSDP(testCase.sessionDescription),
"TestDTLSRoleFromSDP (%s)", testCase.test,
)
}
}
8 changes: 4 additions & 4 deletions peerconnection.go
Expand Up @@ -470,7 +470,7 @@ func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription
d = d.WithValueAttribute(sdp.AttrKeyGroup, bundleValue)

for _, m := range d.MediaDescriptions {
m.WithPropertyAttribute("setup:actpass")
m.WithValueAttribute(sdp.AttrKeyConnectionSetup, "actpass")
}

sdpBytes, err := d.Marshal()
Expand Down Expand Up @@ -968,7 +968,7 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {

// Start the dtls transport
err = pc.dtlsTransport.Start(DTLSParameters{
Role: DTLSRoleAuto,
Role: dtlsRoleFromRemoteSDP(desc.parsed),
Fingerprints: []DTLSFingerprint{{Algorithm: fingerprintHash, Value: fingerprint}},
})
if err != nil {
Expand Down Expand Up @@ -1656,7 +1656,7 @@ func (pc *PeerConnection) addTransceiverSDP(d *sdp.SessionDescription, midValue
// Use the first transceiver to generate the section attributes
t := transceivers[0]
media := sdp.NewJSEPMediaDescription(t.kind.String(), []string{}).
WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()). // pion/webrtc#494
WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()).
WithValueAttribute(sdp.AttrKeyMID, midValue).
WithICECredentials(iceParams.UsernameFragment, iceParams.Password).
WithPropertyAttribute(sdp.AttrKeyRTCPMux).
Expand Down Expand Up @@ -1718,7 +1718,7 @@ func (pc *PeerConnection) addDataMediaSection(d *sdp.SessionDescription, midValu
},
},
}).
WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()). // pion/webrtc#494
WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()).
WithValueAttribute(sdp.AttrKeyMID, midValue).
WithPropertyAttribute(RTPTransceiverDirectionSendrecv.String()).
WithPropertyAttribute("sctpmap:5000 webrtc-datachannel 1024").
Expand Down

0 comments on commit 7f3000d

Please sign in to comment.