sync code

This commit is contained in:
Ned Wright 2025-03-17 14:49:44 +00:00
parent df7be864e2
commit 0246b73bbd
20 changed files with 877 additions and 278 deletions

View File

@ -30,7 +30,7 @@ public:
virtual bool isVersionAboveR8110() = 0; virtual bool isVersionAboveR8110() = 0;
virtual bool isReverseProxy() = 0; virtual bool isReverseProxy() = 0;
virtual bool isCloudStorageEnabled() = 0; virtual bool isCloudStorageEnabled() = 0;
virtual Maybe<std::tuple<std::string, std::string, std::string>> parseNginxMetadata() = 0; virtual Maybe<std::tuple<std::string, std::string, std::string, std::string>> parseNginxMetadata() = 0;
virtual Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>> readCloudMetadata() = 0; virtual Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>> readCloudMetadata() = 0;
virtual std::map<std::string, std::string> getResolvedDetails() = 0; virtual std::map<std::string, std::string> getResolvedDetails() = 0;
#if defined(gaia) || defined(smb) #if defined(gaia) || defined(smb)

View File

@ -46,7 +46,7 @@ public:
bool isReverseProxy() override; bool isReverseProxy() override;
bool isCloudStorageEnabled() override; bool isCloudStorageEnabled() override;
Maybe<tuple<string, string, string, string, string>> readCloudMetadata() override; Maybe<tuple<string, string, string, string, string>> readCloudMetadata() override;
Maybe<tuple<string, string, string>> parseNginxMetadata() override; Maybe<tuple<string, string, string, string>> parseNginxMetadata() override;
#if defined(gaia) || defined(smb) #if defined(gaia) || defined(smb)
bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override; bool compareCheckpointVersion(int cp_version, std::function<bool(int, int)> compare_operator) const override;
#endif // gaia || smb #endif // gaia || smb
@ -230,7 +230,7 @@ isNoResponse(const string &cmd)
return !res.ok() || res.unpack().empty(); return !res.ok() || res.unpack().empty();
} }
Maybe<tuple<string, string, string>> Maybe<tuple<string, string, string, string>>
DetailsResolver::Impl::parseNginxMetadata() DetailsResolver::Impl::parseNginxMetadata()
{ {
auto output_path = getConfigurationWithDefault<string>( auto output_path = getConfigurationWithDefault<string>(
@ -243,6 +243,11 @@ DetailsResolver::Impl::parseNginxMetadata()
"/scripts/cp-nano-makefile-generator.sh -f -o " + "/scripts/cp-nano-makefile-generator.sh -f -o " +
output_path; output_path;
const string script_fresh_exe_cmd =
getFilesystemPathConfig() +
"/scripts/cp-nano-makefile-generator-fresh.sh save --save-location " +
output_path;
dbgTrace(D_ORCHESTRATOR) << "Details resolver, srcipt exe cmd: " << srcipt_exe_cmd; dbgTrace(D_ORCHESTRATOR) << "Details resolver, srcipt exe cmd: " << srcipt_exe_cmd;
if (isNoResponse("which nginx") && isNoResponse("which kong")) { if (isNoResponse("which nginx") && isNoResponse("which kong")) {
return genError("Nginx or Kong isn't installed"); return genError("Nginx or Kong isn't installed");
@ -279,7 +284,37 @@ DetailsResolver::Impl::parseNginxMetadata()
<< " Error: " << exception.what(); << " Error: " << exception.what();
} }
if (!isNoResponse("which nginx")) {
auto script_output = DetailsResolvingHanlder::getCommandOutput(script_fresh_exe_cmd);
if (!script_output.ok()) {
return genError("Failed to generate nginx fresh metadata, Error: " + script_output.getErr());
}
try {
ifstream input_stream(output_path);
if (!input_stream) {
return genError("Cannot open the file with nginx fresh metadata, File: " + output_path);
}
string line;
while (getline(input_stream, line)) {
if (line.find("NGX_MODULE_SIGNATURE") == 0) {
lines.push_back(line);
}
}
input_stream.close();
orchestration_tools->removeFile(output_path);
} catch (const ifstream::failure &exception) {
dbgWarning(D_ORCHESTRATOR)
<< "Cannot read the file with required nginx fresh metadata."
<< " File: " << output_path
<< " Error: " << exception.what();
}
}
if (lines.size() == 0) return genError("Failed to read nginx metadata file"); if (lines.size() == 0) return genError("Failed to read nginx metadata file");
string nginx_signature;
string nginx_version; string nginx_version;
string config_opt; string config_opt;
string cc_opt; string cc_opt;
@ -294,6 +329,11 @@ DetailsResolver::Impl::parseNginxMetadata()
nginx_version = "nginx-" + line.substr(eq_index + 1); nginx_version = "nginx-" + line.substr(eq_index + 1);
continue; continue;
} }
if (line.find("NGX_MODULE_SIGNATURE") != string::npos) {
auto eq_index = line.find("=");
nginx_signature = line.substr(eq_index + 1);
continue;
}
if (line.find("EXTRA_CC_OPT") != string::npos) { if (line.find("EXTRA_CC_OPT") != string::npos) {
auto eq_index = line.find("="); auto eq_index = line.find("=");
cc_opt = line.substr(eq_index + 1); cc_opt = line.substr(eq_index + 1);
@ -303,7 +343,7 @@ DetailsResolver::Impl::parseNginxMetadata()
if (line.back() == '\\') line.pop_back(); if (line.back() == '\\') line.pop_back();
config_opt += line; config_opt += line;
} }
return make_tuple(config_opt, cc_opt, nginx_version); return make_tuple(config_opt, cc_opt, nginx_version, nginx_signature);
} }
Maybe<tuple<string, string, string, string, string>> Maybe<tuple<string, string, string, string, string>>

View File

@ -21,7 +21,7 @@
#include "maybe_res.h" #include "maybe_res.h"
std::ostream & std::ostream &
operator<<(std::ostream &os, const Maybe<std::tuple<std::string, std::string, std::string>> &) operator<<(std::ostream &os, const Maybe<std::tuple<std::string, std::string, std::string, std::string>> &)
{ {
return os; return os;
} }
@ -48,7 +48,7 @@ public:
MOCK_METHOD0(isGwNotVsx, bool()); MOCK_METHOD0(isGwNotVsx, bool());
MOCK_METHOD0(getResolvedDetails, std::map<std::string, std::string>()); MOCK_METHOD0(getResolvedDetails, std::map<std::string, std::string>());
MOCK_METHOD0(isVersionAboveR8110, bool()); MOCK_METHOD0(isVersionAboveR8110, bool());
MOCK_METHOD0(parseNginxMetadata, Maybe<std::tuple<std::string, std::string, std::string>>()); MOCK_METHOD0(parseNginxMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string>>());
MOCK_METHOD0( MOCK_METHOD0(
readCloudMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>>()); readCloudMetadata, Maybe<std::tuple<std::string, std::string, std::string, std::string, std::string>>());
}; };

View File

@ -1465,12 +1465,14 @@ private:
auto nginx_data = i_details_resolver->parseNginxMetadata(); auto nginx_data = i_details_resolver->parseNginxMetadata();
if (nginx_data.ok()) { if (nginx_data.ok()) {
string nginx_signature;
string nginx_version; string nginx_version;
string config_opt; string config_opt;
string cc_opt; string cc_opt;
tie(config_opt, cc_opt, nginx_version) = nginx_data.unpack(); tie(config_opt, cc_opt, nginx_version, nginx_signature) = nginx_data.unpack();
agent_data_report agent_data_report
<< make_pair("attachmentVersion", "Legacy") << make_pair("attachmentVersion", "Legacy")
<< make_pair("nginxSignature", nginx_signature)
<< make_pair("nginxVersion", nginx_version) << make_pair("nginxVersion", nginx_version)
<< make_pair("configureOpt", config_opt) << make_pair("configureOpt", config_opt)
<< make_pair("extraCompilerOpt", cc_opt); << make_pair("extraCompilerOpt", cc_opt);
@ -1529,7 +1531,6 @@ private:
} else { } else {
curr_agent_data_report = agent_data_report; curr_agent_data_report = agent_data_report;
curr_agent_data_report.disableReportSending(); curr_agent_data_report.disableReportSending();
agent_data_report << AgentReportFieldWithLabel("timestamp", i_time->getWalltimeStr());
} }
} }

View File

@ -140,7 +140,7 @@ public:
void void
expectDetailsResolver() expectDetailsResolver()
{ {
Maybe<tuple<string, string, string>> no_nginx(genError("No nginx")); Maybe<tuple<string, string, string, string>> no_nginx(genError("No nginx"));
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux"))); EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64"))); EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false)); EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));

View File

@ -168,7 +168,7 @@ public:
void void
expectDetailsResolver() expectDetailsResolver()
{ {
Maybe<tuple<string, string, string>> no_nginx(genError("No nginx")); Maybe<tuple<string, string, string, string>> no_nginx(genError("No nginx"));
EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux"))); EXPECT_CALL(mock_details_resolver, getPlatform()).WillRepeatedly(Return(string("linux")));
EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64"))); EXPECT_CALL(mock_details_resolver, getArch()).WillRepeatedly(Return(string("x86_64")));
EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false)); EXPECT_CALL(mock_details_resolver, isReverseProxy()).WillRepeatedly(Return(false));

View File

@ -168,10 +168,12 @@ FogAuthenticator::registerAgent(
auto nginx_data = details_resolver->parseNginxMetadata(); auto nginx_data = details_resolver->parseNginxMetadata();
if (nginx_data.ok()) { if (nginx_data.ok()) {
string nginx_signature;
string nginx_version; string nginx_version;
string config_opt; string config_opt;
string cc_opt; string cc_opt;
tie(config_opt, cc_opt, nginx_version) = nginx_data.unpack(); tie(config_opt, cc_opt, nginx_version, nginx_signature) = nginx_data.unpack();
request << make_pair("nginxSignature", nginx_signature);
request << make_pair("nginxVersion", nginx_version); request << make_pair("nginxVersion", nginx_version);
request << make_pair("configureOpt", config_opt); request << make_pair("configureOpt", config_opt);
request << make_pair("extraCompilerOpt", cc_opt); request << make_pair("extraCompilerOpt", cc_opt);

View File

@ -424,6 +424,8 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
std::string unescape(const std::string & s) { std::string unescape(const std::string & s) {
std::string text = s; std::string text = s;
size_t orig_size = text.size();
size_t orig_capacity = text.capacity();
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (0) '" << text << "'"; dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (0) '" << text << "'";
fixBreakingSpace(text); fixBreakingSpace(text);
@ -433,7 +435,17 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
filterUnicode(text); filterUnicode(text);
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) '" << text << "'"; dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) '" << text << "'";
// inplace unescaping must result in a string of the same size or smaller
dbgAssertOpt(text.size() <= orig_size && text.size() <= text.capacity() && text.capacity() <= orig_capacity)
<< AlertInfo(AlertTeam::CORE, "WAAP sample processing")
<< "unescape: original size=" << orig_size << " capacity=" << orig_capacity
<< " new size=" << text.size() << " capacity=" << text.capacity()
<< " text='" << text << "'";
text = filterUTF7(text); text = filterUTF7(text);
// update orig_size and orig_capacity after string copy
orig_size = text.size();
orig_capacity = text.capacity();
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) (after filterUTF7) '" << text << "'"; dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (1) (after filterUTF7) '" << text << "'";
// 2. Replace %xx sequences by their single-character equivalents. // 2. Replace %xx sequences by their single-character equivalents.
@ -512,6 +524,14 @@ WaapAssetState::WaapAssetState(std::shared_ptr<Signatures> signatures,
} }
dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (12) '" << text << "'"; dbgTrace(D_WAAP_SAMPLE_PREPROCESS) << "unescape: (12) '" << text << "'";
// inplace unescaping must result in a string of the same size or smaller
dbgAssertOpt(text.size() <= orig_size && text.size() <= text.capacity() && text.capacity() <= orig_capacity)
<< AlertInfo(AlertTeam::CORE, "WAAP sample processing")
<< "unescape: original size=" << orig_size << " capacity=" << orig_capacity
<< " new size=" << text.size() << " capacity=" << text.capacity()
<< " text='" << text << "'";
return text; return text;
} }

