smaller api

This commit is contained in:
Miek Gieben 2011-02-11 20:54:54 +01:00
parent 00e55ef737
commit 58ccfe317b
3 changed files with 32 additions and 89 deletions

View File

@ -3,11 +3,11 @@
* recursive resolver. When queried for type TXT, it sends back the text
* form of the address. When queried for type A (resp. AAAA), it sends
* back the IPv4 (resp. v6) address.
*
*
* Similar services: whoami.ultradns.net, whoami.akamai.net. Also (but it
* is not their normal goal): rs.dns-oarc.net, porttest.dns-oarc.net,
* amiopen.openresolvers.org.
*
*
* Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>
*
* Adapted to Go DNS (i.e. completely rewritten)
@ -26,19 +26,12 @@ import (
"os/signal"
)
type server dns.Server
func reply(a net.Addr, in []byte, tcp bool) *dns.Msg {
inmsg := new(dns.Msg)
if !inmsg.Unpack(in) {
println("Unpacking failed")
return nil
}
if inmsg.MsgHdr.Response == true {
func reply(a net.Addr, in *dns.Msg, tcp bool) *dns.Msg {
if in.MsgHdr.Response == true {
return nil // Don't answer responses
}
m := new(dns.Msg)
m.MsgHdr.Id = inmsg.MsgHdr.Id
m.MsgHdr.Id = in.MsgHdr.Id
m.MsgHdr.Authoritative = true
m.MsgHdr.Response = true
m.MsgHdr.Opcode = dns.OpcodeQuery
@ -61,14 +54,13 @@ func reply(a net.Addr, in []byte, tcp bool) *dns.Msg {
t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
}
m.Question[0] = inmsg.Question[0]
m.Question[0] = in.Question[0]
m.Answer[0] = r
m.Extra[0] = t
return m
}
func (s *server) ReplyUDP(c *net.UDPConn, a net.Addr, in []byte) {
func replyUDP(c *net.UDPConn, a net.Addr, in *dns.Msg) {
m := reply(a, in, false)
if m == nil {
return
@ -82,8 +74,8 @@ func (s *server) ReplyUDP(c *net.UDPConn, a net.Addr, in []byte) {
dns.SendUDP(out, c, a)
}
func (s *server) ReplyTCP(c *net.TCPConn, a net.Addr, in []byte) {
m := reply(c.RemoteAddr(), in, true)
func replyTCP(c *net.TCPConn, a net.Addr, in *dns.Msg) {
m := reply(a, in, true)
if m == nil {
return
}
@ -96,26 +88,7 @@ func (s *server) ReplyTCP(c *net.TCPConn, a net.Addr, in []byte) {
dns.SendTCP(out, c, a)
}
func main() {
runtime.GOMAXPROCS(10) // Be bold
var srv *server
ch := make(chan bool)
e := make(chan os.Error)
go dns.ListenAndServe("127.0.0.1:8053", srv, ch, e)
forever:
for {
// Wait for a signal to stop
select {
case err := <-e:
fmt.Printf("Error: %s\n", err.String())
break forever
case <-signal.Incoming:
println("Signal received, stopping")
ch <- true
break forever
}
}
close(ch)
dns.ListenAndServeUDP("127.0.0.1:8053", replyUDP)
}

View File

@ -11,34 +11,7 @@ import (
"net"
)
type Server int // Doesn't really matter
// Wrap request in this struct
type Request struct {
Tcp bool // True for tcp, false for udp
Buf []byte // The received message
Addr net.Addr // Remote site
UDPConn *net.UDPConn // Connection for UDP
TCPConn *net.TCPConn // Connection for TCP
Error os.Error // Any errors that are found
}
// Every nameserver implements the Hander interface. It defines
// the kind of nameserver
type Handler interface {
// Receives the raw message content and writes back
// an UDP response. An UDP connection needs a remote
// address to write to. ServeUDP() must take care of sending
// any response back to the requestor.
ReplyUDP(c *net.UDPConn, a net.Addr, in []byte)
// Receives the raw message content and writes back
// a TCP response. A TCP connection does need to
// know explicitly be told the remote address. ServeTCP() must
// take care of sending back a response to the requestor.
ReplyTCP(c *net.TCPConn, a net.Addr, in []byte)
}
func ServeUDP(l *net.UDPConn, f func(*net.UDPConn, net.Addr, []byte)) os.Error {
func ServeUDP(l *net.UDPConn, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
for {
m := make([]byte, DefaultMsgSize)
n, radd, e := l.ReadFromUDP(m)
@ -46,12 +19,16 @@ func ServeUDP(l *net.UDPConn, f func(*net.UDPConn, net.Addr, []byte)) os.Error {
continue
}
m = m[:n]
go f(l, radd, m)
msg := new(Msg)
if ! msg.Unpack(m) {
continue
}
go f(l, radd, msg)
}
panic("not reached")
}
func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, []byte)) os.Error {
func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
b := make([]byte, 2)
for {
c, e := l.AcceptTCP()
@ -81,7 +58,11 @@ func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, []byte)) os.Err
}
i += n
}
go f(c, c.RemoteAddr(), m)
msg := new(Msg)
if ! msg.Unpack(m) {
continue
}
go f(c, c.RemoteAddr(), msg)
}
panic("not reached")
}
@ -105,7 +86,7 @@ func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, []byte)) os.Err
// ch := make(chan bool)
// dns.ListenAndServe("127.0.0.1:8053", m, ch)
// m <- true // stop the goroutine
func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, []byte)) os.Error {
func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
a, err := net.ResolveTCPAddr(addr)
if err != nil {
return err
@ -118,7 +99,7 @@ func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, []byte)) os.E
return err
}
func ListenAndServeUDP(addr string, f func(*net.UDPConn, net.Addr, []byte)) os.Error {
func ListenAndServeUDP(addr string, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
a, err := net.ResolveUDPAddr(addr)
if err != nil {
return err

View File

@ -3,12 +3,9 @@ package dns
import (
"testing"
"net"
"os"
"time"
)
type server int
func createpkg(id uint16, tcp bool, remove net.Addr) []byte {
m := new(Msg)
m.MsgHdr.Id = id
@ -33,35 +30,27 @@ func createpkg(id uint16, tcp bool, remove net.Addr) []byte {
return out
}
func (h *server) ReplyUDP(c *net.UDPConn, a net.Addr, in []byte) {
inmsg := new(Msg)
inmsg.Unpack(in)
if inmsg.MsgHdr.Response == true {
func replyUDP(c *net.UDPConn, a net.Addr, in *Msg) {
if in.MsgHdr.Response == true {
// Uh... answering to an response??
// dont think so
return
}
out := createpkg(inmsg.MsgHdr.Id, false, a)
out := createpkg(in.MsgHdr.Id, false, a)
SendUDP(out, c, a)
}
func (h *server) ReplyTCP(c *net.TCPConn, a net.Addr, in []byte) {
inmsg := new(Msg)
inmsg.Unpack(in)
if inmsg.MsgHdr.Response == true {
func replyTCP(c *net.TCPConn, a net.Addr, in *Msg) {
if in.MsgHdr.Response == true {
return
}
out := createpkg(inmsg.MsgHdr.Id, true, a)
out := createpkg(in.MsgHdr.Id, true, a)
SendTCP(out, c, a)
}
func TestResponder(t *testing.T) {
var h *server
quit := make(chan bool)
e := make(chan os.Error)
go ListenAndServe("127.0.0.1:8053", h, quit, e)
// ListenAndServeTCP("127.0.0.1:8053", replyTCP)
time.Sleep(2 * 1e9)
quit <- true
}
/*