turnserver registration apis

This commit is contained in:
Abhishek Kondur 2023-04-06 08:50:34 +04:00
parent d96360565b
commit f54ae9ae8f
20 changed files with 138 additions and 123 deletions

View file

@ -28,12 +28,11 @@ services:
MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
MQ_USERNAME: "REPLACE_MQ_USERNAME"
STUN_PORT: "3478"
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
TURN_PORT: "3479"
DEFAULT_PROXY_MODE: "off"
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
TURN_SERVER_API_HOST: "https://api.turn.NETMAKER_BASE_DOMAIN"
ports:
- "3478:3478/udp"
- "3479:3479/udp"
netmaker-ui:
container_name: netmaker-ui
image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG
@ -78,9 +77,22 @@ services:
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
- /root/wait.sh:/mosquitto/config/wait.sh
- mosquitto_logs:/mosquitto/log
turn:
container_name: turn
image: gravitl/turnserver:testing
volumes:
- turn_server:/etc/config
environment:
DEBUG_MODE: "on"
VERBOSITY: "4"
TURN_PORT: "3479"
TURN_API_PORT: "8089"
CORS_ALLOWED_ORIGIN: "*"
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
volumes:
caddy_data: {}
caddy_conf: {}
sqldata: {}
dnsconfig: {}
mosquitto_logs: {}
turn_server: {}

View file

@ -76,6 +76,7 @@ type ServerConfig struct {
Proxy string `yaml:"proxy"`
DefaultProxyMode ProxyMode `yaml:"defaultproxymode"`
TurnServer string `yaml:"turn_server"`
TurnApiServer string `yaml:"turn_api_server"`
TurnPort int `yaml:"turn_port"`
}

1
go.mod
View file

@ -41,6 +41,7 @@ require (
)
require (
github.com/devilcove/httpclient v0.6.0
github.com/gin-gonic/gin v1.9.0
github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.1

4
go.sum
View file

@ -27,6 +27,10 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/devilcove/httpclient v0.6.0 h1:M5YAfHeNbu+0QxCiOCo/fKN+Hf0BtF/6aovu3NNgcKk=
github.com/devilcove/httpclient v0.6.0/go.mod h1:ctrAO2gRgTT+GxtRdWBp2SMQ+vacuxXlbhmlM4oWhs8=
github.com/devilcove/httpclient v0.6.1 h1:Q4jiep/pJPt27VTRggsioCHqdx3z9//JHl4lwqz2Zls=
github.com/devilcove/httpclient v0.6.1/go.mod h1:ctrAO2gRgTT+GxtRdWBp2SMQ+vacuxXlbhmlM4oWhs8=
github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=

View file

@ -97,7 +97,6 @@ func CreateHost(h *models.Host) error {
return err
}
h.HostPass = string(hash)
//turnserver.RegisterNewHostWithTurn(h.ID.String(), h.HostPass)
// if another server has already updated proxyenabled, leave it alone
if !h.ProxyEnabledSet {
log.Println("checking default proxy", servercfg.GetServerConfig().DefaultProxyMode)

11
main.go
View file

@ -112,7 +112,6 @@ func initialize() { // Client Mode Prereq Check
logger.Log(0, "error occurred when notifying nodes of startup", err.Error())
}
}
registerCurrHostsWithTurn()
}
func startControllers(wg *sync.WaitGroup, ctx context.Context) {
@ -186,13 +185,3 @@ func setGarbageCollection() {
debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT)
}
}
func registerCurrHostsWithTurn() {
hosts, err := logic.GetAllHosts()
if err == nil {
for _, hostI := range hosts {
//turnserver.RegisterNewHostWithTurn(hostI.ID.String(), hostI.HostPass)
fmt.Println(hostI)
}
}
}

View file

@ -122,3 +122,8 @@ type HostUpdate struct {
Host Host
Node Node
}
type HostTurnRegister struct {
HostID string `json:"host_id"`
HostPassHash string `json:"host_pass_hash"`
}

View file

