コード例 #1
0
ファイル: events.cpp プロジェクト: zwass/osquery
std::vector<std::string> EventSubscriberPlugin::getIndexes(EventTime start,
                                                           EventTime stop) {
  auto index_key = "indexes." + dbNamespace();
  std::vector<std::string> indexes;

  EventTime l_start = (start > 0) ? start / 60 : 0;
  EventTime r_stop = (stop > 0) ? stop / 60 + 1 : 0;

  std::string content;
  getDatabaseValue(kEvents, index_key + ".60", content);
  if (content.empty()) {
    return indexes;
  }

  std::vector<std::string> bins, expirations;
  boost::split(bins, content, boost::is_any_of(","));
  for (const auto& bin : bins) {
    auto step = timeFromRecord(bin);
    auto step_start = step * 60;
    auto step_stop = (step + 1) * 60;
    if (step_stop < expire_time_) {
      expirations.push_back(bin);
    } else if (step_start < expire_time_) {
      expireRecords("60", bin, false);
    }

    if (step >= l_start && (r_stop == 0 || step < r_stop)) {
      indexes.push_back("60." + bin);
    }
  }

  // Rewrite the index lists and delete each expired item.
  if (!expirations.empty()) {
    expireIndexes("60", bins, expirations);
  }

  // Return indexes in binning order.
  std::sort(indexes.begin(),
            indexes.end(),
            [](const std::string& left, const std::string& right) {
              auto n1 = timeFromRecord(left.substr(left.find(".") + 1));
              auto n2 = timeFromRecord(right.substr(right.find(".") + 1));
              return n1 < n2;
            });

  // Update the new time that events expire to now - expiry.
  return indexes;
}
コード例 #2
0
ファイル: events.cpp プロジェクト: eastebry/osquery
std::set<std::string> EventSubscriberPlugin::getIndexes(EventTime start,
                                                        EventTime stop,
                                                        int list_key) {
  auto db = DBHandle::getInstance();
  auto index_key = "indexes." + dbNamespace();
  std::set<std::string> indexes;

  // Keep track of the tail/head of account time while bin searching.
  EventTime start_max = stop, stop_min = stop, local_start, local_stop;
  auto types = kEventTimeLists.size();
  // List types are sized bins of time containing records for this namespace.
  for (size_t i = 0; i < types; ++i) {
    auto size = kEventTimeLists[i];
    if (list_key > 0 && i != list_key) {
      // A specific list_type was requested, only return bins of this key.
      continue;
    }

    std::string time_list;
    auto list_type = boost::lexical_cast<std::string>(size);
    auto status = db->Get(kEvents, index_key + "." + list_type, time_list);
    if (time_list.length() == 0) {
      // No events in this binning size.
      return indexes;
    }

    if (list_key == 0 && i == (types - 1) && types > 1) {
      // Relax the requested start/stop bounds.
      if (start != start_max) {
        start = (start / size) * size;
        start_max = ((start / size) + 1) * size;
        if (start_max < stop) {
          start_max = start + kEventTimeLists[types - 2];
        }
      }

      if (stop != stop_min) {
        stop = ((stop / size) + 1) * size;
        stop_min = (stop / size) * size;
        if (stop_min > start) {
          stop_min = stop_min - kEventTimeLists[types - 1];
        }
      }
    } else if (list_key > 0 || types == 1) {
      // Relax the requested bounds to fit the requested/only index.
      start = (start / size) * size;
      start_max = ((start_max / size) + 1) * size;
    }

    // (1) The first iteration will have 1 range (start to start_max=stop).
    // (2) Intermediate iterations will have 2 (start-start_max, stop-stop_min).
    // For each iteration the range collapses based on the coverage using
    // the first bin's start time and the last bin's stop time.
    // (3) The last iteration's range includes relaxed bounds outside the
    // requested start to stop range.
    std::vector<std::string> all_bins, bins, expirations;
    boost::split(all_bins, time_list, boost::is_any_of(","));
    for (const auto& bin : all_bins) {
      // Bins are identified by the binning size step.
      auto step = boost::lexical_cast<EventTime>(bin);
      // Check if size * step -> size * (step + 1) is within a range.
      int bin_start = size * step, bin_stop = size * (step + 1);
      if (expire_events_ && expire_time_ > 0) {
        if (bin_stop <= expire_time_) {
          expirations.push_back(bin);
        } else if (bin_start < expire_time_) {
          expireRecords(list_type, bin, false);
        }
      }

      if (bin_start >= start && bin_stop <= start_max) {
        bins.push_back(bin);
      } else if ((bin_start >= stop_min && bin_stop <= stop) || stop == 0) {
        bins.push_back(bin);
      }
    }

    // Rewrite the index lists and delete each expired item.
    if (expirations.size() > 0) {
      expireIndexes(list_type, all_bins, expirations);
    }

    if (bins.size() != 0) {
      // If more precision was achieved though this list's binning.
      local_start = boost::lexical_cast<EventTime>(bins.front()) * size;
      start_max = (local_start < start_max) ? local_start : start_max;
      local_stop = (boost::lexical_cast<EventTime>(bins.back()) + 1) * size;
      stop_min = (local_stop < stop_min) ? local_stop : stop_min;
    }

    for (const auto& bin : bins) {
      indexes.insert(list_type + "." + bin);
    }

    if (start == start_max && stop == stop_min) {
      break;
    }
  }

  // Update the new time that events expire to now - expiry.
  return indexes;
}