88 lines
2.2 KiB
Go
Raw Normal View History

package dnsclientpool
import (
"strconv"
"strings"
"sync"
"github.com/projectdiscovery/nuclei/v2/pkg/types"
"github.com/projectdiscovery/retryabledns"
)
var (
poolMutex *sync.RWMutex
normalClient *retryabledns.Client
clientPool map[string]*retryabledns.Client
)
// defaultResolvers contains the list of resolvers known to be trusted.
var defaultResolvers = []string{
"1.1.1.1:53", // Cloudflare
"1.0.0.1:53", // Cloudflare
"8.8.8.8:53", // Google
"8.8.4.4:53", // Google
}
// Init initializes the clientpool implementation
func Init(options *types.Options) error {
2021-09-07 17:31:46 +03:00
// Don't create clients if already created in the past.
if normalClient != nil {
return nil
}
poolMutex = &sync.RWMutex{}
clientPool = make(map[string]*retryabledns.Client)
resolvers := defaultResolvers
if options.ResolversFile != "" {
resolvers = options.InternalResolversList
}
normalClient = retryabledns.New(resolvers, 1)
return nil
}
// Configuration contains the custom configuration options for a client
type Configuration struct {
// Retries contains the retries for the dns client
Retries int
// Resolvers contains the specific per request resolvers
Resolvers []string
}
// Hash returns the hash of the configuration to allow client pooling
func (c *Configuration) Hash() string {
builder := &strings.Builder{}
builder.WriteString("r")
builder.WriteString(strconv.Itoa(c.Retries))
builder.WriteString("l")
builder.WriteString(strings.Join(c.Resolvers, ""))
hash := builder.String()
return hash
}
// Get creates or gets a client for the protocol based on custom configuration
func Get(options *types.Options, configuration *Configuration) (*retryabledns.Client, error) {
if !(configuration.Retries > 1) && len(configuration.Resolvers) == 0 {
return normalClient, nil
}
hash := configuration.Hash()
poolMutex.RLock()
if client, ok := clientPool[hash]; ok {
poolMutex.RUnlock()
return client, nil
}
poolMutex.RUnlock()
2021-02-27 02:23:06 +05:30
resolvers := defaultResolvers
if options.ResolversFile != "" {
resolvers = options.InternalResolversList
} else if len(configuration.Resolvers) > 0 {
resolvers = configuration.Resolvers
2021-02-27 02:23:06 +05:30
}
client := retryabledns.New(resolvers, configuration.Retries)
poolMutex.Lock()
clientPool[hash] = client
poolMutex.Unlock()
return client, nil
}