11package signaler
22
33import (
4+ "crypto/hmac"
5+ "crypto/sha1"
6+ "encoding/base64"
47 "encoding/json"
8+ "fmt"
59 "net"
610 "net/http"
11+ "net/url"
712 "strings"
8-
9- "github.com/gorilla/mux"
13+ "time"
1014
1115 "github.com/cloudwebrtc/flutter-webrtc-server/pkg/logger"
1216 "github.com/cloudwebrtc/flutter-webrtc-server/pkg/turn"
17+ "github.com/cloudwebrtc/flutter-webrtc-server/pkg/util"
1318 "github.com/cloudwebrtc/flutter-webrtc-server/pkg/websocket"
1419)
1520
21+ const (
22+ sharedKey = `flutter-webrtc-turn-server-shared-key`
23+ )
24+
25+ type TurnCredentials struct {
26+ Username string `json:"username"`
27+ Password string `json:"password"`
28+ TTL int `json:"ttl"`
29+ Uris []string `json:"uris"`
30+ }
31+
1632func Marshal (m map [string ]interface {}) string {
1733 if byt , err := json .Marshal (m ); err != nil {
1834 logger .Errorf (err .Error ())
@@ -52,26 +68,33 @@ type Session struct {
5268}
5369
5470type Signaler struct {
55- peers map [string ]Peer
56- sessions map [string ]Session
57- turn * turn.TurnServer
71+ peers map [string ]Peer
72+ sessions map [string ]Session
73+ turn * turn.TurnServer
74+ expresMap * util.ExpiredMap
5875}
5976
6077func NewSignaler (turn * turn.TurnServer ) * Signaler {
6178 var signaler = & Signaler {
62- peers : make (map [string ]Peer ),
63- sessions : make (map [string ]Session ),
64- turn : turn ,
79+ peers : make (map [string ]Peer ),
80+ sessions : make (map [string ]Session ),
81+ turn : turn ,
82+ expresMap : util .NewExpiredMap (),
6583 }
6684 signaler .turn .AuthHandler = signaler .authHandler
6785 return signaler
6886}
6987
7088func (s Signaler ) authHandler (username string , realm string , srcAddr net.Addr ) ([]byte , bool ) {
71- // handle turn auth info.
89+ // handle turn credential.
90+ if found , info := s .expresMap .Get (username ); found {
91+ credential := info .(TurnCredentials )
92+ return []byte (credential .Password ), true
93+ }
7294 return nil , false
7395}
7496
97+ // NotifyPeersUpdate .
7598func (s * Signaler ) NotifyPeersUpdate (conn * websocket.WebSocketConn , peers map [string ]Peer ) {
7699 infos := []PeerInfo {}
77100 for _ , peer := range peers {
@@ -85,35 +108,58 @@ func (s *Signaler) NotifyPeersUpdate(conn *websocket.WebSocketConn, peers map[st
85108 }
86109}
87110
88- // HandleTurnServerCredentials
111+ // HandleTurnServerCredentials .
89112// https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
90113func (s * Signaler ) HandleTurnServerCredentials (writer http.ResponseWriter , request * http.Request ) {
91114 writer .Header ().Set ("Content-Type" , "application/json" )
92- params := mux .Vars (request ) //Get params
93- service := params ["service" ]
115+
116+ params , err := url .ParseQuery (request .URL .RawQuery )
117+ if err != nil {
118+
119+ }
120+ logger .Debugf ("%v" , params )
121+ service := params ["service" ][0 ]
94122 if service != "turn" {
95123 return
96124 }
125+ username := params ["username" ][0 ]
126+ timestamp := time .Now ().Unix ()
127+ turnUsername := fmt .Sprintf ("%d:%s" , timestamp , username )
128+ hmac := hmac .New (sha1 .New , []byte (sharedKey ))
129+ hmac .Write ([]byte (turnUsername ))
130+ turnPassword := base64 .StdEncoding .EncodeToString (hmac .Sum (nil ))
97131 /*
98- username := params["username"]
99-
100- //key := params["key"]
101- timestamp := time.Now().Unix()
102- turnUserName := string(timestamp) + ":" + username
103- // credential = base64(hmac(key, turn_username))
104- credential := ""
105-
106- {
107- "username" : "12334939:mbzrxpgjys",
108- "password" : "adfsaflsjfldssia",
109- "ttl" : 86400,
110- "uris" : [
111- "turn:1.2.3.4:9991?transport=udp",
112- ]
113- }
132+ {
133+ "username" : "12334939:mbzrxpgjys",
134+ "password" : "adfsaflsjfldssia",
135+ "ttl" : 86400,
136+ "uris" : [
137+ "turn:1.2.3.4:9991?transport=udp",
138+ "turn:1.2.3.4:9992?transport=tcp",
139+ "turns:1.2.3.4:443?transport=tcp"
140+ ]
141+ }
142+ For client pc.
143+ var iceServer = {
144+ "username": response.username,
145+ "credential": response.password,
146+ "uris": response.uris
147+ };
148+ var config = {"iceServers": [iceServer]};
149+ var pc = new RTCPeerConnection(config);
150+
114151 */
115- //tuts := make(map[string]interface{})
116- json .NewEncoder (writer ).Encode (params )
152+ ttl := 86400
153+ credential := TurnCredentials {
154+ Username : turnUsername ,
155+ Password : turnPassword ,
156+ TTL : ttl ,
157+ Uris : []string {
158+ "turn:1.2.3.4:19302?transport=udp" ,
159+ },
160+ }
161+ s .expresMap .Set (turnUsername , credential , int64 (ttl ))
162+ json .NewEncoder (writer ).Encode (credential )
117163}
118164
119165func (s * Signaler ) HandleNewWebSocket (conn * websocket.WebSocketConn , request * http.Request ) {
0 commit comments