View File

@ -227,59 +227,66 @@ inline bool isHexDigit(const char ch) {
template<class _IT> template<class _IT>
_IT escape_backslashes(_IT first, _IT last) { _IT escape_backslashes(_IT first, _IT last) {
_IT result = first; _IT src = first;
_IT dst = first;
_IT mark = first;
enum { STATE_COPY, STATE_ESCAPE, STATE_OCTAL, STATE_HEX } state = STATE_COPY; enum { STATE_COPY, STATE_ESCAPE, STATE_OCTAL, STATE_HEX } state = STATE_COPY;
unsigned char accVal = 0; unsigned char accVal = 0;
unsigned char digitsCount = 0; unsigned char digitsCount = 0;
_IT mark = first;
for (; first != last; ++first) { for (; src != last && dst < last; ++src) {
switch (state) { switch (state) {
case STATE_COPY: case STATE_COPY:
if (*first == '\\') { if (*src == '\\') {
mark = first; mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
} } else {
else { *dst++ = *src;
*result++ = *first;
} }
break; break;
case STATE_ESCAPE: { case STATE_ESCAPE: {
if (*first >= '0' && *first <= '7') { if (*src >= '0' && *src <= '7') {
accVal = *first - '0'; accVal = *src - '0';
digitsCount = 1; digitsCount = 1;
state = STATE_OCTAL; state = STATE_OCTAL;
break; break;
} else if (*first == 'x') { } else if (*src == 'x') {
accVal = 0; accVal = 0;
digitsCount = 0; digitsCount = 0;
state = STATE_HEX; state = STATE_HEX;
break; break;
} } else {
else { switch (*src) {
switch (*first) { // Copy a matching character without the backslash before it
case 'a': *result++ = 7; break; // BELL case 'a': *dst++ = 7; break; // BELL
case 'b': *result++ = 8; break; // BACKSPACE case 'b': *dst++ = 8; break; // BACKSPACE
case 't': *result++ = 9; break; // HORIZONTAL TAB case 'e': *dst++ = 27; break; // ESCAPE
case 'n': *result++ = 10; break; // LINEFEED case 't': *dst++ = 9; break; // HORIZONTAL TAB
case 'v': *result++ = 11; break; // VERTICAL TAB case 'n': *dst++ = 10; break; // LINEFEED
case 'f': *result++ = 12; break; // FORMFEED case 'v': *dst++ = 11; break; // VERTICAL TAB
case 'r': *result++ = 13; break; // CARRIAGE RETURN case 'f': *dst++ = 12; break; // FORMFEED
case '\\': *result++ = '\\'; break; // upon seeing double backslash - output only one case 'r': *dst++ = 13; break; // CARRIAGE RETURN
case '\"': *result++ = '"'; break; // backslash followed by '"' - output only '"' case '\?': *dst++ = '\?'; break; // QUESTION MARK
case '\\': *dst++ = '\\'; break; // upon seeing double backslash - output only one
case '\"': *dst++ = '\"'; break; // DOUBLE QUOTE
case '\'': *dst++ = '\''; break; // SINGLE QUOTE
default: default:
// invalid escape sequence - do not replace it (return original characters) // invalid escape sequence - do not replace it (return original characters)
// Copy from back-track, not including current character, and continue // Copy from back-track, not including current character, and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
// Copy current (terminator) character which is not "escape" and return to copy state // Copy current (terminator) character which is not "escape" and return to copy state
// If current character is escape - stay is "escape" state // If current character is escape - stay is "escape" state
if (*first != '\\') { if (*src != '\\') {
*result++ = *mark++; *dst++ = *src;
state = STATE_COPY; state = STATE_COPY;
} else {
mark = src;
} }
break;
} }
state = STATE_COPY; state = STATE_COPY;
@ -288,28 +295,26 @@ _IT escape_backslashes(_IT first, _IT last) {
break; break;
} }
case STATE_OCTAL: { case STATE_OCTAL: {
if (*first >='0' && *first<='7') { if (*src >= '0' && *src <= '7') {
accVal = (accVal << 3) | (*first - '0'); accVal = (accVal << 3) | (*src - '0');
digitsCount++; digitsCount++;
// Up to 3 octal digits imposed by C standard, so after 3 digits accumulation stops. // Up to 3 octal digits imposed by C standard, so after 3 digits accumulation stops.
if (digitsCount == 3) { if (digitsCount == 3) {
*result++ = accVal; // output character corresponding to collected accumulated value *dst++ = accVal; // output character corresponding to collected accumulated value
digitsCount = 0; digitsCount = 0;
state = STATE_COPY; state = STATE_COPY;
} }
} } else {
else {
// invalid octal digit stops the accumulation // invalid octal digit stops the accumulation
*result++ = accVal; // output character corresponding to collected accumulated value *dst++ = accVal; // output character corresponding to collected accumulated value
digitsCount = 0; digitsCount = 0;
if (*first != '\\') { if (*src != '\\') {
// If terminating character is not backslash output the terminating character // If terminating character is not backslash output the terminating character
*result++ = *first; *dst++ = *src;
state = STATE_COPY; state = STATE_COPY;
} } else {
else {
// If terminating character is backslash start next escape sequence // If terminating character is backslash start next escape sequence
mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
} }
} }
@ -317,36 +322,33 @@ _IT escape_backslashes(_IT first, _IT last) {
break; break;
} }
case STATE_HEX: { case STATE_HEX: {
if (!isHexDigit(*first)) { if (!isHexDigit(*src)) {
// Copy from back-track, not including current character (which is absent), and continue // Copy from back-track, not including *src character (which is absent), and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
if (*first != '\\') { if (*src != '\\') {
// If terminating character is not backslash output the terminating character // If terminating character is not backslash output the terminating character
*result++ = *first; *dst++ = *src;
state = STATE_COPY; state = STATE_COPY;
} } else {
else {
// If terminating character is backslash start next escape sequence // If terminating character is backslash start next escape sequence
mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
} }
} } else {
else {
accVal = accVal << 4; accVal = accVal << 4;
if (isdigit(*first)) { if (isdigit(*src)) {
accVal += *first - '0'; accVal += *src - '0';
} } else if (*src >= 'a' && *src <= 'f') {
else if (*first >= 'a' && *first <= 'f') { accVal += *src - 'a' + 10;
accVal += *first - 'a' + 10; } else if (*src >= 'A' && *src <= 'F') {
} accVal += *src - 'A' + 10;
else if (*first >= 'A' && *first <= 'F') {
accVal += *first - 'A' + 10;
} }
digitsCount++; digitsCount++;
// exactly 2 hex digits are anticipated, so after 2 digits accumulation stops. // exactly 2 hex digits are anticipated, so after 2 digits accumulation stops.
if (digitsCount == 2) { if (digitsCount == 2) {
*result++ = accVal; // output character corresponding to collected accumulated value *dst++ = accVal; // output character corresponding to collected accumulated value
digitsCount = 0; digitsCount = 0;
state = STATE_COPY; state = STATE_COPY;
} }
@ -356,6 +358,7 @@ _IT escape_backslashes(_IT first, _IT last) {
} }
} }
if (dst < last) {
// Handle state at end of input // Handle state at end of input
bool copyBackTrack = true; bool copyBackTrack = true;
switch (state) { switch (state) {
@ -365,7 +368,7 @@ _IT escape_backslashes(_IT first, _IT last) {
break; break;
case STATE_OCTAL: case STATE_OCTAL:
// this can only happen when less than 3 octal digits are found at the value end, like '\1' or '\12' // this can only happen when less than 3 octal digits are found at the value end, like '\1' or '\12'
*result++ = accVal; // output character corresponding to collected accumulated value *dst++ = accVal; // output character corresponding to collected accumulated value
copyBackTrack = false; copyBackTrack = false;
break; break;
case STATE_COPY: case STATE_COPY:
@ -378,12 +381,13 @@ _IT escape_backslashes(_IT first, _IT last) {
if (copyBackTrack) { if (copyBackTrack) {
// invalid escape sequence - do not replace it (return original characters) // invalid escape sequence - do not replace it (return original characters)
// Copy from back-track // Copy from back-track
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
}
} }
} }
return result; return dst;
} }
inline bool str_contains(const std::string &haystack, const std::string &needle) inline bool str_contains(const std::string &haystack, const std::string &needle)
@ -401,7 +405,8 @@ extern const size_t g_htmlEntitiesCount;
template<class _IT> template<class _IT>
_IT escape_html(_IT first, _IT last) { _IT escape_html(_IT first, _IT last) {
_IT result = first; _IT dst = first;
_IT src = first;
enum { enum {
STATE_COPY, STATE_COPY,
STATE_ESCAPE, STATE_ESCAPE,
@ -414,26 +419,26 @@ _IT escape_html(_IT first, _IT last) {
std::list<size_t> potentialMatchIndices; std::list<size_t> potentialMatchIndices;
size_t matchLength = 0; size_t matchLength = 0;
size_t lastKnownMatchIndex = -1; size_t lastKnownMatchIndex = -1;
_IT mark = first; _IT mark = src;
for (; first != last; ++first) { for (; src != last && dst < last; ++src) {
switch (state) { switch (state) {
case STATE_COPY: case STATE_COPY:
if (*first == '&') { if (*src == '&') {
mark = first; mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
} }
else { else {
*result++ = *first; *dst++ = *src;
} }
break; break;
case STATE_ESCAPE: case STATE_ESCAPE:
if (isalpha(*first)) { if (isalpha(*src)) {
// initialize potential matches list // initialize potential matches list
potentialMatchIndices.clear(); potentialMatchIndices.clear();
for (size_t index = 0; index < g_htmlEntitiesCount; ++index) { for (size_t index = 0; index < g_htmlEntitiesCount; ++index) {
if (*first == g_htmlEntities[index].name[0]) { if (*src == g_htmlEntities[index].name[0]) {
potentialMatchIndices.push_back(index); potentialMatchIndices.push_back(index);
lastKnownMatchIndex = index; lastKnownMatchIndex = index;
} }
@ -441,8 +446,8 @@ _IT escape_html(_IT first, _IT last) {
// No potential matches - send ampersand and current character to output // No potential matches - send ampersand and current character to output
if (potentialMatchIndices.size() == 0) { if (potentialMatchIndices.size() == 0) {
*result++ = '&'; *dst++ = '&';
*result++ = *first; *dst++ = *src;
state = STATE_COPY; state = STATE_COPY;
break; break;
} }
@ -451,7 +456,7 @@ _IT escape_html(_IT first, _IT last) {
matchLength = 1; matchLength = 1;
state = STATE_NAMED_CHARACTER_REFERENCE; state = STATE_NAMED_CHARACTER_REFERENCE;
} }
else if (*first == '#') { else if (*src == '#') {
digitsSeen = 0; digitsSeen = 0;
accVal = 0; accVal = 0;
state = STATE_NUMERIC_START; state = STATE_NUMERIC_START;
@ -459,8 +464,8 @@ _IT escape_html(_IT first, _IT last) {
else { else {
// not isalpha and not '#' - this is invalid character reference - do not replace it // not isalpha and not '#' - this is invalid character reference - do not replace it
// (return original characters) // (return original characters)
*result++ = '&'; *dst++ = '&';
*result++ = *first; *dst++ = *src;
state = STATE_COPY; state = STATE_COPY;
} }
break; break;
@ -479,7 +484,7 @@ _IT escape_html(_IT first, _IT last) {
// If there are no more characters in the potntial match name, // If there are no more characters in the potntial match name,
// or the next tested character doesn't match - kill the match // or the next tested character doesn't match - kill the match
if ((matchName[matchLength] == '\0') || (matchName[matchLength] != *first)) { if ((matchName[matchLength] == '\0') || (matchName[matchLength] != *src)) {
// remove current element from the list of potential matches // remove current element from the list of potential matches
pPotentialMatchIndex = potentialMatchIndices.erase(pPotentialMatchIndex); pPotentialMatchIndex = potentialMatchIndices.erase(pPotentialMatchIndex);
} }
@ -495,15 +500,15 @@ _IT escape_html(_IT first, _IT last) {
// No more potential matches: unsuccesful match -> flush all consumed characters back to output stream // No more potential matches: unsuccesful match -> flush all consumed characters back to output stream
if (potentialMatchIndices.size() == 0) { if (potentialMatchIndices.size() == 0) {
// Send consumed ampersand to the output // Send consumed ampersand to the output
*result++ = '&'; *dst++ = '&';
// Send those matched characters (these are the same that we consumed) - to the output // Send those matched characters (these are the same that we consumed) - to the output
for (size_t i = 0; i < matchLength; i++) { for (size_t i = 0; i < matchLength; i++) {
*result++ = g_htmlEntities[lastKnownMatchIndex].name[i]; *dst++ = g_htmlEntities[lastKnownMatchIndex].name[i];
} }
// Send the character that terminated our search for possible matches // Send the character that terminated our search for possible matches
*result++ = *first; *dst++ = *src;
// Continue copying text verbatim // Continue copying text verbatim
state = STATE_COPY; state = STATE_COPY;
@ -511,23 +516,23 @@ _IT escape_html(_IT first, _IT last) {
} }
// There are still potential matches and ';' is hit // There are still potential matches and ';' is hit
if (*first == ';') { if (*src == ';') {
// longest match found for the named character reference. // longest match found for the named character reference.
// translate it into output character(s) and we're done. // translate it into output character(s) and we're done.
unsigned short value = g_htmlEntities[lastKnownMatchIndex].value; unsigned short value = g_htmlEntities[lastKnownMatchIndex].value;
// Encode UTF code point as UTF-8 bytes // Encode UTF code point as UTF-8 bytes
if (value < 0x80) { if (value < 0x80) {
*result++ = value; *dst++ = value;
} }
else if (value < 0x800 ) { else if (value < 0x800 ) {
*result++ = (value >> 6) | 0xC0; *dst++ = (value >> 6) | 0xC0;
*result++ = (value & 0x3F) | 0x80; *dst++ = (value & 0x3F) | 0x80;
} }
else { // (value <= 0xFFFF : always true because value type is unsigned short which is 16-bit else { // (value <= 0xFFFF : always true because value type is unsigned short which is 16-bit
*result++ = (value >> 12) | 0xE0; *dst++ = (value >> 12) | 0xE0;
*result++ = ((value >> 6) & 0x3F) | 0x80; *dst++ = ((value >> 6) & 0x3F) | 0x80;
*result++ = (value & 0x3F) | 0x80; *dst++ = (value & 0x3F) | 0x80;
} }
// Continue copying text verbatim // Continue copying text verbatim
@ -538,178 +543,179 @@ _IT escape_html(_IT first, _IT last) {
case STATE_NUMERIC_START: case STATE_NUMERIC_START:
digitsSeen = false; digitsSeen = false;
accVal = 0; accVal = 0;
if (*first == 'x' || *first == 'X') { if (*src == 'x' || *src == 'X') {
state = STATE_HEX; state = STATE_HEX;
} }
else if (isdigit(*first)) { else if (isdigit(*src)) {
digitsSeen = true; digitsSeen = true;
accVal = *first - '0'; accVal = *src - '0';
state = STATE_NUMERIC; state = STATE_NUMERIC;
} }
else { else {
// Sequence started with these two characters: '&#', and here is the third, non-digit character // Sequence started with these two characters: '&#', and here is the third, non-digit character
// Copy from back-track, not including current character, and continue // Copy from back-track, not including current character, and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
if (*first == '&') { if (*src == '&') {
// Terminator is also start of next escape sequence // Terminator is also start of next escape sequence
mark = first; mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
break; break;
} }
else { else {
// Copy the terminating character too // Copy the terminating character too
*result++ = *first; *dst++ = *src;
} }
state = STATE_COPY; state = STATE_COPY;
} }
break; break;
case STATE_NUMERIC: case STATE_NUMERIC:
if (!isdigit(*first)) { if (!isdigit(*src)) {
if (digitsSeen) { if (digitsSeen) {
// Encode UTF code point as UTF-8 bytes // Encode UTF code point as UTF-8 bytes
if (accVal < 0x80) { if (accVal < 0x80) {
*result++ = accVal; *dst++ = accVal;
} }
else if (accVal < 0x800 ) { else if (accVal < 0x800 ) {
*result++ = (accVal >> 6) | 0xC0; *dst++ = (accVal >> 6) | 0xC0;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = (accVal & 0x3F) | 0x80;
} }
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
*result++ = (accVal >> 12) | 0xE0; *dst++ = (accVal >> 12) | 0xE0;
*result++ = ((accVal >> 6) & 0x3F) | 0x80; *dst++ = ((accVal >> 6) & 0x3F) | 0x80;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = (accVal & 0x3F) | 0x80;
} }
} }
else { else {
// Copy from back-track, not including current character (which is absent), and continue // Copy from back-track, not including current character (which is absent), and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
} }
if (*first == '&') { if (*src == '&') {
// Terminator is also start of next escape sequence // Terminator is also start of next escape sequence
mark = first; mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
break; break;
} }
else if (!digitsSeen || *first != ';') { else if (!digitsSeen || *src != ';') {
// Do not copy the ';' but do copy any other terminator // Do not copy the ';' but do copy any other terminator
// Note: the ';' should remain in the output if there were no digits seen. // Note: the ';' should remain in the output if there were no digits seen.
*result++ = *first; *dst++ = *src;
} }
state = STATE_COPY; state = STATE_COPY;
} }
else { else {
digitsSeen = true; digitsSeen = true;
accVal = accVal * 10 + *first - '0'; // TODO:: beware of integer overflow? accVal = accVal * 10 + *src - '0'; // TODO:: beware of integer overflow?
} }
break; break;
case STATE_HEX: case STATE_HEX:
if (!isHexDigit(*first)) { if (!isHexDigit(*src)) {
if (digitsSeen) { if (digitsSeen) {
// Encode UTF code point as UTF-8 bytes // Encode UTF code point as UTF-8 bytes
if (accVal < 0x80) { if (accVal < 0x80) {
*result++ = accVal; *dst++ = accVal;
} }
else if (accVal < 0x800 ) { else if (accVal < 0x800 ) {
*result++ = (accVal >> 6) | 0xC0; *dst++ = (accVal >> 6) | 0xC0;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = (accVal & 0x3F) | 0x80;
} }
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
*result++ = (accVal >> 12) | 0xE0; *dst++ = (accVal >> 12) | 0xE0;
*result++ = ((accVal >> 6) & 0x3F) | 0x80; *dst++ = ((accVal >> 6) & 0x3F) | 0x80;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = (accVal & 0x3F) | 0x80;
} }
} }
else { else {
// Copy from back-track, not including current character (which is absent), and continue // Copy from back-track, not including current character (which is absent), and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
} }
if (*first == '&') { if (*src == '&') {
// Terminator is also start of next escape sequence // Terminator is also start of next escape sequence
mark = first; mark = src;
state = STATE_ESCAPE; state = STATE_ESCAPE;
break; break;
} }
else if (!digitsSeen || *first != ';') { else if (!digitsSeen || *src != ';') {
// Do not copy the ';' but do copy any other terminator // Do not copy the ';' but do copy any other terminator
// Note: the ';' should remain in the output if there were no digits seen. // Note: the ';' should remain in the output if there were no digits seen.
*result++ = *first; *dst++ = *src;
} }
state = STATE_COPY; state = STATE_COPY;
} }
else { else {
digitsSeen = true; digitsSeen = true;
accVal = accVal << 4; accVal = accVal << 4;
if (isdigit(*first)) { if (isdigit(*src)) {
accVal += *first - '0'; accVal += *src - '0';
} }
else if (*first >= 'a' && *first <= 'f') { else if (*src >= 'a' && *src <= 'f') {
accVal += *first - 'a' + 10; accVal += *src - 'a' + 10;
} }
else if (*first >= 'A' && *first <= 'F') { else if (*src >= 'A' && *src <= 'F') {
accVal += *first - 'A' + 10; accVal += *src - 'A' + 10;
} }
} }
break; break;
} }
} }
if (state == STATE_ESCAPE) { if (state == STATE_ESCAPE && dst < last) {
*result++ = '&'; *dst++ = '&';
} }
else if (state == STATE_NAMED_CHARACTER_REFERENCE && potentialMatchIndices.size() > 0) { else if (state == STATE_NAMED_CHARACTER_REFERENCE && potentialMatchIndices.size() > 0 && dst < last) {
// Send consumed ampersand to the output // Send consumed ampersand to the output
*result++ = '&'; *dst++ = '&';
// Send those matched characters (these are the same that we consumed) - to the output // Send those matched characters (these are the same that we consumed) - to the output
for (size_t i = 0; i < matchLength; i++) { for (size_t i = 0; i < matchLength && dst < last; i++) {
// Even if there are multiple potential matches, all of them start with the same // Even if there are multiple potential matches, all of them start with the same
// matchLength characters that we consumed! // matchLength characters that we consumed!
*result++ = g_htmlEntities[lastKnownMatchIndex].name[i]; *dst++ = g_htmlEntities[lastKnownMatchIndex].name[i];
} }
} }
if (state == STATE_HEX && !digitsSeen) { // Special case of "&#x" if (state == STATE_HEX && !digitsSeen) { // Special case of "&#x"
// Copy from back-track, not including current character (which is absent), and continue // Copy from back-track, not including current character (which is absent), and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
state = STATE_COPY; state = STATE_COPY;
} }
else if (state == STATE_HEX || state == STATE_NUMERIC || state == STATE_NUMERIC_START) { else if (state == STATE_HEX || state == STATE_NUMERIC || state == STATE_NUMERIC_START) {
if (digitsSeen) { if (digitsSeen && dst < last) {
// Encode UTF code point as UTF-8 bytes // Encode UTF code point as UTF-8 bytes
if (accVal < 0x80) { if (accVal < 0x80) {
*result++ = accVal; *dst++ = accVal;
} }
else if (accVal < 0x800 ) { else if (accVal < 0x800 && std::distance(dst, last) >= 2) {
*result++ = (accVal >> 6) | 0xC0; *dst++ = (accVal >> 6) | 0xC0;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = (accVal & 0x3F) | 0x80;
} }
else { // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit // (accVal <= 0xFFFF : always true because accVal type is unsigned short which is 16-bit
*result++ = (accVal >> 12) | 0xE0; else if (std::distance(dst, last) >= 3) {
*result++ = ((accVal >> 6) & 0x3F) | 0x80; *dst++ = (accVal >> 12) | 0xE0;
*result++ = (accVal & 0x3F) | 0x80; *dst++ = ((accVal >> 6) & 0x3F) | 0x80;
*dst++ = (accVal & 0x3F) | 0x80;
} }
} }
else { else {
// Copy from back-track, not including current character (which is absent), and continue // Copy from back-track, not including current character (which is absent), and continue
while (mark < first) { while (dst <= mark && mark < src) {
*result++ = *mark++; *dst++ = *mark++;
} }
state = STATE_COPY; state = STATE_COPY;
} }
} }
return result; return dst;
} }
// Compare two buffers, case insensitive. Return true if they are equal (case-insensitive) // Compare two buffers, case insensitive. Return true if they are equal (case-insensitive)

View File

@ -43,6 +43,7 @@
#include "agent_core_utilities.h" #include "agent_core_utilities.h"
#define stack_trace_max_len 64 #define stack_trace_max_len 64
#define STACK_SIZE (1024 * 1024) // 1 MB stack size
using namespace std; using namespace std;
using namespace ReportIS; using namespace ReportIS;
@ -57,6 +58,12 @@ public:
{ {
if (out_trace_file_fd != -1) close(out_trace_file_fd); if (out_trace_file_fd != -1) close(out_trace_file_fd);
out_trace_file_fd = -1; out_trace_file_fd = -1;
if (alt_stack.ss_sp != nullptr) {
free(alt_stack.ss_sp);
alt_stack.ss_sp = nullptr;
alt_stack_initialized = false;
}
} }
void void
@ -69,6 +76,7 @@ public:
void void
init() init()
{ {
alt_stack.ss_sp = nullptr;
addSignalHandlerRoutine(); addSignalHandlerRoutine();
addReloadConfigurationRoutine(); addReloadConfigurationRoutine();
} }
@ -244,6 +252,28 @@ private:
setHandlerPerSignalNum(); setHandlerPerSignalNum();
} }
bool
setupAlternateSignalStack()
{
if (alt_stack_initialized) return true;
alt_stack.ss_sp = malloc(STACK_SIZE);
if (alt_stack.ss_sp == nullptr) {
dbgWarning(D_SIGNAL_HANDLER) << "Failed to allocate alternate stack";
return false;
}
alt_stack.ss_size = STACK_SIZE;
alt_stack.ss_flags = 0;
if (sigaltstack(&alt_stack, nullptr) == -1) {
dbgWarning(D_SIGNAL_HANDLER) << "Failed to set up alternate stack";
free(alt_stack.ss_sp);
return false;
}
dbgInfo(D_SIGNAL_HANDLER) << "Alternate stack allocated successfully. Allocated size: " << STACK_SIZE;
alt_stack_initialized = true;
return true;
}
void void
setHandlerPerSignalNum() setHandlerPerSignalNum()
{ {
@ -261,9 +291,30 @@ private:
SIGUSR2 SIGUSR2
}; };
if (!setupAlternateSignalStack()) {
dbgWarning(D_SIGNAL_HANDLER) << "Failed to set up alternate signal stack";
for (int sig : signals) { for (int sig : signals) {
signal(sig, signalHandlerCB); signal(sig, signalHandlerCB);
} }
return;
}
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sa.sa_sigaction = signalActionHandlerCB;
sigemptyset(&sa.sa_mask);
for (int sig : signals) {
if (sig == SIGKILL || sig == SIGSTOP) {
signal(sig, signalHandlerCB);
continue;
}
if (sigaction(sig, &sa, nullptr) == -1) {
dbgError(D_SIGNAL_HANDLER) << "Failed to set signal handler for signal " << sig;
}
}
} }
// LCOV_EXCL_START Reason: Cannot crash unitest or send signal during execution // LCOV_EXCL_START Reason: Cannot crash unitest or send signal during execution
@ -284,55 +335,30 @@ private:
static void static void
signalHandlerCB(int _signal) signalHandlerCB(int _signal)
{ {
const char *signal_name = ""; const char *signal_name = strsignal(_signal);
char signal_num[3]; char signal_num[3];
snprintf(signal_num, sizeof(signal_num), "%d", _signal);
if (out_trace_file_fd == -1) exit(_signal);
reset_signal_handler = true; reset_signal_handler = true;
switch(_signal) { switch(_signal) {
case SIGABRT: { case SIGABRT:
signal_name = "SIGABRT"; case SIGKILL:
fini_signal_flag = true; case SIGQUIT:
return; case SIGINT:
}
case SIGKILL: {
signal_name = "SIGKILL";
fini_signal_flag = true;
return;
}
case SIGQUIT: {
signal_name = "SIGQUIT";
fini_signal_flag = true;
return;
}
case SIGINT: {
signal_name = "SIGINT";
fini_signal_flag = true;
return;
}
case SIGTERM: { case SIGTERM: {
signal_name = "SIGTERM";
fini_signal_flag = true; fini_signal_flag = true;
return; return;
} }
case SIGSEGV: { case SIGSEGV:
signal_name = "SIGSEGV"; case SIGBUS:
break; case SIGILL:
}
case SIGBUS: {
signal_name = "SIGBUS";
break;
}
case SIGILL: {
signal_name = "SIGILL";
break;
}
case SIGFPE: { case SIGFPE: {
signal_name = "SIGFPE";
break; break;
} }
case SIGPIPE: { case SIGPIPE: {
signal_name = "SIGPIPE";
return; return;
} }
case SIGUSR2: { case SIGUSR2: {
@ -341,13 +367,6 @@ private:
} }
} }
if (out_trace_file_fd == -1) exit(_signal);
for (uint i = 0; i < sizeof(signal_num); ++i) {
uint placement = sizeof(signal_num) - 1 - i;
signal_num[placement] = _signal%10 + '0';
_signal /= 10;
}
const char *signal_error_prefix = "Caught signal "; const char *signal_error_prefix = "Caught signal ";
writeData(signal_error_prefix, strlen(signal_error_prefix)); writeData(signal_error_prefix, strlen(signal_error_prefix));
writeData(signal_num, sizeof(signal_num)); writeData(signal_num, sizeof(signal_num));
@ -367,6 +386,12 @@ private:
exit(_signal); exit(_signal);
} }
static void
signalActionHandlerCB(int signum, siginfo_t *, void *)
{
signalHandlerCB(signum);
}
static void static void
printStackTrace() printStackTrace()
{ {
@ -391,16 +416,22 @@ private:
for (uint i = 0 ; i < stack_trace_max_len ; i++) { for (uint i = 0 ; i < stack_trace_max_len ; i++) {
unw_get_reg(&cursor, UNW_REG_IP, &ip); unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp); unw_get_reg(&cursor, UNW_REG_SP, &sp);
int procNameRc = unw_get_proc_name(&cursor, name, sizeof(name), &off);
if (unw_get_proc_name(&cursor, name, sizeof(name), &off) == 0) { if (procNameRc == 0 || procNameRc == -UNW_ENOMEM) {
const char *open_braces = "<"; const char *open_braces = "<";
writeData(open_braces, strlen(open_braces)); writeData(open_braces, strlen(open_braces));
writeData(name, strlen(name)); writeData(name, strnlen(name, sizeof(name)));
if (procNameRc != 0) {
const char *dots = "...";
writeData(dots, strlen(dots));
}
const char *close_braces = ">\n"; const char *close_braces = ">\n";
writeData(close_braces, strlen(close_braces)); writeData(close_braces, strlen(close_braces));
} else {
const char *error = " -- error: unable to obtain symbol name for this frame\n";
writeData(error, strlen(error));
} }
if (unw_step(&cursor) <= 0) return; if (unw_step(&cursor) <= 0) return;
} }
@ -444,12 +475,16 @@ private:
static bool reload_settings_flag; static bool reload_settings_flag;
static bool reset_signal_handler; static bool reset_signal_handler;
static int out_trace_file_fd; static int out_trace_file_fd;
static stack_t alt_stack;
static bool alt_stack_initialized;
}; };
string SignalHandler::Impl::trace_file_path; string SignalHandler::Impl::trace_file_path;
bool SignalHandler::Impl::reload_settings_flag = false; bool SignalHandler::Impl::reload_settings_flag = false;
bool SignalHandler::Impl::reset_signal_handler = false; bool SignalHandler::Impl::reset_signal_handler = false;
int SignalHandler::Impl::out_trace_file_fd = -1; int SignalHandler::Impl::out_trace_file_fd = -1;
stack_t SignalHandler::Impl::alt_stack;
bool SignalHandler::Impl::alt_stack_initialized = false;
SignalHandler::SignalHandler() : Component("SignalHandler"), pimpl(make_unique<Impl>()) {} SignalHandler::SignalHandler() : Component("SignalHandler"), pimpl(make_unique<Impl>()) {}
SignalHandler::~SignalHandler() {} SignalHandler::~SignalHandler() {}

View File

@ -276,6 +276,7 @@ void
AgentDetails::preload() AgentDetails::preload()
{ {
registerExpectedConfiguration<string>("orchestration", "Agent details path"); registerExpectedConfiguration<string>("orchestration", "Agent details path");
registerExpectedConfiguration<string>("Agent details", "File path");
registerConfigLoadCb([this] () { readAgentDetails(); }); registerConfigLoadCb([this] () { readAgentDetails(); });
} }

View File

@ -68,6 +68,7 @@ public:
const Maybe<string> &agent_version const Maybe<string> &agent_version
) override; ) override;
pair<string, string> generateTimeStamp();
bool addAttr(const string &key, const string &val, bool allow_override = false) override; bool addAttr(const string &key, const string &val, bool allow_override = false) override;
bool addAttr(const map<string, string> &attr, bool allow_override = false) override; bool addAttr(const map<string, string> &attr, bool allow_override = false) override;
void deleteAttr(const string &key) override; void deleteAttr(const string &key) override;
@ -218,6 +219,13 @@ AgentDetailsReporter::Impl::isPersistantAttr(const std::string &key)
return persistant_attributes.count(key) > 0; return persistant_attributes.count(key) > 0;
} }
pair<string, string>
AgentDetailsReporter::Impl::generateTimeStamp()
{
auto time_stamp = Singleton::Consume<I_TimeGet>::by<AgentDetailsReporter>()->getWalltimeStr();
return make_pair("timestamp", time_stamp);
}
bool bool
AgentDetailsReporter::Impl::sendAttributes() AgentDetailsReporter::Impl::sendAttributes()
{ {
@ -232,11 +240,10 @@ AgentDetailsReporter::Impl::sendAttributes()
attributes[new_attr.first] = new_attr.second; attributes[new_attr.first] = new_attr.second;
} }
AttributesSender attr_to_send(attributes); AttributesSender attr_to_send(attributes);
if (is_server) { if (is_server) {
AttrSerializer<ofstream, cereal::JSONOutputArchive>(attributes, "save"); AttrSerializer<ofstream, cereal::JSONOutputArchive>(attributes, "save");
attr_to_send.attributes.get().insert(generateTimeStamp());
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", attr_to_send); messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", attr_to_send);
dbgDebug(D_AGENT_DETAILS) << "Triggered persistent message request with attributes to the Fog"; dbgDebug(D_AGENT_DETAILS) << "Triggered persistent message request with attributes to the Fog";
new_attributes.clear(); new_attributes.clear();
@ -322,6 +329,36 @@ public:
attributes = attr; attributes = attr;
} }
void
addAttr(const string &key, const string &val, bool allow_override = false)
{
dbgDebug(D_AGENT_DETAILS)
<< "Trying to add new attribute. Key: "
<< key
<< ", Value: "
<< val
<< " Should allow override: "
<< (allow_override ? "true" : "false");
auto &attr = attributes.get();
if (!allow_override) {
if (attr.count(key) > 0) {
dbgWarning(D_AGENT_DETAILS)
<< "Cannot override an existing value with a new one. Existing Value: "
<< (attr.count(key) > 0 ? attr[key] : "");
return;
}
}
attr[key] = val;
if (!attributes.isActive()) attributes.setActive(true);
}
void
addAttr(const pair<string, string> &attr, bool allow_override = false)
{
addAttr(attr.first, attr.second, allow_override);
}
private: private:
C2S_PARAM(metaDataReport, additionalMetaData); C2S_PARAM(metaDataReport, additionalMetaData);
C2S_OPTIONAL_PARAM(string, agentVersion); C2S_OPTIONAL_PARAM(string, agentVersion);
@ -402,6 +439,7 @@ AgentDetailsReporter::Impl::sendReport(
additional_metadata.setAdditionalAttributes(attributes); additional_metadata.setAdditionalAttributes(attributes);
} }
additional_metadata.addAttr(generateTimeStamp());
messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", additional_metadata); messaging->sendAsyncMessage(HTTPMethod::PATCH, "/agents", additional_metadata);
} }

View File

@ -8,6 +8,7 @@
#include "mock/mock_messaging.h" #include "mock/mock_messaging.h"
#include "mock/mock_mainloop.h" #include "mock/mock_mainloop.h"
#include "mock/mock_rest_api.h" #include "mock/mock_rest_api.h"
#include "mock/mock_time_get.h"
#include "environment.h" #include "environment.h"
#include "agent_details_report.h" #include "agent_details_report.h"
@ -73,6 +74,7 @@ public:
StrictMock<MockMainLoop> mock_mainloop; StrictMock<MockMainLoop> mock_mainloop;
StrictMock<MockMessaging> mock_messaging; StrictMock<MockMessaging> mock_messaging;
StrictMock<MockRestApi> mock_rest; StrictMock<MockRestApi> mock_rest;
StrictMock<MockTimeGet> mock_time_get;
I_MainLoop::Routine periodic_report; I_MainLoop::Routine periodic_report;
I_AgentDetailsReporter *report; I_AgentDetailsReporter *report;
CPTestTempfile persistence_attr_file; CPTestTempfile persistence_attr_file;
@ -85,6 +87,7 @@ public:
TEST_F(AgentReporterTest, dataReport) TEST_F(AgentReporterTest, dataReport)
{ {
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
string custom_data = "Linux version 24.00.15F"; string custom_data = "Linux version 24.00.15F";
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
@ -92,26 +95,33 @@ TEST_F(AgentReporterTest, dataReport)
"{\n" "{\n"
" \"additionalMetaData\": {\n" " \"additionalMetaData\": {\n"
" \"custom_data\": \"Linux version 24.00.15F\"\n" " \"custom_data\": \"Linux version 24.00.15F\"\n"
" }" " },\n"
"\n}", " \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
_ _
)).Times(1); )).Times(1);
AgentDataReport() << AgentReportField(custom_data);; AgentDataReport() << AgentReportField(custom_data);
} }
TEST_F(AgentReporterTest, labeledDataReport) TEST_F(AgentReporterTest, labeledDataReport)
{ {
string data = "Linux version 24.00.15F"; string data = "Linux version 24.00.15F";
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
"{\n" "{\n"
" \"additionalMetaData\": {\n" " \"additionalMetaData\": {\n"
" \"this_is_custom_label\": \"Linux version 24.00.15F\"\n" " \"this_is_custom_label\": \"Linux version 24.00.15F\"\n"
" }" " },\n"
"\n}", " \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
_ _
@ -123,6 +133,7 @@ TEST_F(AgentReporterTest, multiDataReport)
{ {
string custom_data = "Linux version 24.00.15F"; string custom_data = "Linux version 24.00.15F";
string data_to_report = "Agent Version 95.95.95.00A"; string data_to_report = "Agent Version 95.95.95.00A";
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
@ -130,8 +141,11 @@ TEST_F(AgentReporterTest, multiDataReport)
" \"additionalMetaData\": {\n" " \"additionalMetaData\": {\n"
" \"custom_data\": \"Linux version 24.00.15F\",\n" " \"custom_data\": \"Linux version 24.00.15F\",\n"
" \"this_is_custom_label\": \"Agent Version 95.95.95.00A\"\n" " \"this_is_custom_label\": \"Agent Version 95.95.95.00A\"\n"
" }" " },\n"
"\n}", " \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
_ _
@ -146,7 +160,7 @@ TEST_F(AgentReporterTest, multiDataReportWithRegistrationData)
{ {
string custom_data = "Linux version 24.00.15F"; string custom_data = "Linux version 24.00.15F";
string data_to_report = "Agent Version 95.95.95.00A"; string data_to_report = "Agent Version 95.95.95.00A";
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
@ -158,7 +172,10 @@ TEST_F(AgentReporterTest, multiDataReportWithRegistrationData)
" \"agentVersion\": \"1.15.9\",\n" " \"agentVersion\": \"1.15.9\",\n"
" \"policyVersion\": \"ccc\",\n" " \"policyVersion\": \"ccc\",\n"
" \"platform\": \"bbb\",\n" " \"platform\": \"bbb\",\n"
" \"architecture\": \"aaa\"\n" " \"architecture\": \"aaa\",\n"
" \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
@ -178,11 +195,15 @@ TEST_F(AgentReporterTest, multiDataReportWithRegistrationData)
TEST_F(AgentReporterTest, basicAttrTest) TEST_F(AgentReporterTest, basicAttrTest)
{ {
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
"{\n" "{\n"
" \"additionalMetaData\": {}\n" " \"additionalMetaData\": {},\n"
" \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
@ -193,6 +214,7 @@ TEST_F(AgentReporterTest, basicAttrTest)
AgentDataReport agent_data; AgentDataReport agent_data;
} }
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
@ -201,7 +223,8 @@ TEST_F(AgentReporterTest, basicAttrTest)
" \"attributes\": {\n" " \"attributes\": {\n"
" \"1\": \"2\",\n" " \"1\": \"2\",\n"
" \"a\": \"1\",\n" " \"a\": \"1\",\n"
" \"c\": \"d\"\n" " \"c\": \"d\",\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n" " }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
@ -219,11 +242,15 @@ TEST_F(AgentReporterTest, basicAttrTest)
AgentDataReport agent_data; AgentDataReport agent_data;
} }
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
"{\n" "{\n"
" \"additionalMetaData\": {}\n" " \"additionalMetaData\": {},\n"
" \"attributes\": {\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
@ -242,7 +269,7 @@ TEST_F(AgentReporterTest, advancedAttrTest)
EXPECT_TRUE(report->addAttr({{"c", "d"}, {"1", "2"}, {"send", "me"}})); EXPECT_TRUE(report->addAttr({{"c", "d"}, {"1", "2"}, {"send", "me"}}));
EXPECT_TRUE(report->addAttr("a", "b")); EXPECT_TRUE(report->addAttr("a", "b"));
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
@ -251,7 +278,8 @@ TEST_F(AgentReporterTest, advancedAttrTest)
" \"1\": \"2\",\n" " \"1\": \"2\",\n"
" \"a\": \"b\",\n" " \"a\": \"b\",\n"
" \"c\": \"d\",\n" " \"c\": \"d\",\n"
" \"send\": \"me\"\n" " \"send\": \"me\",\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n" " }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
@ -268,6 +296,7 @@ TEST_F(AgentReporterTest, advancedAttrTest)
EXPECT_TRUE(report->addAttr("new", "key val")); EXPECT_TRUE(report->addAttr("new", "key val"));
EXPECT_TRUE(report->addAttr("a", "key val override", true)); EXPECT_TRUE(report->addAttr("a", "key val override", true));
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
@ -277,7 +306,8 @@ TEST_F(AgentReporterTest, advancedAttrTest)
" \"a\": \"key val override\",\n" " \"a\": \"key val override\",\n"
" \"c\": \"d\",\n" " \"c\": \"d\",\n"
" \"new\": \"key val\",\n" " \"new\": \"key val\",\n"
" \"send\": \"me\"\n" " \"send\": \"me\",\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n" " }\n"
"}", "}",
MessageCategory::GENERIC, MessageCategory::GENERIC,
@ -291,6 +321,7 @@ TEST_F(AgentReporterTest, advancedAttrTest)
TEST_F(AgentReporterTest, RestDetailsTest) TEST_F(AgentReporterTest, RestDetailsTest)
{ {
stringstream rest_call_parameters; stringstream rest_call_parameters;
stringstream rest_call_parameters_with_timestamp;
rest_call_parameters rest_call_parameters
<< "{\n" << "{\n"
<< " \"attributes\": {\n" << " \"attributes\": {\n"
@ -300,17 +331,28 @@ TEST_F(AgentReporterTest, RestDetailsTest)
<< " \"send\": \"me\"\n" << " \"send\": \"me\"\n"
<< " }\n" << " }\n"
<< "}"; << "}";
rest_call_parameters_with_timestamp
<< "{\n"
<< " \"attributes\": {\n"
<< " \"1\": \"2\",\n"
<< " \"a\": \"key val override\",\n"
<< " \"c\": \"d\",\n"
<< " \"send\": \"me\",\n"
<< " \"timestamp\": \"Best Time ever\"\n"
<< " }\n"
<< "}";
add_details_rest_cb->performRestCall(rest_call_parameters); add_details_rest_cb->performRestCall(rest_call_parameters);
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
rest_call_parameters.str(), rest_call_parameters_with_timestamp.str(),
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
_ _
)).Times(1); )).Times(1);
EXPECT_TRUE(report->sendAttributes()); EXPECT_TRUE(report->sendAttributes());
is_server_mode = false; is_server_mode = false;
@ -365,6 +407,18 @@ TEST_F(AgentReporterTest, PersistenceAttrTest)
"}" "}"
); );
string expected_attributes_with_timestamp(
"{\n"
" \"attributes\": {\n"
" \"1\": \"2\",\n"
" \"a\": \"key val override\",\n"
" \"c\": \"d\",\n"
" \"send\": \"me\",\n"
" \"timestamp\": \"Best Time ever\"\n"
" }\n"
"}"
);
write_attributes << expected_attributes; write_attributes << expected_attributes;
write_attributes.close(); write_attributes.close();
@ -372,10 +426,11 @@ TEST_F(AgentReporterTest, PersistenceAttrTest)
EXPECT_CALL(mock_rest, mockRestCall(RestAction::ADD, "agent-details-attr", _)).WillOnce(Return(true)); EXPECT_CALL(mock_rest, mockRestCall(RestAction::ADD, "agent-details-attr", _)).WillOnce(Return(true));
agent_details_reporter_comp.init(); agent_details_reporter_comp.init();
EXPECT_CALL(mock_time_get, getWalltimeStr()).WillOnce(Return("Best Time ever"));
EXPECT_CALL(mock_messaging, sendAsyncMessage( EXPECT_CALL(mock_messaging, sendAsyncMessage(
HTTPMethod::PATCH, HTTPMethod::PATCH,
"/agents", "/agents",
expected_attributes, expected_attributes_with_timestamp,
MessageCategory::GENERIC, MessageCategory::GENERIC,
_, _,
_ _

View File

@ -30,6 +30,7 @@ class AgentDetailsReporter
Singleton::Consume<I_Messaging>, Singleton::Consume<I_Messaging>,
Singleton::Consume<I_MainLoop>, Singleton::Consume<I_MainLoop>,
Singleton::Consume<I_Environment>, Singleton::Consume<I_Environment>,
Singleton::Consume<I_TimeGet>,
Singleton::Consume<I_RestApi> Singleton::Consume<I_RestApi>
{ {
public: public:

View File

@ -53,6 +53,51 @@ private:
std::map<std::string, std::set<std::string>> set_string_attr; std::map<std::string, std::set<std::string>> set_string_attr;
}; };
class IpAddressRange
{
public:
IpAddressRange() = default;
IpAddressRange(const std::string &min, const std::string &max) : min(min), max(max) {}
bool operator==(const IpAddressRange &other) const { return min == other.min && max == other.max; }
const std::string getMin() const { return min; }
const std::string getMax() const { return max; }
template <class Archive>
void serialize(Archive &ar) {
ar(CEREAL_NVP(max), CEREAL_NVP(min));
}
private:
std::string min;
std::string max;
};
class IpAttributes
{
public:
IpAttributes() = default;
IpAttributes & addIpv4Addresses(const std::string &val);
IpAttributes & addIpv6Addresses(const std::string &val);
IpAttributes & addIpv4AddressRanges(const IpAddressRange &val);
IpAttributes & addIpv6AddressRanges(const IpAddressRange &val);
Maybe<std::vector<std::string>, void> getIpv4Addresses() const;
Maybe<std::vector<std::string>, void> getIpv6Addresses() const;
Maybe<std::vector<IpAddressRange>, void> getIpv4AddressRanges() const;
Maybe<std::vector<IpAddressRange>, void> getIpv6AddressRanges() const;
Maybe<std::string, void> genObject() const;
bool isEmpty() const;
bool matches(const IpAttributes &other) const;
void serialize(cereal::JSONInputArchive &ar);
void performOutputingSchema(std::ostream &, int);
private:
std::vector<std::string> ipv4_addresses;
std::vector<std::string> ipv6_addresses;
std::vector<IpAddressRange> ipv4_address_ranges;
std::vector<IpAddressRange> ipv6_address_ranges;
};
class Invalidation class Invalidation
{ {
public: public:
@ -60,14 +105,14 @@ public:
Invalidation & setClassifier(ClassifierType type, const std::string &val); Invalidation & setClassifier(ClassifierType type, const std::string &val);
Invalidation & addMainAttr(const StrAttributes &attr); Invalidation & addMainAttr(const StrAttributes &attr);
Invalidation & addAttr(const StrAttributes &attr); Invalidation & addAttr(const IpAttributes &attr);
Invalidation & setSourceId(const std::string &id); Invalidation & setSourceId(const std::string &id);
Invalidation & setObjectType(ObjectType type); Invalidation & setObjectType(ObjectType type);
Invalidation & setInvalidationType(InvalidationType type); Invalidation & setInvalidationType(InvalidationType type);
std::string getClassifier(ClassifierType type) const { return classifiers[type]; } std::string getClassifier(ClassifierType type) const { return classifiers[type]; }
std::vector<StrAttributes> getMainAttributes() const { return main_attributes; } std::vector<StrAttributes> getMainAttributes() const { return main_attributes; }
std::vector<StrAttributes> getAttributes() const { return attributes; } std::vector<IpAttributes> getAttributes() const { return attributes; }
const Maybe<std::string, void> & getSourceId() const { return source_id; } const Maybe<std::string, void> & getSourceId() const { return source_id; }
const Maybe<ObjectType, void> & getObjectType() const { return object_type; } const Maybe<ObjectType, void> & getObjectType() const { return object_type; }
const Maybe<InvalidationType, void> & getInvalidationType() const { return invalidation_type; } const Maybe<InvalidationType, void> & getInvalidationType() const { return invalidation_type; }
@ -86,10 +131,11 @@ public:
private: private:
bool attr_matches(const std::vector<StrAttributes> &current, const std::vector<StrAttributes> &other) const; bool attr_matches(const std::vector<StrAttributes> &current, const std::vector<StrAttributes> &other) const;
bool attr_matches(const std::vector<IpAttributes> &current, const std::vector<IpAttributes> &other) const;
EnumArray<ClassifierType, std::string, 6> classifiers; EnumArray<ClassifierType, std::string, 6> classifiers;
std::vector<StrAttributes> main_attributes; std::vector<StrAttributes> main_attributes;
std::vector<StrAttributes> attributes; std::vector<IpAttributes> attributes;
Maybe<std::string, void> source_id; Maybe<std::string, void> source_id;
Maybe<ObjectType, void> object_type; Maybe<ObjectType, void> object_type;
Maybe<InvalidationType, void> invalidation_type; Maybe<InvalidationType, void> invalidation_type;

View File

@ -254,7 +254,7 @@ private:
C2S_OPTIONAL_PARAM(string, sourceId); C2S_OPTIONAL_PARAM(string, sourceId);
C2S_OPTIONAL_PARAM(string, invalidationRegistrationId); C2S_OPTIONAL_PARAM(string, invalidationRegistrationId);
C2S_OPTIONAL_PARAM(vector<StrAttributes>, mainAttributes); C2S_OPTIONAL_PARAM(vector<StrAttributes>, mainAttributes);
C2S_OPTIONAL_PARAM(vector<StrAttributes>, attributes); C2S_OPTIONAL_PARAM(vector<IpAttributes>, attributes);
C2S_OPTIONAL_PARAM(string, invalidationType); C2S_OPTIONAL_PARAM(string, invalidationType);
}; };
@ -624,7 +624,7 @@ private:
query_request.isBulk() ? queries_uri : query_uri, query_request.isBulk() ? queries_uri : query_uri,
*json_body, *json_body,
MessageCategory::INTELLIGENCE, MessageCategory::INTELLIGENCE,
global_req_md query_request.getReqMD().getHostName().empty() ? global_req_md : query_request.getReqMD()
); );
if (!req_data.ok()) { if (!req_data.ok()) {
auto response_error = req_data.getErr().toString(); auto response_error = req_data.getErr().toString();

View File

@ -32,6 +32,30 @@ TEST(StringAttributesBasic, SettersAndGetters)
EXPECT_FALSE(string_attributes.isEmpty()); EXPECT_FALSE(string_attributes.isEmpty());
EXPECT_EQ(string_attributes.getStringAttr("attr1").unpack(), "1"); EXPECT_EQ(string_attributes.getStringAttr("attr1").unpack(), "1");
EXPECT_EQ(string_attributes.getStringSetAttr("attr2").unpack(), vals); EXPECT_EQ(string_attributes.getStringSetAttr("attr2").unpack(), vals);
IpAttributes attributes;
EXPECT_TRUE(attributes.isEmpty());
EXPECT_FALSE(attributes.getIpv4Addresses().ok());
EXPECT_FALSE(attributes.getIpv6Addresses().ok());
EXPECT_FALSE(attributes.getIpv4AddressRanges().ok());
EXPECT_FALSE(attributes.getIpv6AddressRanges().ok());
IpAddressRange range("1.1.1.1", "1.1.1.5");
attributes
.addIpv4Addresses("1.1.1.2")
.addIpv4AddressRanges(range)
.addIpv6Addresses("1.1.1.2")
.addIpv6AddressRanges(range);
EXPECT_FALSE(attributes.isEmpty());
vector<string> ip_vector = {"1.1.1.2"};
vector<IpAddressRange> ip_range_vector = {range};
EXPECT_EQ(attributes.getIpv4Addresses().unpack(), ip_vector);
EXPECT_EQ(attributes.getIpv4AddressRanges().unpack(), ip_range_vector);
EXPECT_EQ(attributes.getIpv6Addresses().unpack(), ip_vector);
EXPECT_EQ(attributes.getIpv6AddressRanges().unpack(), ip_range_vector);
} }
TEST(StringAttributesBasic, attr_schema) TEST(StringAttributesBasic, attr_schema)
@ -51,6 +75,39 @@ TEST(StringAttributesBasic, attr_schema)
" ]\n" " ]\n"
"}"; "}";
EXPECT_EQ(ss.str(), expected_schema); EXPECT_EQ(ss.str(), expected_schema);
IpAddressRange range("1.1.1.1", "1.1.1.5");
IpAttributes attributes = IpAttributes()
.addIpv4Addresses("1.1.1.2")
.addIpv4Addresses("1.1.1.3")
.addIpv4AddressRanges(range)
.addIpv6Addresses("1.1.1.4")
.addIpv6AddressRanges(range);
stringstream attr_ss;
attributes.performOutputingSchema(attr_ss, 0);
expected_schema =
"{\n"
" \"ipv4Addresses\": [\n"
" \"1.1.1.2\",\n"
" \"1.1.1.3\"\n"
" ],\n"
" \"ipv6Addresses\": [\n"
" \"1.1.1.4\"\n"
" ],\n"
" \"ipv4AddressesRange\": [\n"
" {\n"
" \"max\": \"1.1.1.5\",\n"
" \"min\": \"1.1.1.1\"\n"
" }\n"
" ],\n"
" \"ipv6AddressesRange\": [\n"
" {\n"
" \"max\": \"1.1.1.5\",\n"
" \"min\": \"1.1.1.1\"\n"
" }\n"
" ]\n"
"}";
EXPECT_EQ(attr_ss.str(), expected_schema);
} }
TEST(StringAttributesBasic, Matching) TEST(StringAttributesBasic, Matching)
@ -105,6 +162,20 @@ TEST(StringAttributesBasic, genObject)
string expected_json = "{ \"attr1\": \"1\", \"attr2\": [ \"2\", \"3\" ] }"; string expected_json = "{ \"attr1\": \"1\", \"attr2\": [ \"2\", \"3\" ] }";
EXPECT_EQ(string_attributes.genObject().unpack(), expected_json); EXPECT_EQ(string_attributes.genObject().unpack(), expected_json);
IpAddressRange range("1.1.1.1", "1.1.1.5");
IpAttributes attributes = IpAttributes()
.addIpv4Addresses("1.1.1.2")
.addIpv4Addresses("1.1.1.3")
.addIpv4AddressRanges(range)
.addIpv6Addresses("1.1.1.4")
.addIpv6AddressRanges(range);
expected_json =
"{ \"ipv4Addresses\": [ \"1.1.1.2\", \"1.1.1.3\" ], \"ipv6Addresses\": [ \"1.1.1.4\" ], "
"\"ipv4AddressesRange\": [ { \"max\": \"1.1.1.5\", \"min\": \"1.1.1.1\" } ], "
"\"ipv6AddressesRange\": [ { \"max\": \"1.1.1.5\", \"min\": \"1.1.1.1\" } ] }";
EXPECT_EQ(attributes.genObject().unpack(), expected_json);
} }
TEST(InvalidationBasic, SettersAndGetters) TEST(InvalidationBasic, SettersAndGetters)
@ -125,15 +196,15 @@ TEST(InvalidationBasic, SettersAndGetters)
EXPECT_FALSE(invalidation.getInvalidationType().ok()); EXPECT_FALSE(invalidation.getInvalidationType().ok());
set<string> main_vals = { "2", "3" }; set<string> main_vals = { "2", "3" };
set<string> vals = { "5", "6" }; vector<string> vals = {"1.1.1.1", "2.2.2.2"};
auto main_attr = StrAttributes() auto main_attr = StrAttributes()
.addStringAttr("main_attr1", "1") .addStringAttr("main_attr1", "1")
.addStringSetAttr("main_attr2", main_vals); .addStringSetAttr("main_attr2", main_vals);
auto attr = StrAttributes() auto attr = IpAttributes()
.addStringAttr("attr1", "4") .addIpv4Addresses("1.1.1.1")
.addStringSetAttr("attr2", vals); .addIpv4Addresses("2.2.2.2");
invalidation invalidation
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -148,8 +219,7 @@ TEST(InvalidationBasic, SettersAndGetters)
EXPECT_EQ(invalidation.getClassifier(ClassifierType::FAMILY), "ccc"); EXPECT_EQ(invalidation.getClassifier(ClassifierType::FAMILY), "ccc");
EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringAttr("main_attr1").unpack(), "1"); EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringAttr("main_attr1").unpack(), "1");
EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringSetAttr("main_attr2").unpack(), main_vals); EXPECT_EQ(invalidation.getMainAttributes().begin()->getStringSetAttr("main_attr2").unpack(), main_vals);
EXPECT_EQ(invalidation.getAttributes().begin()->getStringAttr("attr1").unpack(), "4"); EXPECT_EQ(invalidation.getAttributes().begin()->getIpv4Addresses().unpack(), vals);
EXPECT_EQ(invalidation.getAttributes().begin()->getStringSetAttr("attr2").unpack(), vals);
EXPECT_EQ(invalidation.getSourceId().unpack(), "id"); EXPECT_EQ(invalidation.getSourceId().unpack(), "id");
EXPECT_EQ(invalidation.getObjectType().unpack(), Intelligence::ObjectType::ASSET); EXPECT_EQ(invalidation.getObjectType().unpack(), Intelligence::ObjectType::ASSET);
EXPECT_EQ(invalidation.getInvalidationType().unpack(), InvalidationType::DELETE); EXPECT_EQ(invalidation.getInvalidationType().unpack(), InvalidationType::DELETE);
@ -164,9 +234,9 @@ TEST(InvalidationBasic, Matching)
.addStringAttr("main_attr1", "1") .addStringAttr("main_attr1", "1")
.addStringSetAttr("main_attr2", main_vals); .addStringSetAttr("main_attr2", main_vals);
auto attr = StrAttributes() auto attr = IpAttributes()
.addStringAttr("attr1", "4") .addIpv4Addresses("1.1.1.1")
.addStringSetAttr("attr2", vals); .addIpv4Addresses("2.2.2.2");
auto base_invalidation = Invalidation("aaa") auto base_invalidation = Invalidation("aaa")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -179,10 +249,9 @@ TEST(InvalidationBasic, Matching)
.addStringSetAttr("main_attr2", main_vals) .addStringSetAttr("main_attr2", main_vals)
.addStringAttr("main_attr3", "6"); .addStringAttr("main_attr3", "6");
auto matching_attr = StrAttributes() auto matching_attr = IpAttributes()
.addStringAttr("attr1", "4") .addIpv4Addresses("1.1.1.1")
.addStringSetAttr("attr2", vals) .addIpv4Addresses("2.2.2.2");
.addStringAttr("attr3", "7");
auto matching_invalidation = Invalidation("aaa") auto matching_invalidation = Invalidation("aaa")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -212,10 +281,9 @@ TEST(InvalidationBasic, Matching)
EXPECT_FALSE(base_invalidation.matches(missing_attr_invalidation_main)); EXPECT_FALSE(base_invalidation.matches(missing_attr_invalidation_main));
auto missing_attr = StrAttributes() auto missing_attr = IpAttributes()
.addStringAttr("attr1", "4") .addIpv4Addresses("2.2.2.2")
.addStringAttr("attr2", "2") .addIpv4Addresses("3.3.3.3");
.addStringAttr("attr3", "7");
auto missing_attr_invalidation = Invalidation("aaa") auto missing_attr_invalidation = Invalidation("aaa")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -280,7 +348,7 @@ public:
intelligence.preload(); intelligence.preload();
intelligence.init(); intelligence.init();
main_attr.addStringAttr("attr2", "2"); main_attr.addStringAttr("attr2", "2");
attr.addStringAttr("attr3", "3"); attr.addIpv4Addresses("1.1.1.1");
} }
bool bool
@ -291,7 +359,7 @@ public:
} }
StrAttributes main_attr; StrAttributes main_attr;
StrAttributes attr; IpAttributes attr;
StrictMock<MockMessaging> messaging_mock; StrictMock<MockMessaging> messaging_mock;
StrictMock<MockMainLoop> mock_ml; StrictMock<MockMainLoop> mock_ml;
NiceMock<MockTimeGet> mock_time; NiceMock<MockTimeGet> mock_time;
@ -350,7 +418,7 @@ TEST_F(IntelligenceInvalidation, sending_public_invalidation)
"\"objectType\": \"asset\", " "\"objectType\": \"asset\", "
"\"sourceId\": \"id\", " "\"sourceId\": \"id\", "
"\"mainAttributes\": [ { \"attr2\": \"2\" } ], " "\"mainAttributes\": [ { \"attr2\": \"2\" } ], "
"\"attributes\": [ { \"attr3\": \"3\" } ]" "\"attributes\": [ { \"ipv4Addresses\": [ \"1.1.1.1\" ] } ]"
" } ] }"; " } ] }";
EXPECT_EQ(invalidation_json, expected_json); EXPECT_EQ(invalidation_json, expected_json);
EXPECT_FALSE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN)); EXPECT_FALSE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN));
@ -390,7 +458,7 @@ TEST_F(IntelligenceInvalidation, multiple_assets_invalidation)
"\"objectType\": \"asset\", " "\"objectType\": \"asset\", "
"\"sourceId\": \"id\", " "\"sourceId\": \"id\", "
"\"mainAttributes\": [ { \"attr2\": \"2\" }, { \"attr2\": \"22\", \"attr3\": [ \"33\", \"44\" ] } ], " "\"mainAttributes\": [ { \"attr2\": \"2\" }, { \"attr2\": \"22\", \"attr3\": [ \"33\", \"44\" ] } ], "
"\"attributes\": [ { \"attr3\": \"3\" } ]" "\"attributes\": [ { \"ipv4Addresses\": [ \"1.1.1.1\" ] } ]"
" } ] }"; " } ] }";
EXPECT_EQ(invalidation_json, expected_json); EXPECT_EQ(invalidation_json, expected_json);
} }
@ -439,7 +507,7 @@ TEST_F(IntelligenceInvalidation, sending_private_invalidation)
"\"objectType\": \"asset\", " "\"objectType\": \"asset\", "
"\"sourceId\": \"id\", " "\"sourceId\": \"id\", "
"\"mainAttributes\": [ { \"attr2\": \"2\" } ], " "\"mainAttributes\": [ { \"attr2\": \"2\" } ], "
"\"attributes\": [ { \"attr3\": \"3\" } ]" "\"attributes\": [ { \"ipv4Addresses\": [ \"1.1.1.1\" ] } ]"
" } ] }"; " } ] }";
EXPECT_EQ(invalidation_json, expected_json); EXPECT_EQ(invalidation_json, expected_json);
EXPECT_TRUE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN)); EXPECT_TRUE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN));
@ -484,7 +552,7 @@ TEST_F(IntelligenceInvalidation, register_for_invalidation)
EXPECT_THAT(body, HasSubstr("\"url\": \"http://127.0.0.1:7000/set-new-invalidation\"")); EXPECT_THAT(body, HasSubstr("\"url\": \"http://127.0.0.1:7000/set-new-invalidation\""));
EXPECT_THAT(body, HasSubstr("\"apiVersion\": \"v2\", \"communicationType\": \"sync\"")); EXPECT_THAT(body, HasSubstr("\"apiVersion\": \"v2\", \"communicationType\": \"sync\""));
EXPECT_THAT(body, HasSubstr("\"mainAttributes\": [ { \"attr2\": \"2\" } ]")); EXPECT_THAT(body, HasSubstr("\"mainAttributes\": [ { \"attr2\": \"2\" } ]"));
EXPECT_THAT(body, HasSubstr("\"attributes\": [ { \"attr3\": \"3\" } ]")); EXPECT_THAT(body, HasSubstr("\"attributes\": [ { \"ipv4Addresses\": [ \"1.1.1.1\" ] } ]"));
EXPECT_TRUE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN)); EXPECT_TRUE(md.getConnectionFlags().isSet(MessageConnectionConfig::UNSECURE_CONN));
EXPECT_THAT(body, HasSubstr("\"capabilities\": { \"getBulkCallback\": true }")); EXPECT_THAT(body, HasSubstr("\"capabilities\": { \"getBulkCallback\": true }"));
@ -888,11 +956,19 @@ TEST_F(IntelligenceInvalidation, invalidation_cb_match_by_registration_id)
configuration << "}"; configuration << "}";
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration); Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(configuration);
IpAddressRange range("1.1.1.1", "1.1.1.5");
IpAttributes attributes = IpAttributes()
.addIpv4Addresses("1.1.1.2")
.addIpv4AddressRanges(range)
.addIpv6Addresses("1.1.1.2")
.addIpv6AddressRanges(range);
auto base_main_attr2 = StrAttributes() auto base_main_attr2 = StrAttributes()
.addStringAttr("attr3", "3"); .addStringAttr("attr3", "3");
auto invalidation_to_register = Invalidation("aaa") auto invalidation_to_register = Invalidation("aaa")
.addMainAttr(main_attr) .addMainAttr(main_attr)
.addMainAttr(base_main_attr2) .addMainAttr(base_main_attr2)
.addAttr(attributes)
.setSourceId("id") .setSourceId("id")
.setClassifier(ClassifierType::FAMILY, "ccc") .setClassifier(ClassifierType::FAMILY, "ccc")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -911,6 +987,7 @@ TEST_F(IntelligenceInvalidation, invalidation_cb_match_by_registration_id)
auto matching_invalidation = Invalidation("aaa") auto matching_invalidation = Invalidation("aaa")
.addMainAttr(matching_second_main_attribute) .addMainAttr(matching_second_main_attribute)
.addAttr(attributes)
.setSourceId("id") .setSourceId("id")
.setClassifier(ClassifierType::FAMILY, "ccc") .setClassifier(ClassifierType::FAMILY, "ccc")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")
@ -919,6 +996,7 @@ TEST_F(IntelligenceInvalidation, invalidation_cb_match_by_registration_id)
auto invalidation_2_to_register = Invalidation("aaa") auto invalidation_2_to_register = Invalidation("aaa")
.addMainAttr(base_main_attr2) .addMainAttr(base_main_attr2)
.addAttr(attributes)
.setSourceId("id") .setSourceId("id")
.setClassifier(ClassifierType::FAMILY, "ccc") .setClassifier(ClassifierType::FAMILY, "ccc")
.setClassifier(ClassifierType::CATEGORY, "bbb") .setClassifier(ClassifierType::CATEGORY, "bbb")

