Make probetest wait for a datachannel to open

This commit is contained in:
Cecylia Bocovich 2020-11-05 16:48:00 -05:00
parent b5ce259858
commit 4663599382
2 changed files with 162 additions and 50 deletions

View file

@ -51,8 +51,13 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription,
return nil, fmt.Errorf("accept: NewPeerConnection: %s", err) return nil, fmt.Errorf("accept: NewPeerConnection: %s", err)
} }
pc.OnDataChannel(func(dc *webrtc.DataChannel) { pc.OnDataChannel(func(dc *webrtc.DataChannel) {
dc.OnOpen(func() {
close(dataChan) close(dataChan)
}) })
dc.OnClose(func() {
dc.Close()
})
})
err = pc.SetRemoteDescription(*sdp) err = pc.SetRemoteDescription(*sdp)
if err != nil { if err != nil {

View file

@ -352,7 +352,7 @@ func datachannelHandler(conn *webRTCConn, remoteAddr net.Addr) {
// candidates is complete and the answer is available in LocalDescription. // candidates is complete and the answer is available in LocalDescription.
// Installs an OnDataChannel callback that creates a webRTCConn and passes it to // Installs an OnDataChannel callback that creates a webRTCConn and passes it to
// datachannelHandler. // datachannelHandler.
func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, func makePeerConnection(offering bool, sdp *webrtc.SessionDescription,
config webrtc.Configuration, config webrtc.Configuration,
dataChan chan struct{}, dataChan chan struct{},
handler func(conn *webRTCConn, remoteAddr net.Addr)) (*webrtc.PeerConnection, error) { handler func(conn *webRTCConn, remoteAddr net.Addr)) (*webrtc.PeerConnection, error) {
@ -361,6 +361,38 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription,
if err != nil { if err != nil {
return nil, fmt.Errorf("accept: NewPeerConnection: %s", err) return nil, fmt.Errorf("accept: NewPeerConnection: %s", err)
} }
if offering {
offer, err := pc.CreateOffer(nil)
// TODO: Potentially timeout and retry if ICE isn't working.
if err != nil {
log.Println("Failed to prepare offer", err)
pc.Close()
return nil, err
}
log.Println("WebRTC: Created offer")
err = pc.SetLocalDescription(offer)
if err != nil {
log.Println("Failed to prepare offer", err)
pc.Close()
return nil, err
}
log.Println("WebRTC: Set local description")
dc, err := pc.CreateDataChannel("test", &webrtc.DataChannelInit{})
if err != nil {
log.Printf("CreateDataChannel ERROR: %s", err)
return nil, err
}
dc.OnOpen(func() {
log.Println("WebRTC: DataChannel.OnOpen")
close(dataChan)
})
dc.OnClose(func() {
log.Println("WebRTC: DataChannel.OnClose")
dc.Close()
})
} else {
pc.OnDataChannel(func(dc *webrtc.DataChannel) { pc.OnDataChannel(func(dc *webrtc.DataChannel) {
log.Println("OnDataChannel") log.Println("OnDataChannel")
close(dataChan) close(dataChan)
@ -394,7 +426,6 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription,
go handler(conn, conn.RemoteAddr()) go handler(conn, conn.RemoteAddr())
}) })
err = pc.SetRemoteDescription(*sdp) err = pc.SetRemoteDescription(*sdp)
if err != nil { if err != nil {
if inerr := pc.Close(); inerr != nil { if inerr := pc.Close(); inerr != nil {
@ -423,6 +454,7 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription,
} }
return nil, err return nil, err
} }
}
return pc, nil return pc, nil
} }
@ -435,7 +467,7 @@ func runSession(sid string) {
return return
} }
dataChan := make(chan struct{}) dataChan := make(chan struct{})
pc, err := makePeerConnectionFromOffer(offer, config, dataChan, datachannelHandler) pc, err := makePeerConnection(false, offer, config, dataChan, datachannelHandler)
if err != nil { if err != nil {
log.Printf("error making WebRTC connection: %s", err) log.Printf("error making WebRTC connection: %s", err)
retToken() retToken()
@ -535,6 +567,11 @@ func main() {
updateNATType(config.ICEServers) updateNATType(config.ICEServers)
log.Printf("NAT type: %s", currentNATType) log.Printf("NAT type: %s", currentNATType)
// use probetest to determine NAT compatability
for {
testThroughput(config, "https://snowflake-broker.torproject.net:8443")
}
for { for {
getToken() getToken()
sessionID := genSessionID() sessionID := genSessionID()
@ -542,6 +579,76 @@ func main() {
} }
} }
func testThroughput(config webrtc.Configuration, probeURL string) {
var err error
probe := new(SignalingServer)
probe.transport = http.DefaultTransport.(*http.Transport)
broker.transport.(*http.Transport).ResponseHeaderTimeout = 30 * time.Second
probe.url, err = url.Parse(probeURL)
if err != nil {
log.Printf("Error parsing url: %s", err.Error())
}
probePath := probe.url.ResolveReference(&url.URL{Path: "probe"})
// create offer
dataChan := make(chan struct{})
pc, err := makePeerConnection(true, nil, config, dataChan, func(conn *webRTCConn, addr net.Addr) { conn.Close() })
if err != nil {
log.Printf("error making WebRTC connection: %s", err)
return
}
offer := pc.LocalDescription()
sdp, err := util.SerializeSessionDescription(offer)
if err != nil {
log.Printf("Error encoding probe message: %s", err.Error())
return
}
// send offer
body, err := messages.EncodePollResponse(sdp, true, "")
if err != nil {
log.Printf("Error encoding probe message: %s", err.Error())
return
}
log.Println(string(body))
resp, err := probe.Post(probePath.String(), bytes.NewBuffer(body))
if err != nil {
log.Printf("error polling probe: %s", err.Error())
return
}
sdp, _, err = messages.DecodeAnswerRequest(resp)
if err != nil {
log.Printf("Error reading probe response: %s", err.Error())
return
}
answer, err := util.DeserializeSessionDescription(sdp)
if err != nil {
log.Printf("Error setting answer: %s", err.Error())
return
}
err = pc.SetRemoteDescription(*answer)
if err != nil {
log.Printf("Error setting answer: %s", err.Error())
return
}
log.Println("Trying to open datachannel")
select {
case <-dataChan:
log.Println("Connection successful.")
case <-time.After(dataChannelTimeout):
log.Println("Timed out waiting for client to open data channel.")
if err := pc.Close(); err != nil {
log.Printf("error calling pc.Close: %v", err)
}
}
}
// use provided STUN server(s) to determine NAT type // use provided STUN server(s) to determine NAT type
func updateNATType(servers []webrtc.ICEServer) { func updateNATType(servers []webrtc.ICEServer) {