示例#1
0
Discover::Discover(QObject *parent, Mode mode, QHostAddress multicastAddress, quint16 multicastPort) : QObject(parent)
{
	mServerMode = (mode == ServerMode);
	port = multicastPort;
	groupAddress = multicastAddress;
	announcePeriodMsec = 500;
	running = false;
	announceNeedsResponse = true;
	departure = false;
	defaultScope = "Local";

	setLoggerTag("Discover");

	// Timers
	timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(announceRecords()));
	expireTimer = new QTimer(this);
	connect(expireTimer, SIGNAL(timeout()), this, SLOT(expireRecords()));

	// Server mode?
	if (mServerMode)
	{
		// Server's don't announce periodically
		timer->stop();
	}
	else
	{
		// Announce it immediately after returning to event loop
		if (running) timer->start(0);
	}

	// Loopback socket
//	loopbackSocket = new QUdpSocket(this);
//	connect(loopbackSocket, SIGNAL(readyRead()), this, SLOT(readDatagrams()));
//	if (not loopbackSocket->bind(QHostAddress::LocalHost, port, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint))
//	{
//		qlogDebug() << "Error binding loopbackSocket:" << loopbackSocket->errorString();
//	}

	// Global socket
	globalSocket = new QUdpSocket(this);
	connect(globalSocket, SIGNAL(readyRead()), this, SLOT(readDatagrams()));
	if (mServerMode) logDebug(QString("Discover global server mode on port %1").arg(port));
	if (not globalSocket->bind(QHostAddress::AnyIPv4, mServerMode?port:0))
	{
		logWarning(QString("Error binding globalSocket: %1").arg(globalSocket->errorString()));
	}

}
示例#2
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;
}
示例#3
0
void EventSubscriberPlugin::expireIndexes(
    const std::string& list_type,
    const std::vector<std::string>& indexes,
    const std::vector<std::string>& expirations) {
  auto index_key = "indexes." + dbNamespace();

  // Construct a mutable list of persisting indexes to rewrite as records.
  std::vector<std::string> persisting_indexes = indexes;
  // Remove the records using the list of expired indexes.
  for (const auto& bin : expirations) {
    expireRecords(list_type, bin, true);
    persisting_indexes.erase(
        std::remove(persisting_indexes.begin(), persisting_indexes.end(), bin),
        persisting_indexes.end());
  }

  // Update the list of indexes with the non-expired indexes.
  auto new_indexes = boost::algorithm::join(persisting_indexes, ",");
  setDatabaseValue(kEvents, index_key + "." + list_type, new_indexes);
}
示例#4
0
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;
}