func (s *Server) Query(ctx context.Context, in *pb.RawMsg) (*pb.RawMsg, error) { tr := trace.New("grpctodns", "Query") defer tr.Finish() r := &dns.Msg{} err := r.Unpack(in.Data) if err != nil { return nil, err } if glog.V(3) { tr.LazyPrintf(util.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 { msg := fmt.Sprintf("dns exchange error: %v", err) glog.Info(msg) tr.LazyPrintf(msg) tr.SetError() return nil, err } if from_up == nil { err = fmt.Errorf("no response from upstream") tr.LazyPrintf(err.Error()) tr.SetError() return nil, err } if glog.V(3) { util.TraceAnswer(tr, from_up) } buf, err := from_up.Pack() if err != nil { glog.Infof(" error packing: %v", err) tr.LazyPrintf("error packing: %v", err) tr.SetError() return nil, err } return &pb.RawMsg{Data: buf}, nil }
func (s *Server) Handler(w dns.ResponseWriter, r *dns.Msg) { tr := trace.New("dnstox", "Handler") defer tr.Finish() tr.LazyPrintf("from:%v id:%v", w.RemoteAddr(), r.Id) if glog.V(3) { tr.LazyPrintf(util.QuestionsToString(r.Question)) } // We only support single-question queries. if len(r.Question) != 1 { tr.LazyPrintf("len(Q) != 1, failing") dns.HandleFailed(w, r) return } // Forward to the unqualified upstream server if: // - We have one configured. // - There's only one question in the request, to keep things simple. // - The question is unqualified (only one '.' in the name). useUnqUpstream := s.unqUpstream != "" && strings.Count(r.Question[0].Name, ".") <= 1 if useUnqUpstream { u, err := dns.Exchange(r, s.unqUpstream) if err == nil { tr.LazyPrintf("used unqualified upstream") if glog.V(3) { util.TraceAnswer(tr, u) } w.WriteMsg(u) } else { tr.LazyPrintf("unqualified upstream error: %v", err) dns.HandleFailed(w, r) } return } // Forward to the fallback server if the domain is on our list. if _, ok := s.fallbackDomains[r.Question[0].Name]; ok { u, err := dns.Exchange(r, s.fallbackUpstream) if err == nil { tr.LazyPrintf("used fallback upstream (%s)", s.fallbackUpstream) if glog.V(3) { util.TraceAnswer(tr, u) } w.WriteMsg(u) } else { tr.LazyPrintf("fallback upstream error: %v", err) dns.HandleFailed(w, r) } return } // Create our own IDs, in case different users pick the same id and we // pass that upstream. oldid := r.Id r.Id = <-newId from_up, err := s.resolver.Query(r, tr) if err != nil { glog.Infof(err.Error()) tr.LazyPrintf(err.Error()) tr.SetError() return } if glog.V(3) { util.TraceAnswer(tr, from_up) } from_up.Id = oldid w.WriteMsg(from_up) }