View File

@ -20,6 +20,8 @@
#include "i_intelligence_is_v2.h" #include "i_intelligence_is_v2.h"
USE_DEBUG_FLAG(D_INTELLIGENCE);
using namespace Intelligence; using namespace Intelligence;
using namespace std; using namespace std;
@ -203,6 +205,18 @@ Invalidation::attr_matches(const vector<StrAttributes> &current, const vector<St
return false; return false;
} }
bool
Invalidation::attr_matches(const vector<IpAttributes> &current, const vector<IpAttributes> &other) const
{
if (current.empty()) return true;
for (const auto &attr : current) {
for(const auto &other_attr : other) {
if (attr.matches(other_attr)) return true;
}
}
return false;
}
bool bool
Invalidation::matches(const Invalidation &other) const Invalidation::matches(const Invalidation &other) const
{ {
@ -230,7 +244,7 @@ Invalidation::matches(const Invalidation &other) const
} }
Invalidation & Invalidation &
Invalidation::addAttr(const StrAttributes &attr) Invalidation::addAttr(const IpAttributes &attr)
{ {
attributes.emplace_back(attr); attributes.emplace_back(attr);
return *this; return *this;
@ -378,3 +392,224 @@ StrAttributes::performOutputingSchema(ostream &out, int level) {
} }
RestHelper::printIndent(out, level) << "}"; RestHelper::printIndent(out, level) << "}";
} }
IpAttributes &
IpAttributes::addIpv4Addresses(const string &val)
{
ipv4_addresses.push_back(val);
return *this;
}
IpAttributes &
IpAttributes::addIpv6Addresses(const string &val)
{
ipv6_addresses.push_back(val);
return *this;
}
IpAttributes &
IpAttributes::addIpv4AddressRanges(const IpAddressRange &val)
{
ipv4_address_ranges.push_back(val);
return *this;
}
IpAttributes &
IpAttributes::addIpv6AddressRanges(const IpAddressRange &val)
{
ipv6_address_ranges.push_back(val);
return *this;
}
Maybe<vector<string>, void>
IpAttributes::getIpv4Addresses() const
{
if (ipv4_addresses.empty()) return genError<void>();
return ipv4_addresses;
}
Maybe<vector<string>, void>
IpAttributes::getIpv6Addresses() const
{
if (ipv6_addresses.empty()) return genError<void>();
return ipv6_addresses;
}
Maybe<vector<IpAddressRange>, void>
IpAttributes::getIpv4AddressRanges() const
{
if (ipv4_address_ranges.empty()) return genError<void>();
return ipv4_address_ranges;
}
Maybe<vector<IpAddressRange>, void>
IpAttributes::getIpv6AddressRanges() const
{
if (ipv6_address_ranges.empty()) return genError<void>();
return ipv6_address_ranges;
}
Maybe<string, void>
IpAttributes::genObject() const
{
stringstream attributes_ss;
if (this->isEmpty()) return genError<void>();
bool internal_first = true;
bool first = true;
attributes_ss << "{ ";
if (!ipv4_addresses.empty()) {
attributes_ss << "\"ipv4Addresses\": [ ";
for (auto &attr : ipv4_addresses) {
if (!internal_first) attributes_ss << ", ";
attributes_ss << "\"" << attr << "\"";
internal_first = false;
}
attributes_ss << " ]";
first = false;
}
if (!ipv6_addresses.empty()) {
if (!first) attributes_ss << ", ";
attributes_ss << "\"ipv6Addresses\": [ ";
internal_first = true;
for (auto &attr : ipv6_addresses) {
if (!internal_first) attributes_ss << ", ";
attributes_ss << "\"" << attr << "\"";
internal_first = false;
}
attributes_ss << " ]";
first = false;
}
if (!ipv4_address_ranges.empty()) {
if (!first) attributes_ss << ", ";
attributes_ss << "\"ipv4AddressesRange\": [ ";
internal_first = true;
for (auto &attr : ipv4_address_ranges) {
if (!internal_first) attributes_ss << ", ";
attributes_ss << "{ \"max\": \"" << attr.getMax() << "\", \"min\": \"" << attr.getMin() << "\" }";
internal_first = false;
}
attributes_ss << " ]";
first = false;
}
if (!ipv6_address_ranges.empty()) {
if (!first) attributes_ss << ", ";
attributes_ss << "\"ipv6AddressesRange\": [ ";
internal_first = true;
for (auto &attr : ipv6_address_ranges) {
if (!internal_first) attributes_ss << ", ";
attributes_ss << "{ \"max\": \"" << attr.getMax() << "\", \"min\": \"" << attr.getMin() << "\" }";
internal_first = false;
}
attributes_ss << " ]";
first = false;
}
attributes_ss << " }";
return attributes_ss.str();
}
bool
IpAttributes::isEmpty() const
{
return
ipv4_addresses.empty() &&
ipv6_addresses.empty() &&
ipv4_address_ranges.empty() &&
ipv6_address_ranges.empty();
}
bool
IpAttributes::matches(const IpAttributes &other) const
{
return
ipv4_addresses == other.ipv4_addresses &&
ipv6_addresses == other.ipv6_addresses &&
ipv4_address_ranges == other.ipv4_address_ranges &&
ipv6_address_ranges == other.ipv6_address_ranges;
}
void
IpAttributes::serialize(cereal::JSONInputArchive &ar)
{
try {
ar(cereal::make_nvp("ipv4Addresses", ipv4_addresses));
ar(cereal::make_nvp("ipv4AddressesRange", ipv4_address_ranges));
ar(cereal::make_nvp("ipv6Addresses", ipv6_addresses));
ar(cereal::make_nvp("ipv6AddressesRange", ipv6_address_ranges));
} catch (cereal::Exception &e) {
dbgError(D_INTELLIGENCE) << e.what();
}
}
void
IpAttributes::performOutputingSchema(ostream &out, int level)
{
bool first = true;
bool internal_first = true;
RestHelper::printIndent(out, level) << "{\n";
if (!ipv4_addresses.empty()) {
RestHelper::printIndent(out, level + 1) << "\"ipv4Addresses\": [\n";
for (auto &attr : ipv4_addresses) {
if (!internal_first) out << ",\n";
RestHelper::printIndent(out, level + 2) << "\"" << attr << "\"";
internal_first = false;
}
out << "\n";
RestHelper::printIndent(out, level + 1) << "]";
first = false;
}
if (!ipv6_addresses.empty()) {
if (!first) out << ",\n";
RestHelper::printIndent(out, level + 1) << "\"ipv6Addresses\": [\n";
internal_first = true;
for (auto &attr : ipv6_addresses) {
if (!internal_first) out << ",\n";
RestHelper::printIndent(out, level + 2) << "\"" << attr << "\"";
internal_first = false;
}
out << "\n";
RestHelper::printIndent(out, level + 1) << "]";
first = false;
}
if (!ipv4_address_ranges.empty()) {
if (!first) out << ",\n";
RestHelper::printIndent(out, level + 1) << "\"ipv4AddressesRange\": [\n";
internal_first = true;
for (auto &attr : ipv4_address_ranges) {
if (!internal_first) out << ",\n";
RestHelper::printIndent(out, level + 2) << "{\n";
RestHelper::printIndent(out, level + 3) << "\"max\": \"" << attr.getMax() << "\",\n";
RestHelper::printIndent(out, level + 3) << "\"min\": \"" << attr.getMin() << "\"\n";
RestHelper::printIndent(out, level + 2) << "}";
internal_first = false;
}
out << "\n";
RestHelper::printIndent(out, level + 1) << "]";
first = false;
}
if (!ipv6_address_ranges.empty()) {
if (!first) out << ",\n";
RestHelper::printIndent(out, level + 1) << "\"ipv6AddressesRange\": [\n";
internal_first = true;
for (auto &attr : ipv6_address_ranges) {
if (!internal_first) out << ",\n";
RestHelper::printIndent(out, level + 2) << "{\n";
RestHelper::printIndent(out, level + 3) << "\"max\": \"" << attr.getMax() << "\",\n";
RestHelper::printIndent(out, level + 3) << "\"min\": \"" << attr.getMin() << "\"\n";
RestHelper::printIndent(out, level + 2) << "}";
internal_first = false;
}
out << "\n";
RestHelper::printIndent(out, level + 1) << "]";
first = false;
}
RestHelper::printIndent(out, level) << "\n}";
}

