Fast DNS implementation for Go

Overview

Fast DNS implementation for Go

godoc release goreport coverage

Features

  • 0 Dependency
  • Similar Interface with net/http
  • Fast DoH Server Co-create with fasthttp
  • Fast DNS Client with rich features
  • Compatible metrics with coredns
  • High Performance
    • 0-allocs dns request parser
    • 0-allocs dns records marshaller
    • worker pool + message pool
    • prefork + reuse_port + set_affinity

Getting Started

A fastdns server example

package main

import (
	"log"
	"net"
	"os"

	"github.com/phuslu/fastdns"
)

type DNSHandler struct {
	Debug bool
}

func (h *DNSHandler) ServeDNS(rw fastdns.ResponseWriter, req *fastdns.Message) {
	if h.Debug {
		log.Printf("%s: CLASS %s TYPE %s\n", req.Domain, req.Question.Class, req.Question.Type)
	}

	switch req.Question.Type {
	case fastdns.TypeA:
		fastdns.HOST(rw, req, 60, []net.IP{{8, 8, 8, 8}})
	case fastdns.TypeAAAA:
		fastdns.HOST(rw, req, 60, []net.IP{net.ParseIP("2001:4860:4860::8888")})
	case fastdns.TypeCNAME:
		fastdns.CNAME(rw, req, 60, []string{"dns.google"}, []net.IP{{8, 8, 8, 8}, {8, 8, 4, 4}})
	case fastdns.TypeSRV:
		fastdns.SRV(rw, req, 60, []net.SRV{{"www.google.com", 443, 1000, 1000}})
	case fastdns.TypeNS:
		fastdns.NS(rw, req, 60, []net.NS{{"ns1.google.com"}, {"ns2.google.com"}})
	case fastdns.TypeMX:
		fastdns.MX(rw, req, 60, []net.MX{{"mail.gmail.com", 10}, {"smtp.gmail.com", 10}})
	case fastdns.TypeSOA:
		fastdns.SOA(rw, req, 60, net.NS{"ns1.google"}, net.NS{"ns2.google"}, 60, 90, 90, 180, 60)
	case fastdns.TypePTR:
		fastdns.PTR(rw, req, 0, "ptr.google.com")
	case fastdns.TypeTXT:
		fastdns.TXT(rw, req, 60, "greetingfromgoogle")
	default:
		fastdns.Error(rw, req, fastdns.RcodeNXDomain)
	}
}

func main() {
	addr := ":53"

	server := &fastdns.ForkServer{
		Handler: &DNSHandler{
			Debug: os.Getenv("DEBUG") != "",
		},
		Stats: &fastdns.CoreStats{
			Prefix: "coredns_",
			Family: "1",
			Proto:  "udp",
			Server: "dns://" + addr,
			Zone:   ".",
		},
		ErrorLog: log.Default(),
	}

	err := server.ListenAndServe(addr)
	if err != nil {
		log.Fatalf("dnsserver error: %+v", err)
	}
}

DoH Server

see https://github.com/phuslu/fastdns/tree/master/fastdoh

DNS Client

$ go get github.com/phuslu/fastdns/cmd/fastdig
$ fastdig ip.phus.lu @8.8.8.8

; <<>> DiG 0.0.1-Fastdns <<>> ip.phus.lu
;; global options: +cmd +noedns
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: Success, id: 2775
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;ip.phus.lu.            IN      A

;; ANSWER SECTION:
ip.phus.lu.     299     IN      CNAME   phus.lu.
phus.lu.        299     IN      A       101.32.116.118

;; Query time: 15 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Apr 12 22:07:16 +08 2021
;; MSG SIZE  rcvd: 58

High Performance

A Performance result as below, for daily benchmark results see github actions

# go test -v -cpu=1 -run=none -benchmem -bench=.
goos: linux
goarch: amd64
pkg: github.com/phuslu/fastdns
cpu: Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz

BenchmarkHOST              	39442191	        30.31 ns/op	       0 B/op	       0 allocs/op
BenchmarkCNAME             	22563691	        53.23 ns/op	       0 B/op	       0 allocs/op
BenchmarkSRV               	20890515	        57.63 ns/op	       0 B/op	       0 allocs/op
BenchmarkNS                	16634973	        71.98 ns/op	       0 B/op	       0 allocs/op
BenchmarkSOA               	14635425	        82.16 ns/op	       0 B/op	       0 allocs/op
BenchmarkPTR               	27980914	        42.96 ns/op	       0 B/op	       0 allocs/op
BenchmarkMX                	24721230	        48.75 ns/op	       0 B/op	       0 allocs/op
BenchmarkTXT               	39824239	        30.14 ns/op	       0 B/op	       0 allocs/op
BenchmarkParseMessage      	50639167	        23.86 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetRequestQustion	26985039	        46.08 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetResponseHeader 	175744434	         6.833 ns/op	       0 B/op	       0 allocs/op
BenchmarkDecodeName        	33319760	        36.07 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendHOSTRecord  	55649703	        21.56 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendCNAMERecord 	29943513	        40.04 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSRVRecord   	26827544	        45.00 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendNSRecord    	20113075	        59.70 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSOARecord   	17054136	        69.81 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendPTRRecord   	36748305	        32.60 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendMXRecord    	34203414	        35.04 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendTXTRecord   	65836453	        18.22 ns/op	       0 B/op	       0 allocs/op
BenchmarkUpdateStats       	14161730	        84.78 ns/op	       0 B/op	       0 allocs/op
BenchmarkEncodeDomain      	63253357	        19.27 ns/op	       0 B/op	       0 allocs/op

