[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [snowflake/master] Modified proxy-go to use pion/webrtc
commit 0428797ea09814afb36796014e96d911c2ecc554
Author: Cecylia Bocovich <cohosh@xxxxxxxxxxxxxx>
Date: Fri Jun 14 18:46:07 2019 -0400
Modified proxy-go to use pion/webrtc
The API is very similar, differences were mostly due to:
- closing peer connections and datachannels (no destroy/delete methods)
- different way to set datachannel/peer connection callbacks
- differences in whether functions take pointers or values
- no serialize/deserialize functions in the API
---
proxy-go/snowflake.go | 119 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 84 insertions(+), 35 deletions(-)
diff --git a/proxy-go/snowflake.go b/proxy-go/snowflake.go
index b3c863a..e0c9def 100644
--- a/proxy-go/snowflake.go
+++ b/proxy-go/snowflake.go
@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/rand"
"encoding/base64"
+ "encoding/json"
"flag"
"fmt"
"io"
@@ -19,7 +20,7 @@ import (
"time"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
- "github.com/keroserene/go-webrtc"
+ "github.com/pion/webrtc"
"golang.org/x/net/websocket"
)
@@ -43,7 +44,7 @@ const (
var (
tokens chan bool
- config *webrtc.Configuration
+ config webrtc.Configuration
client http.Client
)
@@ -92,7 +93,7 @@ func (c *webRTCConn) Write(b []byte) (int, error) {
func (c *webRTCConn) Close() (err error) {
c.once.Do(func() {
- err = c.pc.Destroy()
+ err = c.pc.Close()
})
return
}
@@ -103,7 +104,7 @@ func (c *webRTCConn) LocalAddr() net.Addr {
func (c *webRTCConn) RemoteAddr() net.Addr {
//Parse Remote SDP offer and extract client IP
- clientIP := remoteIPFromSDP(c.pc.RemoteDescription().Sdp)
+ clientIP := remoteIPFromSDP(c.pc.RemoteDescription().SDP)
if clientIP == nil {
return nil
}
@@ -178,7 +179,7 @@ func pollOffer(sid string) *webrtc.SessionDescription {
if err != nil {
log.Printf("error reading broker response: %s", err)
} else {
- return webrtc.DeserializeSessionDescription(string(body))
+ return deserializeSessionDescription(string(body))
}
}
}
@@ -187,7 +188,7 @@ func pollOffer(sid string) *webrtc.SessionDescription {
func sendAnswer(sid string, pc *webrtc.PeerConnection) error {
broker := brokerURL.ResolveReference(&url.URL{Path: "answer"})
- body := bytes.NewBuffer([]byte(pc.LocalDescription().Serialize()))
+ body := bytes.NewBuffer([]byte(serializeSessionDescription(pc.LocalDescription())))
req, _ := http.NewRequest("POST", broker.String(), body)
req.Header.Set("X-Session-ID", sid)
resp, err := client.Do(req)
@@ -275,71 +276,63 @@ func datachannelHandler(conn *webRTCConn, remoteAddr net.Addr) {
// candidates is complete and the answer is available in LocalDescription.
// Installs an OnDataChannel callback that creates a webRTCConn and passes it to
// datachannelHandler.
-func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.Configuration, dataChan chan struct{}) (*webrtc.PeerConnection, error) {
+func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config webrtc.Configuration, dataChan chan struct{}) (*webrtc.PeerConnection, error) {
pc, err := webrtc.NewPeerConnection(config)
if err != nil {
return nil, fmt.Errorf("accept: NewPeerConnection: %s", err)
}
- pc.OnNegotiationNeeded = func() {
- panic("OnNegotiationNeeded")
- }
- pc.OnDataChannel = func(dc *webrtc.DataChannel) {
+ pc.OnDataChannel(func(dc *webrtc.DataChannel) {
log.Println("OnDataChannel")
close(dataChan)
pr, pw := io.Pipe()
conn := &webRTCConn{pc: pc, dc: dc, pr: pr}
- dc.OnOpen = func() {
+ dc.OnOpen(func() {
log.Println("OnOpen channel")
- }
- dc.OnClose = func() {
+ })
+ dc.OnClose(func() {
conn.lock.Lock()
defer conn.lock.Unlock()
log.Println("OnClose channel")
conn.dc = nil
- pc.DeleteDataChannel(dc)
+ dc.Close()
pw.Close()
- }
- dc.OnMessage = func(msg []byte) {
- log.Printf("OnMessage <--- %d bytes", len(msg))
- n, err := pw.Write(msg)
+ })
+ dc.OnMessage(func(msg webrtc.DataChannelMessage) {
+ log.Printf("OnMessage <--- %d bytes", len(msg.Data))
+ n, err := pw.Write(msg.Data)
if err != nil {
pw.CloseWithError(err)
}
- if n != len(msg) {
+ if n != len(msg.Data) {
panic("short write")
}
- }
+ })
go datachannelHandler(conn, conn.RemoteAddr())
- }
+ })
- err = pc.SetRemoteDescription(sdp)
+ err = pc.SetRemoteDescription(*sdp)
if err != nil {
- pc.Destroy()
+ pc.Close()
return nil, fmt.Errorf("accept: SetRemoteDescription: %s", err)
}
log.Println("sdp offer successfully received.")
log.Println("Generating answer...")
- answer, err := pc.CreateAnswer()
+ answer, err := pc.CreateAnswer(nil)
// blocks on ICE gathering. we need to add a timeout if needed
// not putting this in a separate go routine, because we need
// SetLocalDescription(answer) to be called before sendAnswer
if err != nil {
- pc.Destroy()
+ pc.Close()
return nil, err
}
- if answer == nil {
- pc.Destroy()
- return nil, fmt.Errorf("Failed gathering ICE candidates.")
- }
-
err = pc.SetLocalDescription(answer)
if err != nil {
- pc.Destroy()
+ pc.Close()
return nil, err
}
@@ -363,7 +356,7 @@ func runSession(sid string) {
err = sendAnswer(sid, pc)
if err != nil {
log.Printf("error sending answer to client through broker: %s", err)
- pc.Destroy()
+ pc.Close()
retToken()
return
}
@@ -375,7 +368,7 @@ func runSession(sid string) {
log.Println("Connection successful.")
case <-time.After(dataChannelTimeout):
log.Println("Timed out waiting for client to open data channel.")
- pc.Destroy()
+ pc.Close()
retToken()
}
}
@@ -422,7 +415,13 @@ func main() {
log.Fatalf("invalid relay url: %s", err)
}
- config = webrtc.NewConfiguration(webrtc.OptionIceServer(stunURL))
+ config = webrtc.Configuration{
+ ICEServers: []webrtc.ICEServer{
+ {
+ URLs: []string{stunURL},
+ },
+ },
+ }
tokens = make(chan bool, capacity)
for i := uint(0); i < capacity; i++ {
tokens <- true
@@ -434,3 +433,53 @@ func main() {
runSession(sessionID)
}
}
+
+func deserializeSessionDescription(msg string) *webrtc.SessionDescription {
+ var parsed map[string]interface{}
+ err := json.Unmarshal([]byte(msg), &parsed)
+ if nil != err {
+ log.Println(err)
+ return nil
+ }
+ if _, ok := parsed["type"]; !ok {
+ log.Println("Cannot deserialize SessionDescription without type field.")
+ return nil
+ }
+ if _, ok := parsed["sdp"]; !ok {
+ log.Println("Cannot deserialize SessionDescription without sdp field.")
+ return nil
+ }
+
+ var stype webrtc.SDPType
+ switch parsed["type"].(string) {
+ default:
+ log.Println("Unknown SDP type")
+ return nil
+ case "offer":
+ stype = webrtc.SDPTypeOffer
+ case "pranswer":
+ stype = webrtc.SDPTypePranswer
+ case "answer":
+ stype = webrtc.SDPTypeAnswer
+ case "rollback":
+ stype = webrtc.SDPTypeRollback
+ }
+
+ if err != nil {
+ log.Println(err)
+ return nil
+ }
+ return &webrtc.SessionDescription{
+ Type: stype,
+ SDP: parsed["sdp"].(string),
+ }
+}
+
+func serializeSessionDescription(desc *webrtc.SessionDescription) string {
+ bytes, err := json.Marshal(*desc)
+ if nil != err {
+ log.Println(err)
+ return ""
+ }
+ return string(bytes)
+}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits