extension_edns0_subnet.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package dns
  2. import (
  3. "net/netip"
  4. "github.com/miekg/dns"
  5. )
  6. func SetClientSubnet(message *dns.Msg, clientSubnet netip.Prefix, override bool) *dns.Msg {
  7. var (
  8. optRecord *dns.OPT
  9. subnetOption *dns.EDNS0_SUBNET
  10. )
  11. findExists:
  12. for _, record := range message.Extra {
  13. var isOPTRecord bool
  14. if optRecord, isOPTRecord = record.(*dns.OPT); isOPTRecord {
  15. for _, option := range optRecord.Option {
  16. var isEDNS0Subnet bool
  17. subnetOption, isEDNS0Subnet = option.(*dns.EDNS0_SUBNET)
  18. if isEDNS0Subnet {
  19. if !override {
  20. return message
  21. }
  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 {
  38. message = message.Copy()
  39. }
  40. if subnetOption == nil {
  41. subnetOption = new(dns.EDNS0_SUBNET)
  42. optRecord.Option = append(optRecord.Option, subnetOption)
  43. }
  44. subnetOption.Code = dns.EDNS0SUBNET
  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. }