Esempio n. 1
0
  uint32_t RuleSetPrivate::upsertRule(const Rule& match_rule, const Rule& new_rule, const bool parent_insensitive)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);
    Pointer<Rule> matching_rule;

    for (auto& rule_ptr : _rules) {
      if (rule_ptr->internal()->appliesTo(match_rule, parent_insensitive)) {
        if (!matching_rule) {
          matching_rule = rule_ptr;
        }
        else {
          throw Exception("Rule set upsert", "rule", "Cannot upsert; multiple matching rules");
        }
      }
    }

    if (matching_rule) {
      const uint32_t id = matching_rule->getRuleID();
      *matching_rule = new_rule;
      matching_rule->setRuleID(id);
      return id;
    }
    else {
      return appendRule(new_rule, Rule::LastID, /*lock=*/false);
    }
  }
Esempio n. 2
0
  void RuleSetPrivate::save(std::ostream& stream) const
  {
    std::unique_lock<std::mutex> io_lock(_io_mutex);
    std::unique_lock<std::mutex> op_lock(_op_mutex);

    for (auto const& rule : _rules) {
      const std::string rule_string = rule->toString();
      stream << rule_string << std::endl;
    }
  }
Esempio n. 3
0
  Pointer<Rule> RuleSetPrivate::getRule(uint32_t id)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);
    for (auto const& rule : _rules) {
      if (rule->getRuleID() == id) {
	return rule;
      }
    }
    throw Exception("Rule set lookup", "rule id", "id doesn't exist");
  }
Esempio n. 4
0
  Pointer<const Rule> RuleSetPrivate::getRule(uint32_t seqn)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);
    for (auto const& rule : _rules) {
      if (rule->getSeqn() == seqn) {
	return rule;
      }
    }
    throw std::out_of_range("Rule not found");
  }
Esempio n. 5
0
  uint32_t RuleSetPrivate::appendRule(const Rule& rule, uint32_t parent_id, bool lock)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex, std::defer_lock);

    if (lock) {
      op_lock.lock();
    }

    auto rule_ptr = makePointer<Rule>(rule);

    /*
     * If the rule doesn't already have a sequence number
     * assigned, do it now. Otherwise update the sequence
     * number counter so that we don't generate a duplicit
     * one if assignID() gets called in the future.
     */
    if (rule_ptr->getRuleID() == Rule::DefaultID) {
      assignID(rule_ptr);
    }
    else {
      _id_next = std::max(_id_next.load(), rule_ptr->getRuleID() + 1);
    }

    /* Initialize conditions */
    rule_ptr->internal()->initConditions(_interface_ptr);

    /* Append the rule to the main rule table */
    if (parent_id == Rule::LastID) {
      _rules.push_back(rule_ptr);
    }
    else if (parent_id == 0) {
      _rules.insert(_rules.begin(), rule_ptr);
    }
    else {
      bool parent_found = false;
      for (auto it = _rules.begin(); it != _rules.end(); ++it) {
	const Rule& rule = **it;
	if (rule.getRuleID() == parent_id) {
	  _rules.insert(it+1, rule_ptr);
	  parent_found = true;
	  break;
	}
      }
      if (!parent_found) {
        throw Exception("Rule set append", "rule", "Invalid parent ID");
      }
    }

    /* If the rule is timed, put it into the priority queue */
    if (rule_ptr->getTimeoutSeconds() > 0) {
      _rules_timed.push(rule_ptr);
    }

    return rule_ptr->getRuleID();
  }
Esempio n. 6
0
 bool RuleSetPrivate::removeRule(uint32_t id)
 {
   std::unique_lock<std::mutex> op_lock(_op_mutex);
   for (auto it = _rules.begin(); it != _rules.end(); ++it) {
     auto const& rule_ptr = *it;
     if (rule_ptr->getRuleID() == id) {
       _rules.erase(it);
       return true;
     }
   }
   /* FIXME: Remove the rule from the priority queue too */
   throw Exception("Rule set remove", "rule id", "id doesn't exist");
 }
