I am using go mongo driver in my sample go application to connect with the help of srv connection string. Currently I have a proxy that intercepts the dns calls and returns custom response. I believe I am doing something wrong with returning responses as I am getting the below error
2025/03/04 19:26:59 Could not connect to MongoDB: server selection error: context deadline exceeded, current topology: { Type: Unknown, Servers: [{ Addr: cluster0.sjlpojg.mongodb.net:16789, Type: Unknown }, ] }
here is the serveDNS function from my dns.go
func (p *Proxy) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
p.logger.Debug("", zap.Any("Source socket info", w.RemoteAddr().String()))
msg := new(dns.Msg)
msg.SetReply(r)
msg.Authoritative = true
p.logger.Debug("Got some Dns queries")
for _, question := range r.Question {
p.logger.Debug("", zap.Any("Record Type", question.Qtype), zap.Any("Received Query", question.Name))
key := generateCacheKey(question.Name, question.Qtype)
// Check if the answer is cached
cache.RLock()
answers, found := cache.m[key]
cache.RUnlock()
if found {
p.logger.Info(fmt.Sprintf("Answers[found in cache]:\n%s\n", key))
}
if !found {
// If not found in cache, resolve the DNS query only in case of record mode
//TODO: Add support for passThrough here using the src<->dst mapping
if models.GetMode() == models.MODE_RECORD {
answers = resolveDNSQuery(p.logger, question.Name)
}
if len(answers) == 0 {
// If the resolution failed, return a default A record with Proxy IP
if question.Qtype == dns.TypeA {
answers = []dns.RR{&dns.A{
Hdr: dns.RR_Header{Name: question.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 3600},
A: net.ParseIP(p.IP4),
}}
p.logger.Debug("failed to resolve dns query hence sending proxy ip4", zap.Any("proxy Ip", p.IP4))
} else if question.Qtype == dns.TypeAAAA {
answers = []dns.RR{&dns.AAAA{
Hdr: dns.RR_Header{Name: question.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 3600},
AAAA: net.ParseIP(p.IP6),
}}
p.logger.Debug("failed to resolve dns query hence sending proxy ip6", zap.Any("proxy Ip", p.IP6))
} else if question.Qtype == dns.TypeSRV {
answers = []dns.RR{&dns.SRV{
Hdr: dns.RR_Header{Name: question.Name, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: 3600},
Priority: 0,
Weight: 0,
Port: uint16(p.Port),
Target: dns.Fqdn("cluster0.sjlpojg.mongodb.net"),
}}
fmt.Println("question name: ", question.Name)
p.logger.Debug("sending default SRV record response")
} else if question.Qtype == dns.TypeTXT {
answers = []dns.RR{&dns.TXT{
Hdr: dns.RR_Header{Name: question.Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 3600},
Txt: []string{"authsource=KeployTest"},
}}
p.logger.Debug("sending default TXT record response")
}
p.logger.Debug(fmt.Sprintf("Answers[when resolution failed for query:%v]:\n%v\n", question.Qtype, answers))
}
// Cache the answer
cache.Lock()
cache.m[key] = answers
cache.Unlock()
p.logger.Debug(fmt.Sprintf("Answers[after caching it]:\n%v\n", answers))
}
p.logger.Debug(fmt.Sprintf("Answers[before appending to msg]:\n%v\n", answers))
msg.Answer = append(msg.Answer, answers...)
p.logger.Debug(fmt.Sprintf("Answers[After appending to msg]:\n%v\n", msg.Answer))
}
p.logger.Debug(fmt.Sprintf("dns msg sending back:\n%v\n", msg))
p.logger.Debug(fmt.Sprintf("dns msg RCODE sending back:\n%v\n", msg.Rcode))
p.logger.Debug("Writing dns info back to the client...")
err := w.WriteMsg(msg)
if err != nil {
utils.LogError(p.logger, err, "failed to write dns info back to the client")
}
}