Add TCP reassembly metrics on session

This commit is contained in:
luwenpeng
2024-04-03 18:59:46 +08:00
parent e8e60cee6d
commit 151b6f8f1d
3 changed files with 279 additions and 269 deletions

View File

@@ -181,19 +181,28 @@ void *session_get_user_data(const struct session *sess)
struct tcp_segment *session_get_tcp_segment(struct session *sess)
{
struct tcp_pcb *pcb = &sess->tcp_pcb;
if (pcb->order_seg.data != NULL && pcb->order_seg.len > 0)
{
return &pcb->order_seg;
}
struct tcp_half *half = NULL;
if (session_get_cur_dir(sess) == SESSION_DIR_C2S)
{
return tcp_reassembly_pop(pcb->c2s_assembler);
half = &sess->tcp_pcb.c2s;
}
else
{
return tcp_reassembly_pop(pcb->s2c_assembler);
half = &sess->tcp_pcb.s2c;
}
if (half->order.data != NULL && half->order.len > 0)
{
return &half->order;
}
else
{
struct tcp_segment *seg = tcp_reassembly_pop(half->assembler);
if (seg)
{
half->nr_seg_reorded++;
}
return seg;
}
}
@@ -204,117 +213,29 @@ void session_free_tcp_segment(struct session *sess, struct tcp_segment *seg)
return;
}
if (seg == &sess->tcp_pcb.order_seg)
struct tcp_half *half = NULL;
if (session_get_cur_dir(sess) == SESSION_DIR_C2S)
{
sess->tcp_pcb.order_seg.data = NULL;
sess->tcp_pcb.order_seg.len = 0;
half = &sess->tcp_pcb.c2s;
}
else
{
half = &sess->tcp_pcb.s2c;
}
if (seg == &half->order)
{
half->order.data = NULL;
half->order.len = 0;
return;
}
else
{
half->nr_seg_released++;
tcp_segment_free(seg);
}
}
/******************************************************************************
* to string
******************************************************************************/
const char *closing_reason_to_str(enum closing_reason reason)
{
switch (reason)
{
case CLOSING_BY_TIMEOUT:
return "closing by timeout";
case CLOSING_BY_EVICTED:
return "closing by evicted";
case CLOSING_BY_CLIENT_FIN:
return "closing by client FIN";
case CLOSING_BY_CLIENT_RST:
return "closing by client RST";
case CLOSING_BY_SERVER_FIN:
return "closing by server FIN";
case CLOSING_BY_SERVER_RST:
return "closing by server RST";
default:
return "unknown";
}
}
const char *session_state_to_str(enum session_state state)
{
switch (state)
{
case SESSION_STATE_INIT:
return "init";
case SESSION_STATE_OPENING:
return "opening";
case SESSION_STATE_ACTIVE:
return "active";
case SESSION_STATE_CLOSING:
return "closing";
case SESSION_STATE_DISCARD:
return "discard";
case SESSION_STATE_CLOSED:
return "closed";
default:
return "unknown";
}
}
const char *session_type_to_str(enum session_type type)
{
switch (type)
{
case SESSION_TYPE_TCP:
return "TCP";
case SESSION_TYPE_UDP:
return "UDP";
default:
return "unknown";
}
}
const char *session_dir_to_str(enum session_dir dir)
{
switch (dir)
{
case SESSION_DIR_C2S:
return "C2S";
case SESSION_DIR_S2C:
return "S2C";
default:
return "unknown";
}
}
void session_dump(struct session *sess)
{
char buffer[1024] = {0};
tuple6_to_str(session_get_tuple(sess), buffer, sizeof(buffer));
printf("session id : %" PRIu64 "\n", session_get_id(sess));
printf("session tuple : %s\n", buffer);
printf("session tuple dir : %s\n", session_dir_to_str(session_get_tuple_dir(sess)));
printf("session state : %s\n", session_state_to_str(session_get_state(sess)));
printf("session type : %s\n", session_type_to_str(session_get_type(sess)));
printf("session dup traffic : %d\n", session_has_dup_traffic(sess));
printf("session closing reason : %s\n", closing_reason_to_str(session_get_closing_reason(sess)));
printf("session C2S packets : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_C2S_PACKETS));
printf("session C2S bytes : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_C2S_BYTES));
printf("session S2C packets : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_S2C_PACKETS));
printf("session S2C bytes : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_S2C_BYTES));
printf("session new time : %" PRIu64 "\n", session_get_timestamp(sess, SESSION_TIMESTAMP_NEW));
printf("session last time : %" PRIu64 "\n", session_get_timestamp(sess, SESSION_TIMESTAMP_LAST));
printf("session current packet ptr : %p\n", (void *)session_get_packet(sess, SESSION_PACKET_CURRENT));
printf("session current packet dir : %s\n", session_dir_to_str(session_get_cur_dir(sess)));
printf("session ex data: \n");
for (uint8_t i = 0; i < g_ex_manager.count; i++)
{
printf(" ex_idx: %d, ex_key: %s, ex_data: %p\n", i, g_ex_manager.schemas[i].key, sess->ex_data[i]);
}
}
/******************************************************************************
* session ex data
******************************************************************************/
@@ -416,3 +337,141 @@ void session_free_all_ex_data(struct session *sess)
}
}
}
/******************************************************************************
* to string
******************************************************************************/
const char *closing_reason_to_str(enum closing_reason reason)
{
switch (reason)
{
case CLOSING_BY_TIMEOUT:
return "closing by timeout";
case CLOSING_BY_EVICTED:
return "closing by evicted";
case CLOSING_BY_CLIENT_FIN:
return "closing by client FIN";
case CLOSING_BY_CLIENT_RST:
return "closing by client RST";
case CLOSING_BY_SERVER_FIN:
return "closing by server FIN";
case CLOSING_BY_SERVER_RST:
return "closing by server RST";
default:
return "unknown";
}
}
const char *session_state_to_str(enum session_state state)
{
switch (state)
{
case SESSION_STATE_INIT:
return "init";
case SESSION_STATE_OPENING:
return "opening";
case SESSION_STATE_ACTIVE:
return "active";
case SESSION_STATE_CLOSING:
return "closing";
case SESSION_STATE_DISCARD:
return "discard";
case SESSION_STATE_CLOSED:
return "closed";
default:
return "unknown";
}
}
const char *session_type_to_str(enum session_type type)
{
switch (type)
{
case SESSION_TYPE_TCP:
return "TCP";
case SESSION_TYPE_UDP:
return "UDP";
default:
return "unknown";
}
}
const char *session_dir_to_str(enum session_dir dir)
{
switch (dir)
{
case SESSION_DIR_C2S:
return "C2S";
case SESSION_DIR_S2C:
return "S2C";
default:
return "unknown";
}
}
void tcp_half_dump(const struct tcp_half *half)
{
char buffer[32] = {0};
int used = 0;
if (half->flags & TH_SYN)
{
used += snprintf(buffer + used, sizeof(buffer) - used, "SYN ");
}
if (half->flags & TH_ACK)
{
used += snprintf(buffer + used, sizeof(buffer) - used, "ACK ");
}
if (half->flags & TH_FIN)
{
used += snprintf(buffer + used, sizeof(buffer) - used, "FIN ");
}
if (half->flags & TH_RST)
{
used += snprintf(buffer + used, sizeof(buffer) - used, "RST ");
}
printf(" flags : %s\n", buffer);
printf(" nr_seg_received : %lu\n", half->nr_seg_received);
printf(" nr_seg_expired : %lu\n", half->nr_seg_expired);
printf(" nr_seg_overlap : %lu\n", half->nr_seg_overlap);
printf(" nr_seg_no_space : %lu\n", half->nr_seg_no_space);
printf(" nr_seg_inorder : %lu\n", half->nr_seg_inorder);
printf(" nr_seg_reorded : %lu\n", half->nr_seg_reorded);
printf(" nr_seg_buffered : %lu\n", half->nr_seg_buffered);
printf(" nr_seg_released : %lu\n", half->nr_seg_released);
}
void session_dump(struct session *sess)
{
char buffer[1024] = {0};
tuple6_to_str(session_get_tuple(sess), buffer, sizeof(buffer));
printf("session id : %" PRIu64 "\n", session_get_id(sess));
printf("session tuple : %s\n", buffer);
printf("session tuple dir : %s\n", session_dir_to_str(session_get_tuple_dir(sess)));
printf("session state : %s\n", session_state_to_str(session_get_state(sess)));
printf("session type : %s\n", session_type_to_str(session_get_type(sess)));
printf("session dup traffic : %d\n", session_has_dup_traffic(sess));
printf("session closing reason : %s\n", closing_reason_to_str(session_get_closing_reason(sess)));
printf("session C2S packets : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_C2S_PACKETS));
printf("session C2S bytes : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_C2S_BYTES));
printf("session S2C packets : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_S2C_PACKETS));
printf("session S2C bytes : %" PRIu64 "\n", session_get_metric(sess, SESSION_METRIC_S2C_BYTES));
printf("session new time : %" PRIu64 "\n", session_get_timestamp(sess, SESSION_TIMESTAMP_NEW));
printf("session last time : %" PRIu64 "\n", session_get_timestamp(sess, SESSION_TIMESTAMP_LAST));
printf("session current packet ptr : %p\n", (void *)session_get_packet(sess, SESSION_PACKET_CURRENT));
printf("session current packet dir : %s\n", session_dir_to_str(session_get_cur_dir(sess)));
printf("session ex data:\n");
for (uint8_t i = 0; i < g_ex_manager.count; i++)
{
printf(" ex_idx: %d, ex_key: %s, ex_data: %p\n", i, g_ex_manager.schemas[i].key, sess->ex_data[i]);
}
if (session_get_type(sess) == SESSION_TYPE_TCP)
{
printf("session TCP C2S:\n");
tcp_half_dump(&sess->tcp_pcb.c2s);
printf("session TCP S2C:\n");
tcp_half_dump(&sess->tcp_pcb.s2c);
}
}