Skip to content

Commit

Permalink
Add simple DNS non-RFC cache
Browse files Browse the repository at this point in the history
  • Loading branch information
crazygreenpenguin committed Jul 29, 2020
1 parent 05a386b commit 4134f2c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
22 changes: 22 additions & 0 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"github.com/crazygreenpenguin/beats-output-http/resolver"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/logp"
Expand All @@ -13,13 +14,16 @@ import (
"github.com/elastic/beats/v7/libbeat/publisher"
"github.com/json-iterator/go"
"io/ioutil"
"net"
"net/http"
"sync"
"time"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

var dnsCache = resolver.NewDNSResolver()

func init() {
outputs.RegisterType("http", makeHTTP)
}
Expand Down Expand Up @@ -89,6 +93,24 @@ func (out *httpOutput) init(beat beat.Info, c config) error {
IdleConnTimeout: time.Duration(out.conf.IdleConnTimeout) * time.Second,
DisableCompression: !out.conf.Compression,
DisableKeepAlives: !out.conf.KeepAlive,
DialContext: func(ctx context.Context, network string, addr string) (conn net.Conn, err error) {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
ips, err := dnsCache.LookupHost(ctx, host)
if err != nil {
return nil, err
}
for _, ip := range ips {
var dialer net.Dialer
conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip, port))
if err == nil {
break
}
}
return
},
}

out.client = &http.Client{
Expand Down
73 changes: 73 additions & 0 deletions resolver/resolver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package resolver

import (
"context"
"net"
"sync"
"time"
)

const MaxCacheSize = 512 //Must be greater then 16

func NewDNSResolver() *DNSResolver {
tmp := DNSResolver{
resolver: net.DefaultResolver,
cache: make(map[string]DNSRecord),
}

go func() {
for range time.Tick(60 * time.Second) {
tmp.refresh()
}
}()
return &tmp
}

type DNSRecord struct {
addr []string
err error
}

type DNSResolver struct {
resolver *net.Resolver

cache map[string]DNSRecord
sync.Mutex
}

func (dr *DNSResolver) LookupHost(ctx context.Context, host string) ([]string, error) {
dr.Lock()
defer dr.Unlock()

if val, ok := dr.cache[host]; ok {
return val.addr, val.err
}

addr, err := dr.resolver.LookupHost(ctx, host)
dr.cache[host] = DNSRecord{
addr: addr,
err: err,
}
return addr, err
}

func (dr *DNSResolver) refresh() {
dr.Lock()
defer dr.Unlock()

//free cache space
if len(dr.cache) > MaxCacheSize {
for key := range dr.cache {
delete(dr.cache, key)
if len(dr.cache) <= MaxCacheSize-16 {
break
}
}
}

for key, val := range dr.cache {
addr, err := net.LookupHost(key)
val.addr = addr
val.err = err
}
}

0 comments on commit 4134f2c

Please sign in to comment.