From 22dade9e129592ef42687db9bf85d8b1f8db2580 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Tue, 22 Mar 2016 08:30:30 +0000 Subject: [PATCH] It compiles; wont work obviously --- middleware/etcd/lookup.go | 67 ++++++++++++++++----------------- middleware/proxy/lookup_test.go | 35 +++++++++++++++++ 2 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 middleware/proxy/lookup_test.go diff --git a/middleware/etcd/lookup.go b/middleware/etcd/lookup.go index e7b684307..c9ad54d4f 100644 --- a/middleware/etcd/lookup.go +++ b/middleware/etcd/lookup.go @@ -6,6 +6,7 @@ import ( "github.com/miekg/coredns/middleware" "github.com/miekg/coredns/middleware/etcd/msg" + "github.com/miekg/dns" ) @@ -39,10 +40,9 @@ func (e Etcd) AddressRecords(zone string, state middleware.State, previousRecord continue } - // Fucks up recursion, need to define this in the function - // are use another var - state.Req.Question[0] = dns.Question{Name: dns.Fqdn(serv.Host), Qtype: state.QType(), Qclass: state.QClass()} - nextRecords, err := e.AddressRecords(zone, state, append(previousRecords, newRecord)) + state1 := copyState(state, serv.Host, state.QType()) + nextRecords, err := e.AddressRecords(zone, state1, append(previousRecords, newRecord)) + if err == nil { // Only have we found something we should add the CNAME and the IP addresses. if len(nextRecords) > 0 { @@ -65,6 +65,7 @@ func (e Etcd) AddressRecords(zone string, state middleware.State, previousRecord records = append(records, newRecord) records = append(records, m1.Answer...) continue + // both here again case ip.To4() != nil && (state.QType() == dns.TypeA): records = append(records, serv.NewA(state.QName(), ip.To4())) case ip.To4() == nil && (state.QType() == dns.TypeAAAA): @@ -77,7 +78,7 @@ func (e Etcd) AddressRecords(zone string, state middleware.State, previousRecord // SRVRecords returns SRV records from etcd. // If the Target is not a name but an IP address, a name is created on the fly. func (e Etcd) SRVRecords(zone string, state middleware.State) (records []dns.RR, extra []dns.RR, err error) { - services, err := e.Records(name, false) + services, err := e.Records(state.Name(), false) if err != nil { return nil, nil, err } @@ -137,20 +138,21 @@ func (e Etcd) SRVRecords(zone string, state middleware.State) (records []dns.RR, // Internal name, we should have some info on them, either v4 or v6 // Clients expect a complete answer, because we are a recursor in their // view. - addr, e1 := e.AddressRecords(dns.Question{srv.Target, dns.ClassINET, dns.TypeA}, - srv.Target, nil, bufsize, dnssec, true) + state1 := copyState(state, srv.Target, dns.TypeA) + // TODO(both is true here! + addr, e1 := e.AddressRecords(zone, state1, nil) if e1 == nil { extra = append(extra, addr...) } case ip.To4() != nil: - serv.Host = msg.Domain(serv.Key) - srv := serv.NewSRV(q.Name, weight) + serv.Host = e.Domain(serv.Key) + srv := serv.NewSRV(state.QName(), weight) records = append(records, srv) extra = append(extra, serv.NewA(srv.Target, ip.To4())) case ip.To4() == nil: - serv.Host = msg.Domain(serv.Key) - srv := serv.NewSRV(q.Name, weight) + serv.Host = e.Domain(serv.Key) + srv := serv.NewSRV(state.QName(), weight) records = append(records, srv) extra = append(extra, serv.NewAAAA(srv.Target, ip.To16())) @@ -162,7 +164,7 @@ func (e Etcd) SRVRecords(zone string, state middleware.State) (records []dns.RR, // MXRecords returns MX records from etcd. // If the Target is not a name but an IP address, a name is created on the fly. func (e Etcd) MXRecords(zone string, state middleware.State) (records []dns.RR, extra []dns.RR, err error) { - services, err := e.Records(name, false) + services, err := e.Records(state.Name(), false) if err != nil { return nil, nil, err } @@ -175,7 +177,7 @@ func (e Etcd) MXRecords(zone string, state middleware.State) (records []dns.RR, ip := net.ParseIP(serv.Host) switch { case ip == nil: - mx := serv.NewMX(q.Name) + mx := serv.NewMX(state.QName()) records = append(records, mx) if _, ok := lookup[mx.Mx]; ok { break @@ -183,7 +185,7 @@ func (e Etcd) MXRecords(zone string, state middleware.State) (records []dns.RR, lookup[mx.Mx] = true - if !dns.IsSubDomain(s.config.Domain, mx.Mx) { + if !dns.IsSubDomain(zone, mx.Mx) { m1, e1 := e.Proxy.Lookup(state, mx.Mx, dns.TypeA) if e1 == nil { extra = append(extra, m1.Answer...) @@ -200,18 +202,19 @@ func (e Etcd) MXRecords(zone string, state middleware.State) (records []dns.RR, break } // Internal name - addr, e1 := s.AddressRecords(dns.Question{mx.Mx, dns.ClassINET, dns.TypeA}, - mx.Mx, nil, bufsize, dnssec, true) + // both is true here as well + state1 := copyState(state, mx.Mx, dns.TypeA) + addr, e1 := e.AddressRecords(zone, state1, nil) if e1 == nil { extra = append(extra, addr...) } case ip.To4() != nil: - serv.Host = msg.Domain(serv.Key) - records = append(records, serv.NewMX(q.Name)) + serv.Host = e.Domain(serv.Key) + records = append(records, serv.NewMX(state.QName())) extra = append(extra, serv.NewA(serv.Host, ip.To4())) case ip.To4() == nil: - serv.Host = msg.Domain(serv.Key) - records = append(records, serv.NewMX(q.Name)) + serv.Host = e.Domain(serv.Key) + records = append(records, serv.NewMX(state.QName())) extra = append(extra, serv.NewAAAA(serv.Host, ip.To16())) } } @@ -219,7 +222,7 @@ func (e Etcd) MXRecords(zone string, state middleware.State) (records []dns.RR, } func (e Etcd) CNAMERecords(zone string, state middleware.State) (records []dns.RR, err error) { - services, err := e.Records(name, true) + services, err := e.Records(state.Name(), true) if err != nil { return nil, err } @@ -229,7 +232,7 @@ func (e Etcd) CNAMERecords(zone string, state middleware.State) (records []dns.R if len(services) > 0 { serv := services[0] if ip := net.ParseIP(serv.Host); ip == nil { - records = append(records, serv.NewCNAME(q.Name, dns.Fqdn(serv.Host))) + records = append(records, serv.NewCNAME(state.QName(), dns.Fqdn(serv.Host))) } } return records, nil @@ -247,7 +250,7 @@ func (e Etcd) TXTRecords(zone string, state middleware.State) (records []dns.RR, if serv.Text == "" { continue } - records = append(records, serv.NewTXT(q.Name)) + records = append(records, serv.NewTXT(state.QName())) } return records, nil } @@ -263,6 +266,12 @@ func isDuplicateCNAME(r *dns.CNAME, records []dns.RR) bool { return false } +func copyState(state middleware.State, target string, typ uint16) middleware.State { + state1 := state + state1.Req.Question[0] = dns.Question{dns.Fqdn(target), dns.ClassINET, typ} + return state1 +} + /* // Move to state.go somehow? func (s *server) NameError(req *dns.Msg) *dns.Msg { @@ -272,16 +281,4 @@ func (s *server) NameError(req *dns.Msg) *dns.Msg { m.Ns[0].Header().Ttl = s.config.MinTtl return m } - -// etcNameError return a NameError to the client if the error -// returned from etcd has ErrorCode == 100. -func isEtcdNameError(err error, s *server) bool { - if e, ok := err.(etcd.Error); ok && e.Code == etcd.ErrorCodeKeyNotFound { - return true - } - if err != nil { - logf("error from backend: %s", err) - } - return false -} */ diff --git a/middleware/proxy/lookup_test.go b/middleware/proxy/lookup_test.go new file mode 100644 index 000000000..7ac100789 --- /dev/null +++ b/middleware/proxy/lookup_test.go @@ -0,0 +1,35 @@ +package proxy + +import ( + "io/ioutil" + "log" + "os" + "testing" + + "github.com/miekg/coredns/middleware" + "github.com/miekg/dns" +) + +func TestLookupProxy(t *testing.T) { + // TODO(miek): make this fakeDNS backend and ask the question locally + log.SetOutput(ioutil.Discard) + defer log.SetOutput(os.Stderr) + + p := New([]string{"8.8.8.8:53"}) + fakestate := fakeState() + resp, err := p.Lookup(fakestate, "example.org.", dns.TypeA) + if err != nil { + t.Error("Expected to receive reply, but didn't") + } + // expect answer section with A record in it + if len(resp.Answer) == 0 { + t.Error("Expected to at least one RR in the answer section, got none") + } + if resp.Answer[0].Header().Rrtype != dns.TypeA { + t.Error("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype) + } +} + +func fakeState() middleware.State { + return middleware.State{W: &middleware.TestResponseWriter{}, Req: new(dns.Msg)} +}