Browse Source

move turn server to a different repo

Abhishek Kondur 2 years ago
parent
commit
e4a770eb72

+ 0 - 21
Dockerfile.turn

@@ -1,21 +0,0 @@
-#first stage - builder
-FROM gravitl/go-builder as builder
-
-ARG version 
-
-WORKDIR /app
-
-COPY . .
-
-WORKDIR /app/turnserver
-ENV GO111MODULE=auto
-
-RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -X 'main.version=${version}'" -o turnserver main.go
-FROM alpine:3.15.2
-
-# set the working directory
-WORKDIR /root/
-
-COPY --from=builder /app/turnserver/turnserver .
-
-ENTRYPOINT ["./turnserver"]

+ 0 - 99
turnserver/config/config.go

@@ -1,99 +0,0 @@
-package config
-
-import (
-	"os"
-	"strconv"
-)
-
-var (
-	Version = "dev"
-)
-
-// GetAllowedOrigin - get the allowed origin
-func GetAllowedOrigin() string {
-	allowedorigin := "*"
-	if os.Getenv("CORS_ALLOWED_ORIGIN") != "" {
-		allowedorigin = os.Getenv("CORS_ALLOWED_ORIGIN")
-	}
-	return allowedorigin
-}
-
-// SetVersion - set version of netmaker
-func SetVersion(v string) {
-	if v != "" {
-		Version = v
-	}
-}
-
-// GetVersion - version of netmaker
-func GetVersion() string {
-	return Version
-}
-
-// IsDebugMode - gets the debug mode for the server
-func IsDebugMode() bool {
-	debugMode := false
-	if os.Getenv("DEBUG_MODE") == "on" {
-		debugMode = true
-	}
-	return debugMode
-}
-
-// GetVerbosity - get logger verbose level
-func GetVerbosity() int32 {
-	var verbosity = 0
-	var err error
-	if os.Getenv("VERBOSITY") != "" {
-		verbosity, err = strconv.Atoi(os.Getenv("VERBOSITY"))
-		if err != nil {
-			verbosity = 0
-		}
-	}
-	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
-}
-
-// GetUserName - gets the username for the apis
-func GetUserName() string {
-	return os.Getenv("USERNAME")
-}
-
-// GetPassword - gets the password for the server apis
-func GetPassword() string {
-	return os.Getenv("PASSWORD")
-}

+ 0 - 65
turnserver/internal/auth/auth.go

@@ -1,65 +0,0 @@
-package auth
-
-import (
-	"encoding/base64"
-	"encoding/json"
-	"os"
-	"path/filepath"
-	"sync"
-
-	"github.com/gravitl/netmaker/logger"
-	"github.com/gravitl/netmaker/turnserver/config"
-	"github.com/pion/turn/v2"
-)
-
-var (
-	authMapLock    = &sync.RWMutex{}
-	HostMap        = make(map[string]string)
-	authBackUpFile = "auth.json"
-	backUpFilePath = filepath.Join("/etc/config", authBackUpFile)
-)
-
-func init() {
-	os.MkdirAll("/etc/config", os.ModePerm)
-	// reads creds from disk if any present
-	loadCredsFromFile()
-}
-
-// RegisterNewHostWithTurn - add new host's creds to map and dumps it to the disk
-func RegisterNewHostWithTurn(hostID, hostPass string) {
-	authMapLock.Lock()
-	HostMap[hostID] = base64.StdEncoding.EncodeToString(turn.GenerateAuthKey(hostID, config.GetTurnHost(), hostPass))
-	dumpCredsToFile()
-	authMapLock.Unlock()
-}
-
-// UnRegisterNewHostWithTurn - deletes the host creds
-func UnRegisterNewHostWithTurn(hostID string) {
-	authMapLock.Lock()
-	delete(HostMap, hostID)
-	dumpCredsToFile()
-	authMapLock.Unlock()
-}
-
-// dumpCredsToFile - saves the creds to file
-func dumpCredsToFile() {
-	d, err := json.MarshalIndent(HostMap, "", " ")
-	if err != nil {
-		logger.Log(0, "failed to dump creds to file: ", err.Error())
-		return
-	}
-
-	err = os.WriteFile(backUpFilePath, d, os.ModePerm)
-	if err != nil {
-		logger.Log(0, "failed to backup auth data: ", err.Error())
-	}
-}
-
-// loadCredsFromFile - loads the creds from disk
-func loadCredsFromFile() error {
-	d, err := os.ReadFile(backUpFilePath)
-	if err != nil {
-		return err
-	}
-	return json.Unmarshal(d, &HostMap)
-}

