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_PASSWORD: "REPLACE_MQ_PASSWORD"
MQ_USERNAME: "REPLACE_MQ_USERNAME" MQ_USERNAME: "REPLACE_MQ_USERNAME"
STUN_PORT: "3478" STUN_PORT: "3478"
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
TURN_PORT: "3479"
DEFAULT_PROXY_MODE: "off" DEFAULT_PROXY_MODE: "off"
TURN_SERVER_HOST: "turn.NETMAKER_BASE_DOMAIN"
TURN_SERVER_API_HOST: "https://api.turn.NETMAKER_BASE_DOMAIN"
ports: ports:
- "3478:3478/udp" - "3478:3478/udp"
- "3479:3479/udp"
netmaker-ui: netmaker-ui:
container_name: netmaker-ui container_name: netmaker-ui
image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG image: gravitl/netmaker-ui:REPLACE_UI_IMAGE_TAG
@@ -78,9 +77,22 @@ services:
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
- /root/wait.sh:/mosquitto/config/wait.sh - /root/wait.sh:/mosquitto/config/wait.sh
- mosquitto_logs:/mosquitto/log - 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: volumes:
caddy_data: {} caddy_data: {}
caddy_conf: {} caddy_conf: {}
sqldata: {} sqldata: {}
dnsconfig: {} dnsconfig: {}
mosquitto_logs: {} mosquitto_logs: {}
turn_server: {}

View File

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

1
go.mod
View File

@@ -41,6 +41,7 @@ require (
) )
require ( require (
github.com/devilcove/httpclient v0.6.0
github.com/gin-gonic/gin v1.9.0 github.com/gin-gonic/gin v1.9.0
github.com/guumaster/tablewriter v0.0.10 github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.1 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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= 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= 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 return err
} }
h.HostPass = string(hash) h.HostPass = string(hash)
//turnserver.RegisterNewHostWithTurn(h.ID.String(), h.HostPass)
// if another server has already updated proxyenabled, leave it alone // if another server has already updated proxyenabled, leave it alone
if !h.ProxyEnabledSet { if !h.ProxyEnabledSet {
log.Println("checking default proxy", servercfg.GetServerConfig().DefaultProxyMode) 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()) logger.Log(0, "error occurred when notifying nodes of startup", err.Error())
} }
} }
registerCurrHostsWithTurn()
} }
func startControllers(wg *sync.WaitGroup, ctx context.Context) { func startControllers(wg *sync.WaitGroup, ctx context.Context) {
@@ -186,13 +185,3 @@ func setGarbageCollection() {
debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT) 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 Host Host
Node Node Node Node
} }
type HostTurnRegister struct {
HostID string `json:"host_id"`
HostPassHash string `json:"host_pass_hash"`
}

View File

