mirror of
https://github.com/miekg/dns.git
synced 2025-10-12 02:11:13 +02:00
94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
// Copyright 2011 Miek Gieben. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// DNS resolver client: see RFC 1035.
|
|
|
|
package dns
|
|
|
|
import (
|
|
"os"
|
|
)
|
|
|
|
// Request a query by sending to this channel.
|
|
var QueryRequest chan Query // *Query
|
|
// Listen for replies on this channel.
|
|
var QueryReply chan Query
|
|
|
|
// Query is used to communicate with the Query* functions.
|
|
type Query struct {
|
|
// The query message.
|
|
Query *Msg
|
|
// The reply message.
|
|
Reply *Msg
|
|
// A Conn. Its only required to fill out Conn.RemoteAddr.
|
|
// Optionally you may set Conn.Tsig if TSIG is required.
|
|
// The rest of the structure is filled by the Query functions.
|
|
Conn *Conn
|
|
//
|
|
Err os.Error
|
|
}
|
|
|
|
// Initialize the QueryRequest and QueryReply
|
|
// channels.
|
|
func QueryInitChannels() {
|
|
QueryRequest = make(chan Query)
|
|
QueryReply = make(chan Query)
|
|
}
|
|
|
|
|
|
// QueryAndServeTCP listens for incoming requests on channel in and
|
|
// then calls f.
|
|
// The function f is executed in a seperate goroutine and performs the actual
|
|
// TCP query.
|
|
func QueryAndServeTCP(f func(*Conn, *Msg)) os.Error {
|
|
if f == nil {
|
|
return ErrHandle
|
|
}
|
|
if QueryReply == nil || QueryRequest == nil {
|
|
return ErrChan
|
|
}
|
|
query("tcp", f)
|
|
return nil
|
|
}
|
|
|
|
// QueryAndServeUDP listens for incoming requests on channel in and
|
|
// then calls f.
|
|
// The function f is executed in a seperate goroutine and performs the actual
|
|
// UDP query.
|
|
func QueryAndServeUDP(f func(*Conn, *Msg)) os.Error {
|
|
if f == nil {
|
|
return ErrHandle
|
|
}
|
|
if QueryReply == nil || QueryRequest == nil {
|
|
return ErrChan
|
|
}
|
|
query("udp", f)
|
|
return nil
|
|
}
|
|
|
|
func query(n string, f func(*Conn, *Msg)) {
|
|
for {
|
|
select {
|
|
case q := <-QueryRequest:
|
|
err := q.Conn.Dial(n)
|
|
if err != nil {
|
|
QueryReply <- Query{Err: err}
|
|
}
|
|
go f(q.Conn, q.Query)
|
|
}
|
|
}
|
|
panic("not reached")
|
|
}
|
|
|
|
// Simple query function that waits for and returns the reply.
|
|
func QuerySimple(n string, d *Conn, m *Msg) (*Msg, os.Error) {
|
|
err := d.Dial(n)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
o, err := d.ExchangeMsg(m, false)
|
|
d.Close()
|
|
return o, err
|
|
}
|