acceptfunc.go raw

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