safing-portmaster/resolver/namerecord.go
Daniel 53eb309e72 Add TLS resolver connection reusing and pooling
Also, fix caching issues and add more tests
2020-05-15 22:43:06 +02:00

75 lines
1.6 KiB
Go

package resolver
import (
"errors"
"fmt"
"sync"
"github.com/safing/portbase/database"
"github.com/safing/portbase/database/record"
)
var (
recordDatabase = database.NewInterface(&database.Options{
AlwaysSetRelativateExpiry: 2592000, // 30 days
CacheSize: 256,
})
)
// NameRecord is helper struct to RRCache to better save data to the database.
type NameRecord struct {
record.Base
sync.Mutex
Domain string
Question string
Answer []string
Ns []string
Extra []string
TTL int64
Server string
ServerScope int8
}
func makeNameRecordKey(domain string, question string) string {
return fmt.Sprintf("cache:intel/nameRecord/%s%s", domain, question)
}
// GetNameRecord gets a NameRecord from the database.
func GetNameRecord(domain string, question string) (*NameRecord, error) {
key := makeNameRecordKey(domain, question)
r, err := recordDatabase.Get(key)
if err != nil {
return nil, err
}
// unwrap
if r.IsWrapped() {
// only allocate a new struct, if we need it
new := &NameRecord{}
err = record.Unwrap(r, new)
if err != nil {
return nil, err
}
return new, nil
}
// or adjust type
new, ok := r.(*NameRecord)
if !ok {
return nil, fmt.Errorf("record not of type *NameRecord, but %T", r)
}
return new, nil
}
// Save saves the NameRecord to the database.
func (rec *NameRecord) Save() error {
if rec.Domain == "" || rec.Question == "" {
return errors.New("could not save NameRecord, missing Domain and/or Question")
}
rec.SetKey(makeNameRecordKey(rec.Domain, rec.Question))
return recordDatabase.PutNew(rec)
}