From f54ae9ae8f11f551a3946adfc71e2ee501ffdcbe Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Thu, 6 Apr 2023 08:50:34 +0400 Subject: [PATCH] turnserver registration apis --- compose/docker-compose.yml | 18 +++++++-- config/config.go | 1 + go.mod | 1 + go.sum | 4 ++ logic/hosts.go | 1 - main.go | 11 ------ models/host.go | 5 +++ models/structs.go | 32 +++++++-------- servercfg/serverconf.go | 49 +++++++++++------------ turnserver/config/config.go | 50 ++++++++++++++++-------- turnserver/internal/auth/auth.go | 30 +++++++------- turnserver/internal/errors/api_errors.go | 2 +- turnserver/internal/host/host.go | 8 ++-- turnserver/internal/models/models.go | 6 --- turnserver/internal/models/response.go | 14 ------- turnserver/internal/utils/response.go | 2 +- turnserver/main.go | 4 +- turnserver/src/controller/controller.go | 5 +-- turnserver/src/routes/routes.go | 10 +++++ turnserver/src/turn/server.go | 8 ++-- 20 files changed, 138 insertions(+), 123 deletions(-) delete mode 100644 turnserver/internal/models/models.go delete mode 100644 turnserver/internal/models/response.go diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 913d292e..07400fb2 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -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: {} diff --git a/config/config.go b/config/config.go index 2476cc40..d0eb169a 100644 --- a/config/config.go +++ b/config/config.go @@ -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"` } diff --git a/go.mod b/go.mod index da950b17..4bc24ec0 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index ef5badcb..54c9dc37 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/logic/hosts.go b/logic/hosts.go index 23d66204..2ea04349 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -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) diff --git a/main.go b/main.go index c899cb99..a3bcaa2f 100644 --- a/main.go +++ b/main.go @@ -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) - } - } -} diff --git a/models/host.go b/models/host.go index d7a32837..6495d512 100644 --- a/models/host.go +++ b/models/host.go @@ -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"` +} diff --git a/models/structs.go b/models/structs.go index 463307e1..61b84a0e 100644 --- a/models/structs.go +++ b/models/structs.go @@ -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 diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index 7685feb6..61d405d9 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -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 diff --git a/turnserver/config/config.go b/turnserver/config/config.go index 96fe2169..6db005c2 100644 --- a/turnserver/config/config.go +++ b/turnserver/config/config.go @@ -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 +} diff --git a/turnserver/internal/auth/auth.go b/turnserver/internal/auth/auth.go index 224b59fb..0c797819 100644 --- a/turnserver/internal/auth/auth.go +++ b/turnserver/internal/auth/auth.go @@ -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()) } } diff --git a/turnserver/internal/errors/api_errors.go b/turnserver/internal/errors/api_errors.go index 6c3e9a33..3e46a988 100644 --- a/turnserver/internal/errors/api_errors.go +++ b/turnserver/internal/errors/api_errors.go @@ -3,7 +3,7 @@ package errors import ( "net/http" - "github.com/gravitl/netmaker/turnserver/internal/models" + "github.com/gravitl/netmaker/models" ) type ApiRespErr string diff --git a/turnserver/internal/host/host.go b/turnserver/internal/host/host.go index df31b1cc..7a92ebc7 100644 --- a/turnserver/internal/host/host.go +++ b/turnserver/internal/host/host.go @@ -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) { diff --git a/turnserver/internal/models/models.go b/turnserver/internal/models/models.go deleted file mode 100644 index 0b9347d2..00000000 --- a/turnserver/internal/models/models.go +++ /dev/null @@ -1,6 +0,0 @@ -package models - -type HostRegister struct { - HostID string `json:"host_id"` - HostPassHash string `json:"host_pass_hash"` -} diff --git a/turnserver/internal/models/response.go b/turnserver/internal/models/response.go deleted file mode 100644 index 9d605ed5..00000000 --- a/turnserver/internal/models/response.go +++ /dev/null @@ -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"` -} diff --git a/turnserver/internal/utils/response.go b/turnserver/internal/utils/response.go index 71457e82..dd0f4969 100644 --- a/turnserver/internal/utils/response.go +++ b/turnserver/internal/utils/response.go @@ -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 diff --git a/turnserver/main.go b/turnserver/main.go index a2eed106..47bbe844 100644 --- a/turnserver/main.go +++ b/turnserver/main.go @@ -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...") diff --git a/turnserver/src/controller/controller.go b/turnserver/src/controller/controller.go index 547d3a56..52c18097 100644 --- a/turnserver/src/controller/controller.go +++ b/turnserver/src/controller/controller.go @@ -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 { diff --git a/turnserver/src/routes/routes.go b/turnserver/src/routes/routes.go index 673b56b2..ddd302b3 100644 --- a/turnserver/src/routes/routes.go +++ b/turnserver/src/routes/routes.go @@ -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"}) } diff --git a/turnserver/src/turn/server.go b/turnserver/src/turn/server.go index 223588b0..a196f2e8 100644 --- a/turnserver/src/turn/server.go +++ b/turnserver/src/turn/server.go @@ -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 },