-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ITrafficMaker から AbstractTrafficMaker に改名 * TrafficMaker の Make を共通化
- Loading branch information
Showing
13 changed files
with
209 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#include <TrafficMaker/AbstractTrafficMaker.hpp> | ||
#include <spdlog/spdlog.h> | ||
|
||
namespace TrafficMaker | ||
{ | ||
AbstractTrafficMaker::AbstractTrafficMaker(const std::filesystem::path &path) : _path(path) | ||
{ | ||
} | ||
|
||
AbstractTrafficMaker::~AbstractTrafficMaker() | ||
{ | ||
} | ||
|
||
std::filesystem::path AbstractTrafficMaker::Path() const | ||
{ | ||
return _path; | ||
} | ||
|
||
std::vector<PcapRecord> AbstractTrafficMaker::ReadPcapFile(const std::filesystem::path &path) | ||
{ | ||
auto pcapRecords = std::vector<PcapRecord>(); | ||
|
||
auto pcap = pcap_open_offline(path.c_str(), NULL); | ||
if (pcap == NULL) | ||
{ | ||
throw std::runtime_error("Failed to open pcap file"); | ||
} | ||
|
||
struct pcap_pkthdr header; | ||
const u_char *packet; | ||
while ((packet = pcap_next(pcap, &header)) != NULL) | ||
{ | ||
std::vector<uint8_t> data(packet, packet + header.len); | ||
auto record = PcapRecord(header, data); | ||
pcapRecords.push_back(record); | ||
} | ||
|
||
pcap_close(pcap); | ||
|
||
return pcapRecords; | ||
} | ||
|
||
std::vector<std::chrono::nanoseconds> AbstractTrafficMaker::NormalizeTimestamps( | ||
const std::vector<std::chrono::nanoseconds> &records, double speedScaleFactor) | ||
{ | ||
auto normalizedTimestamps = std::vector<std::chrono::nanoseconds>(); | ||
std::transform(records.begin(), records.end(), std::back_inserter(normalizedTimestamps), | ||
[speedScaleFactor](const std::chrono::nanoseconds ×tamp) { | ||
return std::chrono::nanoseconds(static_cast<long long>(timestamp.count() / speedScaleFactor)); | ||
}); | ||
return normalizedTimestamps; | ||
} | ||
|
||
std::vector<std::chrono::nanoseconds> AbstractTrafficMaker::RelativizeTimestamps( | ||
const std::vector<std::chrono::nanoseconds> ×tamps) | ||
{ | ||
if (timestamps.empty()) | ||
{ | ||
return {}; | ||
} | ||
|
||
auto relativeTimestamps = std::vector<std::chrono::nanoseconds>{std::chrono::nanoseconds(0)}; | ||
relativeTimestamps.reserve(timestamps.size()); | ||
for (auto i = 1; i < timestamps.size(); i++) | ||
{ | ||
relativeTimestamps.push_back(timestamps[i] - timestamps[i - 1]); | ||
} | ||
return relativeTimestamps; | ||
} | ||
|
||
std::vector<TrafficRecord> AbstractTrafficMaker::Make() | ||
{ | ||
auto pcapRecords = ReadPcapFile(Path()); | ||
auto speedScaleFactor = CalculateSpeedScaleFactor(pcapRecords); | ||
return MakeTrafficRecords(pcapRecords, speedScaleFactor); | ||
} | ||
std::vector<TrafficRecord> AbstractTrafficMaker::MakeTrafficRecords(const std::vector<PcapRecord> &pcapRecords, | ||
const double speedScaleFactor) | ||
{ | ||
spdlog::debug("Speed scale factor: {}", speedScaleFactor); | ||
|
||
auto trafficRecords = std::vector<TrafficRecord>(); | ||
|
||
auto nsecTimestamps = std::vector<std::chrono::nanoseconds>(); | ||
std::transform(pcapRecords.begin(), pcapRecords.end(), std::back_inserter(nsecTimestamps), | ||
[](const PcapRecord &record) { | ||
auto nsec = (uint64_t)(record.Ts().tv_sec * 1e9 + record.Ts().tv_usec * 1e3); | ||
return std::chrono::nanoseconds(nsec); | ||
}); | ||
|
||
auto relativizedTimestamps = RelativizeTimestamps(nsecTimestamps); | ||
auto normalizedTimestamps = NormalizeTimestamps(relativizedTimestamps, speedScaleFactor); | ||
|
||
for (auto i = 0; i < pcapRecords.size(); i++) | ||
{ | ||
auto record = pcapRecords[i]; | ||
auto timestamp = normalizedTimestamps[i]; | ||
auto trafficRecord = TrafficRecord(record.Data(), timestamp); | ||
trafficRecords.push_back(trafficRecord); | ||
} | ||
|
||
return trafficRecords; | ||
} | ||
|
||
std::vector<std::chrono::nanoseconds> AbstractTrafficMaker::GetTimestamps(std::vector<PcapRecord> pcapRecords) | ||
{ | ||
auto nsecTimestamps = std::vector<std::chrono::nanoseconds>(); | ||
std::transform(pcapRecords.begin(), pcapRecords.end(), std::back_inserter(nsecTimestamps), | ||
[](const PcapRecord &record) { | ||
auto nsec = static_cast<uint64_t>(record.Ts().tv_sec * 1e9 + record.Ts().tv_usec * 1e3); | ||
return std::chrono::nanoseconds(nsec); | ||
}); | ||
return nsecTimestamps; | ||
} | ||
} // namespace TrafficMaker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef TRAFFIC_MAKER__ABSTRACT_TRAFFIC_MAKER_HPP | ||
#define TRAFFIC_MAKER__ABSTRACT_TRAFFIC_MAKER_HPP | ||
|
||
#include <TrafficMaker/PcapRecord.hpp> | ||
#include <TrafficRecord.hpp> | ||
#include <filesystem> | ||
#include <pcap.h> | ||
#include <vector> | ||
|
||
namespace TrafficMaker | ||
{ | ||
class AbstractTrafficMaker | ||
{ | ||
public: | ||
AbstractTrafficMaker(const std::filesystem::path &path); | ||
virtual ~AbstractTrafficMaker() = 0; | ||
virtual std::vector<TrafficRecord> Make(); | ||
|
||
protected: | ||
std::filesystem::path Path() const; | ||
virtual std::vector<PcapRecord> ReadPcapFile(const std::filesystem::path &path) final; | ||
virtual double CalculateSpeedScaleFactor(const std::vector<PcapRecord> &pcapRecords) = 0; | ||
static std::vector<std::chrono::nanoseconds> NormalizeTimestamps( | ||
const std::vector<std::chrono::nanoseconds> &records, double speedScaleFactor); | ||
static std::vector<std::chrono::nanoseconds> RelativizeTimestamps( | ||
const std::vector<std::chrono::nanoseconds> ×tamps); | ||
static std::vector<TrafficRecord> MakeTrafficRecords(const std::vector<PcapRecord> &pcapRecords, | ||
const double speedScaleFactor); | ||
static std::vector<std::chrono::nanoseconds> GetTimestamps(std::vector<PcapRecord> pcapRecords); | ||
|
||
private: | ||
std::filesystem::path _path; | ||
}; | ||
} // namespace TrafficMaker | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,23 @@ | ||
#include <TrafficMaker/CustomDurationReplayTrafficMaker.hpp> | ||
#include <algorithm> | ||
#include <numeric> | ||
#include <spdlog/spdlog.h> | ||
|
||
namespace TrafficMaker | ||
{ | ||
|
||
CustomDurationReplayTrafficMaker::CustomDurationReplayTrafficMaker(const std::string &pcapFilePath, | ||
std::chrono::milliseconds durationTime) | ||
: ITrafficMaker(pcapFilePath), _DurationTime(durationTime) | ||
: AbstractTrafficMaker(pcapFilePath), _DurationTime(durationTime) | ||
{ | ||
} | ||
|
||
std::vector<TrafficRecord> CustomDurationReplayTrafficMaker::Make() | ||
double CustomDurationReplayTrafficMaker::CalculateSpeedScaleFactor(const std::vector<PcapRecord> &pcapRecords) | ||
{ | ||
auto pcapRecords = ReadPcapFile(Path()); | ||
auto trafficRecords = std::vector<TrafficRecord>(); | ||
auto durationTime = _DurationTime; | ||
auto timestamps = GetTimestamps(pcapRecords); | ||
auto maxTimestamp = *std::max_element(timestamps.begin(), timestamps.end()); | ||
auto minTimestamp = *std::min_element(timestamps.begin(), timestamps.end()); | ||
auto durationAsNsec = std::chrono::duration_cast<std::chrono::nanoseconds>(_DurationTime); | ||
auto speedScaleFactor = (maxTimestamp - minTimestamp).count() / static_cast<double>(durationAsNsec.count()); | ||
|
||
auto usecTimestamps = std::vector<uint64_t>(); | ||
std::transform(pcapRecords.begin(), pcapRecords.end(), std::back_inserter(usecTimestamps), | ||
[](const PcapRecord &record) { return record.Ts().tv_sec * 1e6 + record.Ts().tv_usec; }); | ||
|
||
auto maxTimestamp = *std::max_element(usecTimestamps.begin(), usecTimestamps.end()); | ||
auto minTimestamp = *std::min_element(usecTimestamps.begin(), usecTimestamps.end()); | ||
auto durationAsUsec = durationTime.count() * 1e3; | ||
auto speedScaleFactor = (maxTimestamp - minTimestamp) / durationAsUsec; | ||
|
||
for (auto i = 0; i < pcapRecords.size(); i++) | ||
{ | ||
auto targetRecord = pcapRecords[i]; | ||
auto targetUsecTimestamp = targetRecord.Ts().tv_sec * 1e6 + targetRecord.Ts().tv_usec; | ||
auto scaledTargetUsecTimestamp = targetUsecTimestamp / speedScaleFactor; | ||
auto nextUsecTimeStamp = (i + 1 < pcapRecords.size()) | ||
? pcapRecords[i + 1].Ts().tv_sec * 1e6 + pcapRecords[i + 1].Ts().tv_usec | ||
: maxTimestamp; | ||
auto scaledNextUsecTimestamp = nextUsecTimeStamp / speedScaleFactor; | ||
|
||
auto scaledChronoNano = std::chrono::nanoseconds( | ||
static_cast<long long>((scaledNextUsecTimestamp - scaledTargetUsecTimestamp) * 1e3)); | ||
|
||
auto trafficRecord = TrafficRecord(targetRecord.Data(), scaledChronoNano); | ||
trafficRecords.push_back(trafficRecord); | ||
} | ||
|
||
return trafficRecords; | ||
return speedScaleFactor; | ||
} | ||
|
||
} // namespace TrafficMaker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,25 @@ | ||
#include <TrafficMaker/PacketsPerSecondTrafficMaker.hpp> | ||
#include <spdlog/spdlog.h> | ||
|
||
namespace TrafficMaker | ||
{ | ||
PacketsPerSecondTrafficMaker::PacketsPerSecondTrafficMaker(std::string pcapFilePath, double packetsPerSecond) | ||
: ITrafficMaker(pcapFilePath), _PacketsPerSecond(packetsPerSecond) | ||
: AbstractTrafficMaker(pcapFilePath), _PacketsPerSecond(packetsPerSecond) | ||
{ | ||
} | ||
|
||
std::vector<TrafficRecord> PacketsPerSecondTrafficMaker::Make() | ||
double PacketsPerSecondTrafficMaker::CalculateSpeedScaleFactor(const std::vector<PcapRecord> &pcapRecords) | ||
{ | ||
auto pcapRecords = ReadPcapFile(Path()); | ||
auto trafficRecords = std::vector<TrafficRecord>(); | ||
auto packetsPerSecond = _PacketsPerSecond; | ||
|
||
auto usecTimestamps = std::vector<uint64_t>(); | ||
std::transform(pcapRecords.begin(), pcapRecords.end(), std::back_inserter(usecTimestamps), | ||
[](const PcapRecord &record) { return record.Ts().tv_sec * 1e6 + record.Ts().tv_usec; }); | ||
auto timestamps = GetTimestamps(pcapRecords); | ||
auto maxTimestamp = *std::max_element(timestamps.begin(), timestamps.end()); | ||
auto minTimestamp = *std::min_element(timestamps.begin(), timestamps.end()); | ||
|
||
auto maxTimestamp = *std::max_element(usecTimestamps.begin(), usecTimestamps.end()); | ||
auto minTimestamp = *std::min_element(usecTimestamps.begin(), usecTimestamps.end()); | ||
auto packetNumber = pcapRecords.size(); | ||
auto actualDuration = (maxTimestamp - minTimestamp) / 1e6; | ||
auto expectedDuration = packetNumber / packetsPerSecond; | ||
auto speedScaleFactor = actualDuration / expectedDuration; | ||
auto actualDuration = maxTimestamp - minTimestamp; | ||
auto expectedDuration = (packetNumber / packetsPerSecond) * 1e9; | ||
auto speedScaleFactor = actualDuration.count() / expectedDuration; | ||
|
||
spdlog::info("Actual duration: {} usec, Expected duration: {} usec, Speed scale factor: {}", actualDuration, | ||
expectedDuration, speedScaleFactor); | ||
|
||
for (auto i = 0; i < pcapRecords.size(); i++) | ||
{ | ||
auto targetRecord = pcapRecords[i]; | ||
auto targetUsecTimestamp = targetRecord.Ts().tv_sec * 1e6 + targetRecord.Ts().tv_usec; | ||
auto scaledTargetUsecTimestamp = targetUsecTimestamp / speedScaleFactor; | ||
auto nextUsecTimeStamp = (i + 1 < pcapRecords.size()) | ||
? pcapRecords[i + 1].Ts().tv_sec * 1e6 + pcapRecords[i + 1].Ts().tv_usec | ||
: maxTimestamp; | ||
auto scaledNextUsecTimestamp = nextUsecTimeStamp / speedScaleFactor; | ||
|
||
auto scaledChronoNano = std::chrono::nanoseconds( | ||
static_cast<long long>((scaledNextUsecTimestamp - scaledTargetUsecTimestamp) * 1e3)); | ||
|
||
auto trafficRecord = TrafficRecord(targetRecord.Data(), scaledChronoNano); | ||
trafficRecords.push_back(trafficRecord); | ||
} | ||
|
||
return trafficRecords; | ||
return speedScaleFactor; | ||
} | ||
} // namespace TrafficMaker |
Oops, something went wrong.