smaller api
This commit is contained in:
parent
00e55ef737
commit
58ccfe317b
|
@ -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)
|
||||
}
|
||||
|
|
47
server.go
47
server.go
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue