115 lines
2.5 KiB
Go
Raw Normal View History

2024-08-24 19:47:10 +03:00
package ruleComposer
import (
"bytes"
"net"
"sync"
"time"
)
type Records struct {
mutex sync.RWMutex
ipv4Addresses map[string]map[string]time.Time
cNames map[string]map[string]time.Time
}
func (r *Records) getCNames(domainName string) []string {
_, ok := r.cNames[domainName]
if !ok {
return nil
}
cNameList := make([]string, 0, len(r.cNames[domainName]))
for cname, ttl := range r.cNames[domainName] {
if time.Now().Sub(ttl).Nanoseconds() < 0 {
cNameList = append(cNameList, cname)
}
}
origCNameLen := len(cNameList)
for i := 0; i < origCNameLen; i++ {
parentList := r.getCNames(cNameList[i])
if parentList != nil {
cNameList = append(cNameList, parentList...)
}
}
return cNameList
}
func (r *Records) GetIPv4Addresses(domainName string) []net.IP {
r.mutex.RLock()
defer r.mutex.RUnlock()
cNameList := append([]string{domainName}, r.getCNames(domainName)...)
ipAddresses := make([]net.IP, 0)
for _, cName := range cNameList {
addresses, ok := r.ipv4Addresses[cName]
if !ok {
continue
}
addressesNetIP := make([]net.IP, 0, len(addresses))
for addr, ttl := range addresses {
if time.Now().Sub(ttl).Nanoseconds() < 0 {
addressesNetIP = append(addressesNetIP, []byte(addr))
}
}
ipAddresses = append(ipAddresses, addressesNetIP...)
}
return ipAddresses
}
func (r *Records) PutCName(domainName string, cName string, ttl int64) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.cNames[domainName] == nil {
r.cNames[domainName] = make(map[string]time.Time)
}
skipPut := false
for name, _ := range r.cNames[domainName] {
if name == cName {
r.cNames[domainName][name] = time.Now().Add(time.Second * time.Duration(ttl))
skipPut = true
break
}
}
if !skipPut {
r.cNames[domainName][cName] = time.Now().Add(time.Second * time.Duration(ttl))
}
}
func (r *Records) PutIPv4Address(domainName string, addr net.IP, ttl int64) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.ipv4Addresses[domainName] == nil {
r.ipv4Addresses[domainName] = make(map[string]time.Time)
}
skipPut := false
for address, _ := range r.ipv4Addresses[domainName] {
if bytes.Compare([]byte(address), addr) == 0 {
r.ipv4Addresses[domainName][address] = time.Now().Add(time.Second * time.Duration(ttl))
skipPut = true
break
}
}
if !skipPut {
r.ipv4Addresses[domainName][string(addr)] = time.Now().Add(time.Second * time.Duration(ttl))
}
}
func NewRecords() *Records {
return &Records{
ipv4Addresses: make(map[string]map[string]time.Time),
cNames: make(map[string]map[string]time.Time),
}
}