mirror of
https://github.com/miekg/dns.git
synced 2025-12-16 09:11:34 +01:00
Documentation!
Make the packet documentation much nicer.
This commit is contained in:
parent
7d4a26deac
commit
65caf6f891
5
Makefile
5
Makefile
@ -20,11 +20,8 @@ include $(GOROOT)/src/Make.pkg
|
|||||||
examples:
|
examples:
|
||||||
(cd examples; make)
|
(cd examples; make)
|
||||||
|
|
||||||
progs: manglertest dnssectest
|
progs: dnssectest
|
||||||
|
|
||||||
# too lazy to lookup how this works again in Makefiles
|
# too lazy to lookup how this works again in Makefiles
|
||||||
manglertest: manglertest.go $(GOFILES)
|
|
||||||
6g -I _obj manglertest.go && 6l -L _obj -o manglertest manglertest.6
|
|
||||||
|
|
||||||
dnssectest: dnssectest.go $(GOFILES)
|
dnssectest: dnssectest.go $(GOFILES)
|
||||||
6g -I _obj dnssectest.go && 6l -L _obj -o dnssectest dnssectest.6
|
6g -I _obj dnssectest.go && 6l -L _obj -o dnssectest dnssectest.6
|
||||||
|
|||||||
19
dnssec.go
19
dnssec.go
@ -5,23 +5,22 @@ import "time"
|
|||||||
// All DNSSEC verification
|
// All DNSSEC verification
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Year68 = 2 << (32 - 1)
|
year68 = 2 << (32 - 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Translate the RRSIG's incep. and expir. time
|
// Translate the RRSIG's incep. and expir. time to the correct date.
|
||||||
// to the correct date, taking into account serial
|
// Taking into account serial arithmetic (RFC 1982)
|
||||||
// arithmetic
|
|
||||||
func timeToDate(t uint32) string {
|
func timeToDate(t uint32) string {
|
||||||
utc := time.UTC().Seconds()
|
utc := time.UTC().Seconds()
|
||||||
mod := (int64(t) - utc) / Year68
|
mod := (int64(t) - utc) / year68
|
||||||
|
|
||||||
// If needed assume wrap around(s)
|
// If needed assume wrap around(s)
|
||||||
ti := time.SecondsToUTC(int64(t) + (mod * Year68)) // abs()? TODO
|
ti := time.SecondsToUTC(int64(t) + (mod * year68)) // abs()? TODO
|
||||||
return ti.Format("20060102030405")
|
return ti.Format("20060102030405")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the signature (RRSIG) valid?
|
// Using RFC1982 calculate if a signature is valid
|
||||||
func validSignaturePeriod(start, end uint32) bool {
|
func validSignaturePeriod(start, end uint32) bool {
|
||||||
utc := time.UTC().Seconds() // maybe as parameter?? TODO MG
|
utc := time.UTC().Seconds() // maybe as parameter?? TODO MG
|
||||||
return int64(start) <= utc && utc <= int64(end)
|
return int64(start) <= utc && utc <= int64(end)
|
||||||
}
|
}
|
||||||
|
|||||||
8
edns.go
8
edns.go
@ -1,10 +1,10 @@
|
|||||||
package dns
|
package dns
|
||||||
|
|
||||||
// Implementation of EDNS0, RFC 2671
|
// EDNS0 option codes
|
||||||
const (
|
const (
|
||||||
OptionCodeLLQ = 1
|
OptionCodeLLQ = 1 // Not used
|
||||||
OptionCodeUL = 2
|
OptionCodeUL = 2 // Not used
|
||||||
OptionCodeNSID = 3
|
OptionCodeNSID = 3 // NSID, RFC5001
|
||||||
// EDNS flag bits (put in Z section)
|
// EDNS flag bits (put in Z section)
|
||||||
_DO = 1 << 15 // dnssec ok
|
_DO = 1 << 15 // dnssec ok
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,77 +2,78 @@ package main
|
|||||||
|
|
||||||
// Print the version.bind and hostname.bind for each
|
// Print the version.bind and hostname.bind for each
|
||||||
// address of NAMESERVER
|
// address of NAMESERVER
|
||||||
|
// (c) Miek Gieben - 2011
|
||||||
import (
|
import (
|
||||||
"dns"
|
"dns"
|
||||||
"os"
|
"os"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
r := new(dns.Resolver)
|
r := new(dns.Resolver)
|
||||||
qr := dns.NewQuerier(r)
|
qr := dns.NewQuerier(r)
|
||||||
r.Servers = []string{"127.0.0.1"}
|
r.Servers = []string{"127.0.0.1"}
|
||||||
r.Timeout = 2
|
r.Timeout = 2
|
||||||
r.Attempts = 1
|
r.Attempts = 1
|
||||||
var in dns.DnsMsg
|
var in dns.DnsMsg
|
||||||
|
|
||||||
if len(os.Args) != 2 {
|
if len(os.Args) != 2 {
|
||||||
fmt.Printf("%s NAMESERVER\n", os.Args[0])
|
fmt.Printf("%s NAMESERVER\n", os.Args[0])
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.Question = make([]dns.Question, 1)
|
m.Question = make([]dns.Question, 1)
|
||||||
for _, a := range addresses(qr, os.Args[0]) {
|
for _, a := range addresses(qr, os.Args[0]) {
|
||||||
// set the resolver to query the NS directly
|
// set the resolver to query the NS directly
|
||||||
r.Servers = []string{a.String()}
|
r.Servers = []string{a.String()}
|
||||||
m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
|
m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
|
||||||
qr <- dns.DnsMsg{m, nil}
|
qr <- dns.DnsMsg{m, nil}
|
||||||
in = <-qr
|
in = <-qr
|
||||||
if in.Dns != nil && in.Dns.Answer != nil {
|
if in.Dns != nil && in.Dns.Answer != nil {
|
||||||
fmt.Printf("%v\n", in.Dns.Answer[0])
|
fmt.Printf("%v\n", in.Dns.Answer[0])
|
||||||
}
|
}
|
||||||
m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
|
m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
|
||||||
qr <- dns.DnsMsg{m, nil}
|
qr <- dns.DnsMsg{m, nil}
|
||||||
in = <-qr
|
in = <-qr
|
||||||
if in.Dns != nil && in.Dns.Answer != nil {
|
if in.Dns != nil && in.Dns.Answer != nil {
|
||||||
fmt.Printf("%v\n", in.Dns.Answer[0])
|
fmt.Printf("%v\n", in.Dns.Answer[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the resolver, send it a null mesg
|
// Stop the resolver, send it a null mesg
|
||||||
qr <- dns.DnsMsg{nil, nil}
|
qr <- dns.DnsMsg{nil, nil}
|
||||||
<-qr
|
<-qr
|
||||||
}
|
}
|
||||||
|
|
||||||
func addresses(qr chan dns.DnsMsg, name string) []net.IP {
|
func addresses(qr chan dns.DnsMsg, name string) []net.IP {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.MsgHdr.Recursion_desired = true //only set this bit
|
m.MsgHdr.Recursion_desired = true //only set this bit
|
||||||
m.Question = make([]dns.Question, 1)
|
m.Question = make([]dns.Question, 1)
|
||||||
var ips []net.IP
|
var ips []net.IP
|
||||||
|
|
||||||
m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET}
|
m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET}
|
||||||
qr <- dns.DnsMsg{m, nil}
|
qr <- dns.DnsMsg{m, nil}
|
||||||
in := <-qr
|
in := <-qr
|
||||||
|
|
||||||
if in.Dns.Rcode != dns.RcodeSuccess {
|
if in.Dns.Rcode != dns.RcodeSuccess {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Stuff must be in the answer section
|
// Stuff must be in the answer section
|
||||||
for _, a := range in.Dns.Answer {
|
for _, a := range in.Dns.Answer {
|
||||||
ips = append(ips, a.(*dns.RR_A).A)
|
ips = append(ips, a.(*dns.RR_A).A)
|
||||||
}
|
}
|
||||||
m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET}
|
m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET}
|
||||||
qr <- dns.DnsMsg{m, nil}
|
qr <- dns.DnsMsg{m, nil}
|
||||||
in = <-qr
|
in = <-qr
|
||||||
|
|
||||||
if in.Dns.Rcode != dns.RcodeSuccess {
|
if in.Dns.Rcode != dns.RcodeSuccess {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Stuff must be in the answer section
|
// Stuff must be in the answer section
|
||||||
for _, a := range in.Dns.Answer {
|
for _, a := range in.Dns.Answer {
|
||||||
ips = append(ips, a.(*dns.RR_AAAA).AAAA)
|
ips = append(ips, a.(*dns.RR_AAAA).AAAA)
|
||||||
}
|
}
|
||||||
return ips
|
return ips
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
// Print the MX records of a domain
|
// Print the MX records of a domain
|
||||||
|
// (c) Miek Gieben - 2011
|
||||||
import (
|
import (
|
||||||
"dns"
|
"dns"
|
||||||
"os"
|
"os"
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"dns"
|
|
||||||
"time"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
NLOOP = 5
|
|
||||||
)
|
|
||||||
|
|
||||||
func identity(msg []byte) []byte {
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func byteflip(msg []byte) []byte {
|
|
||||||
msg[len(msg) - 1] = 0
|
|
||||||
msg[2] = 0 // See what happens
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func bitflip(msg []byte) []byte {
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
res := new(dns.Resolver)
|
|
||||||
ch := dns.NewQuerier(res)
|
|
||||||
|
|
||||||
// configure the resolver
|
|
||||||
res.Servers = []string{"192.168.1.2"}
|
|
||||||
res.Timeout = 2
|
|
||||||
res.Attempts = 1
|
|
||||||
res.Mangle = byteflip
|
|
||||||
|
|
||||||
// Setup done, now for some real work
|
|
||||||
// Create a new message
|
|
||||||
m := new(dns.Msg)
|
|
||||||
m.MsgHdr.Recursion_desired = true //only set this bit
|
|
||||||
m.Question = make([]dns.Question, 1)
|
|
||||||
|
|
||||||
// ask something
|
|
||||||
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
|
|
||||||
ch <- dns.DnsMsg{m, nil}
|
|
||||||
|
|
||||||
// wait for an reply
|
|
||||||
in := <-ch
|
|
||||||
fmt.Printf("%v\n", in.Dns)
|
|
||||||
|
|
||||||
ch <- dns.DnsMsg{nil, nil}
|
|
||||||
|
|
||||||
time.Sleep(1.0e9) // wait for Go routine to do something
|
|
||||||
}
|
|
||||||
16
msg.go
16
msg.go
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
// DNS packet assembly. See RFC 1035.
|
// DNS packet assembly. See RFC 1035.
|
||||||
//
|
//
|
||||||
// This is intended to support name resolution during net.Dial.
|
// This is not (yet) optimized for speed.
|
||||||
// It doesn't have to be blazing fast.
|
|
||||||
//
|
//
|
||||||
// Rather than write the usual handful of routines to pack and
|
// Rather than write the usual handful of routines to pack and
|
||||||
// unpack every message that can appear on the wire, we use
|
// unpack every message that can appear on the wire, we use
|
||||||
@ -13,13 +12,7 @@
|
|||||||
// use it. Thus, if in the future we need to define new message
|
// use it. Thus, if in the future we need to define new message
|
||||||
// structs, no new pack/unpack/printing code needs to be written.
|
// structs, no new pack/unpack/printing code needs to be written.
|
||||||
//
|
//
|
||||||
// The first half of this file defines the DNS message formats.
|
|
||||||
// The second half implements the conversion to and from wire format.
|
|
||||||
// A few of the structure elements have string tags to aid the
|
|
||||||
// generic pack/unpack routines.
|
|
||||||
//
|
//
|
||||||
// TODO(miekg):
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -171,7 +164,6 @@ Loop:
|
|||||||
return s, off1, true
|
return s, off1, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(rsc): Move into generic library?
|
|
||||||
// Pack a reflect.StructValue into msg. Struct members can only be uint8, uint16, uint32, string,
|
// Pack a reflect.StructValue into msg. Struct members can only be uint8, uint16, uint32, string,
|
||||||
// slices and other (often anonymous) structs.
|
// slices and other (often anonymous) structs.
|
||||||
func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, ok bool) {
|
func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, ok bool) {
|
||||||
@ -503,6 +495,8 @@ type MsgHdr struct {
|
|||||||
Rcode int
|
Rcode int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a MsgHdr to a string, mimic the way dig displays
|
||||||
|
// headers:
|
||||||
//;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48404
|
//;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48404
|
||||||
//;; flags: qr aa rd ra;
|
//;; flags: qr aa rd ra;
|
||||||
func (h *MsgHdr) String() string {
|
func (h *MsgHdr) String() string {
|
||||||
@ -544,6 +538,7 @@ func (h *MsgHdr) String() string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The layout of a DNS message.
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
MsgHdr
|
MsgHdr
|
||||||
Question []Question
|
Question []Question
|
||||||
@ -598,7 +593,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
|
|||||||
// Could work harder to calculate message size,
|
// Could work harder to calculate message size,
|
||||||
// but this is far more than we need and not
|
// but this is far more than we need and not
|
||||||
// big enough to hurt the allocator.
|
// big enough to hurt the allocator.
|
||||||
msg = make([]byte, 4096) // TODO, calculate REAL size
|
msg = make([]byte, defaultSize) // TODO, calculate REAL size
|
||||||
|
|
||||||
// Pack it in: header and then the pieces.
|
// Pack it in: header and then the pieces.
|
||||||
off := 0
|
off := 0
|
||||||
@ -665,6 +660,7 @@ func (dns *Msg) Unpack(msg []byte) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a complete message to a string. Again use dig-like output
|
||||||
func (dns *Msg) String() string {
|
func (dns *Msg) String() string {
|
||||||
if dns == nil {
|
if dns == nil {
|
||||||
return "<nil> MsgHdr"
|
return "<nil> MsgHdr"
|
||||||
|
|||||||
67
resolver.go
67
resolver.go
@ -5,9 +5,23 @@
|
|||||||
// DNS resolver client: see RFC 1035.
|
// DNS resolver client: see RFC 1035.
|
||||||
// A dns resolver is to be run as a seperate goroutine.
|
// A dns resolver is to be run as a seperate goroutine.
|
||||||
// For every reply the resolver answers by sending the
|
// For every reply the resolver answers by sending the
|
||||||
// received packet back on the channel.
|
// received packet (with a possible error) back on the channel.
|
||||||
// TODO: resolverFromConf (/etc/resolv.conf) parsing??
|
// A simple resolver can be setup with the following code:
|
||||||
|
//
|
||||||
|
// res := new(Resolver)
|
||||||
|
// ch := NewQuerier(res) // start new resolver
|
||||||
|
//
|
||||||
|
// res.Servers = []string{"127.0.0.1"} // set the nameserver
|
||||||
|
// res.Timeout = 2 // some optional extra config
|
||||||
|
// res.Attempts = 1
|
||||||
|
//
|
||||||
|
// m := new(Msg) // prepare a new message
|
||||||
|
// m.MsgHdr.Recursion_desired = true // header bits
|
||||||
|
// m.Question = make([]Question, 1) // 1 RR in question sec.
|
||||||
|
// m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
|
||||||
|
// ch <- DnsMsg{m, nil} // send the query
|
||||||
|
// in := <-ch // wait for reply
|
||||||
|
//
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -17,37 +31,40 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// For communicating with a resolver
|
const defaultSize = 4096
|
||||||
// A nil msg ends the resolver goroutine
|
|
||||||
|
// When communicating with a resolver, we use this structure
|
||||||
|
// to send packets to it, when sending Error must be nil.
|
||||||
|
// A resolver responds with a simular message and a possible
|
||||||
|
// error.
|
||||||
|
// Sending a nil message instructs to resolver to stop.
|
||||||
type DnsMsg struct {
|
type DnsMsg struct {
|
||||||
Dns *Msg
|
Dns *Msg
|
||||||
Error os.Error
|
Error os.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
Servers []string // servers to use
|
Servers []string // servers to use
|
||||||
rtt []int // round trip times for each NS (TODO)
|
Search []string // suffixes to append to local name
|
||||||
Search []string // suffixes to append to local name
|
Port string // what port to use
|
||||||
Port string // what port to use
|
Ndots int // number of dots in name to trigger absolute lookup
|
||||||
Ndots int // number of dots in name to trigger absolute lookup
|
Timeout int // seconds before giving up on packet
|
||||||
Timeout int // seconds before giving up on packet
|
Attempts int // lost packets before giving up on server
|
||||||
Attempts int // lost packets before giving up on server
|
Rotate bool // round robin among servers
|
||||||
Rotate bool // round robin among servers
|
Tcp bool // use TCP
|
||||||
Tcp bool // use TCP
|
Mangle func([]byte) []byte // Mangle the packet
|
||||||
Mangle func([]byte) []byte // Mangle the packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a new querier as a goroutine, return
|
// Start a new resolver as a goroutine, return the communication channel
|
||||||
// the communication channel
|
|
||||||
func NewQuerier(res *Resolver) (ch chan DnsMsg) {
|
func NewQuerier(res *Resolver) (ch chan DnsMsg) {
|
||||||
ch = make(chan DnsMsg)
|
ch = make(chan DnsMsg)
|
||||||
go query(res, ch)
|
go query(res, ch)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The query function.
|
||||||
// do it
|
|
||||||
func query(res *Resolver, msg chan DnsMsg) {
|
func query(res *Resolver, msg chan DnsMsg) {
|
||||||
|
// TODO port number, error checking, robustness
|
||||||
var c net.Conn
|
var c net.Conn
|
||||||
var err os.Error
|
var err os.Error
|
||||||
var in *Msg
|
var in *Msg
|
||||||
@ -56,8 +73,8 @@ func query(res *Resolver, msg chan DnsMsg) {
|
|||||||
case out := <-msg: //msg received
|
case out := <-msg: //msg received
|
||||||
if out.Dns == nil {
|
if out.Dns == nil {
|
||||||
// nil message, quit the goroutine
|
// nil message, quit the goroutine
|
||||||
msg <- DnsMsg{nil, nil}
|
msg <- DnsMsg{nil, nil}
|
||||||
close(msg)
|
close(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +88,7 @@ func query(res *Resolver, msg chan DnsMsg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(res.Servers); i++ {
|
for i := 0; i < len(res.Servers); i++ {
|
||||||
// server := res.Servers[i] + ":" + res.Port
|
// server := res.Servers[i] + ":" + res.Port
|
||||||
server := res.Servers[i] + ":53"
|
server := res.Servers[i] + ":53"
|
||||||
if res.Tcp == true {
|
if res.Tcp == true {
|
||||||
c, cerr = net.Dial("tcp", "", server)
|
c, cerr = net.Dial("tcp", "", server)
|
||||||
@ -100,8 +117,6 @@ func query(res *Resolver, msg chan DnsMsg) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Pack to create a DNS question, from a msg
|
|
||||||
|
|
||||||
// Send a request on the connection and hope for a reply.
|
// Send a request on the connection and hope for a reply.
|
||||||
// Up to res.Attempts attempts.
|
// Up to res.Attempts attempts.
|
||||||
func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
|
func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
|
||||||
@ -117,7 +132,7 @@ func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
|
|||||||
|
|
||||||
c.SetReadTimeout(int64(r.Timeout) * 1e9) // nanoseconds
|
c.SetReadTimeout(int64(r.Timeout) * 1e9) // nanoseconds
|
||||||
// EDNS TODO
|
// EDNS TODO
|
||||||
buf := make([]byte, 2000) // More than enough.
|
buf := make([]byte, defaultSize) // More than enough.
|
||||||
n, err = c.Read(buf)
|
n, err = c.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// More Go foo needed
|
// More Go foo needed
|
||||||
|
|||||||
@ -21,8 +21,13 @@ func TestResolverEdns(t *testing.T) {
|
|||||||
edns := new(RR_OPT)
|
edns := new(RR_OPT)
|
||||||
edns.Hdr.Name = "." // must . be for edns
|
edns.Hdr.Name = "." // must . be for edns
|
||||||
edns.Hdr.Rrtype = TypeOPT
|
edns.Hdr.Rrtype = TypeOPT
|
||||||
edns.Hdr.Class = ClassINET
|
// You can handle an OTP RR as any other, but there
|
||||||
edns.Hdr.Ttl = 3600
|
// are some convience functions
|
||||||
|
ends.UDPSize(4096, true)
|
||||||
|
edns.DoBit(true, true)
|
||||||
|
// edns.Nsid("mieks-server", true)
|
||||||
|
// edns.Hdr.Class = ClassINET
|
||||||
|
// edns.Hdr.Ttl = 3600
|
||||||
// no options for now
|
// no options for now
|
||||||
// edns.Option = make([]Option, 1)
|
// edns.Option = make([]Option, 1)
|
||||||
// edns.Option[0].Code = OptionCodeNSID
|
// edns.Option[0].Code = OptionCodeNSID
|
||||||
@ -30,7 +35,7 @@ func TestResolverEdns(t *testing.T) {
|
|||||||
|
|
||||||
// ask something
|
// ask something
|
||||||
m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
|
m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
|
||||||
m.Ns[0] = edns
|
m.Extra[0] = edns
|
||||||
|
|
||||||
ch <- DnsMsg{m, nil}
|
ch <- DnsMsg{m, nil}
|
||||||
in := <-ch
|
in := <-ch
|
||||||
@ -41,5 +46,5 @@ func TestResolverEdns(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
ch <- DnsMsg{nil, nil}
|
ch <- DnsMsg{nil, nil}
|
||||||
<-ch
|
<-ch // wait for ch to close channel
|
||||||
}
|
}
|
||||||
|
|||||||
23
strconv.go
23
strconv.go
@ -1,21 +1,18 @@
|
|||||||
package dns
|
package dns
|
||||||
|
|
||||||
// subpackage?
|
// Convert a string to an resource record. The string must fir on one line.
|
||||||
|
|
||||||
// Convert a string to an resource record
|
|
||||||
// The string must fit on one line and must be fully formatted
|
|
||||||
// IN A 192.168.1.1 // not ok
|
|
||||||
// miek.nl. 3600 IN A 192.168.1.1 // ok
|
// miek.nl. 3600 IN A 192.168.1.1 // ok
|
||||||
// miek.nl. IN A 192.168.1.1 // ok, ttl may be omitted
|
// miek.nl. IN A 192.168.1.1 // ok, ttl may be omitted
|
||||||
// miek.nl. A 192.168.1.1 // ok, ttl and class omitted
|
// miek.nl. A 192.168.1.1 // ok, ttl and class omitted
|
||||||
// miek.nl. 3600 A 192.168.1.1 // ok, class omitted
|
// miek.nl. 3600 A 192.168.1.1 // ok, class omitted
|
||||||
|
// IN A 192.168.1.1 // not ok
|
||||||
func AtoRR(s string) *RR {
|
func AtoRR(s string) *RR {
|
||||||
// up to first whitespace is domainname
|
// up to first whitespace is domainname
|
||||||
// next word is:
|
// next word is:
|
||||||
// <number> -> TTL
|
// <number> -> TTL
|
||||||
// IN|CH|HS -> Class
|
// IN|CH|HS -> Class
|
||||||
// <rest> -> Type
|
// <rest> -> Type
|
||||||
// When the type is seen, we can read the rest
|
// When the type is seen, we can read the rest
|
||||||
// of the string in an rr-specific manner
|
// of the string in an rr-specific manner
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
25
types.go
25
types.go
@ -1,10 +1,25 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
// Extended and bugfixes by Miek Gieben
|
||||||
|
|
||||||
// DNS Resource Records Types. See RFC 1035 and ...
|
// Package dns implements a full featured interface to the DNS.
|
||||||
|
// Supported RFCs include:
|
||||||
|
// * 1034/1035
|
||||||
|
// * 2671 - EDNS
|
||||||
|
// * 4033/4034/4035 - DNSSEC + validation functions
|
||||||
|
// * 1982 - Serial Arithmetic
|
||||||
|
// * IP6 support
|
||||||
|
// The package allow full control over what is send out to the DNS.
|
||||||
|
//
|
||||||
|
// DNS RR types definitions. See RFC 1035/.../4034 and many more.
|
||||||
|
// To create quad-A record: "a.miek.nl" IN AAAA 2001:7b8:206:1:200:39ff:fe59:b187
|
||||||
|
//
|
||||||
|
// import "net" // for IP functions
|
||||||
|
// r := new(RR_AAAA)
|
||||||
|
// r.AAAA = net.ParseIP("2001:7b8:206:1:200:39ff:fe59:b187").To16()
|
||||||
|
// r.Hdr = RR_Header{Name: "a.miek.nl", Rrtype: TypeAAAA, Class: ClassINET, Ttl: 3600}
|
||||||
//
|
//
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -88,8 +103,7 @@ const (
|
|||||||
_CD = 1 << 4 // checking disabled
|
_CD = 1 << 4 // checking disabled
|
||||||
)
|
)
|
||||||
|
|
||||||
// Why not use the official cryptstuff here too???
|
// DNSSEC encryption algorithm codes.
|
||||||
// or at least map them
|
|
||||||
const (
|
const (
|
||||||
// DNSSEC algorithms
|
// DNSSEC algorithms
|
||||||
AlgRSAMD5 = 1
|
AlgRSAMD5 = 1
|
||||||
@ -102,6 +116,7 @@ const (
|
|||||||
AlgECCGOST = 12
|
AlgECCGOST = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DNSSEC hashing codes.
|
||||||
const (
|
const (
|
||||||
HashSHA1 = 1 //?
|
HashSHA1 = 1 //?
|
||||||
HashSHA256 = 2 //?
|
HashSHA256 = 2 //?
|
||||||
@ -457,7 +472,7 @@ type RR_NSEC3 struct {
|
|||||||
Salt string "hex"
|
Salt string "hex"
|
||||||
HashLength uint8
|
HashLength uint8
|
||||||
NextDomain string "domain-name"
|
NextDomain string "domain-name"
|
||||||
TypeBitMap []int "NSEC3" // &{TypeSOA,TypeDS,etc}
|
TypeBitMap []int "NSEC3" // &{TypeSOA,TypeDS,etc}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_NSEC3) Header() *RR_Header {
|
func (rr *RR_NSEC3) Header() *RR_Header {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user