Make the new resolver API better

This commit is contained in:
Miek Gieben 2011-03-28 10:33:57 +02:00
parent 135772de9f
commit f9088e1e75
2 changed files with 31 additions and 11 deletions

6
dns.go
View File

@ -80,13 +80,13 @@ type Conn struct {
// The current TCP connection. // The current TCP connection.
TCP *net.TCPConn TCP *net.TCPConn
// The remote side of the connection. // The remote side of open the connection.
Addr net.Addr Addr net.Addr
// The remote port number of the connection. // The remote port number of open the connection.
Port int Port int
// Remove server (for resolver) // The remote addr which is going to be dialed.
RemoteAddr string RemoteAddr string
// If TSIG is used, this holds all the information. // If TSIG is used, this holds all the information.

View File

@ -12,23 +12,33 @@ import (
"time" "time"
) )
// Query is used to communicate with the Query* functions.
type Query struct { type Query struct {
// The query message.
Msg *Msg Msg *Msg
// A Conn. Its only required to fill out Conn.RemoteAddr.
// The rest of the structure is filled in by the Query Functions.
Conn *Conn Conn *Conn
// Any erros when querying are returned in Err. The caller
// should just set this to nil.
Err os.Error Err os.Error
} }
// A query implementation that is asyn. and concurrent. Is also // QueryUDP handles one query. It reads an incoming request from
// completely mirrors the server side implementation // the in channel. The function f is executed in a seperate
// goroutine and performs the actual UDP query.
func QueryTCP(in, out chan Query, f func(*Conn, *Msg, chan Query)) {
query("tcp", in, out, f)
}
func QueryUDP(in, out chan Query, f func(*Conn, *Msg, chan Query)) { func QueryUDP(in, out chan Query, f func(*Conn, *Msg, chan Query)) {
query("udp", in, out, f) query("udp", in, out, f)
} }
// QueryTCP handles one query. It reads an incoming request from
// the in channel. The function f is executed in a seperate
// goroutine and performas the actual TCP query.
func QueryTCP(in, out chan Query, f func(*Conn, *Msg, chan Query)) {
query("tcp", in, out, f)
}
// helper function.
func query(n string, in, out chan Query, f func(*Conn, *Msg, chan Query)) { func query(n string, in, out chan Query, f func(*Conn, *Msg, chan Query)) {
for { for {
select { select {
@ -42,18 +52,28 @@ func query(n string, in, out chan Query, f func(*Conn, *Msg, chan Query)) {
} else { } else {
q.Conn.SetUDPConn(c.(*net.UDPConn), nil) q.Conn.SetUDPConn(c.(*net.UDPConn), nil)
} }
go f(q.Conn, q.Msg, out) if f == nil {
out <- Query{Err: ErrHandle}
} else {
go f(q.Conn, q.Msg, out)
}
} }
} }
panic("not reached") panic("not reached")
} }
// QueryAndServeTCP listens for incoming requests on channel in and
// then calls QueryTCP with f to the handle the request.
// It returns a channel on which the response is returned.
func QueryAndServeTCP(in chan Query, f func(*Conn, *Msg, chan Query)) chan Query { func QueryAndServeTCP(in chan Query, f func(*Conn, *Msg, chan Query)) chan Query {
out := make(chan Query) out := make(chan Query)
go QueryTCP(in, out, f) go QueryTCP(in, out, f)
return out return out
} }
// QueryAndServeUDP listens for incoming requests on channel in and
// then calls QueryUDP with f to the handle the request.
// It returns a channel on which the response is returned.
func QueryAndServeUDP(in chan Query, f func(*Conn, *Msg, chan Query)) chan Query { func QueryAndServeUDP(in chan Query, f func(*Conn, *Msg, chan Query)) chan Query {
out := make(chan Query) out := make(chan Query)
go QueryUDP(in, out, f) go QueryUDP(in, out, f)