@ -226,22 +226,22 @@ type NodeJoinResponse struct {
// ServerConfig - struct for dealing with the server information for a netclient
type ServerConfig struct {
CoreDNSAddr string `yaml:"corednsaddr"`
API string `yaml:"api"`
APIPort string `yaml:"apiport"`
DNSMode string `yaml:"dnsmode"`
Version string `yaml:"version"`
MQPort string `yaml:"mqport"`
MQUserName string `yaml:"mq_username"`
MQPassword string `yaml:"mq_password"`
Server string `yaml:"server"`
Broker string `yaml:"broker"`
Is_EE bool `yaml:"isee"`
StunPort int `yaml:"stun_port"`
StunList []StunServer `yaml:"stun_list"`
TrafficKey []byte `yaml:"traffickey"`
TurnDomain string `yaml:"turn_domain"`
TurnPort int `yaml:"turn_port"`
CoreDNSAddr string `yaml:"corednsaddr"`
API string `yaml:"api"`
APIPort string `yaml:"apiport"`
DNSMode string `yaml:"dnsmode"`
Version string `yaml:"version"`
MQPort string `yaml:"mqport"`
MQUserName string `yaml:"mq_username"`
MQPassword string `yaml:"mq_password"`
Server string `yaml:"server"`
Broker string `yaml:"broker"`
Is_EE bool `yaml:"isee"`
StunPort int `yaml:"stun_port"`
StunList []StunServer `yaml:"stun_list"`
TrafficKey []byte `yaml:"traffickey"`
TurnDomain string `yaml:"turn_domain"`
TurnApiDomain string `yaml:"turn_api_domain"`
}
// User.NameInCharset - returns if name is in charset below or not

View file

@ -103,10 +103,32 @@ func GetServerInfo() models.ServerConfig {
cfg.StunPort = GetStunPort()
cfg.StunList = GetStunList()
cfg.TurnDomain = GetTurnHost()
cfg.TurnPort = GetTurnPort()
cfg.TurnApiDomain = GetTurnApiHost()
return cfg
}
// GetTurnHost - fetches the turn host domain
func GetTurnHost() string {
turnServer := ""
if os.Getenv("TURN_SERVER_HOST") != "" {
turnServer = os.Getenv("TURN_SERVER_HOST")
} else if config.Config.Server.TurnServer != "" {
turnServer = config.Config.Server.TurnServer
}
return turnServer
}
// GetTurnApiHost - fetches the turn api host domain
func GetTurnApiHost() string {
turnApiServer := ""
if os.Getenv("TURN_SERVER_API_HOST") != "" {
turnApiServer = os.Getenv("TURN_SERVER_API_HOST")
} else if config.Config.Server.TurnApiServer != "" {
turnApiServer = config.Config.Server.TurnApiServer
}
return turnApiServer
}
// GetFrontendURL - gets the frontend url
func GetFrontendURL() string {
var frontend = ""
@ -627,31 +649,6 @@ func GetStunPort() int {
return port
}
// GetTurnPort - Get the port to run the turn server on
func GetTurnPort() int {
port := 3479 //default
if os.Getenv("TURN_PORT") != "" {
portInt, err := strconv.Atoi(os.Getenv("TURN_PORT"))
if err == nil {
port = portInt
}
} else if config.Config.Server.TurnPort != 0 {
port = config.Config.Server.TurnPort
}
return port
}
// GetTurnHost - fetches the turn host name
func GetTurnHost() string {
turnServer := ""
if os.Getenv("TURN_SERVER_HOST") != "" {
turnServer = os.Getenv("TURN_SERVER_HOST")
} else if config.Config.Server.TurnServer != "" {
turnServer = config.Config.Server.TurnServer
}
return turnServer
}
// IsProxyEnabled - is proxy on or off
func IsProxyEnabled() bool {
var enabled = false //default

View file

@ -3,8 +3,6 @@ package config
import (
"os"
"strconv"
"github.com/gravitl/netmaker/config"
)
var (
@ -16,23 +14,10 @@ func GetAllowedOrigin() string {
allowedorigin := "*"
if os.Getenv("CORS_ALLOWED_ORIGIN") != "" {
allowedorigin = os.Getenv("CORS_ALLOWED_ORIGIN")
} else if config.Config.Server.AllowedOrigin != "" {
allowedorigin = config.Config.Server.AllowedOrigin
}
return allowedorigin
}
// GetAPIPort - gets the api port
func GetAPIPort() string {
apiport := "8086"
if os.Getenv("API_PORT") != "" {
apiport = os.Getenv("API_PORT")
} else if config.Config.Server.APIPort != "" {
apiport = config.Config.Server.APIPort
}
return apiport
}
// SetVersion - set version of netmaker
func SetVersion(v string) {
if v != "" {
@ -63,11 +48,42 @@ func GetVerbosity() int32 {
if err != nil {
verbosity = 0
}
} else if config.Config.Server.Verbosity != 0 {
verbosity = int(config.Config.Server.Verbosity)
}
if verbosity < 0 || verbosity > 4 {
verbosity = 0
}
return int32(verbosity)
}
// GetTurnHost - fetches the turn host name
func GetTurnHost() string {
turnServer := ""
if os.Getenv("TURN_SERVER_HOST") != "" {
turnServer = os.Getenv("TURN_SERVER_HOST")
}
return turnServer
}
// GetTurnPort - Get the port to run the turn server on
func GetTurnPort() int {
port := 3479 //default
if os.Getenv("TURN_PORT") != "" {
portInt, err := strconv.Atoi(os.Getenv("TURN_PORT"))
if err == nil {
port = portInt
}
}
return port
}
// GetAPIPort - gets the api port
func GetAPIPort() int {
apiport := 8089
if os.Getenv("TURN_API_PORT") != "" {
portInt, err := strconv.Atoi(os.Getenv("TURN_API_PORT"))
if err == nil {
apiport = portInt
}
}
return apiport
}

View file

@ -7,28 +7,32 @@ import (
"sync"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/servercfg"
"github.com/gravitl/netmaker/turnserver/config"
"github.com/pion/turn/v2"
)
var (
AuthMapLock = &sync.RWMutex{}
HostMap = make(map[string][]byte)
authMapLock = &sync.RWMutex{}
HostMap = make(map[string]string)
authBackUpFile = "auth.json"
)
func init() {
os.MkdirAll("/etc/config", os.ModePerm)
}
func RegisterNewHostWithTurn(hostID, hostPass string) {
AuthMapLock.Lock()
HostMap[hostID] = turn.GenerateAuthKey(hostID, servercfg.GetTurnHost(), hostPass)
authMapLock.Lock()
HostMap[hostID] = string(turn.GenerateAuthKey(hostID, config.GetTurnHost(), hostPass))
dumpCredsToFile()
AuthMapLock.Unlock()
authMapLock.Unlock()
}
func UnRegisterNewHostWithTurn(hostID string) {
AuthMapLock.Lock()
authMapLock.Lock()
delete(HostMap, hostID)
dumpCredsToFile()
AuthMapLock.Unlock()
authMapLock.Unlock()
}
func dumpCredsToFile() {
@ -37,13 +41,9 @@ func dumpCredsToFile() {
logger.Log(0, "failed to dump creds to file: ", err.Error())
return
}
userHomeDir, err := os.UserHomeDir()
err = os.WriteFile(filepath.Join("/etc/config", authBackUpFile), d, os.ModePerm)
if err != nil {
logger.Log(0, "failed to get user's home directory")
return
}
err = os.WriteFile(filepath.Join(userHomeDir, authBackUpFile), d, os.ModePerm)
if err != nil {
logger.Log(0, "failed to backup auth data: ", userHomeDir, err.Error())
logger.Log(0, "failed to backup auth data: ", err.Error())
}
}

View file

@ -3,7 +3,7 @@ package errors
import (
"net/http"
"github.com/gravitl/netmaker/turnserver/internal/models"
"github.com/gravitl/netmaker/models"
)
type ApiRespErr string

View file

@ -3,25 +3,27 @@ package host
import (
"errors"
"fmt"
"log"
"github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/turnserver/internal/auth"
errpkg "github.com/gravitl/netmaker/turnserver/internal/errors"
"github.com/gravitl/netmaker/turnserver/internal/models"
"github.com/gravitl/netmaker/turnserver/internal/utils"
)
func Register(c *gin.Context) {
req := models.HostRegister{}
req := models.HostTurnRegister{}
if err := c.ShouldBindJSON(&req); err != nil {
utils.ReturnErrorResponse(c, errpkg.FormatError(err, errpkg.Internal))
return
}
log.Printf("----> REG: %+v", req)
auth.RegisterNewHostWithTurn(req.HostID, req.HostPassHash)
utils.ReturnSuccessResponse(c,
fmt.Sprintf("registred host (%s) successfully", req.HostID), nil)
fmt.Sprintf("registered host (%s) successfully", req.HostID), nil)
}
func Remove(c *gin.Context) {

View file

@ -1,6 +0,0 @@
package models
type HostRegister struct {
HostID string `json:"host_id"`
HostPassHash string `json:"host_pass_hash"`
}

View file

@ -1,14 +0,0 @@
package models
// ErrorResponse is struct for error
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
// SuccessResponse is struct for sending error message with code.
type SuccessResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Response interface{} `json:"response"`
}

View file

@ -4,7 +4,7 @@ import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/turnserver/internal/models"
"github.com/gravitl/netmaker/models"
)
// ReturnSuccessResponse - success api response

View file

@ -22,9 +22,9 @@ func main() {
// kill -2 is syscall.SIGINT
// kill -9 is syscall. SIGKILL but cant be caught, so don't need add it
wg.Add(1)
controller.HandleRESTRequests(ctx, wg)
go controller.HandleRESTRequests(ctx, wg)
wg.Add(1)
turn.Start(ctx, wg)
go turn.Start(ctx, wg)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Log(0, "Recieved Shutdown Signal...")

View file

@ -43,9 +43,8 @@ func HandleRESTRequests(ctx context.Context, wg *sync.WaitGroup) {
// get server port from config
port := config.GetAPIPort()
srv := &http.Server{
Addr: ":" + port,
Addr: fmt.Sprintf(":%d", port),
Handler: handlers.CORS(originsOk, headersOk, methodsOk)(router),
}
go func() {
@ -54,7 +53,7 @@ func HandleRESTRequests(ctx context.Context, wg *sync.WaitGroup) {
log.Fatalf("listen: %s\n", err)
}
}()
logger.Log(0, fmt.Sprintf("REST Server (Version: %s) successfully started on port (%s) ", config.GetVersion(), port))
logger.Log(0, fmt.Sprintf("REST Server (Version: %s) successfully started on port (%d) ", config.GetVersion(), port))
<-ctx.Done()
log.Println("Shutdown Server ...")
if err := srv.Shutdown(ctx); err != nil {

View file

@ -1,6 +1,8 @@
package routes
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/turnserver/internal/host"
)
@ -14,4 +16,12 @@ func Init(r *gin.Engine) *gin.Engine {
func registerRoutes(r *gin.RouterGroup) {
r.POST("/host/register", host.Register)
r.DELETE("/host/unregister", host.Remove)
r.GET("/status", status)
}
func status(c *gin.Context) {
c.JSON(http.StatusOK, struct {
Msg string `json:"msg"`
}{Msg: "hello"})
}

View file

@ -9,7 +9,7 @@ import (
"time"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/servercfg"
"github.com/gravitl/netmaker/turnserver/config"
"github.com/gravitl/netmaker/turnserver/internal/auth"
"github.com/gravitl/netmaker/turnserver/internal/utils"
"github.com/pion/turn/v2"
@ -20,7 +20,7 @@ func Start(ctx context.Context, wg *sync.WaitGroup) {
// Create a UDP listener to pass into pion/turn
// pion/turn itself doesn't allocate any UDP sockets, but lets the user pass them in
// this allows us to add logging, storage or modify inbound/outbound traffic
udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(servercfg.GetTurnPort()))
udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(config.GetTurnPort()))
if err != nil {
log.Panicf("Failed to create TURN server listener: %s", err)
}
@ -29,13 +29,13 @@ func Start(ctx context.Context, wg *sync.WaitGroup) {
logger.FatalLog("failed to get public ip: ", err.Error())
}
s, err := turn.NewServer(turn.ServerConfig{
Realm: servercfg.GetTurnHost(),
Realm: config.GetTurnHost(),
// Set AuthHandler callback
// This is called every time a user tries to authenticate with the TURN server
// Return the key for that user, or false when no user is found
AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) {
if key, ok := auth.HostMap[username]; ok {
return key, true
return []byte(key), true
}
return nil, false
},