+ 0 - 48
turnserver/internal/errors/api_errors.go

@@ -1,48 +0,0 @@
-package errors
-
-import (
-	"net/http"
-
-	"github.com/gravitl/netmaker/models"
-)
-
-type ApiRespErr string
-
-const (
-	Internal     ApiRespErr = "internal"
-	BadRequest   ApiRespErr = "badrequest"
-	NotFound     ApiRespErr = "notfound"
-	UnAuthorized ApiRespErr = "unauthorized"
-	Forbidden    ApiRespErr = "forbidden"
-	Unavailable  ApiRespErr = "unavailable"
-)
-
-// FormatError - formats into api error resp
-func FormatError(err error, errType ApiRespErr) models.ErrorResponse {
-
-	var status = http.StatusInternalServerError
-	switch errType {
-	case Internal:
-		status = http.StatusInternalServerError
-	case BadRequest:
-		status = http.StatusBadRequest
-	case NotFound:
-		status = http.StatusNotFound
-	case UnAuthorized:
-		status = http.StatusUnauthorized
-	case Forbidden:
-		status = http.StatusForbidden
-	case Unavailable:
-		status = http.StatusServiceUnavailable
-	default:
-		status = http.StatusInternalServerError
-	}
-
-	var response = models.ErrorResponse{
-		Code: status,
-	}
-	if err != nil {
-		response.Message = err.Error()
-	}
-	return response
-}

+ 0 - 41
turnserver/internal/host/host.go

@@ -1,41 +0,0 @@
-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/utils"
-)
-
-// Register - handles the host registration
-func Register(c *gin.Context) {
-	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("registered host (%s) successfully", req.HostID), nil)
-}
-
-// Remove - unregisters the host from turn server
-func Remove(c *gin.Context) {
-	hostID, _ := c.GetQuery("host_id")
-	if hostID == "" {
-		logger.Log(0, "host id is required")
-		utils.ReturnErrorResponse(c,
-			errpkg.FormatError(errors.New("host id is required"), errpkg.BadRequest))
-		return
-	}
-	utils.ReturnSuccessResponse(c,
-		fmt.Sprintf("unregistered host (%s) successfully", hostID), nil)
-}

+ 0 - 35
turnserver/internal/utils/response.go

@@ -1,35 +0,0 @@
-package utils
-
-import (
-	"net/http"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gravitl/netmaker/models"
-)
-
-// ReturnSuccessResponse - success api response
-func ReturnSuccessResponse(c *gin.Context, message string, responseBody interface{}) {
-	var httpResponse models.SuccessResponse
-	httpResponse.Code = http.StatusOK
-	httpResponse.Message = message
-	httpResponse.Response = responseBody
-	if httpResponse.Response == nil {
-		httpResponse.Response = struct{}{}
-	}
-	c.Writer.Header().Set("Content-Type", "application/json")
-	c.JSON(http.StatusOK, httpResponse)
-}
-
-// ReturnErrorResponse - error api response
-func ReturnErrorResponse(c *gin.Context, errorMessage models.ErrorResponse) {
-	httpResponse := &models.ErrorResponse{Code: errorMessage.Code, Message: errorMessage.Message}
-	c.Writer.Header().Set("Content-Type", "application/json")
-	c.JSON(errorMessage.Code, httpResponse)
-}
-
-// AbortWithError - abort api request with error
-func AbortWithError(c *gin.Context, errorMessage models.ErrorResponse) {
-	httpResponse := &models.ErrorResponse{Code: errorMessage.Code, Message: errorMessage.Message}
-	c.Writer.Header().Set("Content-Type", "application/json")
-	c.AbortWithStatusJSON(errorMessage.Code, httpResponse)
-}

+ 0 - 32
turnserver/main.go