Esempio n. 7
0
  bool RuleSetPrivate::removeRule(uint32_t seqn)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);
    for (auto it = _rules.begin(); it != _rules.end(); ++it) {
      auto const& rule_ptr = *it;
      if (rule_ptr->getSeqn() == seqn) {
	_rules.erase(it);
	return true;
      }
    }
    /* FIXME: Remove the rule from the priority queue too */
    return false;
  }
Esempio n. 8
0
  Pointer<Rule> RuleSetPrivate::getFirstMatchingRule(Pointer<const Rule> device_rule, uint32_t from_id) const
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);

    for (auto& rule_ptr : _rules) {
      if (rule_ptr->internal()->appliesToWithConditions(*device_rule, /*with_update*/true)) {
	return rule_ptr;
      }
    }

    Pointer<Rule> default_rule = makePointer<Rule>();

    default_rule->setRuleID(Rule::ImplicitID);
    default_rule->setTarget(_default_target);

    return default_rule;
  }
Esempio n. 9
0
  Pointer<const Rule> RuleSetPrivate::getFirstMatchingRule(Pointer<const Rule> device_rule, uint32_t from_seqn)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);

    for (auto const& rule_ptr : _rules) {
      if (rule_ptr->appliesTo(device_rule)) {
	return rule_ptr;
      }
    }

    Pointer<Rule> default_rule = makePointer<Rule>();

    default_rule->setSeqn(Rule::SeqnDefault);
    default_rule->setTarget(_default_target);
    default_rule->setAction(_default_action);

    return default_rule;
  }
Esempio n. 10
0
  Pointer<Rule> RuleSetPrivate::getTimedOutRule()
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);

    if (_rules_timed.size() < 1) {
      return nullptr;
    }

    Pointer<Rule> oldest_rule = _rules_timed.top();
    std::chrono::steady_clock::time_point tp_current =	\
      std::chrono::steady_clock::now();

    if ((tp_current - oldest_rule->internal()->metadata().tp_created) \
	< std::chrono::seconds(oldest_rule->getTimeoutSeconds())) {
      return nullptr;
    } else {
      _rules_timed.pop();
    }

    return oldest_rule;
  }
Esempio n. 11
0
  uint32_t RuleSetPrivate::appendRule(const Rule& rule, uint32_t parent_seqn)
  {
    std::unique_lock<std::mutex> op_lock(_op_mutex);
    auto rule_ptr = makePointer<Rule>(rule);

    /* Assign a unique sequence number to the rule */
    assignSeqn(rule_ptr);

    /* Set time */
    rule_ptr->setTimePointAdded(std::chrono::steady_clock::now());

    /* Append the rule to the main rule table */
    if (parent_seqn == Rule::SeqnLast) {
      _rules.push_back(rule_ptr);
    }
    else if (parent_seqn == 0) {
      _rules.insert(_rules.begin(), rule_ptr);
    }
    else {
      bool parent_found = false;
      for (auto it = _rules.begin(); it != _rules.end(); ++it) {
	const Rule& rule = **it;
	if (rule.getSeqn() == parent_seqn) {
	  _rules.insert(it+1, rule_ptr);
	  parent_found = true;
	  break;
	}
      }
      if (!parent_found) {
	throw std::runtime_error("Invalid parent_seqn");
      }
    }

    /* If the rule is timed, put it into the priority queue */
    if (rule_ptr->getTimeoutSeconds() > 0) {
      _rules_timed.push(rule_ptr);
    }

    return rule_ptr->getSeqn();
  }
Esempio n. 12
0
 void RuleSetPrivate::setDefaultAction(const String& action)
 {
   std::unique_lock<std::mutex> op_lock(_op_mutex);
   _default_action = action;
 }
Esempio n. 13
0
 Rule::Target RuleSetPrivate::getDefaultTarget() const
 {
   std::unique_lock<std::mutex> op_lock(_op_mutex);
   return _default_target;
 }
Esempio n. 14
0
 void RuleSetPrivate::setDefaultTarget(Rule::Target target)
 {
   std::unique_lock<std::mutex> op_lock(_op_mutex);
   _default_target = target;
 }