Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No ice #2539

Closed
wants to merge 2 commits into from
Closed

No ice #2539

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions configuration.go
Expand Up @@ -52,4 +52,7 @@ type Configuration struct {
// SDPSemantics controls the type of SDP offers accepted by and
// SDP answers generated by the PeerConnection.
SDPSemantics SDPSemantics `json:"sdpSemantics,omitempty"`

// ICENone controls if skip stun steps for data channel establish
ICENone bool `json:"iceNone,omitempty"`
}
113 changes: 113 additions & 0 deletions datachannel_go_test.go
Expand Up @@ -10,6 +10,7 @@ import (
"bytes"
"crypto/rand"
"encoding/binary"
"fmt"
"io"
"io/ioutil"
"math/big"
Expand Down Expand Up @@ -558,6 +559,118 @@ func TestEOF(t *testing.T) {
t.Fatal(err)
}

// When dca closes the channel,
// (1) dca.Onclose() will fire immediately, then
// (2) dcb.OnClose will also fire
<-dcaClosedCh // (1)
<-dcbClosedCh // (2)
})
//ICENone
t.Run("No detach and ICENone", func(t *testing.T) {
lim := test.TimeOut(time.Second * 500)
defer lim.Stop()

settingEngine := &SettingEngine{}
settingEngine.SetInterfaceFilter(func(s string) bool {
return s == "eth0"
})
settingEngine.SetNetworkTypes([]NetworkType{
NetworkTypeUDP4,
})

settingEngine.SetSDPMediaLevelFingerprints(true)

// Set up two peer connections.
config := Configuration{ICENone: true}

pca, err := NewAPI(WithSettingEngine(*settingEngine)).NewPeerConnection(config)
if err != nil {
t.Fatal(err)
}
pcb, err := NewAPI(WithSettingEngine(*settingEngine)).NewPeerConnection(config)
if err != nil {
t.Fatal(err)
}

defer closePairNow(t, pca, pcb)

var dca, dcb *DataChannel
dcaClosedCh := make(chan struct{})
dcbClosedCh := make(chan struct{})

pcb.OnDataChannel(func(dc *DataChannel) {
if dc.Label() != label {
return
}

fmt.Printf("pcAnswer: new datachannel: %s\n", dc.Label())
// fmt.Printf("pcb: new datachannel: %s\n", dc.Label())

dcb = dc
// Register channel opening handling
dcb.OnOpen(func() {
fmt.Printf("pcAnswer: datachannel opened\n")
// fmt.Print("pcAnswer: datachannel opened\n")
})

dcb.OnClose(func() {
// (2)
fmt.Printf("pcAnswer: data channel closed\n")
// fmt.Print("pcAnswer: data channel closed\n")
close(dcbClosedCh)
})

// Register the OnMessage to handle incoming messages
// fmt.Printf("pcAnswer: registering onMessage callback")
// fmt.Print("pcAnswer: registering onMessage callback")
dcb.OnMessage(func(dcMsg DataChannelMessage) {
fmt.Printf("pcAnswer: received ping: %s\n", string(dcMsg.Data))
// fmt.Printf("pcAnswer: received ping: %s\n", string(dcMsg.Data))
if !reflect.DeepEqual(dcMsg.Data, testData) {
t.Error("data mismatch")
}
})
})

dca, err = pca.CreateDataChannel(label, nil)
if err != nil {
t.Fatal(err)
}

dca.OnOpen(func() {
fmt.Printf("pcOffer: data channel opened\n")
// fmt.Print("pca: data channel opened\n")
fmt.Printf("pcOffer: sending \"%s\"\n", string(testData))
// fmt.Printf("pca: sending \"%s\"\n", string(testData))
if err := dca.Send(testData); err != nil {
t.Fatal(err)
}

assert.NoError(t, dca.Close(), "should succeed") // <-- dca closes
})

dca.OnClose(func() {
// (1)
fmt.Printf("pcOffer: data channel closed\n")
// fmt.Print("pca: data channel closed\n")
close(dcaClosedCh)
})

// Register the OnMessage to handle incoming messages
// fmt.Printf("pcOffer: registering onMessage callback")
// fmt.Print("pca: registering onMessage callback\n")
dca.OnMessage(func(dcMsg DataChannelMessage) {
fmt.Printf("pcOffer: received pong: %s\n", string(dcMsg.Data))
// fmt.Printf("pca: received pong: %s\n", string(dcMsg.Data))
if !reflect.DeepEqual(dcMsg.Data, testData) {
t.Error("data mismatch")
}
})

if err := signalPair(pca, pcb); err != nil {
t.Fatal(err)
}

// When dca closes the channel,
// (1) dca.Onclose() will fire immediately, then
// (2) dcb.OnClose will also fire
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Expand Up @@ -2,12 +2,15 @@ module github.com/pion/webrtc/v3

go 1.13

replace github.com/pion/ice/v2 => ../ice

require (
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.17.0 // indirect
github.com/pion/datachannel v1.5.5
github.com/pion/dtls/v2 v2.2.7
github.com/pion/ice/v2 v2.3.10
github.com/pion/ice/v2 v2.0.0-00010101000000-000000000000
// github.com/pion/ice/v2 v2.3.10
github.com/pion/interceptor v0.1.17
github.com/pion/logging v0.2.2
github.com/pion/randutil v0.1.0
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Expand Up @@ -20,8 +20,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand All @@ -44,8 +44,6 @@ github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/ice/v2 v2.3.10 h1:T3bUJKqh7pGEdMyTngUcTeQd6io9X8JjgsVWZDannnY=
github.com/pion/ice/v2 v2.3.10/go.mod h1:hHGCibDfmXGqukayQw979xEctASp2Pe5Oe0iDU8pRus=
github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w=
github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
Expand Down
6 changes: 4 additions & 2 deletions icegatherer.go
Expand Up @@ -35,8 +35,8 @@ type ICEGatherer struct {

// Used for GatheringCompletePromise
onGatheringCompleteHandler atomic.Value // func()

api *API
ICENone bool
api *API
}

// NewICEGatherer creates a new NewICEGatherer.
Expand All @@ -58,6 +58,7 @@ func (api *API) NewICEGatherer(opts ICEGatherOptions) (*ICEGatherer, error) {
state: ICEGathererStateNew,
gatherPolicy: opts.ICEGatherPolicy,
validatedServers: validatedServers,
ICENone: opts.ICENone,
api: api,
log: api.settingEngine.LoggerFactory.NewLogger("ice"),
}, nil
Expand Down Expand Up @@ -95,6 +96,7 @@ func (g *ICEGatherer) createAgent() error {
}

config := &ice.AgentConfig{
ICENone: g.ICENone,
Lite: g.api.settingEngine.candidates.ICELite,
Urls: g.validatedServers,
PortMin: g.api.settingEngine.ephemeralUDP.PortMin,
Expand Down
1 change: 1 addition & 0 deletions icegatheroptions.go
Expand Up @@ -7,4 +7,5 @@ package webrtc
type ICEGatherOptions struct {
ICEServers []ICEServer
ICEGatherPolicy ICETransportPolicy
ICENone bool
}
34 changes: 25 additions & 9 deletions peerconnection.go
Expand Up @@ -241,6 +241,8 @@ func (pc *PeerConnection) initConfiguration(configuration Configuration) error {
pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy
}

pc.configuration.ICENone = configuration.ICENone

if configuration.SDPSemantics != SDPSemantics(Unknown) {
pc.configuration.SDPSemantics = configuration.SDPSemantics
}
Expand Down Expand Up @@ -725,6 +727,7 @@ func (pc *PeerConnection) createICEGatherer() (*ICEGatherer, error) {
g, err := pc.api.NewICEGatherer(ICEGatherOptions{
ICEServers: pc.configuration.getICEServers(),
ICEGatherPolicy: pc.configuration.ICETransportPolicy,
ICENone: pc.configuration.ICENone,
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -1137,12 +1140,25 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
}
}

remoteUfrag, remotePwd, candidates, err := extractICEDetails(desc.parsed, pc.log)
if err != nil {
return err
var remoteUfrag string
var remotePwd string
var candidates []ICECandidate
var err error

if !pc.configuration.ICENone {
remoteUfrag, remotePwd, candidates, err = extractICEDetails(desc.parsed, pc.log)
if err != nil {
return err
}
} else {
//new candidate for ICENone
candidates, err = extracICENone(desc.parsed, pc.log)
if err != nil {
return err
}
}

if isRenegotation && pc.iceTransport.haveRemoteCredentialsChange(remoteUfrag, remotePwd) {
if isRenegotation && !pc.configuration.ICENone && pc.iceTransport.haveRemoteCredentialsChange(remoteUfrag, remotePwd) {
// An ICE Restart only happens implicitly for a SetRemoteDescription of type offer
if !weOffer {
if err = pc.iceTransport.restart(); err != nil {
Expand Down Expand Up @@ -1188,7 +1204,7 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
// If one of the agents is lite and the other one is not, the lite agent must be the controlling agent.
// If both or neither agents are lite the offering agent is controlling.
// RFC 8445 S6.1.1
if (weOffer && remoteIsLite == pc.api.settingEngine.candidates.ICELite) || (remoteIsLite && !pc.api.settingEngine.candidates.ICELite) {
if (weOffer && pc.configuration.ICENone) || (weOffer && remoteIsLite == pc.api.settingEngine.candidates.ICELite) || (remoteIsLite && !pc.api.settingEngine.candidates.ICELite) {
iceRole = ICERoleControlling
}

Expand Down Expand Up @@ -2112,7 +2128,7 @@ func (pc *PeerConnection) CurrentLocalDescription() *SessionDescription {
iceGather := pc.iceGatherer
iceGatheringState := pc.ICEGatheringState()
pc.mu.Unlock()
return populateLocalCandidates(localDescription, iceGather, iceGatheringState)
return populateLocalCandidates(localDescription, iceGather, iceGatheringState, pc.configuration.ICENone)
}

// PendingLocalDescription represents a local description that is in the
Expand All @@ -2125,7 +2141,7 @@ func (pc *PeerConnection) PendingLocalDescription() *SessionDescription {
iceGather := pc.iceGatherer
iceGatheringState := pc.ICEGatheringState()
pc.mu.Unlock()
return populateLocalCandidates(localDescription, iceGather, iceGatheringState)
return populateLocalCandidates(localDescription, iceGather, iceGatheringState, pc.configuration.ICENone)
}

// CurrentRemoteDescription represents the last remote description that was
Expand Down Expand Up @@ -2353,7 +2369,7 @@ func (pc *PeerConnection) generateUnmatchedSDP(transceivers []*RTPTransceiver, u
return nil, err
}

return populateSDP(d, isPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, true, pc.api.mediaEngine, connectionRoleFromDtlsRole(defaultDtlsRoleOffer), candidates, iceParams, mediaSections, pc.ICEGatheringState())
return populateSDP(d, isPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, true, pc.api.mediaEngine, connectionRoleFromDtlsRole(defaultDtlsRoleOffer), candidates, iceParams, mediaSections, pc.ICEGatheringState(), pc.configuration.ICENone)
}

// generateMatchedSDP generates a SDP and takes the remote state into account
Expand Down Expand Up @@ -2480,7 +2496,7 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use
return nil, err
}

return populateSDP(d, detectedPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, isExtmapAllowMixed, pc.api.mediaEngine, connectionRole, candidates, iceParams, mediaSections, pc.ICEGatheringState())
return populateSDP(d, detectedPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, isExtmapAllowMixed, pc.api.mediaEngine, connectionRole, candidates, iceParams, mediaSections, pc.ICEGatheringState(), pc.configuration.ICENone)
}

func (pc *PeerConnection) setGatherCompleteHandler(handler func()) {
Expand Down
5 changes: 5 additions & 0 deletions peerconnection_test.go
Expand Up @@ -4,6 +4,7 @@
package webrtc

import (
"log"
"reflect"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -45,13 +46,15 @@ func signalPairWithModification(pcOffer *PeerConnection, pcAnswer *PeerConnectio
if err != nil {
return err
}
// log.Printf("pcOffer createOffer %v", offer)
offerGatheringComplete := GatheringCompletePromise(pcOffer)
if err = pcOffer.SetLocalDescription(offer); err != nil {
return err
}
<-offerGatheringComplete

offer.SDP = modificationFunc(pcOffer.LocalDescription().SDP)
log.Printf("pcOffer %v", offer)
if err = pcAnswer.SetRemoteDescription(offer); err != nil {
return err
}
Expand All @@ -60,11 +63,13 @@ func signalPairWithModification(pcOffer *PeerConnection, pcAnswer *PeerConnectio
if err != nil {
return err
}
// log.Printf("pcAnswer create answer %v", answer)
answerGatheringComplete := GatheringCompletePromise(pcAnswer)
if err = pcAnswer.SetLocalDescription(answer); err != nil {
return err
}
<-answerGatheringComplete
log.Printf("pcAnswer %v", *pcAnswer.LocalDescription())
return pcOffer.SetRemoteDescription(*pcAnswer.LocalDescription())
}

Expand Down