dd76e9f685
- Apply parsed readTimeout as connection read deadline (was dead code) - Use context.WithoutCancel for async cache refresh goroutine - Add doc comments to all exported symbols - Add 40 tests covering metadata parsing, init, rate limiting, exchanger selection, host lookup, cache, bypass, async refresh, and concurrent request handling
68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
package dns
|
|
|
|
import (
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
|
|
mdata "github.com/go-gost/core/metadata"
|
|
mdutil "github.com/go-gost/x/metadata/util"
|
|
)
|
|
|
|
const (
|
|
// defaultTimeout is the fallback timeout for DNS exchanges.
|
|
defaultTimeout = 5 * time.Second
|
|
// defaultBufferSize is the fallback buffer size for DNS message I/O.
|
|
defaultBufferSize = 1024
|
|
)
|
|
|
|
// metadata holds parsed DNS handler configuration.
|
|
type metadata struct {
|
|
readTimeout time.Duration
|
|
ttl time.Duration
|
|
timeout time.Duration
|
|
clientIP net.IP
|
|
// nameservers
|
|
dns []string
|
|
bufferSize int
|
|
async bool
|
|
}
|
|
|
|
func (h *dnsHandler) parseMetadata(md mdata.Metadata) (err error) {
|
|
const (
|
|
readTimeout = "readTimeout"
|
|
ttl = "ttl"
|
|
timeout = "timeout"
|
|
clientIP = "clientIP"
|
|
dns = "dns"
|
|
bufferSize = "bufferSize"
|
|
async = "async"
|
|
)
|
|
|
|
h.md.readTimeout = mdutil.GetDuration(md, readTimeout)
|
|
h.md.ttl = mdutil.GetDuration(md, ttl)
|
|
h.md.timeout = mdutil.GetDuration(md, timeout)
|
|
if h.md.timeout <= 0 {
|
|
h.md.timeout = defaultTimeout
|
|
}
|
|
sip := mdutil.GetString(md, clientIP)
|
|
if sip != "" {
|
|
h.md.clientIP = net.ParseIP(sip)
|
|
}
|
|
for _, v := range strings.Split(mdutil.GetString(md, dns), ",") {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
continue
|
|
}
|
|
h.md.dns = append(h.md.dns, v)
|
|
}
|
|
|
|
h.md.bufferSize = mdutil.GetInt(md, bufferSize)
|
|
if h.md.bufferSize <= 0 {
|
|
h.md.bufferSize = defaultBufferSize
|
|
}
|
|
h.md.async = mdutil.GetBool(md, async)
|
|
|
|
return
|
|
}
|