bugfix: tcp segment free

This commit is contained in:
luwenpeng
2024-11-27 11:37:43 +08:00
parent 1e072950d7
commit 035b393a94
3 changed files with 27 additions and 23 deletions

View File

@@ -157,8 +157,11 @@ void session_manager_on_thread_exit(struct module_manager *mod_mgr, int thread_i
struct module *session_monitor_on_init(struct module_manager *mod_mgr);
void session_monitor_on_exit(struct module_manager *mod_mgr, struct module *mod);
#define TCP_SEGMENT_FROM_RAW_PACKET 1
#define TCP_SEGMENT_FROM_REASSEMBLY 0
struct tcp_segment
{
uint8_t from; // TCP_SEGMENT_FROM_RAW_PACKET or TCP_SEGMENT_FROM_REASSEMBLY
uint32_t len;
const void *data;
struct tcp_segment *next;

View File

@@ -262,7 +262,6 @@ void session_manager_on_packet_output(struct packet *pkt, struct module *mod)
}
session_set_current_packet(sess, NULL);
session_set_flow_type(sess, FLOW_TYPE_NONE);
}
if (packet_get_origin(pkt) == NULL)

View File

@@ -1,3 +1,5 @@
#include <assert.h>
#include "stellar/exdata.h"
#include "session_internal.h"
#include "session_manager_stat.h"
@@ -202,18 +204,23 @@ void *session_get_user_data(const struct session *sess)
struct tcp_segment *session_get_tcp_segment(struct session *sess)
{
struct tcp_segment *seg = NULL;
enum flow_type type = session_get_flow_type(sess);
assert(type == FLOW_TYPE_C2S || type == FLOW_TYPE_S2C);
struct tcp_half *half = &sess->tcp_halfs[type];
if (half->inorder_seg.data != NULL && half->inorder_seg.len > 0 && !half->inorder_seg_consumed)
{
sess->sess_mgr_stat->tcp_segs_consumed++;
half->inorder_seg_consumed = 1;
return &half->inorder_seg;
sess->sess_mgr_stat->tcp_segs_consumed++;
seg = tcp_segment_new(0, half->inorder_seg.data, half->inorder_seg.len);
seg->from = TCP_SEGMENT_FROM_RAW_PACKET;
}
else
{
struct tcp_segment *seg = tcp_reassembly_pop(half->tcp_reass);
seg = tcp_reassembly_pop(half->tcp_reass);
if (seg)
{
session_inc_stat(sess, type, STAT_TCP_SEGMENTS_REORDERED, 1);
@@ -222,34 +229,29 @@ struct tcp_segment *session_get_tcp_segment(struct session *sess)
// TODO
sess->sess_mgr_stat->tcp_segs_consumed++;
sess->sess_mgr_stat->tcp_segs_reordered++;
seg->from = TCP_SEGMENT_FROM_REASSEMBLY;
}
return seg;
}
return seg;
}
void session_free_tcp_segment(struct session *sess, struct tcp_segment *seg)
{
if (seg == NULL)
if (seg)
{
return;
}
enum flow_type type = session_get_flow_type(sess);
struct tcp_half *half = &sess->tcp_halfs[type];
if (seg->from == TCP_SEGMENT_FROM_REASSEMBLY)
{
enum flow_type type = session_get_flow_type(sess);
assert(type == FLOW_TYPE_C2S || type == FLOW_TYPE_S2C);
// in order segment
if (seg == &half->inorder_seg)
{
half->inorder_seg.data = NULL;
half->inorder_seg.len = 0;
return;
}
// tcp reassembly segment
else
{
session_inc_stat(sess, type, STAT_TCP_SEGMENTS_RELEASED, 1);
session_inc_stat(sess, type, STAT_TCP_PAYLOADS_RELEASED, seg->len);
sess->sess_mgr_stat->tcp_segs_freed++;
session_inc_stat(sess, type, STAT_TCP_SEGMENTS_RELEASED, 1);
session_inc_stat(sess, type, STAT_TCP_PAYLOADS_RELEASED, seg->len);
sess->sess_mgr_stat->tcp_segs_freed++;
}
tcp_segment_free(seg);
}