Browse Source

Add function for Add Code generate/allocate/delete

wip-tls
Jaeha Choi 2 months ago
parent
commit
8894b1c8d4
Signed by: Jaeha.Choi GPG Key ID: D6133D1D117FF503
  1. 107
      internal/server/server.go
  2. 39
      internal/server/server_test.go

107
internal/server/server.go

@ -3,13 +3,22 @@ package server
import (
"crypto/rand"
"crypto/tls"
"encoding/binary"
"errors"
"fmt"
"github.com/jaeha-choi/Proj_Coconut_Utility/log"
"gopkg.in/yaml.v3"
"io/ioutil"
mRand "math/rand"
"net"
"os"
"path/filepath"
"sync"
)
const (
keyPairName = "server"
addCodeArrSize = 999999
)
// Server related configurations
@ -17,15 +26,92 @@ type Server struct {
Host string `yaml:"host"`
Port uint16 `yaml:"port"`
CertPath string `yaml:"cert_path"`
tls *tls.Config
// addCodeArr stores shuffled Add Code in integer with a boolean indicating
// the status of the Add Code.
// True if available for the server to allocate the Add Code to other device, false otherwise.
// 000 000 is reserved for initial value, and should not be used for allocation.
// i.e. addCodeArr[index] = [Add Code (int), isUsed (bool)]
addCodeArr [addCodeArrSize][2]interface{} // TODO: Add mutex for addCodeArr
// addCodeIdx stores indices to actual Add Code (inverse of addCodeArr)
// i.e. addCodeIdx[addCode] = index to Add Code in addCodeArr
addCodeIdx [addCodeArrSize]int `yaml:"add_code_idx"`
// nextAddCodeIdx represents index of next available Add Code element in addCodeArr
nextAddCodeIdx int // TODO: Add mutex for nextAddCodeIdx
// devices store Add Codes as a key (int) and hash of a public key as a value (string).
devices sync.Map
tls *tls.Config
}
const (
keyPairName = "server"
)
var NoAvailableAddCodeError = errors.New("no available add code error")
func init() {
log.Init(os.Stdout, log.DEBUG)
var seed [8]byte
_, err := rand.Read(seed[:])
if err != nil {
log.Debug(err)
log.Error("Error while setting up math/random seed")
os.Exit(1)
return
}
mRand.Seed(int64(binary.LittleEndian.Uint64(seed[:])))
}
func (serv *Server) initAddCode() {
for i := 0; i < addCodeArrSize; i++ {
serv.addCodeArr[i] = [2]interface{}{i + 1, false}
}
mRand.Shuffle(addCodeArrSize, func(i, j int) {
serv.addCodeArr[i], serv.addCodeArr[j] = serv.addCodeArr[j], serv.addCodeArr[i]
serv.addCodeIdx[serv.addCodeArr[i][0].(int)-1] = i
serv.addCodeIdx[serv.addCodeArr[j][0].(int)-1] = j
})
}
func (serv *Server) RemoveDevice(addCode int) {
addCodeIdx := serv.addCodeIdx[addCode]
serv.addCodeArr[addCodeIdx][1] = false
serv.devices.Delete(addCode)
//log.Debug("removeDev//addCodeArr: ", serv.addCodeArr[addCodeIdx])
//log.Debug(serv.devices.Load(addCode))
}
func (serv *Server) AddDevice(pubKeyHash string) (addCode int, err error) {
retry := 0
elem := serv.addCodeArr[serv.nextAddCodeIdx]
// Repeat until available code is found.
// elem[1] is always boolean; no need to check for error
for elem[1].(bool) {
serv.nextAddCodeIdx += 1
elem = serv.addCodeArr[serv.nextAddCodeIdx]
retry += 1
// If every possible code is taken, return error
if retry == addCodeArrSize {
log.Error("Every add code is being used")
return -1, NoAvailableAddCodeError
}
}
// Get Add Code
// elem[0] is always int; no need to check for error
addCode = elem[0].(int)
// Mark current Add Code as being used
serv.addCodeArr[serv.nextAddCodeIdx][1] = true
// Increment next available Add Code index
serv.nextAddCodeIdx += 1
// if serv.nextAddCodeIdx reaches the max size, reset to 0
if serv.nextAddCodeIdx == addCodeArrSize {
serv.nextAddCodeIdx = 0
}
// Add device public key hash to online devices
serv.devices.Store(addCode, pubKeyHash)
//log.Debug("addDev//addCodeArr: ", serv.addCodeArr[serv.nextAddCodeIdx-1])
//log.Debug(serv.devices.Load(addCode))
return addCode, nil
}
func (serv *Server) tlsConfig() (err error) {
@ -59,10 +145,16 @@ func (serv *Server) tlsConfig() (err error) {
func InitConfig() (serv *Server, err error) {
serv = &Server{
Host: "127.0.0.1",
Port: 9129,
CertPath: "./data/cert",
Host: "127.0.0.1",
Port: 9129,
CertPath: "./data/cert",
addCodeArr: [addCodeArrSize][2]interface{}{},
addCodeIdx: [addCodeArrSize]int{},
nextAddCodeIdx: 0,
devices: sync.Map{},
tls: nil,
}
serv.initAddCode()
if err := serv.tlsConfig(); err != nil {
return nil, err
}
@ -83,6 +175,7 @@ func ReadConfig(fileName string) (serv *Server, err error) {
log.Error("Error while parsing config.yml")
return nil, err
}
serv.initAddCode()
if err := serv.tlsConfig(); err != nil {
return nil, err
}

39
internal/server/server_test.go

@ -47,6 +47,45 @@ func TestInitConfig(t *testing.T) {
}
}
func TestAddRemoveDev(t *testing.T) {
t.Cleanup(cleanUpHelper)
createCopy("../../data/cert/server.crt", "./data/cert/server.crt")
createCopy("../../data/cert/server.key", "./data/cert/server.key")
if err := os.MkdirAll("./config", os.ModePerm); err != nil {
log.Debug(err)
log.Error("Error while creating tmp directory")
return
}
confPath := "../../config/config.yml"
var serv *Server
var err error
if serv, err = ReadConfig(confPath); err != nil {
log.Debug(err)
log.Warning("Could not read config, trying default config")
if serv, err = InitConfig(); err != nil {
log.Debug(err)
t.Error("Could not load default config")
return
}
}
code, err := serv.AddDevice("abcd")
if err != nil {
log.Debug(err)
t.Error("Error in AddDevice")
return
}
code2, err := serv.AddDevice("efgh")
if err != nil {
log.Debug(err)
t.Error("Error in AddDevice")
return
}
serv.RemoveDevice(code)
serv.RemoveDevice(code2)
}
// Comment out until the function is implemented
//func TestStartListener(t *testing.T) {
// testConf, err := ReadConfig("../../config/config.yml")

Loading…
Cancel
Save