sync code

This commit is contained in:
Daniel Eisenberg
2026-01-06 16:31:33 +02:00
parent 7ce1fba437
commit 599aa34732
82 changed files with 7557 additions and 807 deletions

View File

@@ -225,35 +225,35 @@ void FreeAttachmentResponseContent(
);
///
/// @brief Compresses HttpBody and return allocated compressed body.
/// @brief Compresses NanoHttpBody and return allocated compressed body.
///
/// @param attachment The NanoAttachment object associated with the session.
/// @param session_data The HttpSessionData object representing the session.
/// @param bodies The bodies pointer to be compressed.
///
HttpBody * compressBody(
NanoHttpBody * compressBody(
NanoAttachment *attachment,
HttpSessionData *session_data,
HttpBody *bodies
NanoHttpBody *bodies
);
///
/// @brief Compresses HttpBody and return allocated compressed body.
/// @brief Compresses NanoHttpBody and return allocated compressed body.
///
/// @param attachment The NanoAttachment object associated with the session.
/// @param session_data The HttpSessionData object representing the session.
/// @param bodies The bodies pointer to be decompressed.
///
HttpBody * decompressBody(
NanoHttpBody * decompressBody(
NanoAttachment *attachment,
HttpSessionData *session_data,
HttpBody *bodies
NanoHttpBody *bodies
);
///
/// @brief Free allocated compressed body.
///
/// This function frees the allocated resources of HttpBody object.
/// This function frees the allocated resources of NanoHttpBody object.
///
/// @param attachment The NanoAttachment object associated with the session.
/// @param session_data The HttpSessionData object representing the session.
@@ -263,31 +263,7 @@ void
freeCompressedBody(
NanoAttachment *attachment,
HttpSessionData *session_data,
HttpBody *bodies
NanoHttpBody *bodies
);
///
/// @brief Gets the request processing timeout in milliseconds.
///
/// This function retrieves the configured timeout value for request processing
/// from the NanoAttachment configuration.
///
/// @param attachment A pointer to the NanoAttachment structure.
///
/// @return The request processing timeout in milliseconds.
///
uint32_t GetRequestProcessingTimeout(NanoAttachment *attachment);
///
/// @brief Gets the response processing timeout in milliseconds.
///
/// This function retrieves the configured timeout value for response processing
/// from the NanoAttachment configuration.
///
/// @param attachment A pointer to the NanoAttachment structure.
///
/// @return The response processing timeout in milliseconds.
///
uint32_t GetResponseProcessingTimeout(NanoAttachment *attachment);
#endif // __NANO_ATTACHMENT_H__

View File

@@ -7,10 +7,16 @@
#include <sys/types.h>
#include <assert.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "compression_utils.h"
typedef uint32_t SessionID;
typedef void* DataBuffer;
typedef int64_t NanoHttpCpInjectPos;
#define MAX_NGINX_UID_LEN 32
#define MAX_SHARED_MEM_PATH_LEN 128
@@ -175,7 +181,9 @@ typedef enum AttachmentDataType
RESPONSE_END,
CONTENT_LENGTH,
METRIC_DATA_FROM_PLUGIN,
REQUEST_DELAYED_VERDICT
REQUEST_DELAYED_VERDICT,
COUNT
} AttachmentDataType;
#ifdef __cplusplus
@@ -207,9 +215,23 @@ typedef enum ServiceVerdict
TRAFFIC_VERDICT_INJECT,
TRAFFIC_VERDICT_IRRELEVANT,
TRAFFIC_VERDICT_RECONF,
TRAFFIC_VERDICT_DELAYED
TRAFFIC_VERDICT_DELAYED,
LIMIT_RESPONSE_HEADERS,
TRAFFIC_VERDICT_CUSTOM_RESPONSE
} ServiceVerdict;
#ifdef __cplusplus
typedef enum class AttachmentContentType
#else
typedef enum AttachmentContentType
#endif
{
CONTENT_TYPE_APPLICATION_JSON,
CONTENT_TYPE_TEXT_HTML,
CONTENT_TYPE_TEXT_PLAIN,
CONTENT_TYPE_OTHER
} AttachmentContentType;
#ifdef __cplusplus
typedef enum class AttachmentVerdict
#else
@@ -234,7 +256,7 @@ typedef enum HttpModificationType
} HttpModificationType;
typedef struct __attribute__((__packed__)) HttpInjectData {
int64_t injection_pos;
NanoHttpCpInjectPos injection_pos;
HttpModificationType mod_type;
uint16_t injection_size;
uint8_t is_header;
@@ -263,6 +285,13 @@ typedef struct __attribute__((__packed__)) HttpWebResponseData {
} response_data;
} HttpWebResponseData;
typedef struct __attribute__((__packed__)) HttpJsonResponseData {
uint16_t response_code;
uint16_t body_size;
AttachmentContentType content_type;
char body[0];
} HttpJsonResponseData;
typedef struct {
size_t len;
unsigned char *data;
@@ -308,6 +337,8 @@ typedef enum HttpMetaDataType
PARSED_HOST_DATA,
PARSED_URI_SIZE,
PARSED_URI_DATA,
WAF_TAG_SIZE,
WAF_TAG_DATA,
META_DATA_COUNT
} HttpMetaDataType;
@@ -402,10 +433,10 @@ typedef struct ResHttpHeaders {
uint64_t content_length;
} ResHttpHeaders;
typedef struct HttpBody {
typedef struct NanoHttpBody {
nano_str_t *data;
size_t bodies_count;
} HttpBody;
} NanoHttpBody;
typedef struct AttachmentData {
SessionID session_id;
@@ -417,6 +448,7 @@ typedef struct AttachmentData {
typedef union __attribute__((__packed__)) HttpModifyData {
HttpInjectData inject_data[0];
HttpWebResponseData web_response_data[0];
HttpJsonResponseData json_response_data[0];
} HttpModifyData;
typedef struct __attribute__((__packed__)) HttpReplyFromService {
@@ -479,6 +511,12 @@ typedef struct NanoResponseModifications {
NanoHttpModificationList *modifications;
} NanoResponseModifications;
typedef struct __attribute__((__packed__)) NanoHttpRequestData {
uint16_t data_type;
uint32_t session_id;
unsigned char data[0];
} NanoHttpRequestData;
typedef struct __attribute__((__packed__)) NanoHttpMetricData {
uint16_t data_type;
#ifdef __cplusplus
@@ -488,4 +526,147 @@ typedef struct __attribute__((__packed__)) NanoHttpMetricData {
#endif
} NanoHttpMetricData;
// Simple but reliable hash function for generating consistent, well-distributed offsets
// Uses a basic polynomial hash that avoids large intermediate values
static inline uint32_t hash_string(const char *str) {
uint32_t hash = 0;
while (*str) {
hash = (hash * 31 + (unsigned char)*str++) % 10000; // Keep values under 10000
}
return hash; // Return bounded hash - modulo will be applied by caller
}
static inline int set_affinity_by_uid(uint32_t uid) {
int num_cores = sysconf(_SC_NPROCESSORS_CONF);
// Debug print for troubleshooting
fprintf(stderr, "[DEBUG] set_affinity_by_uid: num_cores=%d, uid=%u\n", num_cores, uid);
uint32_t core_num = (uid - 1) % num_cores; // Ensure core_num is within bounds
cpu_set_t mask, mask_check;
CPU_ZERO(&mask);
CPU_ZERO(&mask_check);
CPU_SET(core_num, &mask);
pid_t pid = getpid(); // Use process PID, not thread ID
if (sched_setaffinity(pid, sizeof(mask), &mask) != 0) {
return -1; // Error setting affinity
}
if (sched_getaffinity(pid, sizeof(mask_check), &mask_check) != 0) {
return -2; // Error getting affinity
}
// Compare mask and mask_check
int i;
for (i = 0; i < num_cores; ++i) {
if (CPU_ISSET(i, &mask) != CPU_ISSET(i, &mask_check)) {
return -3; // Affinity not set as expected
}
}
return 0; // Success
}
static inline int set_affinity_by_uid_with_offset(uint32_t uid, uint32_t offset) {
int num_cores = sysconf(_SC_NPROCESSORS_CONF);
// Debug print for troubleshooting
fprintf(
stderr, "[DEBUG] set_affinity_by_uid_with_offset: num_cores=%d, uid=%u, offset=%u\n", num_cores, uid, offset);
// Prevent integer overflow by applying modulo to offset first
uint32_t safe_offset = offset % num_cores;
uint32_t core_num = ((uid - 1) + safe_offset) % num_cores;
cpu_set_t mask, mask_check;
CPU_ZERO(&mask);
CPU_ZERO(&mask_check);
CPU_SET(core_num, &mask);
pid_t pid = getpid(); // Use process PID, not thread ID
if (sched_setaffinity(pid, sizeof(mask), &mask) != 0) {
return -1; // Error setting affinity
}
if (sched_getaffinity(pid, sizeof(mask_check), &mask_check) != 0) {
return -2; // Error getting affinity
}
// Compare mask and mask_check
int i;
for (i = 0; i < num_cores; ++i) {
if (CPU_ISSET(i, &mask) != CPU_ISSET(i, &mask_check)) {
return -3; // Affinity not set as expected
}
}
return 0; // Success
}
static inline int set_affinity_by_uid_with_offset_fixed_cores(uint32_t uid, uint32_t offset, int num_cores) {
// Debug print for troubleshooting
fprintf(
stderr,
"[DEBUG] set_affinity_by_uid_with_offset_fixed_cores: num_cores=%d, uid=%u, offset=%u\n",
num_cores,
uid,
offset
);
// Prevent integer overflow by applying modulo to offset first
uint32_t safe_offset = offset % num_cores;
uint32_t core_num = ((uid - 1) + safe_offset) % num_cores;
cpu_set_t mask, mask_check;
CPU_ZERO(&mask);
CPU_ZERO(&mask_check);
CPU_SET(core_num, &mask);
pid_t pid = getpid(); // Use process PID, not thread ID
if (sched_setaffinity(pid, sizeof(mask), &mask) != 0) {
return -1; // Error setting affinity
}
if (sched_getaffinity(pid, sizeof(mask_check), &mask_check) != 0) {
return -2; // Error getting affinity
}
// Compare mask and mask_check
int i;
for (i = 0; i < num_cores; ++i) {
if (CPU_ISSET(i, &mask) != CPU_ISSET(i, &mask_check)) {
return -3; // Affinity not set as expected
}
}
return 0; // Success
}
static inline int set_affinity_to_core(int target_core) {
// Debug print for troubleshooting
fprintf(stderr, "[DEBUG] set_affinity_to_core: target_core=%d\n", target_core);
cpu_set_t mask, mask_check;
CPU_ZERO(&mask);
CPU_ZERO(&mask_check);
CPU_SET(target_core, &mask);
pid_t pid = getpid(); // Use process PID, not thread ID
if (sched_setaffinity(pid, sizeof(mask), &mask) != 0) {
return -1; // Error setting affinity
}
if (sched_getaffinity(pid, sizeof(mask_check), &mask_check) != 0) {
return -2; // Error getting affinity
}
// Compare mask and mask_check
int num_cores = sysconf(_SC_NPROCESSORS_CONF);
int i;
for (i = 0; i < num_cores; ++i) {
if (CPU_ISSET(i, &mask) != CPU_ISSET(i, &mask_check)) {
return -3; // Affinity not set as expected
}
}
return 0; // Success
}
static inline int reset_affinity() {
int num_cores = sysconf(_SC_NPROCESSORS_CONF);
// Debug print for troubleshooting
fprintf(stderr, "[DEBUG] reset_affinity: num_cores=%d\n", num_cores);
cpu_set_t mask;
CPU_ZERO(&mask);
int i;
for (i = 0; i < num_cores; ++i) CPU_SET(i, &mask);
pid_t pid = getpid(); // Use process PID, not thread ID
if (sched_setaffinity(pid, sizeof(mask), &mask) != 0) {
return -1; // Error setting affinity
}
return 0; // Success
}
#endif // __NANO_ATTACHMENT_COMMON_H__

View File

@@ -15,286 +15,10 @@
#ifndef __NGINX_ATTACHMENT_COMMON_H__
#define __NGINX_ATTACHMENT_COMMON_H__
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <assert.h>
// This file has been deprecated. Do not add anything here.
// Any future additions should be added to nano_attachment_common.h
// For any inquiries please contact Daniel Yashin.
#define MAX_NGINX_UID_LEN 32
#define NUM_OF_NGINX_IPC_ELEMENTS 200
#define DEFAULT_KEEP_ALIVE_INTERVAL_MSEC 300000
#define SHARED_MEM_PATH "/dev/shm/"
#define SHARED_REGISTRATION_SIGNAL_PATH SHARED_MEM_PATH "check-point/cp-nano-attachment-registration"
#define SHARED_KEEP_ALIVE_PATH SHARED_MEM_PATH "check-point/cp-nano-attachment-registration-expiration-socket"
#define SHARED_VERDICT_SIGNAL_PATH SHARED_MEM_PATH "check-point/cp-nano-http-transaction-handler"
#define SHARED_ATTACHMENT_CONF_PATH SHARED_MEM_PATH "cp_nano_http_attachment_conf"
#define DEFAULT_STATIC_RESOURCES_PATH SHARED_MEM_PATH "static_resources"
#define INJECT_POS_IRRELEVANT -1
#define CORRUPTED_SESSION_ID 0
#define METRIC_PERIODIC_TIMEOUT 600
extern char shared_verdict_signal_path[];
extern int workers_amount_to_send;
typedef int64_t ngx_http_cp_inject_pos_t;
#ifdef __cplusplus
typedef enum class ngx_http_modification_type
#else
typedef enum ngx_http_modification_type
#endif
{
APPEND,
INJECT,
REPLACE
} ngx_http_modification_type_e;
#ifdef __cplusplus
typedef enum class ngx_http_chunk_type
#else
typedef enum ngx_http_chunk_type
#endif
{
REQUEST_START,
REQUEST_HEADER,
REQUEST_BODY,
REQUEST_END,
RESPONSE_CODE,
RESPONSE_HEADER,
RESPONSE_BODY,
RESPONSE_END,
CONTENT_LENGTH,
METRIC_DATA_FROM_PLUGIN,
HOLD_DATA,
COUNT
} ngx_http_chunk_type_e;
#ifdef __cplusplus
typedef enum class ngx_http_plugin_metric_type
#else
typedef enum ngx_http_plugin_metric_type
#endif
{
TRANSPARENTS_COUNT,
TOTAL_TRANSPARENTS_TIME,
INSPECTION_OPEN_FAILURES_COUNT,
INSPECTION_CLOSE_FAILURES_COUNT,
INSPECTION_SUCCESSES_COUNT,
INJECT_VERDICTS_COUNT,
DROP_VERDICTS_COUNT,
ACCEPT_VERDICTS_COUNT,
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,
AVERAGE_REQ_PPROCESSING_TIME_UNTIL_VERDICT,
MAX_REQ_PPROCESSING_TIME_UNTIL_VERDICT,
MIN_REQ_PPROCESSING_TIME_UNTIL_VERDICT,
AVERAGE_RES_PPROCESSING_TIME_UNTIL_VERDICT,
MAX_RES_PPROCESSING_TIME_UNTIL_VERDICT,
MIN_RES_PPROCESSING_TIME_UNTIL_VERDICT,
THREAD_TIMEOUT,
REG_THREAD_TIMEOUT,
REQ_HEADER_THREAD_TIMEOUT,
REQ_BODY_THREAD_TIMEOUT,
AVERAGE_REQ_BODY_SIZE_UPON_TIMEOUT,
MAX_REQ_BODY_SIZE_UPON_TIMEOUT,
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,
THREAD_FAILURE,
REQ_PROCCESSING_TIMEOUT,
RES_PROCCESSING_TIMEOUT,
REQ_FAILED_TO_REACH_UPSTREAM,
REQ_FAILED_COMPRESSION_COUNT,
RES_FAILED_COMPRESSION_COUNT,
REQ_FAILED_DECOMPRESSION_COUNT,
RES_FAILED_DECOMPRESSION_COUNT,
REQ_SUCCESSFUL_COMPRESSION_COUNT,
RES_SUCCESSFUL_COMPRESSION_COUNT,
REQ_SUCCESSFUL_DECOMPRESSION_COUNT,
RES_SUCCESSFUL_DECOMPRESSION_COUNT,
CORRUPTED_ZIP_SKIPPED_SESSION_COUNT,
CPU_USAGE,
AVERAGE_VM_MEMORY_USAGE,
AVERAGE_RSS_MEMORY_USAGE,
MAX_VM_MEMORY_USAGE,
MAX_RSS_MEMORY_USAGE,
REQUEST_OVERALL_SIZE_COUNT,
RESPONSE_OVERALL_SIZE_COUNT,
METRIC_TYPES_COUNT
} ngx_http_plugin_metric_type_e;
#ifdef __cplusplus
typedef enum class ngx_http_cp_verdict
#else
typedef enum ngx_http_cp_verdict
#endif
{
TRAFFIC_VERDICT_INSPECT,
TRAFFIC_VERDICT_ACCEPT,
TRAFFIC_VERDICT_DROP,
TRAFFIC_VERDICT_INJECT,
TRAFFIC_VERDICT_IRRELEVANT,
TRAFFIC_VERDICT_RECONF,
TRAFFIC_VERDICT_WAIT,
LIMIT_RESPONSE_HEADERS
} ngx_http_cp_verdict_e;
#ifdef __cplusplus
typedef enum class ngx_http_cp_debug_level
#else
typedef enum ngx_http_cp_debug_level
#endif
{
DBG_LEVEL_TRACE,
DBG_LEVEL_DEBUG,
DBG_LEVEL_INFO,
DBG_LEVEL_WARNING,
DBG_LEVEL_ERROR,
#ifndef __cplusplus
DBG_LEVEL_ASSERT,
#endif
DBG_LEVEL_COUNT
} ngx_http_cp_debug_level_e;
#ifdef __cplusplus
typedef enum class ngx_http_meta_data
#else
typedef enum ngx_http_meta_data
#endif
{
HTTP_PROTOCOL_SIZE,
HTTP_PROTOCOL_DATA,
HTTP_METHOD_SIZE,
HTTP_METHOD_DATA,
HOST_NAME_SIZE,
HOST_NAME_DATA,
LISTENING_ADDR_SIZE,
LISTENING_ADDR_DATA,
LISTENING_PORT,
URI_SIZE,
URI_DATA,
CLIENT_ADDR_SIZE,
CLIENT_ADDR_DATA,
CLIENT_PORT,
PARSED_HOST_SIZE,
PARSED_HOST_DATA,
PARSED_URI_SIZE,
PARSED_URI_DATA,
WAF_TAG_SIZE,
WAF_TAG_DATA,
META_DATA_COUNT
} ngx_http_meta_data_e;
#ifdef __cplusplus
typedef enum class ngx_http_header_data
#else
typedef enum ngx_http_header_data
#endif
{
HEADER_KEY_SIZE,
HEADER_KEY_DATA,
HEADER_VAL_SIZE,
HEADER_VAL_DATA,
HEADER_DATA_COUNT
} ngx_http_header_data_e;
typedef enum ngx_http_inspection_mode
{
NON_BLOCKING_THREAD,
BLOCKING_THREAD,
NO_THREAD,
INSPECTION_MODE_COUNT
} ngx_http_inspection_mode_e;
#ifdef __cplusplus
typedef enum class ngx_web_response_type
#else
typedef enum ngx_web_response_type
#endif
{
CUSTOM_WEB_RESPONSE,
CUSTOM_WEB_BLOCK_PAGE_RESPONSE,
RESPONSE_CODE_ONLY,
REDIRECT_WEB_RESPONSE,
NO_WEB_RESPONSE
} ngx_web_response_type_e;
typedef struct __attribute__((__packed__)) ngx_http_cp_inject_data {
ngx_http_cp_inject_pos_t injection_pos;
ngx_http_modification_type_e mod_type;
uint16_t injection_size;
uint8_t is_header;
uint8_t orig_buff_index;
char data[0];
} ngx_http_cp_inject_data_t;
typedef struct __attribute__((__packed__)) ngx_http_cp_web_response_data {
uint8_t web_repsonse_type;
uint8_t uuid_size;
union {
struct __attribute__((__packed__)) ngx_http_cp_custom_web_response_data {
uint16_t response_code;
uint8_t title_size;
uint8_t body_size;
char data[0];
} custom_response_data;
struct __attribute__((__packed__)) ngx_http_cp_redirect_data {
uint8_t unused_dummy;
uint8_t add_event_id;
uint16_t redirect_location_size;
char redirect_location[0];
} redirect_data;
} response_data;
} ngx_http_cp_web_response_data_t;
static_assert(
sizeof(((ngx_http_cp_web_response_data_t*)0)->response_data.custom_response_data) ==
sizeof(((ngx_http_cp_web_response_data_t*)0)->response_data.redirect_data),
"custom_response_data must be equal to redirect_data in size"
);
typedef union __attribute__((__packed__)) ngx_http_cp_modify_data {
ngx_http_cp_inject_data_t inject_data[0];
ngx_http_cp_web_response_data_t web_response_data[0];
} ngx_http_cp_modify_data_t;
typedef struct __attribute__((__packed__)) ngx_http_cp_reply_from_service {
uint16_t verdict;
uint32_t session_id;
uint8_t modification_count;
ngx_http_cp_modify_data_t modify_data[0];
} ngx_http_cp_reply_from_service_t;
typedef struct __attribute__((__packed__)) ngx_http_cp_request_data {
uint16_t data_type;
uint32_t session_id;
unsigned char data[0];
} ngx_http_cp_request_data_t;
typedef struct __attribute__((__packed__)) ngx_http_cp_metric_data {
uint16_t data_type;
#ifdef __cplusplus
uint64_t data[static_cast<int>(ngx_http_plugin_metric_type::METRIC_TYPES_COUNT)];
#else
uint64_t data[METRIC_TYPES_COUNT];
#endif
} ngx_http_cp_metric_data_t;
#endif // __NGINX_ATTACHMENT_COMMON_H__

View File

@@ -17,7 +17,7 @@
#include <stdio.h>
#include "nginx_attachment_common.h"
#include "nano_attachment_common.h"
#ifdef __cplusplus
extern "C" {
@@ -29,7 +29,7 @@ typedef const char * c_str;
int initAttachmentConfig(c_str conf_file);
ngx_http_inspection_mode_e getInspectionMode();
NanoHttpInspectionMode getInspectionMode();
unsigned int getNumOfNginxIpcElements();
unsigned int getKeepAliveIntervalMsec();
unsigned int getDbgLevel();
@@ -61,11 +61,16 @@ unsigned int getMinRetriesForVerdict();
unsigned int getMaxRetriesForVerdict();
unsigned int getReqBodySizeTrigger();
unsigned int getRemoveResServerHeader();
unsigned int getDecompressionPoolSize();
unsigned int getRecompressionPoolSize();
unsigned int getIsBrotliInspectionEnabled();
unsigned int getWaitingForVerdictThreadTimeout();
int isIPAddress(c_str ip_str);
int isSkipSource(c_str ip_str);
unsigned int isPairedAffinityEnabled();
unsigned int isAsyncModeEnabled();
#ifdef __cplusplus
}