acceptfunc.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package dns
  2. // MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError.
  3. // It returns a MsgAcceptAction to indicate what should happen with the message.
  4. type MsgAcceptFunc func(dh Header) MsgAcceptAction
  5. // DefaultMsgAcceptFunc checks the request and will reject if:
  6. //
  7. // * isn't a request (don't respond in that case)
  8. //
  9. // * opcode isn't OpcodeQuery or OpcodeNotify
  10. //
  11. // * Zero bit isn't zero
  12. //
  13. // * has more than 1 question in the question section
  14. //
  15. // * has more than 1 RR in the Answer section
  16. //
  17. // * has more than 0 RRs in the Authority section
  18. //
  19. // * has more than 2 RRs in the Additional section
  20. //
  21. var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
  22. // MsgAcceptAction represents the action to be taken.
  23. type MsgAcceptAction int
  24. // Allowed returned values from a MsgAcceptFunc.
  25. const (
  26. MsgAccept MsgAcceptAction = iota // Accept the message
  27. MsgReject // Reject the message with a RcodeFormatError
  28. MsgIgnore // Ignore the error and send nothing back.
  29. MsgRejectNotImplemented // Reject the message with a RcodeNotImplemented
  30. )
  31. func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {
  32. if isResponse := dh.Bits&_QR != 0; isResponse {
  33. return MsgIgnore
  34. }
  35. // Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs.
  36. opcode := int(dh.Bits>>11) & 0xF
  37. if opcode != OpcodeQuery && opcode != OpcodeNotify {
  38. return MsgRejectNotImplemented
  39. }
  40. if dh.Qdcount != 1 {
  41. return MsgReject
  42. }
  43. // NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11.
  44. if dh.Ancount > 1 {
  45. return MsgReject
  46. }
  47. // IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3.
  48. if dh.Nscount > 1 {
  49. return MsgReject
  50. }
  51. if dh.Arcount > 2 {
  52. return MsgReject
  53. }
  54. return MsgAccept
  55. }