mirror of
https://github.com/jech/galene.git
synced 2024-12-22 15:25:48 +01:00
Move ICE code into own module, add tests.
This commit is contained in:
parent
845dccc2bb
commit
450601f0e8
5 changed files with 89 additions and 21 deletions
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
"github.com/jech/galene/diskwriter"
|
||||
"github.com/jech/galene/group"
|
||||
"github.com/jech/galene/ice"
|
||||
"github.com/jech/galene/webserver"
|
||||
)
|
||||
|
||||
|
@ -39,7 +40,7 @@ func main() {
|
|||
flag.StringVar(&mutexprofile, "mutexprofile", "",
|
||||
"store mutex profile in `file`")
|
||||
flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses")
|
||||
flag.BoolVar(&group.ICERelayOnly, "relay-only", false,
|
||||
flag.BoolVar(&ice.ICERelayOnly, "relay-only", false,
|
||||
"require use of TURN relays for all media traffic")
|
||||
flag.Parse()
|
||||
|
||||
|
@ -81,7 +82,7 @@ func main() {
|
|||
}()
|
||||
}
|
||||
|
||||
group.ICEFilename = filepath.Join(dataDir, "ice-servers.json")
|
||||
ice.ICEFilename = filepath.Join(dataDir, "ice-servers.json")
|
||||
|
||||
go group.ReadPublicGroups()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package group
|
||||
package ice
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -16,14 +16,14 @@ import (
|
|||
"github.com/pion/webrtc/v3"
|
||||
)
|
||||
|
||||
type ICEServer struct {
|
||||
type Server struct {
|
||||
URLs []string `json:"urls"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Credential interface{} `json:"credential,omitempty"`
|
||||
CredentialType string `json:"credentialType,omitempty"`
|
||||
}
|
||||
|
||||
func getICEServer(server ICEServer) (webrtc.ICEServer, error) {
|
||||
func getServer(server Server) (webrtc.ICEServer, error) {
|
||||
s := webrtc.ICEServer{
|
||||
URLs: server.URLs,
|
||||
Username: server.Username,
|
||||
|
@ -65,16 +65,16 @@ func getICEServer(server ICEServer) (webrtc.ICEServer, error) {
|
|||
var ICEFilename string
|
||||
var ICERelayOnly bool
|
||||
|
||||
type iceConf struct {
|
||||
type configuration struct {
|
||||
conf webrtc.Configuration
|
||||
timestamp time.Time
|
||||
}
|
||||
|
||||
var iceConfiguration atomic.Value
|
||||
var conf atomic.Value
|
||||
|
||||
func updateICEConfiguration() *iceConf {
|
||||
func updateICEConfiguration() *configuration {
|
||||
now := time.Now()
|
||||
var conf webrtc.Configuration
|
||||
var cf webrtc.Configuration
|
||||
|
||||
if ICEFilename != "" {
|
||||
file, err := os.Open(ICEFilename)
|
||||
|
@ -83,36 +83,36 @@ func updateICEConfiguration() *iceConf {
|
|||
} else {
|
||||
defer file.Close()
|
||||
d := json.NewDecoder(file)
|
||||
var servers []ICEServer
|
||||
var servers []Server
|
||||
err = d.Decode(&servers)
|
||||
if err != nil {
|
||||
log.Printf("Get ICE configuration: %v", err)
|
||||
}
|
||||
for _, s := range servers {
|
||||
ss, err := getICEServer(s)
|
||||
ss, err := getServer(s)
|
||||
if err != nil {
|
||||
log.Printf("parse ICE server: %v", err)
|
||||
continue
|
||||
}
|
||||
conf.ICEServers = append(conf.ICEServers, ss)
|
||||
cf.ICEServers = append(cf.ICEServers, ss)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ICERelayOnly {
|
||||
conf.ICETransportPolicy = webrtc.ICETransportPolicyRelay
|
||||
cf.ICETransportPolicy = webrtc.ICETransportPolicyRelay
|
||||
}
|
||||
|
||||
iceConf := iceConf{
|
||||
conf: conf,
|
||||
iceConf := configuration{
|
||||
conf: cf,
|
||||
timestamp: now,
|
||||
}
|
||||
iceConfiguration.Store(&iceConf)
|
||||
conf.Store(&iceConf)
|
||||
return &iceConf
|
||||
}
|
||||
|
||||
func ICEConfiguration() *webrtc.Configuration {
|
||||
conf, ok := iceConfiguration.Load().(*iceConf)
|
||||
conf, ok := conf.Load().(*configuration)
|
||||
if !ok || time.Since(conf.timestamp) > 5*time.Minute {
|
||||
conf = updateICEConfiguration()
|
||||
} else if time.Since(conf.timestamp) > 2*time.Minute {
|
65
ice/ice_test.go
Normal file
65
ice/ice_test.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package ice
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pion/webrtc/v3"
|
||||
)
|
||||
|
||||
func TestPassword(t *testing.T) {
|
||||
s := Server{
|
||||
URLs: []string{"turn:turn.example.org"},
|
||||
Username: "jch",
|
||||
Credential: "secret",
|
||||
}
|
||||
|
||||
ss := webrtc.ICEServer{
|
||||
URLs: []string{"turn:turn.example.org"},
|
||||
Username: "jch",
|
||||
Credential: "secret",
|
||||
}
|
||||
|
||||
sss, err := getServer(s)
|
||||
|
||||
if err != nil || !reflect.DeepEqual(sss, ss) {
|
||||
t.Errorf("Got %v, expected %v", sss, ss)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHMAC(t *testing.T) {
|
||||
s := Server{
|
||||
URLs: []string{"turn:turn.example.org"},
|
||||
Username: "jch",
|
||||
Credential: "secret",
|
||||
CredentialType: "hmac-sha1",
|
||||
}
|
||||
|
||||
ss := webrtc.ICEServer{
|
||||
URLs: []string{"turn:turn.example.org"},
|
||||
}
|
||||
|
||||
sss, err := getServer(s)
|
||||
|
||||
if !strings.HasSuffix(sss.Username, ":"+s.Username) {
|
||||
t.Errorf("username is %v", ss.Username)
|
||||
}
|
||||
ss.Username = sss.Username
|
||||
|
||||
mac := hmac.New(sha1.New, []byte(s.Credential.(string)))
|
||||
mac.Write([]byte(sss.Username))
|
||||
buf := bytes.Buffer{}
|
||||
e := base64.NewEncoder(base64.StdEncoding, &buf)
|
||||
e.Write(mac.Sum(nil))
|
||||
e.Close()
|
||||
ss.Credential = string(buf.Bytes())
|
||||
|
||||
if err != nil || !reflect.DeepEqual(sss, ss) {
|
||||
t.Errorf("Got %v, expected %v", sss, ss)
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/jech/galene/conn"
|
||||
"github.com/jech/galene/estimator"
|
||||
"github.com/jech/galene/group"
|
||||
"github.com/jech/galene/ice"
|
||||
"github.com/jech/galene/jitter"
|
||||
"github.com/jech/galene/packetcache"
|
||||
"github.com/jech/galene/rtptime"
|
||||
|
@ -138,7 +139,7 @@ type rtpDownConnection struct {
|
|||
|
||||
func newDownConn(c group.Client, id string, remote conn.Up) (*rtpDownConnection, error) {
|
||||
api := group.APIFromCodecs(remote.Codecs())
|
||||
pc, err := api.NewPeerConnection(*group.ICEConfiguration())
|
||||
pc, err := api.NewPeerConnection(*ice.ICEConfiguration())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -457,7 +458,7 @@ func pushConn(up *rtpUpConnection, g *group.Group, cs []group.Client) {
|
|||
}
|
||||
|
||||
func newUpConn(c group.Client, id string, labels map[string]string) (*rtpUpConnection, error) {
|
||||
pc, err := c.Group().API().NewPeerConnection(*group.ICEConfiguration())
|
||||
pc, err := c.Group().API().NewPeerConnection(*ice.ICEConfiguration())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/jech/galene/diskwriter"
|
||||
"github.com/jech/galene/estimator"
|
||||
"github.com/jech/galene/group"
|
||||
"github.com/jech/galene/ice"
|
||||
)
|
||||
|
||||
func errorToWSCloseMessage(id string, err error) (*clientMessage, []byte) {
|
||||
|
@ -877,7 +878,7 @@ func clientLoop(c *webClient, ws *websocket.Conn) error {
|
|||
Kind: "change",
|
||||
Group: g.Name(),
|
||||
Permissions: &perms,
|
||||
RTCConfiguration: group.ICEConfiguration(),
|
||||
RTCConfiguration: ice.ICEConfiguration(),
|
||||
})
|
||||
if !c.permissions.Present {
|
||||
up := getUpConns(c)
|
||||
|
@ -1084,7 +1085,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
|||
Kind: "join",
|
||||
Group: m.Group,
|
||||
Permissions: &perms,
|
||||
RTCConfiguration: group.ICEConfiguration(),
|
||||
RTCConfiguration: ice.ICEConfiguration(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue