feature: debug plugin support output per session stat
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
||||||
void hexdump_to_fd(int fd, const char *data, uint16_t len)
|
void hexdump_to_fd(int fd, uint32_t idx, const char *data, uint16_t len)
|
||||||
{
|
{
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
uint16_t used = 0;
|
uint16_t used = 0;
|
||||||
@@ -8,20 +8,31 @@ void hexdump_to_fd(int fd, const char *data, uint16_t len)
|
|||||||
|
|
||||||
#define LINE_LEN 80
|
#define LINE_LEN 80
|
||||||
char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */
|
char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */
|
||||||
|
|
||||||
dprintf(fd, "dump data at [%p], len=%u\n", data, len);
|
|
||||||
while (offset < len)
|
while (offset < len)
|
||||||
{
|
{
|
||||||
/* format the line in the buffer, then use printf to usedput to screen */
|
used = snprintf(line, LINE_LEN, "%08X ", idx + offset);
|
||||||
used = snprintf(line, LINE_LEN, "%08X:", offset);
|
|
||||||
|
// hexdump
|
||||||
for (i = 0; ((offset + i) < len) && (i < 16); i++)
|
for (i = 0; ((offset + i) < len) && (i < 16); i++)
|
||||||
{
|
{
|
||||||
used += snprintf(line + used, LINE_LEN - used, " %02X", (data[offset + i] & 0xff));
|
if (i == 8)
|
||||||
|
{
|
||||||
|
used += snprintf(line + used, LINE_LEN - used, " ");
|
||||||
|
}
|
||||||
|
used += snprintf(line + used, LINE_LEN - used, " %02x", (data[offset + i] & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// padding
|
||||||
for (; i <= 16; i++)
|
for (; i <= 16; i++)
|
||||||
{
|
{
|
||||||
used += snprintf(line + used, LINE_LEN - used, " | ");
|
if (i == 8)
|
||||||
|
{
|
||||||
|
used += snprintf(line + used, LINE_LEN - used, " ");
|
||||||
|
}
|
||||||
|
used += snprintf(line + used, LINE_LEN - used, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ascii
|
||||||
for (i = 0; (offset < len) && (i < 16); i++, offset++)
|
for (i = 0; (offset < len) && (i < 16); i++, offset++)
|
||||||
{
|
{
|
||||||
unsigned char c = data[offset];
|
unsigned char c = data[offset];
|
||||||
@@ -29,9 +40,12 @@ void hexdump_to_fd(int fd, const char *data, uint16_t len)
|
|||||||
{
|
{
|
||||||
c = '.';
|
c = '.';
|
||||||
}
|
}
|
||||||
|
if (i == 8)
|
||||||
|
{
|
||||||
|
used += snprintf(line + used, LINE_LEN - used, " ");
|
||||||
|
}
|
||||||
used += snprintf(line + used, LINE_LEN - used, "%c", c);
|
used += snprintf(line + used, LINE_LEN - used, "%c", c);
|
||||||
}
|
}
|
||||||
dprintf(fd, "%s\n", line);
|
dprintf(fd, "%s\n", line);
|
||||||
}
|
}
|
||||||
dprintf(fd, "\n");
|
}
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ extern "C"
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void hexdump_to_fd(int fd, const char *data, uint16_t len);
|
void hexdump_to_fd(int fd, uint32_t idx, const char *data, uint16_t len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void packet_dump_hex(const struct packet *pkt, int fd)
|
|||||||
uint16_t len = packet_get_raw_len(pkt);
|
uint16_t len = packet_get_raw_len(pkt);
|
||||||
const char *data = packet_get_raw_data(pkt);
|
const char *data = packet_get_raw_data(pkt);
|
||||||
|
|
||||||
hexdump_to_fd(fd, data, len);
|
hexdump_to_fd(fd, 0, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int packet_dump_str(const struct packet *pkt, char *buff, int size)
|
int packet_dump_str(const struct packet *pkt, char *buff, int size)
|
||||||
@@ -113,7 +113,7 @@ int packet_dump_str(const struct packet *pkt, char *buff, int size)
|
|||||||
for (uint8_t i = 0; i < pkt->layers_used; i++)
|
for (uint8_t i = 0; i < pkt->layers_used; i++)
|
||||||
{
|
{
|
||||||
const struct raw_layer *layer = &pkt->layers[i];
|
const struct raw_layer *layer = &pkt->layers[i];
|
||||||
used += snprintf(buff + used, size - used, "=> layer[%u]: %p, proto: %s, header: {offset: %u, ptr: %p, len: %u}, payload: {ptr: %p, len: %u}\n",
|
used += snprintf(buff + used, size - used, "layer[%u]: %p, proto: %s, header: {offset: %u, ptr: %p, len: %u}, payload: {ptr: %p, len: %u}\n",
|
||||||
i, layer, layer_proto_to_str(layer->proto), layer->hdr_offset,
|
i, layer, layer_proto_to_str(layer->proto), layer->hdr_offset,
|
||||||
layer->hdr_ptr, layer->hdr_len, layer->pld_ptr, layer->pld_len);
|
layer->hdr_ptr, layer->hdr_len, layer->pld_ptr, layer->pld_len);
|
||||||
switch (layer->proto)
|
switch (layer->proto)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
set(SOURCE stellar_config.cpp stellar_stat.cpp stellar_core.cpp)
|
set(SOURCE stellar_config.cpp stellar_stat.cpp stellar_core.cpp)
|
||||||
set(LIBRARY times session_manager plugin_manager ip_reassembly packet_io packet pthread fieldstat4 toml)
|
set(LIBRARY times session_manager plugin_manager ip_reassembly packet_io packet pthread fieldstat4 toml hexdump)
|
||||||
|
|
||||||
add_library(stellar_core STATIC ${SOURCE})
|
add_library(stellar_core STATIC ${SOURCE})
|
||||||
target_link_libraries(stellar_core PUBLIC ${LIBRARY})
|
target_link_libraries(stellar_core PUBLIC ${LIBRARY})
|
||||||
|
|
||||||
add_library(stellar_devel SHARED ${SOURCE})
|
add_library(stellar_devel SHARED ${SOURCE})
|
||||||
#target_link_libraries(stellar_devel ${LIBRARY})
|
|
||||||
set_target_properties(stellar_devel PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map")
|
set_target_properties(stellar_devel PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map")
|
||||||
target_link_libraries(stellar_devel PRIVATE -Wl,--whole-archive ${LIBRARY} -Wl,--no-whole-archive)
|
target_link_libraries(stellar_devel PRIVATE -Wl,--whole-archive ${LIBRARY} -Wl,--no-whole-archive)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# build libdebug_plugin.so
|
# build libdebug_plugin.so
|
||||||
add_library(debug_plugin SHARED debug_plugin.cpp)
|
add_library(debug_plugin SHARED debug_plugin.cpp)
|
||||||
# Note: The debug plugin here uses stellar_core instead of stellar_devel, in order to output more session/packet information for development debugging.
|
target_link_libraries(debug_plugin stellar_devel hexdump session_manager packet)
|
||||||
target_link_libraries(debug_plugin stellar_core toml)
|
|
||||||
target_include_directories(debug_plugin PUBLIC ${CMAKE_SOURCE_DIR}/include/)
|
target_include_directories(debug_plugin PUBLIC ${CMAKE_SOURCE_DIR}/include/)
|
||||||
set_target_properties(debug_plugin PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map")
|
set_target_properties(debug_plugin PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/version.map")
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "packet_dump.h"
|
#include "packet_dump.h"
|
||||||
#include "stellar/packet.h"
|
#include "stellar/packet.h"
|
||||||
#include "stellar/stellar_mq.h"
|
#include "stellar/stellar_mq.h"
|
||||||
|
#include "stellar/stellar_exdata.h"
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
@@ -57,18 +58,38 @@ static void log_print(int fd, const char *module, const char *fmt, ...)
|
|||||||
struct plugin_ctx
|
struct plugin_ctx
|
||||||
{
|
{
|
||||||
struct stellar *st;
|
struct stellar *st;
|
||||||
|
int sess_exdata_idx;
|
||||||
int sess_plug_id;
|
int sess_plug_id;
|
||||||
int tcp_topic_id;
|
int tcp_topic_id;
|
||||||
int udp_topic_id;
|
int udp_topic_id;
|
||||||
int tcp_stream_topic_id;
|
int tcp_stream_topic_id;
|
||||||
int fd;
|
int fd;
|
||||||
|
int c2s_tcp_seg_hexdump_fd;
|
||||||
|
int s2c_tcp_seg_hexdump_fd;
|
||||||
pthread_spinlock_t lock; // for hexdump thread safe
|
pthread_spinlock_t lock; // for hexdump thread safe
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sess_exdta
|
||||||
|
{
|
||||||
|
uint64_t c2s_rx_pkts;
|
||||||
|
uint64_t s2c_rx_pkts;
|
||||||
|
|
||||||
|
uint64_t c2s_rx_bytes;
|
||||||
|
uint64_t s2c_rx_bytes;
|
||||||
|
|
||||||
|
uint64_t c2s_rx_tcp_seg;
|
||||||
|
uint64_t s2c_rx_tcp_seg;
|
||||||
|
|
||||||
|
uint64_t c2s_rx_tcp_bytes;
|
||||||
|
uint64_t s2c_rx_tcp_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
static void *on_sess_new(struct session *sess, void *plugin_ctx)
|
static void *on_sess_new(struct session *sess, void *plugin_ctx)
|
||||||
{
|
{
|
||||||
char buff[4096];
|
char buff[4096];
|
||||||
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
||||||
|
struct sess_exdta *stat = (struct sess_exdta *)calloc(1, sizeof(struct sess_exdta));
|
||||||
|
session_exdata_set(sess, ctx->sess_exdata_idx, stat);
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
memset(buff, 0, sizeof(buff));
|
||||||
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
||||||
@@ -81,10 +102,21 @@ static void on_sess_free(struct session *sess, void *sess_ctx, void *plugin_ctx)
|
|||||||
{
|
{
|
||||||
char buff[4096];
|
char buff[4096];
|
||||||
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
||||||
|
struct sess_exdta *stat = (struct sess_exdta *)session_exdata_get(sess, ctx->sess_exdata_idx);
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
memset(buff, 0, sizeof(buff));
|
||||||
session_to_str(sess, 0, buff, sizeof(buff) - 1);
|
session_to_str(sess, 0, buff, sizeof(buff) - 1);
|
||||||
log_print(ctx->fd, "debug plugin", "sess free: %s", buff);
|
log_print(ctx->fd, "debug plugin", "sess free: %s", buff);
|
||||||
|
log_print(ctx->fd, "debug plugin", "session %lu %s stat:\n"
|
||||||
|
"C2S rx packets: %6lu, C2S rx bytes: %6lu\n"
|
||||||
|
"S2C rx packets: %6lu, S2C rx bytes: %6lu\n"
|
||||||
|
"C2S rx TCP segments: %6lu, C2S rx TCP bytes: %6lu\n"
|
||||||
|
"S2C rx TCP segments: %6lu, S2C rx TCP bytes: %6lu\n",
|
||||||
|
session_get_id(sess), session_get0_readable_addr(sess),
|
||||||
|
stat->c2s_rx_pkts, stat->c2s_rx_bytes,
|
||||||
|
stat->s2c_rx_pkts, stat->s2c_rx_bytes,
|
||||||
|
stat->c2s_rx_tcp_seg, stat->c2s_rx_tcp_bytes,
|
||||||
|
stat->s2c_rx_tcp_seg, stat->s2c_rx_tcp_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_sess_udp_msg(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_ctx)
|
static void on_sess_udp_msg(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_ctx)
|
||||||
@@ -97,6 +129,17 @@ static void on_sess_udp_msg(struct session *sess, int topic_id, const void *msg,
|
|||||||
char buff[4096];
|
char buff[4096];
|
||||||
struct packet *pkt = (struct packet *)msg;
|
struct packet *pkt = (struct packet *)msg;
|
||||||
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
||||||
|
struct sess_exdta *stat = (struct sess_exdta *)session_exdata_get(sess, ctx->sess_exdata_idx);
|
||||||
|
if (session_get_current_flow_direction(sess) == FLOW_DIRECTION_C2S)
|
||||||
|
{
|
||||||
|
stat->c2s_rx_pkts++;
|
||||||
|
stat->c2s_rx_bytes += packet_get_raw_len(pkt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat->s2c_rx_pkts++;
|
||||||
|
stat->s2c_rx_bytes += packet_get_raw_len(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
memset(buff, 0, sizeof(buff));
|
||||||
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
||||||
@@ -121,6 +164,17 @@ static void on_sess_tcp_msg(struct session *sess, int topic_id, const void *msg,
|
|||||||
char buff[4096];
|
char buff[4096];
|
||||||
struct packet *pkt = (struct packet *)msg;
|
struct packet *pkt = (struct packet *)msg;
|
||||||
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
||||||
|
struct sess_exdta *stat = (struct sess_exdta *)session_exdata_get(sess, ctx->sess_exdata_idx);
|
||||||
|
if (session_get_current_flow_direction(sess) == FLOW_DIRECTION_C2S)
|
||||||
|
{
|
||||||
|
stat->c2s_rx_pkts++;
|
||||||
|
stat->c2s_rx_bytes += packet_get_raw_len(pkt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat->s2c_rx_pkts++;
|
||||||
|
stat->s2c_rx_bytes += packet_get_raw_len(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
memset(buff, 0, sizeof(buff));
|
||||||
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
||||||
@@ -147,15 +201,31 @@ static void on_sess_tcp_stream_msg(struct session *sess, int topic_id, const voi
|
|||||||
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
struct plugin_ctx *ctx = (struct plugin_ctx *)plugin_ctx;
|
||||||
const char *data = tcp_segment_get_data(seg);
|
const char *data = tcp_segment_get_data(seg);
|
||||||
uint16_t len = tcp_segment_get_len(seg);
|
uint16_t len = tcp_segment_get_len(seg);
|
||||||
|
struct sess_exdta *stat = (struct sess_exdta *)session_exdata_get(sess, ctx->sess_exdata_idx);
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
memset(buff, 0, sizeof(buff));
|
||||||
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
session_to_str(sess, 1, buff, sizeof(buff) - 1);
|
||||||
log_print(ctx->fd, "debug plugin", "on TCP stream msg: %s", buff);
|
log_print(ctx->fd, "debug plugin", "on TCP stream msg: %s", buff);
|
||||||
|
|
||||||
log_print(ctx->fd, "debug plugin", "rx TCP segment: len: %d, data: %p\n", len, data);
|
|
||||||
|
|
||||||
pthread_spin_lock(&ctx->lock);
|
pthread_spin_lock(&ctx->lock);
|
||||||
hexdump_to_fd(ctx->fd, data, len);
|
if (session_get_current_flow_direction(sess) == FLOW_DIRECTION_C2S)
|
||||||
|
{
|
||||||
|
log_print(ctx->fd, "debug plugin", "rx C2S TCP segment: len: %d, data: %p\n", len, data);
|
||||||
|
hexdump_to_fd(ctx->fd, stat->c2s_rx_tcp_bytes, data, len);
|
||||||
|
hexdump_to_fd(ctx->c2s_tcp_seg_hexdump_fd, stat->c2s_rx_tcp_bytes, data, len);
|
||||||
|
|
||||||
|
stat->c2s_rx_tcp_seg++;
|
||||||
|
stat->c2s_rx_tcp_bytes += len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_print(ctx->fd, "debug plugin", "rx S2C TCP segment: len: %d, data: %p\n", len, data);
|
||||||
|
hexdump_to_fd(ctx->fd, stat->s2c_rx_tcp_bytes, data, len);
|
||||||
|
hexdump_to_fd(ctx->s2c_tcp_seg_hexdump_fd, stat->s2c_rx_tcp_bytes, data, len);
|
||||||
|
|
||||||
|
stat->s2c_rx_tcp_seg++;
|
||||||
|
stat->s2c_rx_tcp_bytes += len;
|
||||||
|
}
|
||||||
pthread_spin_unlock(&ctx->lock);
|
pthread_spin_unlock(&ctx->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,14 +243,19 @@ extern "C"
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->fd = open("./log/debug_plugin.log", O_WRONLY | O_APPEND | O_CREAT, 0644);
|
ctx->fd = open("./log/debug_plugin_log", O_WRONLY | O_APPEND | O_CREAT, 0644);
|
||||||
if (ctx->fd == -1)
|
ctx->c2s_tcp_seg_hexdump_fd = open("./log/debug_plugin_log_c2s_tcp_segment", O_WRONLY | O_APPEND | O_CREAT, 0644);
|
||||||
|
ctx->s2c_tcp_seg_hexdump_fd = open("./log/debug_plugin_log_s2c_tcp_segment", O_WRONLY | O_APPEND | O_CREAT, 0644);
|
||||||
|
if (ctx->fd == -1 || ctx->c2s_tcp_seg_hexdump_fd == -1 || ctx->s2c_tcp_seg_hexdump_fd == -1)
|
||||||
{
|
{
|
||||||
ctx->fd = STDOUT_FILENO;
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_spin_init(&ctx->lock, PTHREAD_PROCESS_PRIVATE);
|
pthread_spin_init(&ctx->lock, PTHREAD_PROCESS_PRIVATE);
|
||||||
|
|
||||||
ctx->st = st;
|
ctx->st = st;
|
||||||
|
ctx->sess_exdata_idx = stellar_exdata_new_index(st, "DEBUG_PLUGIN_SESS_EXDATA", stellar_exdata_free_default, NULL);
|
||||||
ctx->sess_plug_id = stellar_session_plugin_register(st, on_sess_new, on_sess_free, ctx);
|
ctx->sess_plug_id = stellar_session_plugin_register(st, on_sess_new, on_sess_free, ctx);
|
||||||
ctx->udp_topic_id = stellar_mq_get_topic_id(st, TOPIC_UDP);
|
ctx->udp_topic_id = stellar_mq_get_topic_id(st, TOPIC_UDP);
|
||||||
ctx->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP);
|
ctx->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP);
|
||||||
@@ -205,6 +280,14 @@ extern "C"
|
|||||||
{
|
{
|
||||||
close(ctx->fd);
|
close(ctx->fd);
|
||||||
}
|
}
|
||||||
|
if (ctx->c2s_tcp_seg_hexdump_fd > 0)
|
||||||
|
{
|
||||||
|
close(ctx->c2s_tcp_seg_hexdump_fd);
|
||||||
|
}
|
||||||
|
if (ctx->s2c_tcp_seg_hexdump_fd > 0)
|
||||||
|
{
|
||||||
|
close(ctx->s2c_tcp_seg_hexdump_fd);
|
||||||
|
}
|
||||||
pthread_spin_destroy(&ctx->lock);
|
pthread_spin_destroy(&ctx->lock);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user