@@ -241,7 +241,7 @@ type ServerConfig struct {
StunList []StunServer `yaml:"stun_list"` StunList []StunServer `yaml:"stun_list"`
TrafficKey []byte `yaml:"traffickey"` TrafficKey []byte `yaml:"traffickey"`
TurnDomain string `yaml:"turn_domain"` TurnDomain string `yaml:"turn_domain"`
TurnPort int `yaml:"turn_port"` TurnApiDomain string `yaml:"turn_api_domain"`
} }
// User.NameInCharset - returns if name is in charset below or not // 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.StunPort = GetStunPort()
cfg.StunList = GetStunList() cfg.StunList = GetStunList()
cfg.TurnDomain = GetTurnHost() cfg.TurnDomain = GetTurnHost()
cfg.TurnPort = GetTurnPort() cfg.TurnApiDomain = GetTurnApiHost()
return cfg 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 // GetFrontendURL - gets the frontend url
func GetFrontendURL() string { func GetFrontendURL() string {
var frontend = "" var frontend = ""
@@ -627,31 +649,6 @@ func GetStunPort() int {
return port 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 // IsProxyEnabled - is proxy on or off
func IsProxyEnabled() bool { func IsProxyEnabled() bool {
var enabled = false //default var enabled = false //default

View File

@@ -3,8 +3,6 @@ package config
import ( import (
"os" "os"
"strconv" "strconv"
"github.com/gravitl/netmaker/config"
) )
var ( var (
@@ -16,23 +14,10 @@ func GetAllowedOrigin() string {
allowedorigin := "*" allowedorigin := "*"
if os.Getenv("CORS_ALLOWED_ORIGIN") != "" { if os.Getenv("CORS_ALLOWED_ORIGIN") != "" {
allowedorigin = os.Getenv("CORS_ALLOWED_ORIGIN") allowedorigin = os.Getenv("CORS_ALLOWED_ORIGIN")
} else if config.Config.Server.AllowedOrigin != "" {
allowedorigin = config.Config.Server.AllowedOrigin
} }
return 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 // SetVersion - set version of netmaker
func SetVersion(v string) { func SetVersion(v string) {
if v != "" { if v != "" {
@@ -63,11 +48,42 @@ func GetVerbosity() int32 {
if err != nil { if err != nil {
verbosity = 0 verbosity = 0
} }
} else if config.Config.Server.Verbosity != 0 {
verbosity = int(config.Config.Server.Verbosity)
} }
if verbosity < 0 || verbosity > 4 { if verbosity < 0 || verbosity > 4 {
verbosity = 0 verbosity = 0
} }
return int32(verbosity) 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" "sync"
"github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/turnserver/config"
"github.com/pion/turn/v2" "github.com/pion/turn/v2"
) )
var ( var (
AuthMapLock = &sync.RWMutex{} authMapLock = &sync.RWMutex{}
HostMap = make(map[string][]byte) HostMap = make(map[string]string)
authBackUpFile = "auth.json" authBackUpFile = "auth.json"
) )
func init() {
os.MkdirAll("/etc/config", os.ModePerm)
}
func RegisterNewHostWithTurn(hostID, hostPass string) { func RegisterNewHostWithTurn(hostID, hostPass string) {
AuthMapLock.Lock() authMapLock.Lock()
HostMap[hostID] = turn.GenerateAuthKey(hostID, servercfg.GetTurnHost(), hostPass) HostMap[hostID] = string(turn.GenerateAuthKey(hostID, config.GetTurnHost(), hostPass))
dumpCredsToFile() dumpCredsToFile()
AuthMapLock.Unlock() authMapLock.Unlock()
} }
func UnRegisterNewHostWithTurn(hostID string) { func UnRegisterNewHostWithTurn(hostID string) {
AuthMapLock.Lock() authMapLock.Lock()
delete(HostMap, hostID) delete(HostMap, hostID)
dumpCredsToFile() dumpCredsToFile()
AuthMapLock.Unlock() authMapLock.Unlock()
} }
func dumpCredsToFile() { func dumpCredsToFile() {
@@ -37,13 +41,9 @@ func dumpCredsToFile() {
logger.Log(0, "failed to dump creds to file: ", err.Error()) logger.Log(0, "failed to dump creds to file: ", err.Error())
return return
} }
userHomeDir, err := os.UserHomeDir()
err = os.WriteFile(filepath.Join("/etc/config", authBackUpFile), d, os.ModePerm)
if err != nil { if err != nil {
logger.Log(0, "failed to get user's home directory") logger.Log(0, "failed to backup auth data: ", err.Error())
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())
} }
} }

View File

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

View File

@@ -3,25 +3,27 @@ package host
import ( import (
"errors" "errors"
"fmt" "fmt"
"log"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/turnserver/internal/auth" "github.com/gravitl/netmaker/turnserver/internal/auth"
errpkg "github.com/gravitl/netmaker/turnserver/internal/errors" errpkg "github.com/gravitl/netmaker/turnserver/internal/errors"
"github.com/gravitl/netmaker/turnserver/internal/models"
"github.com/gravitl/netmaker/turnserver/internal/utils" "github.com/gravitl/netmaker/turnserver/internal/utils"
) )
func Register(c *gin.Context) { func Register(c *gin.Context) {
req := models.HostRegister{} req := models.HostTurnRegister{}
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
utils.ReturnErrorResponse(c, errpkg.FormatError(err, errpkg.Internal)) utils.ReturnErrorResponse(c, errpkg.FormatError(err, errpkg.Internal))
return return
} }
log.Printf("----> REG: %+v", req)
auth.RegisterNewHostWithTurn(req.HostID, req.HostPassHash) auth.RegisterNewHostWithTurn(req.HostID, req.HostPassHash)
utils.ReturnSuccessResponse(c, 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) { 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" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/turnserver/internal/models" "github.com/gravitl/netmaker/models"
) )
// ReturnSuccessResponse - success api response // ReturnSuccessResponse - success api response

View File

@@ -22,9 +22,9 @@ func main() {
// kill -2 is syscall.SIGINT // kill -2 is syscall.SIGINT
// kill -9 is syscall. SIGKILL but cant be caught, so don't need add it // kill -9 is syscall. SIGKILL but cant be caught, so don't need add it
wg.Add(1) wg.Add(1)
controller.HandleRESTRequests(ctx, wg) go controller.HandleRESTRequests(ctx, wg)
wg.Add(1) wg.Add(1)
turn.Start(ctx, wg) go turn.Start(ctx, wg)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit <-quit
logger.Log(0, "Recieved Shutdown Signal...") 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 // get server port from config
port := config.GetAPIPort() port := config.GetAPIPort()
srv := &http.Server{ srv := &http.Server{
Addr: ":" + port, Addr: fmt.Sprintf(":%d", port),
Handler: handlers.CORS(originsOk, headersOk, methodsOk)(router), Handler: handlers.CORS(originsOk, headersOk, methodsOk)(router),
} }
go func() { go func() {
@@ -54,7 +53,7 @@ func HandleRESTRequests(ctx context.Context, wg *sync.WaitGroup) {
log.Fatalf("listen: %s\n", err) 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() <-ctx.Done()
log.Println("Shutdown Server ...") log.Println("Shutdown Server ...")
if err := srv.Shutdown(ctx); err != nil { if err := srv.Shutdown(ctx); err != nil {

View File

@@ -1,6 +1,8 @@
package routes package routes
import ( import (
"net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gravitl/netmaker/turnserver/internal/host" "github.com/gravitl/netmaker/turnserver/internal/host"
) )
@@ -14,4 +16,12 @@ func Init(r *gin.Engine) *gin.Engine {
func registerRoutes(r *gin.RouterGroup) { func registerRoutes(r *gin.RouterGroup) {
r.POST("/host/register", host.Register) 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" "time"
"github.com/gravitl/netmaker/logger" "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/auth"
"github.com/gravitl/netmaker/turnserver/internal/utils" "github.com/gravitl/netmaker/turnserver/internal/utils"
"github.com/pion/turn/v2" "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 // 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 // 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 // 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 { if err != nil {
log.Panicf("Failed to create TURN server listener: %s", err) 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()) logger.FatalLog("failed to get public ip: ", err.Error())
} }
s, err := turn.NewServer(turn.ServerConfig{ s, err := turn.NewServer(turn.ServerConfig{
Realm: servercfg.GetTurnHost(), Realm: config.GetTurnHost(),
// Set AuthHandler callback // Set AuthHandler callback
// This is called every time a user tries to authenticate with the TURN server // 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 // Return the key for that user, or false when no user is found
AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) { AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) {
if key, ok := auth.HostMap[username]; ok { if key, ok := auth.HostMap[username]; ok {
return key, true return []byte(key), true
} }
return nil, false return nil, false
}, },