mirror of
https://github.com/projectdiscovery/httpx
synced 2026-06-08 16:50:17 +00:00
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package cache
|
|
|
|
import (
|
|
"net"
|
|
|
|
"github.com/coocood/freecache"
|
|
dns "github.com/projectdiscovery/httpx/common/resolver"
|
|
)
|
|
|
|
// Cache is a strcture for caching DNS lookups
|
|
type Cache struct {
|
|
dnsClient Resolver
|
|
cache *freecache.Cache
|
|
defaultExpirationTime int
|
|
}
|
|
|
|
// Resolver interface
|
|
type Resolver interface {
|
|
Resolve(string) (dns.Result, error)
|
|
}
|
|
|
|
// Options of the cache
|
|
type Options struct {
|
|
BaseResolvers []string
|
|
CacheSize int
|
|
ExpirationTime int
|
|
MaxRetries int
|
|
}
|
|
|
|
// DefaultOptions of the cache
|
|
var DefaultOptions = Options{
|
|
BaseResolvers: DefaultResolvers,
|
|
CacheSize: 10,
|
|
ExpirationTime: 5 * 60,
|
|
MaxRetries: 5,
|
|
}
|
|
|
|
// DefaultResolvers trusted
|
|
var DefaultResolvers = []string{
|
|
"1.1.1.1:53",
|
|
"1.0.0.1:53",
|
|
"8.8.8.8:53",
|
|
"8.8.4.4:53",
|
|
}
|
|
|
|
// New creates a new caching dns resolver
|
|
func New(options Options) (*Cache, error) {
|
|
dnsClient, err := dns.New(options.BaseResolvers, options.MaxRetries)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cache := freecache.NewCache(options.CacheSize * 1024 * 1024)
|
|
return &Cache{dnsClient: dnsClient, cache: cache, defaultExpirationTime: options.ExpirationTime}, nil
|
|
}
|
|
|
|
// Lookup a hostname
|
|
func (c *Cache) Lookup(hostname string) (*dns.Result, error) {
|
|
if ip := net.ParseIP(hostname); ip != nil {
|
|
return &dns.Result{IPs: []string{hostname}}, nil
|
|
}
|
|
hostnameBytes := []byte(hostname)
|
|
value, err := c.cache.Get(hostnameBytes)
|
|
if err != nil {
|
|
if len(err.Error()) != 15 {
|
|
return nil, err
|
|
}
|
|
result, err := c.dnsClient.Resolve(hostname)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if result.TTL == 0 {
|
|
result.TTL = c.defaultExpirationTime
|
|
}
|
|
b, _ := result.Marshal()
|
|
c.cache.Set(hostnameBytes, b, result.TTL)
|
|
|
|
return &result, nil
|
|
}
|
|
|
|
var result dns.Result
|
|
result.Unmarshal(value)
|
|
|
|
return &result, nil
|
|
}
|