dns/_examples/reflect/reflect.go

114 lines
2.5 KiB
Go
Raw Normal View History

2011-01-18 02:11:11 +11:00
/*
* A name server which sends back the IP address of its client, the
* 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.
2011-02-12 06:54:54 +11:00
*
2011-01-18 02:11:11 +11:00
* 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.
2011-02-12 06:54:54 +11:00
*
2011-01-18 02:11:11 +11:00
* Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>
*
* Adapted to Go DNS (i.e. completely rewritten)
* Miek Gieben <miek@miek.nl>
*/
package main
import (
"os"
2011-01-18 02:11:11 +11:00
"net"
"dns"
2011-02-12 07:29:40 +11:00
"fmt"
2011-03-22 08:53:15 +11:00
"os/signal"
"strconv"
2011-01-18 02:11:11 +11:00
)
2011-03-22 08:53:15 +11:00
func reply(c *dns.Conn, in *dns.Msg) []byte {
m := new(dns.Msg)
2011-03-24 19:31:50 +11:00
m.SetReply(in)
2011-01-18 02:11:11 +11:00
m.Question = make([]dns.Question, 1)
m.Answer = make([]dns.RR, 1)
m.Extra = make([]dns.RR, 1)
2011-01-18 02:11:11 +11:00
2011-03-24 19:31:50 +11:00
// Copy the question.
2011-03-22 08:53:15 +11:00
m.Question[0] = in.Question[0]
2011-03-24 19:31:50 +11:00
// Some foo to check if we are called through ip6 or ip4.
// We add the correct reply RR.
var ad net.IP
if c.UDP != nil {
ad = c.Addr.(*net.UDPAddr).IP
} else {
ad = c.Addr.(*net.TCPAddr).IP
}
2011-03-22 08:59:50 +11:00
2011-03-24 19:31:50 +11:00
if ad.To4() != nil {
r := new(dns.RR_A)
r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
r.A = ad
m.Answer[0] = r
} else {
r := new(dns.RR_AAAA)
r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0}
r.AAAA = ad
m.Answer[0] = r
}
2011-01-18 02:11:11 +11:00
t := new(dns.RR_TXT)
t.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
2011-03-22 08:53:15 +11:00
if c.TCP != nil {
t.Txt = "Port: " + strconv.Itoa(c.Port) + " (tcp)"
} else {
2011-03-22 08:53:15 +11:00
t.Txt = "Port: " + strconv.Itoa(c.Port) + " (udp)"
}
m.Extra[0] = t
2011-03-22 08:53:15 +11:00
b, _ := m.Pack()
2011-03-24 19:31:50 +11:00
return b
2011-01-18 02:11:11 +11:00
}
2011-03-22 08:53:15 +11:00
func handle(c *dns.Conn, in *dns.Msg) {
if in.MsgHdr.Response == true {
2011-03-24 19:31:50 +11:00
return // We don't do responses
}
2011-03-22 08:53:15 +11:00
answer := reply(c, in)
c.Write(answer)
2011-01-18 02:11:11 +11:00
}
2011-02-12 07:46:35 +11:00
func tcp(addr string, e chan os.Error) {
2011-03-22 08:53:15 +11:00
err := dns.ListenAndServeTCP(addr, handle)
2011-02-12 07:29:40 +11:00
e <- err
return
}
2011-02-12 07:46:35 +11:00
func udp(addr string, e chan os.Error) {
2011-03-24 19:31:50 +11:00
err := dns.ListenAndServeUDP(addr, handle)
2011-02-12 07:29:40 +11:00
e <- err
return
}
2011-02-12 06:54:54 +11:00
func main() {
2011-02-12 07:29:40 +11:00
e := make(chan os.Error)
2011-02-12 07:46:35 +11:00
go udp("127.0.0.1:8053", e)
2011-02-22 03:57:50 +11:00
go udp("[::1]:8053", e)
2011-02-12 07:46:35 +11:00
go tcp("127.0.0.1:8053", e)
2011-02-22 03:57:50 +11:00
go tcp("[::1]:8053", e)
2011-02-12 07:29:40 +11:00
forever:
for {
// Wait for a signal to stop
select {
case err := <-e:
fmt.Printf("Error received, stopping: %s\n", err.String())
break forever
case <-signal.Incoming:
fmt.Printf("Signal received, stopping\n")
break forever
}
}
close(e)
2011-01-18 02:11:11 +11:00
}