mirror of
https://github.com/openappsec/attachment.git
synced 2025-09-30 11:44:29 +03:00
Add docket support
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
add_subdirectory(shmem_ipc)
|
||||
add_subdirectory(compression)
|
||||
add_subdirectory(attachments)
|
||||
|
1
core/attachments/CMakeLists.txt
Normal file
1
core/attachments/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(http_configuration)
|
1
core/attachments/http_configuration/CMakeLists.txt
Normal file
1
core/attachments/http_configuration/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_library(http_configuration http_configuration.cc)
|
220
core/attachments/http_configuration/http_configuration.cc
Normal file
220
core/attachments/http_configuration/http_configuration.cc
Normal file
@@ -0,0 +1,220 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "http_configuration.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "cereal/types/vector.hpp"
|
||||
|
||||
#define DEFAULT_KEEP_ALIVE_INTERVAL_MSEC 30000
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
DebugConfig::save(cereal::JSONOutputArchive &archive) const
|
||||
{
|
||||
archive(
|
||||
cereal::make_nvp("clientIp", client),
|
||||
cereal::make_nvp("listeningIp", server),
|
||||
cereal::make_nvp("uriPrefix", uri),
|
||||
cereal::make_nvp("hostName", host),
|
||||
cereal::make_nvp("httpMethod", method),
|
||||
cereal::make_nvp("listeningPort", port)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
DebugConfig::load(cereal::JSONInputArchive &archive)
|
||||
{
|
||||
try {
|
||||
archive(
|
||||
cereal::make_nvp("clientIp", client),
|
||||
cereal::make_nvp("listeningIp", server),
|
||||
cereal::make_nvp("uriPrefix", uri),
|
||||
cereal::make_nvp("hostName", host),
|
||||
cereal::make_nvp("httpMethod", method),
|
||||
cereal::make_nvp("listeningPort", port)
|
||||
);
|
||||
} catch (const cereal::Exception &) {
|
||||
client = "";
|
||||
server = "";
|
||||
uri = "";
|
||||
host = "";
|
||||
method = "";
|
||||
port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DebugConfig::operator==(const DebugConfig &another) const
|
||||
{
|
||||
return
|
||||
client == another.client &&
|
||||
server == another.server &&
|
||||
port == another.port &&
|
||||
method == another.method &&
|
||||
host == another.host &&
|
||||
uri == another.uri;
|
||||
}
|
||||
|
||||
int
|
||||
HttpAttachmentConfiguration::init(const string &conf_file)
|
||||
{
|
||||
try {
|
||||
ifstream file(conf_file);
|
||||
cereal::JSONInputArchive ar(file);
|
||||
load(ar);
|
||||
return 1;
|
||||
} catch (exception &e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HttpAttachmentConfiguration::save(cereal::JSONOutputArchive &archive) const
|
||||
{
|
||||
archive(
|
||||
cereal::make_nvp("context_values", dbg),
|
||||
cereal::make_nvp("ip_ranges", exclude_sources),
|
||||
cereal::make_nvp("dbg_level", getNumericalValue("dbg_level")),
|
||||
cereal::make_nvp("static_resources_path", getStringValue("static_resources_path")),
|
||||
cereal::make_nvp("is_fail_open_mode_enabled", getNumericalValue("is_fail_open_mode_enabled")),
|
||||
cereal::make_nvp("fail_open_timeout", getNumericalValue("fail_open_timeout")),
|
||||
cereal::make_nvp("is_fail_open_mode_hold_enabled", getNumericalValue("is_fail_open_mode_hold_enabled")),
|
||||
cereal::make_nvp("fail_open_hold_timeout", getNumericalValue("fail_open_hold_timeout")),
|
||||
cereal::make_nvp("sessions_per_minute_limit_verdict", getStringValue("sessions_per_minute_limit_verdict")),
|
||||
cereal::make_nvp("max_sessions_per_minute", getNumericalValue("max_sessions_per_minute")),
|
||||
cereal::make_nvp("res_proccessing_timeout_msec", getNumericalValue("res_proccessing_timeout_msec")),
|
||||
cereal::make_nvp("req_proccessing_timeout_msec", getNumericalValue("req_proccessing_timeout_msec")),
|
||||
cereal::make_nvp("registration_thread_timeout_msec", getNumericalValue("registration_thread_timeout_msec")),
|
||||
cereal::make_nvp("req_header_thread_timeout_msec", getNumericalValue("req_header_thread_timeout_msec")),
|
||||
cereal::make_nvp("req_body_thread_timeout_msec", getNumericalValue("req_body_thread_timeout_msec")),
|
||||
cereal::make_nvp("res_header_thread_timeout_msec", getNumericalValue("res_header_thread_timeout_msec")),
|
||||
cereal::make_nvp("res_body_thread_timeout_msec", getNumericalValue("res_body_thread_timeout_msec")),
|
||||
cereal::make_nvp(
|
||||
"waiting_for_verdict_thread_timeout_msec",
|
||||
getNumericalValue("waiting_for_verdict_thread_timeout_msec")
|
||||
),
|
||||
cereal::make_nvp("nginx_inspection_mode", getNumericalValue("inspection_mode")),
|
||||
cereal::make_nvp("num_of_nginx_ipc_elements", getNumericalValue("num_of_nginx_ipc_elements")),
|
||||
cereal::make_nvp("keep_alive_interval_msec", getNumericalValue("keep_alive_interval_msec"))
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
HttpAttachmentConfiguration::load(cereal::JSONInputArchive &archive)
|
||||
{
|
||||
try {
|
||||
archive(cereal::make_nvp("context_values", dbg));
|
||||
} catch (const cereal::Exception &) {
|
||||
dbg = DebugConfig();
|
||||
}
|
||||
|
||||
try {
|
||||
archive(cereal::make_nvp("ip_ranges", exclude_sources));
|
||||
} catch (const cereal::Exception &) {
|
||||
exclude_sources = {};
|
||||
}
|
||||
|
||||
try {
|
||||
string str;
|
||||
archive(cereal::make_nvp("static_resources_path", str));
|
||||
string_values["static_resources_path"] = str;
|
||||
} catch (const cereal::Exception &) {
|
||||
string_values.erase("static_resources_path");
|
||||
}
|
||||
|
||||
try {
|
||||
string str;
|
||||
archive(cereal::make_nvp("sessions_per_minute_limit_verdict", str));
|
||||
string_values["sessions_per_minute_limit_verdict"] = str;
|
||||
} catch (const cereal::Exception &) {
|
||||
string_values.erase("sessions_per_minute_limit_verdict");
|
||||
}
|
||||
|
||||
loadNumericalValue(archive, "dbg_level", 0);
|
||||
loadNumericalValue(archive, "is_fail_open_mode_enabled", 0);
|
||||
loadNumericalValue(archive, "fail_open_timeout", 50);
|
||||
loadNumericalValue(archive, "is_fail_open_mode_hold_enabled", 0);
|
||||
loadNumericalValue(archive, "fail_open_hold_timeout", 200);
|
||||
loadNumericalValue(archive, "sessions_per_minute_limit_verdict", 0);
|
||||
loadNumericalValue(archive, "max_sessions_per_minute", 0);
|
||||
loadNumericalValue(archive, "res_proccessing_timeout_msec", 3000);
|
||||
loadNumericalValue(archive, "req_proccessing_timeout_msec", 3000);
|
||||
loadNumericalValue(archive, "registration_thread_timeout_msec", 100);
|
||||
loadNumericalValue(archive, "req_header_thread_timeout_msec", 100);
|
||||
loadNumericalValue(archive, "req_body_thread_timeout_msec", 150);
|
||||
loadNumericalValue(archive, "res_header_thread_timeout_msec", 100);
|
||||
loadNumericalValue(archive, "res_body_thread_timeout_msec", 150);
|
||||
loadNumericalValue(archive, "waiting_for_verdict_thread_timeout_msec", 150);
|
||||
loadNumericalValue(archive, "nginx_inspection_mode", 0);
|
||||
loadNumericalValue(archive, "num_of_nginx_ipc_elements", 200);
|
||||
loadNumericalValue(archive, "keep_alive_interval_msec", DEFAULT_KEEP_ALIVE_INTERVAL_MSEC);
|
||||
|
||||
try {
|
||||
string user_check_logo_path;
|
||||
archive(cereal::make_nvp("user_check_logo_path", user_check_logo_path));
|
||||
ifstream logo_file(user_check_logo_path);
|
||||
if (!logo_file.is_open()) {
|
||||
string_values.erase("user_check_logo");
|
||||
} else {
|
||||
string_values["user_check_logo"] = string(
|
||||
istreambuf_iterator<char>(logo_file),
|
||||
istreambuf_iterator<char>()
|
||||
);
|
||||
}
|
||||
} catch (const cereal::Exception &) {
|
||||
string_values.erase("user_check_logo");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HttpAttachmentConfiguration::operator==(const HttpAttachmentConfiguration &other) const
|
||||
{
|
||||
return
|
||||
dbg == other.dbg &&
|
||||
numerical_values == other.numerical_values &&
|
||||
string_values == other.string_values &&
|
||||
exclude_sources == other.exclude_sources;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
HttpAttachmentConfiguration::getNumericalValue(const string &key) const
|
||||
{
|
||||
auto elem = numerical_values.find(key);
|
||||
return elem != numerical_values.end() ? elem->second : 0;
|
||||
}
|
||||
|
||||
const string &
|
||||
HttpAttachmentConfiguration::getStringValue(const string &key) const
|
||||
{
|
||||
auto elem = string_values.find(key);
|
||||
return elem != string_values.end() ? elem->second : empty;
|
||||
}
|
||||
|
||||
void
|
||||
HttpAttachmentConfiguration::loadNumericalValue(
|
||||
cereal::JSONInputArchive &ar,
|
||||
const string &name,
|
||||
unsigned int default_value
|
||||
)
|
||||
{
|
||||
try {
|
||||
unsigned int value;
|
||||
ar(cereal::make_nvp(name, value));
|
||||
numerical_values[name] = value;
|
||||
} catch (const cereal::Exception &) {
|
||||
numerical_values[name] = default_value;
|
||||
}
|
||||
}
|
@@ -105,6 +105,7 @@ static const int zlib_no_flush = Z_NO_FLUSH;
|
||||
struct CompressionStream
|
||||
{
|
||||
CompressionStream() { bzero(&stream, sizeof(z_stream)); }
|
||||
~CompressionStream() { fini(); }
|
||||
|
||||
tuple<basic_string<unsigned char>, bool>
|
||||
decompress(const unsigned char *data, uint32_t size)
|
||||
|
@@ -29,7 +29,7 @@ struct DebugConfig
|
||||
|
||||
std::string client;
|
||||
std::string server;
|
||||
uint port = 0;
|
||||
unsigned int port = 0;
|
||||
std::string method;
|
||||
std::string host;
|
||||
std::string uri;
|
||||
@@ -45,21 +45,21 @@ public:
|
||||
|
||||
bool operator==(const HttpAttachmentConfiguration &other) const;
|
||||
|
||||
uint getNumericalValue(const std::string &key) const;
|
||||
unsigned int getNumericalValue(const std::string &key) const;
|
||||
const std::string & getStringValue(const std::string &key) const;
|
||||
const std::vector<std::string> & getExcludeSources() const { return exclude_sources; }
|
||||
const DebugConfig & getDebugContext() const { return dbg; }
|
||||
|
||||
void setNumericalValue(const std::string &key, uint value) { numerical_values[key] = value; }
|
||||
void setNumericalValue(const std::string &key, unsigned int value) { numerical_values[key] = value; }
|
||||
void setStringValue(const std::string &key, const std::string &value) { string_values[key] = value; }
|
||||
void setExcludeSources(const std::vector<std::string> &new_sources) { exclude_sources = new_sources; }
|
||||
void setDebugContext(const DebugConfig &_dbg) { dbg = _dbg; }
|
||||
|
||||
private:
|
||||
void loadNumericalValue(cereal::JSONInputArchive &archive, const std::string &name, uint default_value);
|
||||
void loadNumericalValue(cereal::JSONInputArchive &archive, const std::string &name, unsigned int default_value);
|
||||
|
||||
DebugConfig dbg;
|
||||
std::map<std::string, uint> numerical_values;
|
||||
std::map<std::string, unsigned int> numerical_values;
|
||||
std::map<std::string, std::string> string_values;
|
||||
std::vector<std::string> exclude_sources;
|
||||
std::string empty;
|
||||
|
@@ -64,6 +64,7 @@ typedef enum ngx_http_chunk_type
|
||||
RESPONSE_END,
|
||||
CONTENT_LENGTH,
|
||||
METRIC_DATA_FROM_PLUGIN,
|
||||
HOLD_DATA,
|
||||
|
||||
COUNT
|
||||
} ngx_http_chunk_type_e;
|
||||
@@ -85,6 +86,7 @@ typedef enum ngx_http_plugin_metric_type
|
||||
IRRELEVANT_VERDICTS_COUNT,
|
||||
RECONF_VERDICTS_COUNT,
|
||||
INSPECT_VERDICTS_COUNT,
|
||||
HOLD_VERDICTS_COUNT,
|
||||
AVERAGE_OVERALL_PPROCESSING_TIME_UNTIL_VERDICT,
|
||||
MAX_OVERALL_PPROCESSING_TIME_UNTIL_VERDICT,
|
||||
MIN_OVERALL_PPROCESSING_TIME_UNTIL_VERDICT,
|
||||
@@ -103,6 +105,7 @@ typedef enum ngx_http_plugin_metric_type
|
||||
MIN_REQ_BODY_SIZE_UPON_TIMEOUT,
|
||||
RES_HEADER_THREAD_TIMEOUT,
|
||||
RES_BODY_THREAD_TIMEOUT,
|
||||
HOLD_THREAD_TIMEOUT,
|
||||
AVERAGE_RES_BODY_SIZE_UPON_TIMEOUT,
|
||||
MAX_RES_BODY_SIZE_UPON_TIMEOUT,
|
||||
MIN_RES_BODY_SIZE_UPON_TIMEOUT,
|
||||
@@ -139,7 +142,8 @@ typedef enum ngx_http_cp_verdict
|
||||
TRAFFIC_VERDICT_DROP,
|
||||
TRAFFIC_VERDICT_INJECT,
|
||||
TRAFFIC_VERDICT_IRRELEVANT,
|
||||
TRAFFIC_VERDICT_RECONF
|
||||
TRAFFIC_VERDICT_RECONF,
|
||||
TRAFFIC_VERDICT_WAIT
|
||||
} ngx_http_cp_verdict_e;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -33,12 +33,15 @@ ngx_http_inspection_mode_e getInspectionMode();
|
||||
unsigned int getNumOfNginxIpcElements();
|
||||
unsigned int getKeepAliveIntervalMsec();
|
||||
unsigned int getDbgLevel();
|
||||
int isDebugContext(c_str client, c_str server, unsigned int port, c_str method, c_str host , c_str uri);
|
||||
int isDebugContext(c_str client, c_str server, unsigned int port, c_str method, c_str host, c_str uri);
|
||||
c_str getStaticResourcesPath();
|
||||
|
||||
int isFailOpenMode();
|
||||
unsigned int getFailOpenTimeout();
|
||||
|
||||
int isFailOpenHoldMode();
|
||||
unsigned int getFailOpenHoldTimeout();
|
||||
|
||||
unsigned int getMaxSessionsPerMinute();
|
||||
int isFailOpenOnSessionLimit();
|
||||
|
||||
@@ -52,6 +55,8 @@ unsigned int getResProccessingTimeout();
|
||||
unsigned int getResHeaderThreadTimeout();
|
||||
unsigned int getResBodyThreadTimeout();
|
||||
|
||||
unsigned int getWaitingForVerdictThreadTimeout();
|
||||
|
||||
int isIPAddress(c_str ip_str);
|
||||
int isSkipSource(c_str ip_str);
|
||||
|
||||
|
@@ -26,8 +26,9 @@
|
||||
|
||||
#include "shared_ipc_debug.h"
|
||||
|
||||
static const uint16_t empty_buff_mgmt_magic = 0xcafe;
|
||||
static const uint16_t skip_buff_mgmt_magic = 0xbeef;
|
||||
static const uint16_t empty_buff_mgmt_magic = 0xfffe;
|
||||
static const uint16_t skip_buff_mgmt_magic = 0xfffd;
|
||||
static const uint32_t max_write_size = 0xfffc;
|
||||
const uint16_t max_num_of_data_segments = sizeof(DataSegment)/sizeof(uint16_t);
|
||||
|
||||
char g_rx_location_name[MAX_ONE_WAY_QUEUE_NAME_LENGTH] = "";
|
||||
@@ -52,11 +53,8 @@ getNumOfDataSegmentsNeeded(uint16_t data_size)
|
||||
}
|
||||
|
||||
static int
|
||||
isThereEnoughMemoryInQueue(SharedRingQueue *queue, uint8_t num_of_elem_to_push)
|
||||
isThereEnoughMemoryInQueue(uint16_t write_pos, uint16_t read_pos, uint8_t num_of_elem_to_push)
|
||||
{
|
||||
uint16_t write_pos = queue->write_pos;
|
||||
uint16_t read_pos = queue->read_pos;
|
||||
uint16_t num_of_data_segments = queue->num_of_data_segments;
|
||||
int res;
|
||||
|
||||
writeDebug(
|
||||
@@ -65,21 +63,21 @@ isThereEnoughMemoryInQueue(SharedRingQueue *queue, uint8_t num_of_elem_to_push)
|
||||
num_of_elem_to_push,
|
||||
write_pos,
|
||||
read_pos,
|
||||
num_of_data_segments
|
||||
g_num_of_data_segments
|
||||
);
|
||||
if (num_of_elem_to_push >= num_of_data_segments) {
|
||||
if (num_of_elem_to_push >= g_num_of_data_segments) {
|
||||
writeDebug(TraceLevel, "Amount of elements to push is larger then amount of available elements in the queue");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add skipped elements during write that does not fit from cur write position till end of queue
|
||||
if (write_pos + num_of_elem_to_push > num_of_data_segments) {
|
||||
num_of_elem_to_push += num_of_data_segments - write_pos;
|
||||
if (write_pos + num_of_elem_to_push > g_num_of_data_segments) {
|
||||
num_of_elem_to_push += g_num_of_data_segments - write_pos;
|
||||
}
|
||||
|
||||
// removing the aspect of circularity in queue and simulating as if the queue continued at its end
|
||||
if (write_pos + num_of_elem_to_push >= num_of_data_segments) {
|
||||
read_pos += num_of_data_segments;
|
||||
if (write_pos + num_of_elem_to_push >= g_num_of_data_segments) {
|
||||
read_pos += g_num_of_data_segments;
|
||||
}
|
||||
|
||||
res = write_pos + num_of_elem_to_push < read_pos || write_pos >= read_pos;
|
||||
@@ -87,6 +85,22 @@ isThereEnoughMemoryInQueue(SharedRingQueue *queue, uint8_t num_of_elem_to_push)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
isGetPossitionSucceccful(SharedRingQueue *queue, uint16_t *read_pos, uint16_t *write_pos)
|
||||
{
|
||||
if (g_num_of_data_segments == 0) return 0;
|
||||
|
||||
*read_pos = queue->read_pos;
|
||||
*write_pos = queue->write_pos;
|
||||
|
||||
if (queue->num_of_data_segments != g_num_of_data_segments) return 0;
|
||||
if (queue->size_of_memory != g_memory_size) return 0;
|
||||
if (*read_pos > g_num_of_data_segments) return 0;
|
||||
if (*write_pos > g_num_of_data_segments) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
resetRingQueue(SharedRingQueue *queue, uint16_t num_of_data_segments)
|
||||
{
|
||||
@@ -126,13 +140,14 @@ createSharedRingQueue(const char *shared_location_name, uint16_t num_of_data_seg
|
||||
|
||||
g_num_of_data_segments = num_of_data_segments;
|
||||
|
||||
fd = shm_open(shared_location_name, shmem_fd_flags, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
fd = shm_open(shared_location_name, shmem_fd_flags, S_IRUSR | S_IWUSR);
|
||||
if (fd == -1) {
|
||||
writeDebug(
|
||||
WarningLevel,
|
||||
"createSharedRingQueue: Failed to open shared memory for '%s'. Errno: %d\n",
|
||||
"createSharedRingQueue: Failed to open shared memory for '%s'. Errno: %d (%s)\n",
|
||||
shared_location_name,
|
||||
errno
|
||||
errno,
|
||||
strerror(errno)
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
@@ -257,7 +272,7 @@ dumpRingQueueShmem(SharedRingQueue *queue)
|
||||
|
||||
writeDebug(WarningLevel, "mgmt_segment:");
|
||||
buffer_mgmt = (uint16_t *)queue->mgmt_segment.data;
|
||||
for (segment_idx = 0; segment_idx < max_num_of_data_segments; segment_idx++) {
|
||||
for (segment_idx = 0; segment_idx < queue->num_of_data_segments; segment_idx++) {
|
||||
writeDebug(WarningLevel, "%s%u", (segment_idx == 0 ? " " : ", "), buffer_mgmt[segment_idx]);
|
||||
}
|
||||
|
||||
@@ -275,39 +290,44 @@ dumpRingQueueShmem(SharedRingQueue *queue)
|
||||
int
|
||||
peekToQueue(SharedRingQueue *queue, const char **output_buffer, uint16_t *output_buffer_size)
|
||||
{
|
||||
uint16_t read_pos = queue->read_pos;
|
||||
const uint16_t num_of_data_segments = queue->num_of_data_segments;
|
||||
uint16_t read_pos;
|
||||
uint16_t write_pos;
|
||||
uint16_t *buffer_mgmt = (uint16_t *)queue->mgmt_segment.data;
|
||||
|
||||
if (!isGetPossitionSucceccful(queue, &read_pos, &write_pos)) {
|
||||
writeDebug(WarningLevel, "Corrupted shared memory - cannot peek");
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeDebug(
|
||||
TraceLevel,
|
||||
"Reading data from queue. Read index: %u, number of queue elements: %u",
|
||||
read_pos,
|
||||
num_of_data_segments
|
||||
g_num_of_data_segments
|
||||
);
|
||||
|
||||
if (isQueueEmpty(queue)) {
|
||||
if (read_pos == write_pos) {
|
||||
writeDebug(WarningLevel, "peekToQueue: Failed to read from an empty queue\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_pos >= num_of_data_segments) {
|
||||
if (read_pos >= g_num_of_data_segments) {
|
||||
writeDebug(
|
||||
WarningLevel,
|
||||
"peekToQueue: Failed to read from a corrupted queue! (read_pos= %d > num_of_data_segments=%d)\n",
|
||||
read_pos,
|
||||
num_of_data_segments
|
||||
g_num_of_data_segments
|
||||
);
|
||||
return CORRUPTED_SHMEM_ERROR;
|
||||
}
|
||||
|
||||
if (buffer_mgmt[read_pos] == skip_buff_mgmt_magic) {
|
||||
for ( ; read_pos < num_of_data_segments && buffer_mgmt[read_pos] == skip_buff_mgmt_magic; ++read_pos) {
|
||||
for ( ; read_pos < g_num_of_data_segments && buffer_mgmt[read_pos] == skip_buff_mgmt_magic; ++read_pos) {
|
||||
buffer_mgmt[read_pos] = empty_buff_mgmt_magic;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_pos == num_of_data_segments) read_pos = 0;
|
||||
if (read_pos == g_num_of_data_segments) read_pos = 0;
|
||||
|
||||
*output_buffer_size = buffer_mgmt[read_pos];
|
||||
*output_buffer = queue->data_segment[read_pos].data;
|
||||
@@ -332,25 +352,42 @@ pushBuffersToQueue(
|
||||
)
|
||||
{
|
||||
int idx;
|
||||
const uint16_t num_of_queue_elem = queue->num_of_data_segments;
|
||||
uint16_t write_pos = queue->write_pos;
|
||||
uint16_t total_elem_size = 0;
|
||||
uint32_t large_total_elem_size = 0;
|
||||
uint16_t read_pos;
|
||||
uint16_t write_pos;
|
||||
uint16_t total_elem_size;
|
||||
uint16_t *buffer_mgmt = (uint16_t *)queue->mgmt_segment.data;
|
||||
uint16_t end_pos;
|
||||
uint16_t num_of_segments_to_write;
|
||||
char *current_copy_pos;
|
||||
|
||||
if (!isGetPossitionSucceccful(queue, &read_pos, &write_pos)) {
|
||||
writeDebug(WarningLevel, "Corrupted shared memory - cannot push new buffers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeDebug(
|
||||
TraceLevel,
|
||||
"Writing new data to queue. write index: %u, number of queue elements: %u, number of elements to push: %u",
|
||||
write_pos,
|
||||
num_of_queue_elem,
|
||||
g_num_of_data_segments,
|
||||
num_of_input_buffers
|
||||
);
|
||||
|
||||
for (idx = 0; idx < num_of_input_buffers; idx++) {
|
||||
total_elem_size += input_buffers_sizes[idx];
|
||||
large_total_elem_size += input_buffers_sizes[idx];
|
||||
|
||||
if (large_total_elem_size > max_write_size) {
|
||||
writeDebug(
|
||||
WarningLevel,
|
||||
"Requested write size %u exceeds the %u write limit",
|
||||
large_total_elem_size,
|
||||
max_write_size
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
total_elem_size = (uint16_t)large_total_elem_size;
|
||||
|
||||
num_of_segments_to_write = getNumOfDataSegmentsNeeded(total_elem_size);
|
||||
|
||||
@@ -362,23 +399,23 @@ pushBuffersToQueue(
|
||||
);
|
||||
|
||||
|
||||
if (!isThereEnoughMemoryInQueue(queue, num_of_segments_to_write)) {
|
||||
if (!isThereEnoughMemoryInQueue(write_pos, read_pos, num_of_segments_to_write)) {
|
||||
writeDebug(WarningLevel, "Cannot write to a full queue\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_pos >= num_of_queue_elem) {
|
||||
if (write_pos >= g_num_of_data_segments) {
|
||||
writeDebug(
|
||||
WarningLevel,
|
||||
"Cannot write to a location outside the queue. Write index: %u, number of queue elements: %u",
|
||||
write_pos,
|
||||
num_of_queue_elem
|
||||
g_num_of_data_segments
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_pos + num_of_segments_to_write > num_of_queue_elem) {
|
||||
for ( ; write_pos < num_of_queue_elem; ++write_pos) {
|
||||
if (write_pos + num_of_segments_to_write > g_num_of_data_segments) {
|
||||
for ( ; write_pos < g_num_of_data_segments; ++write_pos) {
|
||||
buffer_mgmt[write_pos] = skip_buff_mgmt_magic;
|
||||
}
|
||||
write_pos = 0;
|
||||
@@ -411,8 +448,9 @@ pushBuffersToQueue(
|
||||
buffer_mgmt[write_pos] = skip_buff_mgmt_magic;
|
||||
}
|
||||
|
||||
queue->write_pos = write_pos < num_of_queue_elem ? write_pos : 0;
|
||||
writeDebug(TraceLevel, "Successfully pushed data to queue. New write index: %u", queue->write_pos);
|
||||
if (write_pos >= g_num_of_data_segments) write_pos = 0;
|
||||
queue->write_pos = write_pos;
|
||||
writeDebug(TraceLevel, "Successfully pushed data to queue. New write index: %u", write_pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -427,19 +465,24 @@ int
|
||||
popFromQueue(SharedRingQueue *queue)
|
||||
{
|
||||
uint16_t num_of_read_segments;
|
||||
uint16_t read_pos = queue->read_pos;
|
||||
uint16_t read_pos;
|
||||
uint16_t write_pos;
|
||||
uint16_t end_pos;
|
||||
uint16_t num_of_data_segments = queue->num_of_data_segments;
|
||||
uint16_t *buffer_mgmt = (uint16_t *)queue->mgmt_segment.data;
|
||||
|
||||
if (!isGetPossitionSucceccful(queue, &read_pos, &write_pos)) {
|
||||
writeDebug(WarningLevel, "Corrupted shared memory - cannot pop data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
writeDebug(
|
||||
TraceLevel,
|
||||
"Removing data from queue. new data to queue. Read index: %u, number of queue elements: %u",
|
||||
read_pos,
|
||||
num_of_data_segments
|
||||
g_num_of_data_segments
|
||||
);
|
||||
|
||||
if (isQueueEmpty(queue)) {
|
||||
if (read_pos == write_pos) {
|
||||
writeDebug(TraceLevel, "Cannot pop data from empty queue");
|
||||
return -1;
|
||||
}
|
||||
@@ -460,16 +503,16 @@ popFromQueue(SharedRingQueue *queue)
|
||||
buffer_mgmt[read_pos] = empty_buff_mgmt_magic;
|
||||
}
|
||||
|
||||
if (read_pos < num_of_data_segments && buffer_mgmt[read_pos] == skip_buff_mgmt_magic) {
|
||||
for ( ; read_pos < num_of_data_segments; ++read_pos ) {
|
||||
if (read_pos < g_num_of_data_segments && buffer_mgmt[read_pos] == skip_buff_mgmt_magic) {
|
||||
for ( ; read_pos < g_num_of_data_segments; ++read_pos ) {
|
||||
buffer_mgmt[read_pos] = empty_buff_mgmt_magic;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_pos == num_of_data_segments) read_pos = 0;
|
||||
if (read_pos == g_num_of_data_segments) read_pos = 0;
|
||||
|
||||
queue->read_pos = read_pos;
|
||||
writeDebug(TraceLevel, "Successfully popped data from queue. New read index: %u", queue->read_pos);
|
||||
writeDebug(TraceLevel, "Successfully popped data from queue. New read index: %u", read_pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@ debugInitial(int is_error, const char *func, const char *file, int line_num, con
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void (*debug_int)(int is_error, const char *func, const char *file, int line_num, const char *fmt, ...) = debugInitial;
|
||||
@@ -100,7 +101,7 @@ createOneWayIPCQueue(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_owner && chmod(shmem_path, 0666) == -1) {
|
||||
if (is_owner && chown(shmem_path, user_id, group_id) == -1) {
|
||||
writeDebug(WarningLevel, "Failed to set the permissions");
|
||||
destroySharedRingQueue(ring_queue, is_owner, isTowardsOwner(is_owner, is_tx_queue));
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user