author | Alberto Bertogli
<albertito@blitiri.com.ar> 2015-09-06 22:14:22 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2015-09-06 22:14:22 UTC |
parent | 94ba7d7f57d888333a018f256bdafc97600b4279 |
dnss.go | +32 | -3 |
dnstogrpc/dnstogrpc.go | +5 | -6 |
grpctodns/grpctodns.go | +81 | -0 |
diff --git a/dnss.go b/dnss.go index ea6df66..9c30f84 100644 --- a/dnss.go +++ b/dnss.go @@ -5,14 +5,23 @@ package main import ( "flag" + "sync" "blitiri.com.ar/go/dnss/dnstogrpc" + "blitiri.com.ar/go/dnss/grpctodns" "blitiri.com.ar/go/profile" ) var ( - dnsaddr = flag.String("dnsaddr", ":53", "address to listen on") - dnsupstream = flag.String("dnsupstream", "8.8.8.8:53", "upstream address") + dnsaddr = flag.String("dnsaddr", ":53", + "address to listen on for DNS") + grpcupstream = flag.String("grpcupstream", "localhost:9953", + "address of the upstream GRPC server") + + grpcaddr = flag.String("grpcaddr", ":9953", + "address to listen on for GRPC") + dnsupstream = flag.String("dnsupstream", "8.8.8.8:53", + "address of the upstream DNS server") ) func main() { @@ -20,9 +29,29 @@ func main() { profile.Init() + var wg sync.WaitGroup + + // DNS to GRPC. dtg := &dnstogrpc.Server{ Addr: *dnsaddr, + Upstream: *grpcupstream, + } + wg.Add(1) + go func() { + defer wg.Done() + dtg.ListenAndServe() + }() + + // GRPC to DNS. + gtd := &grpctodns.Server{ + Addr: *grpcaddr, Upstream: *dnsupstream, } - dtg.ListenAndServe() + wg.Add(1) + go func() { + defer wg.Done() + gtd.ListenAndServe() + }() + + wg.Wait() } diff --git a/dnstogrpc/dnstogrpc.go b/dnstogrpc/dnstogrpc.go index ced0d05..e59c59f 100644 --- a/dnstogrpc/dnstogrpc.go +++ b/dnstogrpc/dnstogrpc.go @@ -38,25 +38,24 @@ type Server struct { } func (s *Server) Handler(w dns.ResponseWriter, r *dns.Msg) { - fmt.Printf("%v %v\n", l(w, r), questionsToString(r.Question)) + fmt.Printf("DNS %v %v\n", l(w, r), questionsToString(r.Question)) // TODO: we should create our own IDs, in case different users pick the // same id and we pass that upstream. from_up, err := dns.Exchange(r, s.Upstream) if err != nil { - fmt.Printf("%v ERR: %v\n", l(w, r), err) - fmt.Printf("%v UP: %v\n", l(w, r), from_up) + fmt.Printf("DNS %v ERR: %v\n", l(w, r), err) + fmt.Printf("DNS %v UP: %v\n", l(w, r), from_up) } if from_up != nil { if from_up.Rcode != dns.RcodeSuccess { rcode := dns.RcodeToString[from_up.Rcode] - fmt.Printf("%v !-> %v\n", l(w, r), rcode) - + fmt.Printf("DNS %v !-> %v\n", l(w, r), rcode) } for _, rr := range from_up.Answer { - fmt.Printf("%v -> %v\n", l(w, r), rr) + fmt.Printf("DNS %v -> %v\n", l(w, r), rr) } w.WriteMsg(from_up) } diff --git a/grpctodns/grpctodns.go b/grpctodns/grpctodns.go new file mode 100644 index 0000000..37771fc --- /dev/null +++ b/grpctodns/grpctodns.go @@ -0,0 +1,81 @@ +// GRPC to DNS. + +package grpctodns + +import ( + "fmt" + "strings" + "sync" + + "github.com/miekg/dns" +) + +func questionsToString(qs []dns.Question) string { + var s []string + for _, q := range qs { + s = append(s, fmt.Sprintf("(%s %s %s)", q.Name, + dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass])) + } + return "Q[" + strings.Join(s, " ") + "]" +} + +func rrsToString(rrs []dns.RR) string { + var s []string + for _, rr := range rrs { + s = append(s, fmt.Sprintf("(%s)", rr)) + } + return "RR[" + strings.Join(s, " ") + "]" + +} + +func l(w dns.ResponseWriter, r *dns.Msg) string { + return fmt.Sprintf("%v %v", w.RemoteAddr(), r.Id) +} + +type Server struct { + Addr string + Upstream string +} + +func (s *Server) Handler(w dns.ResponseWriter, r *dns.Msg) { + fmt.Printf("GRPC %v %v\n", l(w, r), questionsToString(r.Question)) + + // TODO: we should create our own IDs, in case different users pick the + // same id and we pass that upstream. + + from_up, err := dns.Exchange(r, s.Upstream) + if err != nil { + fmt.Printf("GRPC %v ERR: %v\n", l(w, r), err) + fmt.Printf("GRPC %v UP: %v\n", l(w, r), from_up) + } + + if from_up != nil { + if from_up.Rcode != dns.RcodeSuccess { + rcode := dns.RcodeToString[from_up.Rcode] + fmt.Printf("GPRC %v !-> %v\n", l(w, r), rcode) + } + for _, rr := range from_up.Answer { + fmt.Printf("GRPC %v -> %v\n", l(w, r), rr) + } + w.WriteMsg(from_up) + } +} + +func (s *Server) ListenAndServe() { + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + err := dns.ListenAndServe(s.Addr, "udp", dns.HandlerFunc(s.Handler)) + fmt.Printf("Exiting UDP: %v\n", err) + }() + + wg.Add(1) + go func() { + defer wg.Done() + err := dns.ListenAndServe(s.Addr, "tcp", dns.HandlerFunc(s.Handler)) + fmt.Printf("Exiting TCP: %v\n", err) + }() + + wg.Wait() +}