code: func Typify(m *dns.Msg, t time.Time) (Type, *dns.OPT) {
  	if m == nil {
  		return OtherError, nil
  	}
  	opt := m.IsEdns0()
  	do := false
  	if opt != nil {
  		do = opt.Do()
  	}
  
  	if m.Opcode == dns.OpcodeUpdate {
  		return Update, opt
  	}
  
  	// Check transfer and update first
  	if m.Opcode == dns.OpcodeNotify {
  		return Meta, opt
  	}
  
  	if len(m.Question) > 0 {
  		if m.Question[0].Qtype == dns.TypeAXFR || m.Question[0].Qtype == dns.TypeIXFR {
  			return Meta, opt
  		}
  	}
  
  	// If our message contains any expired sigs and we care about that, we should return expired
  	if do {
  		if expired := typifyExpired(m, t); expired {
  			return OtherError, opt
  		}
  	}
  
  	if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess {
  		return NoError, opt
  	}
  
  	soa := false
  	ns := 0
  	for _, r := range m.Ns {
  		if r.Header().Rrtype == dns.TypeSOA {
  			soa = true
  			continue
  		}
  		if r.Header().Rrtype == dns.TypeNS {
  			ns++
  		}
  	}
  
  	if soa && m.Rcode == dns.RcodeSuccess {
  		return NoData, opt
  	}
  	if soa && m.Rcode == dns.RcodeNameError {
  		return NameError, opt
  	}
  
  	if ns > 0 && m.Rcode == dns.RcodeSuccess {
  		return Delegation, opt
  	}
  
  	if m.Rcode == dns.RcodeSuccess {
  		return NoError, opt
  	}
  
  	return OtherError, opt
  }
docs: // Typify classifies a message, it returns the Type.