1
1
package signaler
2
2
3
3
import (
4
+ "crypto/hmac"
5
+ "crypto/sha1"
6
+ "encoding/base64"
4
7
"encoding/json"
8
+ "fmt"
5
9
"net"
6
10
"net/http"
11
+ "net/url"
7
12
"strings"
8
-
9
- "github.com/gorilla/mux"
13
+ "time"
10
14
11
15
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/logger"
12
16
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/turn"
17
+ "github.com/cloudwebrtc/flutter-webrtc-server/pkg/util"
13
18
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/websocket"
14
19
)
15
20
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
+
16
32
func Marshal (m map [string ]interface {}) string {
17
33
if byt , err := json .Marshal (m ); err != nil {
18
34
logger .Errorf (err .Error ())
@@ -52,26 +68,33 @@ type Session struct {
52
68
}
53
69
54
70
type 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
58
75
}
59
76
60
77
func NewSignaler (turn * turn.TurnServer ) * Signaler {
61
78
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 (),
65
83
}
66
84
signaler .turn .AuthHandler = signaler .authHandler
67
85
return signaler
68
86
}
69
87
70
88
func (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
+ }
72
94
return nil , false
73
95
}
74
96
97
+ // NotifyPeersUpdate .
75
98
func (s * Signaler ) NotifyPeersUpdate (conn * websocket.WebSocketConn , peers map [string ]Peer ) {
76
99
infos := []PeerInfo {}
77
100
for _ , peer := range peers {
@@ -85,35 +108,58 @@ func (s *Signaler) NotifyPeersUpdate(conn *websocket.WebSocketConn, peers map[st
85
108
}
86
109
}
87
110
88
- // HandleTurnServerCredentials
111
+ // HandleTurnServerCredentials .
89
112
// https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
90
113
func (s * Signaler ) HandleTurnServerCredentials (writer http.ResponseWriter , request * http.Request ) {
91
114
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 ]
94
122
if service != "turn" {
95
123
return
96
124
}
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 ))
97
131
/*
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
+
114
151
*/
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 )
117
163
}
118
164
119
165
func (s * Signaler ) HandleNewWebSocket (conn * websocket.WebSocketConn , request * http.Request ) {
0 commit comments