@@ -1,32 +0,0 @@
-package main
-
-import (
-	"context"
-	"os"
-	"os/signal"
-	"sync"
-	"syscall"
-
-	"github.com/gravitl/netmaker/logger"
-	"github.com/gravitl/netmaker/turnserver/src/controller"
-	"github.com/gravitl/netmaker/turnserver/src/turn"
-)
-
-func main() {
-	ctx, cancel := context.WithCancel(context.Background())
-	wg := &sync.WaitGroup{}
-	quit := make(chan os.Signal, 2)
-	wg.Add(1)
-	go controller.HandleRESTRequests(ctx, wg)
-	wg.Add(1)
-	go turn.Start(ctx, wg)
-	// kill (no param) default send syscanll.SIGTERM
-	// kill -2 is syscall.SIGINT
-	// kill -9 is syscall. SIGKILL but cant be caught, so don't need add it
-	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
-	<-quit
-	logger.Log(0, "Recieved Shutdown Signal...")
-	cancel()
-	wg.Wait()
-	logger.Log(0, "Stopping Turn Server...")
-}

+ 0 - 80
turnserver/src/controller/controller.go

@@ -1,80 +0,0 @@
-package controller
-
-import (
-	"context"
-	"fmt"
-	"log"
-	"net/http"
-	"os"
-	"sync"
-	"time"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gorilla/handlers"
-
-	"github.com/gravitl/netmaker/logger"
-	"github.com/gravitl/netmaker/turnserver/config"
-	"github.com/gravitl/netmaker/turnserver/src/middleware"
-	"github.com/gravitl/netmaker/turnserver/src/routes"
-)
-
-// HandleRESTRequests - handles the rest requests
-func HandleRESTRequests(ctx context.Context, wg *sync.WaitGroup) {
-	defer wg.Done()
-	// Set GIN MODE (debug or release)
-	gin.SetMode(gin.ReleaseMode)
-	if config.GetVersion() == "dev" || config.IsDebugMode() {
-		gin.SetMode(gin.DebugMode)
-	}
-	// Register gin router with default configuration
-	// comes with default middleware and recovery handlers.
-	router := gin.Default()
-	// Intialize all routes
-	routes.Init(router)
-	// Attach custom logger to gin to print incoming requests to stdout.
-	router.Use(ginLogger())
-	// Attach rate limiter to middleware
-	router.Use(middleware.RateLimiter())
-	// Currently allowed dev origin is all. Should change in prod
-	// should consider analyzing the allowed methods further
-	headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization"})
-	originsOk := handlers.AllowedOrigins([]string{config.GetAllowedOrigin()})
-	methodsOk := handlers.AllowedMethods([]string{"GET", "PUT", "POST", "DELETE"})
-
-	// get server port from config
-	port := config.GetAPIPort()
-	srv := &http.Server{
-		Addr:    fmt.Sprintf(":%d", port),
-		Handler: handlers.CORS(originsOk, headersOk, methodsOk)(router),
-	}
-	go func() {
-		// service connections
-		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
-			log.Fatalf("listen: %s\n", err)
-		}
-	}()
-	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 {
-		log.Fatal("Server Shutdown:", err)
-	}
-	logger.Log(0, "Server exiting...")
-	os.Exit(0)
-}
-
-func ginLogger() gin.HandlerFunc {
-	return func(c *gin.Context) {
-
-		// Get the client IP address
-		clientIP := c.ClientIP()
-
-		// Get the current time
-		now := time.Now()
-		// Log the request
-		log.Printf("[%s] %s %s %s", now.Format(time.RFC3339), c.Request.Method, c.Request.URL.Path, clientIP)
-
-		// Proceed to the next handler
-		c.Next()
-	}
-}

+ 0 - 25
turnserver/src/middleware/middleware.go

@@ -1,25 +0,0 @@
-package middleware
-
-import (
-	"github.com/gin-gonic/gin"
-	"github.com/gravitl/netmaker/logger"
-	"github.com/ulule/limiter/v3"
-	mgin "github.com/ulule/limiter/v3/drivers/middleware/gin"
-	"github.com/ulule/limiter/v3/drivers/store/memory"
-)
-
-// RateLimiter - middleware handler to enforce rate limiting on requests
-func RateLimiter() gin.HandlerFunc {
-
-	rate, err := limiter.NewRateFromFormatted("1000-H")
-	if err != nil {
-		logger.FatalLog(err.Error())
-	}
-	store := memory.NewStore()
-
-	// Then, create the limiter instance which takes the store and the rate as arguments.
-	// Now, you can add this instance to gin middleware.
-	instance := limiter.New(store, rate)
-	return mgin.NewMiddleware(instance)
-
-}

