2020-04-24 19:38:21 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
2021-04-29 22:02:36 +02:00
|
|
|
"fmt"
|
2020-04-24 19:38:21 +02:00
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"path/filepath"
|
2020-05-20 23:04:31 +02:00
|
|
|
"runtime"
|
|
|
|
"runtime/pprof"
|
2020-04-24 19:38:21 +02:00
|
|
|
"syscall"
|
2020-12-01 19:30:45 +01:00
|
|
|
"time"
|
2020-09-13 11:56:35 +02:00
|
|
|
|
2020-12-19 17:37:48 +01:00
|
|
|
"github.com/jech/galene/diskwriter"
|
|
|
|
"github.com/jech/galene/group"
|
2021-01-02 00:20:47 +01:00
|
|
|
"github.com/jech/galene/ice"
|
2021-07-29 14:26:41 +02:00
|
|
|
"github.com/jech/galene/limit"
|
2023-03-22 04:04:22 +01:00
|
|
|
"github.com/jech/galene/token"
|
2021-01-18 20:24:52 +01:00
|
|
|
"github.com/jech/galene/turnserver"
|
2020-12-19 17:37:48 +01:00
|
|
|
"github.com/jech/galene/webserver"
|
2020-04-24 19:38:21 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2021-10-26 20:10:24 +02:00
|
|
|
var cpuprofile, memprofile, mutexprofile, httpAddr string
|
2021-04-29 22:02:36 +02:00
|
|
|
var udpRange string
|
2020-05-20 23:04:31 +02:00
|
|
|
|
2020-04-24 19:38:21 +02:00
|
|
|
flag.StringVar(&httpAddr, "http", ":8443", "web server `address`")
|
2020-09-18 13:11:21 +02:00
|
|
|
flag.StringVar(&webserver.StaticRoot, "static", "./static/",
|
2020-04-24 19:38:21 +02:00
|
|
|
"web server root `directory`")
|
2020-12-24 14:44:16 +01:00
|
|
|
flag.BoolVar(&webserver.Insecure, "insecure", false,
|
|
|
|
"act as an HTTP server rather than HTTPS")
|
2021-10-26 20:10:24 +02:00
|
|
|
flag.StringVar(&group.DataDirectory, "data", "./data/",
|
2020-04-24 19:38:21 +02:00
|
|
|
"data `directory`")
|
2020-09-13 11:56:35 +02:00
|
|
|
flag.StringVar(&group.Directory, "groups", "./groups/",
|
2020-04-25 02:25:51 +02:00
|
|
|
"group description `directory`")
|
2020-10-04 19:01:06 +02:00
|
|
|
flag.StringVar(&diskwriter.Directory, "recordings", "./recordings/",
|
2020-05-23 01:48:36 +02:00
|
|
|
"recordings `directory`")
|
2020-05-20 23:04:31 +02:00
|
|
|
flag.StringVar(&cpuprofile, "cpuprofile", "",
|
|
|
|
"store CPU profile in `file`")
|
|
|
|
flag.StringVar(&memprofile, "memprofile", "",
|
|
|
|
"store memory profile in `file`")
|
|
|
|
flag.StringVar(&mutexprofile, "mutexprofile", "",
|
|
|
|
"store mutex profile in `file`")
|
2021-04-29 22:02:36 +02:00
|
|
|
flag.StringVar(&udpRange, "udp-range", "",
|
|
|
|
"UDP port `range`")
|
2020-10-06 06:08:29 +02:00
|
|
|
flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses")
|
2021-01-02 00:20:47 +01:00
|
|
|
flag.BoolVar(&ice.ICERelayOnly, "relay-only", false,
|
2020-12-28 02:56:49 +01:00
|
|
|
"require use of TURN relays for all media traffic")
|
2021-01-19 18:04:39 +01:00
|
|
|
flag.StringVar(&turnserver.Address, "turn", "auto",
|
2021-01-19 01:18:11 +01:00
|
|
|
"built-in TURN server `address` (\"\" to disable)")
|
2020-04-24 19:38:21 +02:00
|
|
|
flag.Parse()
|
2020-05-20 23:04:31 +02:00
|
|
|
|
2021-04-29 22:02:36 +02:00
|
|
|
if udpRange != "" {
|
|
|
|
var min, max uint16
|
|
|
|
n, err := fmt.Sscanf(udpRange, "%v-%v", &min, &max)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("UDP range: %v", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
if n != 2 || min <= 0 || max <= 0 || min > max {
|
|
|
|
log.Printf("UDP range: bad range")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
group.UDPMin = min
|
|
|
|
group.UDPMax = max
|
|
|
|
}
|
|
|
|
|
2020-05-20 23:04:31 +02:00
|
|
|
if cpuprofile != "" {
|
|
|
|
f, err := os.Create(cpuprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Create(cpuprofile): %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
pprof.StartCPUProfile(f)
|
|
|
|
defer func() {
|
|
|
|
pprof.StopCPUProfile()
|
|
|
|
f.Close()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
if memprofile != "" {
|
|
|
|
defer func() {
|
|
|
|
f, err := os.Create(memprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Create(memprofile): %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
pprof.WriteHeapProfile(f)
|
|
|
|
f.Close()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
if mutexprofile != "" {
|
|
|
|
runtime.SetMutexProfileFraction(1)
|
|
|
|
defer func() {
|
|
|
|
f, err := os.Create(mutexprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Create(mutexprofile): %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
pprof.Lookup("mutex").WriteTo(f, 0)
|
|
|
|
f.Close()
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2021-07-29 14:26:41 +02:00
|
|
|
n, err := limit.Nofile(0xFFFF)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Couldn't set file descriptor limit: %v", err)
|
|
|
|
} else if n < 0xFFFF {
|
|
|
|
log.Printf("File descriptor limit is %v, please increase it!", n)
|
|
|
|
}
|
|
|
|
|
2021-10-26 20:10:24 +02:00
|
|
|
ice.ICEFilename = filepath.Join(group.DataDirectory, "ice-servers.json")
|
2023-03-22 04:04:22 +01:00
|
|
|
token.SetStatefulFilename(
|
|
|
|
filepath.Join(
|
|
|
|
filepath.Join(group.DataDirectory, "var"),
|
|
|
|
"tokens.jsonl",
|
|
|
|
),
|
|
|
|
)
|
2020-04-24 19:38:21 +02:00
|
|
|
|
2021-08-22 16:36:18 +02:00
|
|
|
// make sure the list of public groups is updated early
|
|
|
|
go group.Update()
|
2020-09-18 14:14:26 +02:00
|
|
|
|
2021-01-19 01:18:11 +01:00
|
|
|
// causes the built-in server to start if required
|
|
|
|
ice.Update()
|
2021-01-18 20:24:52 +01:00
|
|
|
defer turnserver.Stop()
|
|
|
|
|
2020-09-18 14:14:26 +02:00
|
|
|
serverDone := make(chan struct{})
|
|
|
|
go func() {
|
2021-10-26 20:10:24 +02:00
|
|
|
err := webserver.Serve(httpAddr, group.DataDirectory)
|
2020-09-18 14:14:26 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("Server: %v", err)
|
|
|
|
}
|
|
|
|
close(serverDone)
|
|
|
|
}()
|
2020-04-24 19:38:21 +02:00
|
|
|
|
|
|
|
terminate := make(chan os.Signal, 1)
|
2020-09-12 12:42:48 +02:00
|
|
|
signal.Notify(terminate, syscall.SIGINT, syscall.SIGTERM)
|
2020-12-01 19:30:45 +01:00
|
|
|
|
2021-01-14 01:47:56 +01:00
|
|
|
go relayTest()
|
|
|
|
|
2020-12-01 19:30:45 +01:00
|
|
|
ticker := time.NewTicker(15 * time.Minute)
|
|
|
|
defer ticker.Stop()
|
|
|
|
|
2021-01-14 01:47:56 +01:00
|
|
|
slowTicker := time.NewTicker(12 * time.Hour)
|
|
|
|
defer slowTicker.Stop()
|
|
|
|
|
2020-12-01 19:30:45 +01:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ticker.C:
|
2023-04-04 01:03:02 +02:00
|
|
|
go func() {
|
|
|
|
group.Update()
|
|
|
|
token.Expire()
|
|
|
|
}()
|
2021-01-14 01:47:56 +01:00
|
|
|
case <-slowTicker.C:
|
|
|
|
go relayTest()
|
2020-12-01 19:30:45 +01:00
|
|
|
case <-terminate:
|
|
|
|
webserver.Shutdown()
|
|
|
|
return
|
|
|
|
case <-serverDone:
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2020-09-18 14:14:26 +02:00
|
|
|
}
|
2020-04-24 19:38:21 +02:00
|
|
|
}
|
2021-01-14 01:47:56 +01:00
|
|
|
|
|
|
|
func relayTest() {
|
|
|
|
now := time.Now()
|
2021-02-26 13:22:47 +01:00
|
|
|
d, err := ice.RelayTest(20 * time.Second)
|
2021-01-14 01:47:56 +01:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("Relay test failed: %v", err)
|
|
|
|
log.Printf("Perhaps you didn't configure a TURN server?")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Printf("Relay test successful in %v, RTT = %v", time.Since(now), d)
|
|
|
|
}
|