GithubHelp home page GithubHelp logo

phuslu / fastdns Goto Github PK

View Code? Open in Web Editor NEW
159.0 4.0 11.0 301 KB

Fast DNS package for Go. Tuned for high performance. Zero memory allocations in almost paths. Up to 1M QPS on a single host.

License: MIT License

Go 100.00%
dns-server dns doh

fastdns's Introduction

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

DNS Server

package main

import (
	"log"
	"net"
	"net/netip"
	"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.HOST1(rw, req, 60, netip.AddrFrom4([4]byte{8, 8, 8, 8}))
	case fastdns.TypeAAAA:
		fastdns.HOST(rw, req, 60, []netip.Addr{netip.MustParseAddr("2001:4860:4860::8888")})
	case fastdns.TypeCNAME:
		fastdns.CNAME(rw, req, 60, []string{"dns.google"}, []netip.Addr{netip.MustParseAddr("8.8.8.8")})
	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)
	}
}

DNS Client

$ go install github.com/phuslu/fastdns/cmd/fastdig@master
$ 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

DoH Server

$ go install github.com/phuslu/fastdns/cmd/fastdoh@master
$ fastdoh :8080

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: AMD EPYC 7763 64-Core Processor

BenchmarkHOST1-4               	56613120	        21.09 ns/op	       0 B/op	       0 allocs/op
BenchmarkHOST-4                	57722778	        20.82 ns/op	       0 B/op	       0 allocs/op
BenchmarkCNAME-4               	40001464	        30.00 ns/op	       0 B/op	       0 allocs/op
BenchmarkSRV-4                 	26439794	        44.84 ns/op	       0 B/op	       0 allocs/op
BenchmarkNS-4                  	22967035	        52.28 ns/op	       0 B/op	       0 allocs/op
BenchmarkSOA-4                 	19650216	        61.16 ns/op	       0 B/op	       0 allocs/op
BenchmarkPTR-4                 	50205879	        30.12 ns/op	       0 B/op	       0 allocs/op
BenchmarkMX-4                  	39453458	        29.81 ns/op	       0 B/op	       0 allocs/op
BenchmarkTXT-4                 	62278441	        19.15 ns/op	       0 B/op	       0 allocs/op
BenchmarkParseMessage-4        	83152729	        14.84 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetQuestion-4         	37922407	        31.28 ns/op	       0 B/op	       0 allocs/op
BenchmarkSetResponseHeader-4   	336013587	         3.583 ns/op	       0 B/op	       0 allocs/op
BenchmarkDecodeName-4          	52855680	        22.86 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendHOSTRecord-4    	71025451	        16.81 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendCNAMERecord-4   	52953403	        23.92 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSRVRecord-4     	30775414	        36.37 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendNSRecord-4      	27102512	        43.92 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendSOARecord-4     	21295884	        56.13 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendPTRRecord-4     	62573373	        24.38 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendMXRecord-4      	43072573	        28.30 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendTXTRecord-4     	100000000	        11.15 ns/op	       0 B/op	       0 allocs/op
BenchmarkUpdateStats-4         	40084848	        29.85 ns/op	       0 B/op	       0 allocs/op
BenchmarkAppendOpenMetrics-4   	  110046	     10824 ns/op	       0 B/op	       0 allocs/op
BenchmarkEncodeDomain-4        	100000000	        11.54 ns/op	       0 B/op	       0 allocs/op

PASS
ok  	github.com/phuslu/fastdns	30.430s

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.

fastdns's People

Contributors

dependabot[bot] avatar glaslos avatar phuslu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fastdns's Issues

decode name panic

panic: runtime error: index out of range [201] with length 9

goroutine 852 [running]:
github.com/phuslu/fastdns.(*Message).DecodeName(0xc00f291260, {0x0?, 0x0, 0x7a4a58?}, {0xc0037f352b, 0x9, 0x5cc46c?})
/root/go/pkg/mod/github.com/phuslu/[email protected]/message.go:201 +0x431

	req, resp := fastdns.AcquireMessage(), fastdns.AcquireMessage()
	defer fastdns.ReleaseMessage(req)
	defer fastdns.ReleaseMessage(resp)

	req.SetRequestQustion(domain, fastdns.TypeMX, fastdns.ClassINET)

	err := fastdnsClient.Exchange(req, resp)
	if err != nil {
		log.Println(err)
		return "", "", err
	}

	var hosts []string
	_ = resp.Walk(func(name []byte, typ fastdns.Type, class fastdns.Class, ttl uint32, data []byte) bool {
		if typ == fastdns.TypeMX {
			hosts = append(hosts, string(resp.DecodeName(nil, data[2:])))
		}

		return true
	})

Cant get TXT Record of some Domains

Hey,
in short term, im trying to use fastdig as an alternative for "dig". When im using "dig" everything works expected, but on fastdig the result is missing. Example:

; <<>> DiG 9.16.44-Debian <<>> @1.1.1.1 t3n.de TXT
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21655
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;t3n.de.				IN	TXT

;; ANSWER SECTION:
t3n.de.			20995	IN	TXT	"nJg0mOQ"
t3n.de.			20995	IN	TXT	"v3nk3wg16gqgph0x4q2g45kj1j6g0b9f"
t3n.de.			20995	IN	TXT	"loaderio=6cead61edf5d0ea1a2297c1e7a409e87"
t3n.de.			20995	IN	TXT	"google-site-verification=ojkBs6li65pAGMwyGZl3Q1O0Q4DDMn8CPebe5bgeGNo"
t3n.de.			20995	IN	TXT	"hns-claim:aakgrn5php6ppybp6bjmlczduk3gplljzyfp5kfgaeaaaaaaaaaklzaororjdpl6qzexi75h7ofhv447lownw5btzuxvs4ibaaaabnvuzysq"
t3n.de.			20995	IN	TXT	"v=spf1 include:servers.mcsv.net include:spf.mailjet.com mx include:helpscoutemail.com include:_spf.intan.net include:_spf.google.com include:eu.zcsend.net ~all"

;; Query time: 4 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Wed Mar 20 15:40:46 EDT 2024
;; MSG SIZE  rcvd: 538

; <<>> DiG 0.0.1-fastdns-go1.21.5 <<>> t3n.de
;; global options: +cmd +noedns
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65246
;; flags: qr tc rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;t3n.de.		IN	TXT

;; AUTHORITY SECTION:

;; Query time: 7 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Wed Mar 20 15:40:36 EDT 2024
;; MSG SIZE  rcvd: 24

Im using the master, maybe its a bug?

//edit:
i downgraded till v0.6.0. looks like a basic problem

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.