+ 0 - 34
turnserver/src/routes/routes.go

@@ -1,34 +0,0 @@
-package routes
-
-import (
-	"net/http"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gravitl/netmaker/turnserver/config"
-	"github.com/gravitl/netmaker/turnserver/internal/host"
-)
-
-func Init(r *gin.Engine) *gin.Engine {
-	api := r.Group("/api")
-	v1 := api.Group("/v1")
-	registerRoutes(v1)
-	return r
-}
-
-func registerRoutes(r *gin.RouterGroup) {
-	r.POST("/host/register", gin.BasicAuth(gin.Accounts{
-		config.GetUserName(): config.GetPassword(),
-	}), host.Register)
-	r.DELETE("/host/deregister", gin.BasicAuth(gin.Accounts{
-		config.GetUserName(): config.GetPassword(),
-	}), host.Remove)
-	r.GET("/status", gin.BasicAuth(gin.Accounts{
-		config.GetUserName(): config.GetPassword(),
-	}), status)
-}
-
-func status(c *gin.Context) {
-	c.JSON(http.StatusOK, struct {
-		Msg string `json:"msg"`
-	}{Msg: "active"})
-}

+ 0 - 98
turnserver/src/turn/server.go

@@ -1,98 +0,0 @@
-package turn
-
-import (
-	"context"
-	"encoding/base64"
-	"log"
-	"net"
-	"strconv"
-	"sync"
-	"syscall"
-	"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/pion/turn/v2"
-	"golang.org/x/sys/unix"
-)
-
-// Start - initializes and handles the turn connections
-func Start(ctx context.Context, wg *sync.WaitGroup) {
-	defer wg.Done()
-	// 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
-	addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:"+strconv.Itoa(config.GetTurnPort()))
-	if err != nil {
-		log.Fatalf("Failed to parse server address: %s", err)
-	}
-	publicIP, err := servercfg.GetPublicIP()
-	if err != nil {
-		logger.FatalLog("failed to get public ip: ", err.Error())
-	}
-
-	// Create `numThreads` UDP listeners to pass into pion/turn
-	// UDP listeners share the same local address:port with setting SO_REUSEPORT and the kernel
-	// will load-balance received packets per the IP 5-tuple
-	listenerConfig := &net.ListenConfig{
-		Control: func(network, address string, conn syscall.RawConn) error {
-			var operr error
-			if err = conn.Control(func(fd uintptr) {
-				operr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1)
-			}); err != nil {
-				return err
-			}
-
-			return operr
-		},
-	}
-	relayAddressGenerator := &turn.RelayAddressGeneratorStatic{
-		RelayAddress: net.ParseIP(publicIP),
-		Address:      "0.0.0.0",
-	}
-	packetConnConfigs := []turn.PacketConnConfig{}
-	for i := 0; i < 5; i++ {
-		conn, listErr := listenerConfig.ListenPacket(context.Background(), addr.Network(), addr.String())
-		if listErr != nil {
-			log.Fatalf("Failed to allocate UDP listener at %s:%s", addr.Network(), addr.String())
-		}
-
-		packetConnConfigs = append(packetConnConfigs, turn.PacketConnConfig{
-			PacketConn:            conn,
-			RelayAddressGenerator: relayAddressGenerator,
-		})
-
-		log.Printf("Server %d listening on %s\n", i, conn.LocalAddr().String())
-	}
-
-	s, err := turn.NewServer(turn.ServerConfig{
-		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 {
-				keyBytes, err := base64.StdEncoding.DecodeString(key)
-				if err != nil {
-					return nil, false
-				}
-				return keyBytes, true
-			}
-			return nil, false
-		},
-		ChannelBindTimeout: time.Duration(time.Minute * 10),
-		// PacketConnConfigs is a list of UDP Listeners and the configuration around them
-		PacketConnConfigs: packetConnConfigs,
-	})
-	if err != nil {
-		log.Panic(err)
-	}
-	// Block until user sends SIGINT or SIGTERM
-	<-ctx.Done()
-	logger.Log(0, "## Stopping Turn Server...")
-	if err = s.Close(); err != nil {
-		log.Panic(err)
-	}
-}