Make it more go like

Start the goroutine and return the channel to the caller.
Only use 1 channel, a nil message signals the end of the
routine.

Still need a good name for the MsgErr
This commit is contained in:
Miek Gieben 2010-12-18 23:35:30 +01:00
parent 354b8e559e
commit b5640dba89
3 changed files with 45 additions and 54 deletions

3
TODO
View File

@ -2,5 +2,4 @@ EDNS -- add EDNS0 support
DNSSEC - validation and the remaining records
DS, RRSIG, NSEC, etc.
Generic version of TryOneName
testing
Get rid of parse.go
quotes in quotes in txt records

View File

@ -32,55 +32,54 @@ type Resolver struct {
Rotate bool // round robin among servers
}
// Start a new querier as a goroutine, return
// the communication channel
func NewQuerier(res *Resolver) (ch chan MsgErr) {
ch = make(chan MsgErr)
go query(res, ch)
return
}
// do it
func Query(res *Resolver, msg chan MsgErr, quit chan bool) {
func query(res *Resolver, msg chan MsgErr) {
var c net.Conn
var err os.Error
var in *Msg
for {
select {
case <-quit: // quit signal recevied
println("Quiting")
// send something back on the channel?
return
case out := <-msg: //msg received
if out.M == nil {
// nil message, quit the goroutine
return
}
var cerr os.Error
println("Getting a message")
// Set an id
//if len(name) >= 256 {
out.M.Id = uint16(rand.Int()) ^ uint16(time.Nanoseconds())
println("Setting the id", out.M.Id)
sending, ok := out.M.Pack()
if !ok {
println("error converting")
msg <- MsgErr{nil, nil} // todo error
}
println("here")
for i := 0; i < len(res.Servers); i++ {
println("here", i)
server := res.Servers[i] + ":53"
println(server)
println("before dial")
c, cerr = net.Dial("udp", "", server)
println("after dial")
if cerr != nil {
println("error sending")
err = cerr
continue
}
println("exchange")
in, err = exchange(c, sending, res.Attempts, res.Timeout)
// Check id in.id != out.id
c.Close()
if err != nil {
println("Err not nil")
continue
}
}
println("komt ik hier dan")
if err != nil {
msg <- MsgErr{nil, err}
} else {
@ -88,7 +87,6 @@ func Query(res *Resolver, msg chan MsgErr, quit chan bool) {
}
}
}
println("Mag nooit hier komen")
return
}

View File

@ -2,26 +2,17 @@ package main
import (
"dns"
"fmt"
"time"
"fmt"
)
const (
NLOOP = 5
)
func main() {
res := new(dns.Resolver) // create a new resolver
// Create a new message
m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]dns.Question, 1)
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
// send config (or res with Query)
msgch := make(chan dns.MsgErr)
qch := make(chan bool)
// start the resolver
go dns.Query(res, msgch, qch)
res := new(dns.Resolver)
ch := dns.NewQuerier(res)
// configure the resolver
res.Servers = []string{"192.168.1.2"}
@ -29,28 +20,31 @@ func main() {
res.Attempts = 1
// 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
msgch <- dns.MsgErr{m, nil}
for i:=0; i< NLOOP; i++ {
// ask something
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
ch <- dns.MsgErr{m, nil}
// wait for an reply
in := <-msgch
fmt.Printf("%v\n", in.M)
// kill resolver
// qch <- true does not work yet
// wait for an reply
in := <-ch
fmt.Printf("%v\n", in.M)
m.Question[0] = dns.Question{"a.miek.nl", dns.TypeTXT, dns.ClassINET}
msgch <- dns.MsgErr{m, nil}
// wait for an reply
in = <-msgch
fmt.Printf("%v\n", in.M)
m.Question[0] = dns.Question{"a.miek.nl", dns.TypeTXT, dns.ClassINET}
ch <- dns.MsgErr{m, nil}
in = <-ch
fmt.Printf("%v\n", in.M)
m.Question[0] = dns.Question{"miek.nl", dns.TypeTXT, dns.ClassINET}
// ask something
msgch <- dns.MsgErr{m, nil}
// wait for an reply
in = <-msgch
fmt.Printf("%v\n", in.M)
m.Question[0] = dns.Question{"miek.nl", dns.TypeTXT, dns.ClassINET}
ch <- dns.MsgErr{m, nil}
in = <-ch
fmt.Printf("%v\n", in.M)
}
ch <- dns.MsgErr{nil, nil}
time.Sleep(2.0e9) // wait for Go routine to do something
}