Browse Source

add comments

master
Brett Langdon 10 years ago
parent
commit
1a718de165
3 changed files with 45 additions and 11 deletions
  1. +7
    -0
      cmd/realm/main.go
  2. +18
    -7
      server.go
  3. +20
    -4
      zone.go

+ 7
- 0
cmd/realm/main.go View File

@ -8,6 +8,7 @@ import (
)
func main() {
// Setup our CLI app
var app *cli.App = cli.NewApp()
app.Name = "realm"
app.Version = "0.1.0"
@ -26,12 +27,16 @@ func main() {
Usage: "'[<host>]:<port>' to bind too",
},
}
// This action is called for all commands
app.Action = func(c *cli.Context) {
// Ensure that a zone filename was provided
var filename string = c.String("zone")
if filename == "" {
log.Fatal("must supply zone file via \"--zone\" flag or \"REALM_ZONE\" environment variable")
}
// Load and parse the zone file
var zone *realm.Zone
var err error
log.Printf("parsing zone file \"%s\"\n", filename)
@ -40,11 +45,13 @@ func main() {
log.Fatal(err)
}
// Create and start the server
var bind string = c.String("bind")
log.Printf("starting the server on \"%s\"\n", bind)
var server *realm.Server = realm.NewServer(bind, zone)
log.Fatal(server.ListenAndServe())
}
// Parse command arguments and run `app.Action`
app.RunAndExitOnError()
}

+ 18
- 7
server.go View File

@ -2,34 +2,45 @@ package realm
import "github.com/miekg/dns"
// A Server listens for DNS requests over UDP and responds with answers from the provided Zone.
type Server struct {
server *dns.Server
zone *Zone
}
// NewServer returns a new initialized *Server that will bind to listen and will look up answers from zone.
func NewServer(listen string, zone *Zone) *Server {
var server *Server = &Server{zone: zone}
server.server = &dns.Server{
var server *Server
s = &Server{zone: zone}
s.server = &dns.Server{
Addr: listen,
Net: "udp",
Handler: server,
}
return server
return s
}
func (server *Server) ListenAndServe() error {
// ListenAndServe will start the nameserver on the configured address.
func (s *Server) ListenAndServe() error {
return server.server.ListenAndServe()
}
func (server *Server) ServeDNS(w dns.ResponseWriter, request *dns.Msg) {
var response *dns.Msg = &dns.Msg{}
// ServeDNS will be called for every DNS request to this server.
// It will attempt to provide answers to all questions from the configured zone.
func (s *Server) ServeDNS(w dns.ResponseWriter, request *dns.Msg) {
// Setup the default response
var response *dns.Msg
response = &dns.Msg{}
response.SetReply(request)
response.Compress = true
// Lookup answers to any of the questions
for _, question := range request.Question {
var records []dns.RR = server.zone.Lookup(question.Name, question.Qtype, question.Qclass)
var records []dns.RR
records = s.zone.Lookup(question.Name, question.Qtype, question.Qclass)
response.Answer = append(response.Answer, records...)
}
// Respond to the request
w.WriteMsg(response)
}

+ 20
- 4
zone.go View File

@ -7,10 +7,13 @@ import (
"github.com/miekg/dns"
)
// A Zone a container for records parsed from a zone file.
type Zone struct {
records []dns.RR
}
// ParseZone will attempt to parse a zone file from the provided filename and return a Zone.
// ParseZone will return an error if the file provided does not exist or could not be properly parsed.
func ParseZone(filename string) (*Zone, error) {
var zone *Zone
var err error
@ -18,6 +21,7 @@ func ParseZone(filename string) (*Zone, error) {
records: make([]dns.RR, 0),
}
// Open the file
var file *os.File
file, err = os.Open(filename)
if err != nil {
@ -25,6 +29,7 @@ func ParseZone(filename string) (*Zone, error) {
}
defer file.Close()
// Parse the file into records
var tokens chan *dns.Token
tokens = dns.ParseZone(file, "", "")
for token := range tokens {
@ -37,21 +42,32 @@ func ParseZone(filename string) (*Zone, error) {
return zone, nil
}
// Lookup will find all records which we should respond with for the given name, request type, and request class.
func (zone *Zone) Lookup(name string, reqType uint16, reqClass uint16) []dns.RR {
name = dns.Fqdn(name)
var records []dns.RR = make([]dns.RR, 0)
var records []dns.RR
records = make([]dns.RR, 0)
for _, record := range zone.records {
var header *dns.RR_Header = record.Header()
var header *dns.RR_Header
header = record.Header()
// Skip this record if the name or class do not match
if header.Name != name || (header.Class != reqClass && reqClass != dns.ClassANY) {
continue
}
// Collect this record if the types match or this record is a CNAME
if reqType == dns.TypeANY || reqType == header.Rrtype {
records = append(records, record)
} else if header.Rrtype == dns.TypeCNAME {
// Append this CNAME record as a response
records = append(records, record)
var cname *dns.CNAME = record.(*dns.CNAME)
var cnameRecords []dns.RR = zone.Lookup(dns.Fqdn(cname.Target), reqType, reqClass)
// Attempt to resolve this CNAME record
var cname *dns.CNAME
cname = record.(*dns.CNAME)
var cnameRecords []dns.RR
cnameRecords = zone.Lookup(dns.Fqdn(cname.Target), reqType, reqClass)
records = append(records, cnameRecords...)
}
}


Loading…
Cancel
Save