dns_server.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package main
  2. import (
  3. "github.com/miekg/dns"
  4. "henrymail/config"
  5. "henrymail/dkim"
  6. "henrymail/spf"
  7. "log"
  8. "net"
  9. "strings"
  10. )
  11. /**
  12. * Fake DNS server for local testing.
  13. * This lets us pretend that our DKIM and TXT records are right
  14. */
  15. func StartFakeDns(addr, proto string) {
  16. s := &dns.Server{
  17. Addr: addr,
  18. Net: proto,
  19. }
  20. dns.HandleFunc(config.GetString(config.Domain)+".", func(writer dns.ResponseWriter, r *dns.Msg) {
  21. //log.Printf("Request %v", r)
  22. m := new(dns.Msg)
  23. m.SetReply(r)
  24. for _, q := range r.Question {
  25. switch q.Qtype {
  26. case dns.TypeA:
  27. m.Answer = append(m.Answer, &dns.A{
  28. Hdr: dns.RR_Header{Name: q.Name, Rrtype: q.Qtype, Class: dns.ClassINET, Ttl: 0},
  29. A: net.IPv4(127, 0, 0, 1),
  30. })
  31. case dns.TypeMX:
  32. m.Answer = append(m.Answer, &dns.MX{
  33. Hdr: dns.RR_Header{Name: q.Name, Rrtype: q.Qtype, Class: dns.ClassINET, Ttl: 0},
  34. Preference: 10,
  35. Mx: config.GetString(config.ServerName) + ".",
  36. })
  37. case dns.TypeTXT:
  38. result := ""
  39. if strings.Contains(q.Name, "mx._domainkey.") {
  40. result, _ = dkim.GetDkimRecordString()
  41. } else {
  42. result = spf.GetSpfRecordString()
  43. }
  44. m.Answer = append(m.Answer, &dns.TXT{
  45. Hdr: dns.RR_Header{Name: q.Name, Rrtype: q.Qtype, Class: dns.ClassINET, Ttl: 0},
  46. Txt: chunk(result, 255),
  47. })
  48. }
  49. }
  50. //log.Printf("Reply %v", m)
  51. e := writer.WriteMsg(m)
  52. if e != nil {
  53. log.Print(e)
  54. }
  55. })
  56. go func() { log.Fatal(s.ListenAndServe()) }()
  57. log.Printf("Started FAKE DNS SERVER at " + config.GetString(config.FakeDnsAddress))
  58. }
  59. func chunk(buf string, lim int) []string {
  60. var chunk string
  61. chunks := make([]string, 0, len(buf)/lim+1)
  62. for len(buf) >= lim {
  63. chunk, buf = buf[:lim], buf[lim:]
  64. chunks = append(chunks, chunk)
  65. }
  66. if len(buf) > 0 {
  67. chunks = append(chunks, buf[:len(buf)])
  68. }
  69. return chunks
  70. }