PASS
ok  	github.com/phuslu/fastdns	19.026s

Here is the real-world flamegraph flamegraph when fastdns reaches 1.4M QPS on a single machine with Xeon 4216 and Intel X710.

Acknowledgment

This dns server is inspired by fasthttp, rawdns and miekg/dns.

Issues
  • Bump github.com/valyala/fasthttp from 1.23.0 to 1.34.0 in /fastdoh

    Bump github.com/valyala/fasthttp from 1.23.0 to 1.34.0 in /fastdoh

    Bumps github.com/valyala/fasthttp from 1.23.0 to 1.34.0.

    Release notes

    Sourced from github.com/valyala/fasthttp's releases.

    v1.34.0

    • 59f94a3 Update github.com/klauspost/compress (#1237) (Mikhail Faraponov)
    • 62c15a5 Don't reset RequestCtx.s (#1234) (Erik Dubbelboer)
    • 7670c6e Fix windows tests (#1235) (Erik Dubbelboer)
    • f54ffa1 feature: Keep the memory usage of the service at a stable level (#1216) (Rennbon)
    • 15262ec Warn about unsafe ServeFile usage (#1228) (Erik Dubbelboer)
    • 1116d03 Fix panic while reading invalid trailers (Erik Dubbelboer)
    • 856ca8e Update dependencies (#1230) (Mikhail Faraponov)
    • 6b5bc7b Add windows support to normalizePath (Erik Dubbelboer)
    • f0b0cfe Don't log ErrBadTrailer by default (Erik Dubbelboer)
    • 6937fee fix: (useless check), skip Response body if http method HEAD (#1224) (Pavel Burak)
    • b85d2a2 Fix http proxy behavior (#1221) (Aoang)
    • ad8a07a RequestHeader support set no default ContentType (#1218) (Jack.Ju)
    • c94581c support configure HostClient (#1214) (lin longhjui)
    • 632e222 Client examples (#1208) (Sergey Ponomarev)
    • 6a3cc23 uri_test.go use example.com for clearness (#1212) (Sergey Ponomarev)
    • 9d665e0 Update dependencies (#1204) (Mikhail Faraponov)
    • 8d7953e Fix scheme check for not yet parsed requests (#1203) (ArminBTVS)

    v1.33.0

    • 61aa8b1 remove redundant code (#1202) (tyltr)
    • 4369776 fix(hijack): reuse RequestCtx (#1201) (Sergio VS)
    • 2aca3e8 fix(hijack): reset userValues after hijack handler execution (#1199) (Sergio VS)
    • 9123060 Updated dependencies (#1194) (Mikhail Faraponov)

    v1.32.0

    • 7eeb00e Make tests less flaky (#1189) (Erik Dubbelboer)
    • d19b872 Update tcpdialer.go (#1188) (Mikhail Faraponov)
    • c727b99 Release UseHostHeader in ReleaseRequest() (#1185) (Tolyar)
    • 6c0518b Fix UseHostHeader for DoTimeout + tests (#1184) (Tolyar)
    • 6b55811 Add MaxIdleWorkerDuration to Server. (#1183) (Kilos Liu)
    • 4517204 Allow to set Host header for Client (#1169) (Tolyar)
    • 258a4c1 fix: reset response after reset user values on keep-alive connections (#1176) (Sergio VS)
    • e9db537 Use %w to wrap errors (#1175) (Erik Dubbelboer)
    • 7db0597 Fix bad request trailer panic (Erik Dubbelboer)
    • 4aadf9a Fix parseTrailer panic (Erik Dubbelboer)
    • da7ff7a Add trailer support (#1165) (ichx)
    • 017f0aa fix: reset request after reset user values on keep-alive connections (#1162) (Sergio VS)
    • 3b117f8 feat: close idle connections when server shutdown (#1155) (ichx)
    • a94a2c3 Remove redundant code (#1154) (ichx)
    • f7c354c Fix race condition in Client.mCleaner (Erik Dubbelboer)
    • c078a9d Add string and bytes buffer convert trick in README (#1151) (ichx)
    • 3ff6aaa uri: isHttps() and isHttp() (#1150) (Sergey Ponomarev)
    • 8febad0 http.go: Request.SetURI() (Fix #1141) (#1148) (Sergey Ponomarev)
    • 2ca01c7 fix: Status Line parsing and writing (#1135) (Shivansh Vij)
    • 931d0a4 Fix lint (Erik Dubbelboer)
    • d613502 use sync.map is better (#1145) (halst)
    • c15e642 Don't run all race tests on windows (#1143) (Erik Dubbelboer)
    • 6006c87 chore (#1137) (tyltr)
    • 6d4db9b Fix race condition in getTCPAddrs (Erik Dubbelboer)

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Owner
phuslu
Geek
phuslu
Verify IP addresses of respectful crawlers like Googlebot by reverse dns and forward dns lookups

goodbots - trust but verify goodbots verifies the IP addresses of respectful crawlers like Googlebot by performing reverse dns and forward dns lookups

Eric Wu 29 Jun 21, 2022
The Dual-Stack Dynamic DNS client, the world's first dynamic DNS client built for IPv6.

dsddns DsDDNS is the Dual-Stack Dynamic DNS client. A dynamic DNS client keeps your DNS records in sync with the IP addresses associated with your hom

Ryan Young 10 Jun 20, 2022
netcup DNS module for caddy: dns.providers.netcup

netcup DNS module for Caddy This package contains a DNS provider module for Caddy. It can be used to manage DNS records with the netcup DNS API using

null 6 Mar 3, 2022
A fork on miekg/dns (since I've already forked zmap/dns)

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

null 0 Jan 19, 2022
A simple DNS forwarder that forwards DNS queries to various upstreams

A simple DNS forwarder that forwards DNS queries to various upstreams. If an upstream returns NXDomain, the next upstream is tried.

null 1 May 10, 2022
Fast DNS implementation for Go

Fast DNS implementation for Go Features 0 Dependency Similar Interface with net/http Fast DoH Server Co-create with fasthttp Fast DNS Client with rich

phuslu 67 May 29, 2022
Fast Private DNS,提供自定义的DNS记录配置和DNS解析缓存。

fpdns Fast Private DNS,提供自定义的DNS记录配置和DNS解析缓存。 特性: A记录 CNAME 泛解析 DNS负载均衡 缓存DNS解析结果 上游同时多DNS Server查询 各系统测试情况 Linux: 已稳定运行3年多 Darwin: 已开发测试 Windows: 未测试

QLeelulu 24 Nov 4, 2021
Privacy important, fast, recursive dns resolver server with dnssec support

?? Privacy important, fast, recursive dns resolver server with dnssec support Installation go get github.com/semihalev/sdns Pre-build Binaries Downloa

Yasar Alev 704 Jun 27, 2022
sonarbyte is a simple and fast subdomain scanner written in go to extract subdomain from Rapid7's DNS Database using omnisint's api.

sonarbyte Description Sonarbyte is a simple and fast subdomain scanner written in go to extract subdomains from Rapid7's DNS Database using omnisint's

Chan Nyein Wai 24 Mar 31, 2022
fast tool for separate existing domains from list of domains using DNS/HTTP.

NETGREP How To Install • How to use Description netgrep can send http/https request or resolve domain from dns (can customize dns server) to separate

aWolver 2 Jan 27, 2022
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Kirill Danshin 12 Jan 23, 2022
DNS library in Go

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

Miek Gieben 6.4k Jun 30, 2022
A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms

acme-dns-client A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms. It

null 60 Jun 9, 2022
Network-wide ads & trackers blocking DNS server

Privacy protection center for you and your devices Free and open source, powerful network-wide ads & trackers blocking DNS server. AdGuard.com | Wiki

AdGuard 12k Jul 2, 2022
A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ.

q A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ. Usage q command line DNS client (https://github.com/natesales/q) Usage: q

Nate Sales 670 Jun 28, 2022
Information Gathering tool - DNS / Subdomains / Ports / Directories enumeration

Information Gathering tool - DNS / Subdomains / Ports / Directories enumeration

gilfoyle97 464 Jun 28, 2022
一个 DNS 转发器。

mosdns-cn 一个 DNS 转发器。 上游服务器支持 UDP/TCP/DoT/DoH 协议。支持 socks5 代理。 自带本地/远程 DNS 分流功能。可以根据域名和 IP 分流。 数据可以直接从 v2ray dat 文件载入。 无需配置。一键安装。开箱即用。 参数 -s, --serv

Irine Sistiana 186 Jun 28, 2022
IONOS DNS module for caddy

This package contains a DNS provider module for Caddy. It is used to manage DNS records with the IONOS DNS API using libdns-ionos..

null 5 May 19, 2022
A simple tool to detect WAN IP changes and updates your cloudflare DNS entries.

Cloudflare IP Updater A simple tool to detect WAN IP changes and updates your cloudflare DNS entries. Usage Create a new Cloudflare API token Copy the

AJ 11 Dec 10, 2021