319 lines
7.6 KiB
Go
Executable File
319 lines
7.6 KiB
Go
Executable File
package internal
|
|
|
|
import (
|
|
"bufio"
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/allegro/bigcache/v3"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var InMemoryCache *bigcache.BigCache
|
|
|
|
var (
|
|
SelfLifeWindow time.Duration = 86400
|
|
SelfHardMaxCacheSize int = 2048
|
|
SelfShards = 512
|
|
isDebugBigCache bool
|
|
)
|
|
|
|
func InitBigcache(debug bool) {
|
|
|
|
SelfLifeWindow = time.Duration(GetSocketInfoInt("Go_Shield_Server_Cache_Time"))
|
|
SelfHardMaxCacheSize = GetSocketInfoInt("Go_Shield_Server_DB_Size")
|
|
isDebugBigCache = debug
|
|
SelfShards = GetSocketInfoInt("Go_Shield_Server_DB_Shards")
|
|
if SelfLifeWindow == 0 {
|
|
SelfLifeWindow = time.Duration(86400)
|
|
}
|
|
|
|
if SelfHardMaxCacheSize == 0 {
|
|
SelfHardMaxCacheSize = 2048
|
|
}
|
|
|
|
if SelfShards == 0 {
|
|
SelfShards = 1024
|
|
}
|
|
|
|
config := bigcache.Config{
|
|
// number of shards (must be a power of 2)
|
|
Shards: SelfShards,
|
|
|
|
// time after which entry can be evicted
|
|
LifeWindow: SelfLifeWindow * time.Second,
|
|
|
|
// Interval between removing expired entries (clean up).
|
|
// If set to <= 0 then no action is performed.
|
|
// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
|
|
CleanWindow: 5 * time.Minute,
|
|
|
|
// rps * lifeWindow, used only in initial memory allocation
|
|
MaxEntriesInWindow: 1000 * 10 * 60,
|
|
|
|
// max entry size in bytes, used only in initial memory allocation
|
|
MaxEntrySize: 512,
|
|
|
|
// prints information about additional memory allocation
|
|
Verbose: isDebugBigCache,
|
|
|
|
// cache will not allocate more memory than this limit, value in MB
|
|
// if value is reached then the oldest entries can be overridden for the new ones
|
|
// 0 value means no size limit
|
|
HardMaxCacheSize: SelfHardMaxCacheSize,
|
|
|
|
// callback fired when the oldest entry is removed because of its expiration time or no space left
|
|
// for the new entry, or because delete was called. A bitmask representing the reason will be returned.
|
|
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
|
OnRemove: nil,
|
|
|
|
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
|
|
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
|
|
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
|
// Ignored if OnRemove is specified.
|
|
OnRemoveWithReason: nil,
|
|
}
|
|
InMemoryCache, _ = bigcache.NewBigCache(config)
|
|
}
|
|
func Md5string(str string) string {
|
|
h := md5.New()
|
|
io.WriteString(h, str)
|
|
hashed := hex.EncodeToString(h.Sum(nil))
|
|
return hashed
|
|
}
|
|
|
|
func Append(key string, value string) {
|
|
InMemoryCache.Append(key, []byte(value))
|
|
}
|
|
|
|
func Fetch(key string) (response *string, error error) {
|
|
if value, err := InMemoryCache.Get(key); err == nil {
|
|
val := string(value)
|
|
if val == "" {
|
|
err = errors.New("empty val")
|
|
if isDebugBigCache {
|
|
log.Printf("Unable to Fetch %s due %s", key, err)
|
|
}
|
|
return nil, err
|
|
}
|
|
return &val, nil
|
|
} else {
|
|
if isDebugBigCache {
|
|
log.Printf("Unable to Fetch %s due %s", key, err)
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
//return nil
|
|
}
|
|
|
|
func Increment(key string) {
|
|
counter, _ := Fetch(key)
|
|
if counter == nil {
|
|
val := 0
|
|
val = val + 1
|
|
Append(key, strconv.Itoa(val))
|
|
} else {
|
|
val, err := strconv.Atoi(*counter)
|
|
if err == nil {
|
|
val = val + 1
|
|
Append(key, strconv.Itoa(val))
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func Decrement(key string) {
|
|
counter, _ := Fetch(key)
|
|
val, err := strconv.Atoi(*counter)
|
|
if err == nil {
|
|
val = val - 1
|
|
if val < 0 {
|
|
val = 0
|
|
}
|
|
Append(key, strconv.Itoa(val))
|
|
}
|
|
}
|
|
|
|
func UserAliases(mac string, ipaddr string, ipstrongswan string, isDebugBigCache bool) string {
|
|
mac = strings.ToLower(mac)
|
|
val := ""
|
|
key := ""
|
|
if len(mac) > 5 {
|
|
key = fmt.Sprintf("%s:alias", mac)
|
|
macpath := fmt.Sprintf("/home/artica/UsersMac/Caches/%s", mac)
|
|
//val = Get(key, isDebugBigCache)
|
|
//if val != "" {
|
|
// if val == "NONE" {
|
|
// return ""
|
|
// }
|
|
// sfinl := strings.Split(val, "|")
|
|
// if len(sfinl) > 0 {
|
|
// return sfinl[0]
|
|
// }
|
|
// return val
|
|
//}
|
|
if value, err := InMemoryCache.Get(key); err == nil {
|
|
val = string(value)
|
|
if val != "" {
|
|
if val == "NONE" {
|
|
return ""
|
|
}
|
|
sfinl := strings.Split(val, "|")
|
|
if len(sfinl) > 0 {
|
|
return sfinl[0]
|
|
}
|
|
return val
|
|
}
|
|
}
|
|
|
|
if _, err := os.Stat(macpath); !os.IsNotExist(err) {
|
|
f, err := os.Open(macpath)
|
|
|
|
if err != nil {
|
|
if isDebugBigCache {
|
|
log.Printf("error reading %s %s", macpath, err)
|
|
}
|
|
|
|
}
|
|
defer f.Close()
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
Set(key, scanner.Text(), 600)
|
|
sfinl := strings.Split(scanner.Text(), "|")
|
|
if len(sfinl) > 0 {
|
|
return sfinl[0]
|
|
}
|
|
return scanner.Text()
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
if isDebugBigCache {
|
|
log.Printf("error scanning %s %s", macpath, err)
|
|
}
|
|
}
|
|
}
|
|
Set(key, "NONE", 600)
|
|
if len(ipstrongswan) > 0 {
|
|
key = fmt.Sprintf("%s:vpnalias", ipaddr)
|
|
//val = Get(key, isDebugBigCache)
|
|
//
|
|
//if val != "" {
|
|
// if val == "NONE" {
|
|
// return ""
|
|
// }
|
|
// return val
|
|
//}
|
|
if value, err := InMemoryCache.Get(key); err == nil {
|
|
val = string(value)
|
|
if val != "" {
|
|
if val == "NONE" {
|
|
return ""
|
|
}
|
|
return val
|
|
}
|
|
}
|
|
|
|
val = StrongSwanAlias(ipaddr, isDebugBigCache)
|
|
if val == "" {
|
|
Set(key, "NONE", 150)
|
|
return ""
|
|
}
|
|
Set(key, val, 150)
|
|
}
|
|
key = fmt.Sprintf("%s:alias", ipaddr)
|
|
cachepath := fmt.Sprintf("/home/artica/UsersMac/Caches/%s", ipaddr)
|
|
//val = Get(key, isDebugBigCache)
|
|
//if val != "" {
|
|
// if val == "NONE" {
|
|
// return ""
|
|
// }
|
|
// sfinl := strings.Split(val, "|")
|
|
// if len(sfinl) > 0 {
|
|
// return sfinl[0]
|
|
// }
|
|
// return val
|
|
//}
|
|
|
|
if value, err := InMemoryCache.Get(key); err == nil {
|
|
val = string(value)
|
|
if val != "" {
|
|
if val == "NONE" {
|
|
return ""
|
|
}
|
|
sfinl := strings.Split(val, "|")
|
|
if len(sfinl) > 0 {
|
|
return sfinl[0]
|
|
}
|
|
return val
|
|
}
|
|
}
|
|
|
|
if _, err := os.Stat(cachepath); !os.IsNotExist(err) {
|
|
f, err := os.Open(cachepath)
|
|
|
|
if err != nil {
|
|
if isDebugBigCache {
|
|
log.Printf("error reading %s %s", cachepath, err)
|
|
}
|
|
|
|
}
|
|
defer f.Close()
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
Set(key, scanner.Text(), 600)
|
|
sfinl := strings.Split(scanner.Text(), "|")
|
|
if len(sfinl) > 0 {
|
|
return sfinl[0]
|
|
}
|
|
return scanner.Text()
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
if isDebugBigCache {
|
|
log.Printf("error scanning %s %s", cachepath, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
Set(key, "NONE", 600)
|
|
return ""
|
|
}
|
|
|
|
func StrongSwanAlias(ipaddr string, isDebugBigCache bool) string {
|
|
//TODO implement this method
|
|
//data := GetSocketInfoString("strongSwanClientsArray")
|
|
//out, err := gophp.Unserialize([]byte(data))
|
|
//
|
|
//if err != nil {
|
|
// if isDebugBigCache {
|
|
// log.Printf("error Unserialize strongSwanClientsArray: ", err)
|
|
// }
|
|
// return ""
|
|
//}
|
|
//if mout, ok := out.(map[string]interface{}); ok {
|
|
// for _, main_index := range mout {
|
|
// subarray := main_index.(map[string]interface{})
|
|
// for _, main_index2 := range subarray {
|
|
// subarray2 := mout[main_index][main_index2]
|
|
// }
|
|
// }
|
|
//}
|
|
return ""
|
|
}
|
|
|
|
func ShieldsFullCache(username string, ipaddr string, mac string, sitename string, method string) string {
|
|
sitename = strings.ToLower(sitename)
|
|
username = strings.ToLower(username)
|
|
method = strings.ToLower(mac)
|
|
PrepareCache := []byte(fmt.Sprintf("%s|%s|%s|%s|%s", username, ipaddr, mac, sitename, method))
|
|
PrepareCache = []byte(Md5string(string(PrepareCache)))
|
|
smd5 := fmt.Sprintf("SHIELD.%s", PrepareCache)
|
|
return smd5
|
|
}
|