View File

@ -163,10 +163,14 @@ RestServer::Impl::init()
} }
} }
bool is_ipv6 = false;
if (accept_get_from_external_ip) { if (accept_get_from_external_ip) {
is_ipv6 = true;
fd = socket(AF_INET6, SOCK_STREAM, 0); fd = socket(AF_INET6, SOCK_STREAM, 0);
} else { }
if (fd == -1) {
fd = socket(AF_INET, SOCK_STREAM, 0); fd = socket(AF_INET, SOCK_STREAM, 0);
is_ipv6 = false;
} }
dbgAssert(fd >= 0) << alert << "Failed to open a socket"; dbgAssert(fd >= 0) << alert << "Failed to open a socket";
@ -175,7 +179,8 @@ RestServer::Impl::init()
dbgWarning(D_API) << "Could not set the socket options"; dbgWarning(D_API) << "Could not set the socket options";
} }
if (accept_get_from_external_ip) { if (is_ipv6) {
dbgDebug(D_API) << "IPv6 socket opened successfully";
int option = 0; int option = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof(option)) < 0) { if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof(option)) < 0) {
dbgWarning(D_API) << "Could not set the IPV6_V6ONLY option"; dbgWarning(D_API) << "Could not set the IPV6_V6ONLY option";
@ -185,16 +190,24 @@ RestServer::Impl::init()
bzero(&addr6, sizeof(addr6)); bzero(&addr6, sizeof(addr6));
addr6.sin6_family = AF_INET6; addr6.sin6_family = AF_INET6;
addr6.sin6_addr = in6addr_any; addr6.sin6_addr = in6addr_any;
dbgDebug(D_API) << "Socket listening on any address";
while (!bindRestServerSocket(addr6, port_range)) { while (!bindRestServerSocket(addr6, port_range)) {
mainloop->yield(bind_retry_interval_msec); mainloop->yield(bind_retry_interval_msec);
} }
listening_port = ntohs(addr6.sin6_port); listening_port = ntohs(addr6.sin6_port);
} else { } else {
dbgDebug(D_API) << "IPv4 socket opened successfully";
struct sockaddr_in addr; struct sockaddr_in addr;
bzero(&addr, sizeof(addr)); bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
if (accept_get_from_external_ip) {
addr.sin_addr.s_addr = htonl(INADDR_ANY);
dbgDebug(D_API) << "Socket listening on any address";
} else {
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
dbgDebug(D_API) << "Socket listening on local address";
}
while (!bindRestServerSocket(addr, port_range)) { while (!bindRestServerSocket(addr, port_range)) {
mainloop->yield(bind_retry_interval_msec); mainloop->yield(bind_retry_interval_msec);

View File

@ -29,8 +29,10 @@ is_wlp_orchestration="false"
ORCHESTRATION_EXE_SOURCE_PATH="./bin/orchestration_comp" ORCHESTRATION_EXE_SOURCE_PATH="./bin/orchestration_comp"
NGINX_METADAT_EXTRACTOR_PATH="./scripts/cp-nano-makefile-generator.sh" NGINX_METADAT_EXTRACTOR_PATH="./scripts/cp-nano-makefile-generator.sh"
NGINX_FRESH_METADATA_EXTRACTOR_PATH="./scripts/cp-nano-makefile-generator-fresh.sh"
ORCHESTRATION_FILE_NAME="cp-nano-orchestration" ORCHESTRATION_FILE_NAME="cp-nano-orchestration"
NGINX_METADDATA_EXTRACTOR_NAME="cp-nano-makefile-generator.sh" NGINX_METADDATA_EXTRACTOR_NAME="cp-nano-makefile-generator.sh"
NGINX_FRESH_METADATA_EXTRACTOR_NAME="cp-nano-makefile-generator-fresh.sh"
GET_CLOUD_METADATA_PATH="get-cloud-metadata.sh" GET_CLOUD_METADATA_PATH="get-cloud-metadata.sh"
AGENT_UNINSTALL="cp-agent-uninstall.sh" AGENT_UNINSTALL="cp-agent-uninstall.sh"
ORCHESTRATION_NAME="orchestration" ORCHESTRATION_NAME="orchestration"
@ -336,6 +338,10 @@ while true; do
elif [ "$1" = "--cloud-storage" ]; then elif [ "$1" = "--cloud-storage" ]; then
shift shift
var_cloud_storage=$1 var_cloud_storage=$1
elif [ "$1" = "--only_unpack_lib64_path" ]; then
shift
USR_LIB_PATH=$1
var_only_unpack_lib64="set"
elif echo "$1" | grep -q ${FORCE_CLEAN_FLAG}; then elif echo "$1" | grep -q ${FORCE_CLEAN_FLAG}; then
var_upgrade_mode= var_upgrade_mode=
elif echo "$1" | grep -q ${DEBUG_FLAG}; then elif echo "$1" | grep -q ${DEBUG_FLAG}; then
@ -849,6 +855,13 @@ copy_nginx_metadata_script()
cp_exec "chmod +x ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${NGINX_METADDATA_EXTRACTOR_NAME}" cp_exec "chmod +x ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${NGINX_METADDATA_EXTRACTOR_NAME}"
} }
copy_nginx_fresh_metadata_script()
{
cp_copy "$NGINX_FRESH_METADATA_EXTRACTOR_PATH" ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${NGINX_FRESH_METADATA_EXTRACTOR_NAME}
cp_exec "chmod 700 ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${NGINX_FRESH_METADATA_EXTRACTOR_NAME}"
cp_exec "chmod +x ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${NGINX_FRESH_METADATA_EXTRACTOR_NAME}"
}
copy_and_run_cloud_metadata_script() copy_and_run_cloud_metadata_script()
{ {
cp_copy "${SCRIPTS_PATH}/$GET_CLOUD_METADATA_PATH" ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${GET_CLOUD_METADATA_PATH} cp_copy "${SCRIPTS_PATH}/$GET_CLOUD_METADATA_PATH" ${FILESYSTEM_PATH}/${SCRIPTS_PATH}/${GET_CLOUD_METADATA_PATH}
@ -925,6 +938,19 @@ get_status_content()
install_orchestration() install_orchestration()
{ {
INSTALLATION_TIME=$(date) INSTALLATION_TIME=$(date)
if [ "$var_only_unpack_lib64" = "set" ]; then
cp_exec "mkdir ${USR_LIB_PATH}"
if [ ! -d "$USR_LIB_PATH" ]; then
cp_print "No valid path: ${USR_LIB_PATH}. please do --only_unpack_lib64_path <Path>" ${FORCE_STDOUT}
exit 1
fi
${INSTALL_COMMAND} lib/*.so* ${USR_LIB_PATH}/
${INSTALL_COMMAND} lib/boost/*.so* ${USR_LIB_PATH}/
cp_print "Done successfully doing only unpacking lib64 to Path: ${USR_LIB_PATH}" ${FORCE_STDOUT}
exit 0
fi
if [ "$is_smb" != "1" ]; then if [ "$is_smb" != "1" ]; then
cp_exec "mkdir -p ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}" cp_exec "mkdir -p ${USR_LIB_PATH}/cpnano${VS_LIB_SUB_FOLDER}"
else else
@ -1038,6 +1064,7 @@ install_orchestration()
copy_orchestration_executable copy_orchestration_executable
copy_k8s_executable copy_k8s_executable
copy_nginx_metadata_script copy_nginx_metadata_script
copy_nginx_fresh_metadata_script
copy_and_run_cloud_metadata_script copy_and_run_cloud_metadata_script
install_watchdog "--upgrade" install_watchdog "--upgrade"
@ -1133,6 +1160,7 @@ install_orchestration()
copy_orchestration_executable copy_orchestration_executable
copy_k8s_executable copy_k8s_executable
copy_nginx_metadata_script copy_nginx_metadata_script
copy_nginx_fresh_metadata_script
copy_and_run_cloud_metadata_script copy_and_run_cloud_metadata_script
install_cp_nano_ctl install_cp_nano_ctl