MagiTrickle/records.go

135 lines
3.0 KiB
Go
Raw Normal View History

2024-08-26 19:10:40 +03:00
package main
2024-08-24 19:47:10 +03:00
import (
"net"
"sync"
"time"
)
type Records struct {
2024-08-25 00:18:15 +03:00
mutex sync.RWMutex
aRecords map[string]map[string]time.Time
cnameRecords map[string]map[string]time.Time
2024-08-24 19:47:10 +03:00
}
2024-08-25 00:18:15 +03:00
func (r *Records) getCNames(domainName string, recursive bool) []string {
cNameList := make([]string, 0)
for cname, ttl := range r.cnameRecords[domainName] {
if time.Now().Sub(ttl).Nanoseconds() > 0 {
delete(r.cnameRecords[domainName], cname)
2024-08-25 00:28:34 +03:00
if len(r.cnameRecords[domainName]) == 0 {
delete(r.cnameRecords, domainName)
return nil
}
2024-08-25 00:18:15 +03:00
continue
2024-08-24 19:47:10 +03:00
}
2024-08-25 00:18:15 +03:00
cNameList = append(cNameList, cname)
2024-08-24 19:47:10 +03:00
}
2024-08-25 00:18:15 +03:00
if recursive {
origCNameLen := len(cNameList)
for i := 0; i < origCNameLen; i++ {
parentList := r.getCNames(cNameList[i], true)
if parentList != nil {
cNameList = append(cNameList, parentList...)
}
2024-08-24 19:47:10 +03:00
}
}
return cNameList
}
2024-08-25 00:18:15 +03:00
func (r *Records) GetCNameRecords(domainName string, recursive bool) []string {
2024-08-24 19:47:10 +03:00
r.mutex.RLock()
defer r.mutex.RUnlock()
2024-08-25 00:18:15 +03:00
return r.getCNames(domainName, recursive)
}
func (r *Records) GetARecords(domainName string, recursive bool) []net.IP {
r.mutex.RLock()
defer r.mutex.RUnlock()
2024-08-24 19:47:10 +03:00
2024-08-25 00:18:15 +03:00
cNameList := []string{domainName}
if recursive {
cNameList = append(cNameList, r.getCNames(domainName, true)...)
}
aRecords := make([]net.IP, 0)
for _, cName := range cNameList {
for addr, ttl := range r.aRecords[cName] {
if time.Now().Sub(ttl).Nanoseconds() > 0 {
delete(r.aRecords[cName], addr)
2024-08-25 00:28:34 +03:00
if len(r.aRecords[cName]) == 0 {
delete(r.aRecords, cName)
break
}
2024-08-25 00:18:15 +03:00
continue
2024-08-24 19:47:10 +03:00
}
2024-08-25 00:18:15 +03:00
aRecords = append(aRecords, []byte(addr))
2024-08-24 19:47:10 +03:00
}
}
2024-08-25 00:18:15 +03:00
return aRecords
2024-08-24 19:47:10 +03:00
}
2024-08-26 19:10:40 +03:00
func (r *Records) PutCNameRecord(domainName string, cName string, ttl time.Duration) {
2024-08-24 19:47:10 +03:00
r.mutex.Lock()
defer r.mutex.Unlock()
2024-08-25 00:18:15 +03:00
if r.cnameRecords[domainName] == nil {
r.cnameRecords[domainName] = make(map[string]time.Time)
2024-08-24 19:47:10 +03:00
}
2024-08-26 19:10:40 +03:00
r.cnameRecords[domainName][cName] = time.Now().Add(ttl)
2024-08-24 19:47:10 +03:00
}
2024-08-26 19:10:40 +03:00
func (r *Records) PutARecord(domainName string, addr net.IP, ttl time.Duration) {
2024-08-24 19:47:10 +03:00
r.mutex.Lock()
defer r.mutex.Unlock()
2024-08-25 00:18:15 +03:00
if r.aRecords[domainName] == nil {
r.aRecords[domainName] = make(map[string]time.Time)
2024-08-24 19:47:10 +03:00
}
2024-08-26 19:10:40 +03:00
r.aRecords[domainName][string(addr)] = time.Now().Add(ttl)
2024-08-24 19:47:10 +03:00
}
2024-08-25 00:28:34 +03:00
func (r *Records) Cleanup() {
r.mutex.Lock()
defer r.mutex.Unlock()
for domainName, _ := range r.aRecords {
for aRecord, ttl := range r.aRecords[domainName] {
if time.Now().Sub(ttl).Nanoseconds() <= 0 {
continue
}
delete(r.aRecords[domainName], aRecord)
if len(r.aRecords[domainName]) == 0 {
delete(r.aRecords, domainName)
break
}
}
}
for domainName, _ := range r.cnameRecords {
for cname, ttl := range r.cnameRecords[domainName] {
if time.Now().Sub(ttl).Nanoseconds() <= 0 {
continue
}
delete(r.cnameRecords[domainName], cname)
if len(r.cnameRecords[domainName]) == 0 {
delete(r.cnameRecords, domainName)
break
}
}
}
}
2024-08-24 19:47:10 +03:00
func NewRecords() *Records {
return &Records{
2024-08-25 00:18:15 +03:00
aRecords: make(map[string]map[string]time.Time),
cnameRecords: make(map[string]map[string]time.Time),
2024-08-24 19:47:10 +03:00
}
}