extension_edns0_subnet.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package dns
  2. import (
  3. "net/netip"
  4. "github.com/miekg/dns"
  5. )
  6. func SetClientSubnet(message *dns.Msg, clientSubnet netip.Prefix) *dns.Msg {
  7. return setClientSubnet(message, clientSubnet, true)
  8. }
  9. func setClientSubnet(message *dns.Msg, clientSubnet netip.Prefix, clone bool) *dns.Msg {
  10. var (
  11. optRecord *dns.OPT
  12. subnetOption *dns.EDNS0_SUBNET
  13. )
  14. findExists:
  15. for _, record := range message.Extra {
  16. var isOPTRecord bool
  17. if optRecord, isOPTRecord = record.(*dns.OPT); isOPTRecord {
  18. for _, option := range optRecord.Option {
  19. var isEDNS0Subnet bool
  20. subnetOption, isEDNS0Subnet = option.(*dns.EDNS0_SUBNET)
  21. if isEDNS0Subnet {
  22. break findExists
  23. }
  24. }
  25. }
  26. }
  27. if optRecord == nil {
  28. exMessage := *message
  29. message = &exMessage
  30. optRecord = &dns.OPT{
  31. Hdr: dns.RR_Header{
  32. Name: ".",
  33. Rrtype: dns.TypeOPT,
  34. },
  35. }
  36. message.Extra = append(message.Extra, optRecord)
  37. } else if clone {
  38. return setClientSubnet(message.Copy(), clientSubnet, false)
  39. }
  40. if subnetOption == nil {
  41. subnetOption = new(dns.EDNS0_SUBNET)
  42. subnetOption.Code = dns.EDNS0SUBNET
  43. optRecord.Option = append(optRecord.Option, subnetOption)
  44. }
  45. if clientSubnet.Addr().Is4() {
  46. subnetOption.Family = 1
  47. } else {
  48. subnetOption.Family = 2
  49. }
  50. subnetOption.SourceNetmask = uint8(clientSubnet.Bits())
  51. subnetOption.Address = clientSubnet.Addr().AsSlice()
  52. return message
  53. }