diff options
| author | luwenpeng <[email protected]> | 2024-08-28 18:00:37 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2024-08-28 18:00:37 +0800 |
| commit | 18827c6de9f6541382b25c00e73504c7c2974a26 (patch) | |
| tree | 230c652eb3876146c49f1b7fbac2b23faaae1b5b /infra/session_manager/session_utils.c | |
| parent | 500d697b5c8d1afc35f1499054ac307ecc4f8079 (diff) | |
refactor(infra/session_manager): from *.cpp to *.c
Diffstat (limited to 'infra/session_manager/session_utils.c')
| -rw-r--r-- | infra/session_manager/session_utils.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/infra/session_manager/session_utils.c b/infra/session_manager/session_utils.c new file mode 100644 index 0000000..528f1b2 --- /dev/null +++ b/infra/session_manager/session_utils.c @@ -0,0 +1,463 @@ +#include "session_private.h" +#include "session_manager.h" + +void session_init(struct session *sess) +{ + memset(sess, 0, sizeof(struct session)); +} + +void session_set_id(struct session *sess, uint64_t id) +{ + sess->id = id; +} + +uint64_t session_get_id(const struct session *sess) +{ + return sess->id; +} + +void session_set_tuple6(struct session *sess, const struct tuple6 *tuple) +{ + memcpy(&sess->tuple, tuple, sizeof(struct tuple6)); +} + +const struct tuple6 *session_get_tuple6(const struct session *sess) +{ + return &sess->tuple; +} + +const char *session_get0_readable_addr(const struct session *sess) +{ + return sess->tuple_str; +} + +void session_set_direction(struct session *sess, enum session_direction dir) +{ + sess->sess_dir = dir; +} + +enum session_direction session_get_direction(const struct session *sess) +{ + return sess->sess_dir; +} + +void session_set_current_flow_direction(struct session *sess, enum flow_direction dir) +{ + sess->flow_dir = dir; +} + +enum flow_direction session_get_current_flow_direction(const struct session *sess) +{ + return sess->flow_dir; +} + +void session_set_current_state(struct session *sess, enum session_state state) +{ + sess->state = state; +} + +enum session_state session_get_current_state(const struct session *sess) +{ + return sess->state; +} + +void session_set_type(struct session *sess, enum session_type type) +{ + sess->type = type; +} + +enum session_type session_get_type(const struct session *sess) +{ + return sess->type; +} + +void session_set_duplicate_traffic(struct session *sess) +{ + sess->dup = 1; +} + +int session_has_duplicate_traffic(const struct session *sess) +{ + return sess->dup; +} + +void session_set_closing_reason(struct session *sess, enum closing_reason reason) +{ + sess->reason = reason; +} + +enum closing_reason session_get_closing_reason(const struct session *sess) +{ + return sess->reason; +} + +void session_inc_stat(struct session *sess, enum flow_direction dir, enum session_stat stat, uint64_t val) +{ + sess->stats[dir][stat] += val; +} + +uint64_t session_get_stat(const struct session *sess, enum flow_direction dir, enum session_stat stat) +{ + return sess->stats[dir][stat]; +} + +void session_set_timestamp(struct session *sess, enum session_timestamp type, uint64_t value) +{ + sess->timestamps[type] = value; +} + +uint64_t session_get_timestamp(const struct session *sess, enum session_timestamp type) +{ + return sess->timestamps[type]; +} + +void session_clear_sids(struct session *sess, enum flow_direction dir) +{ + memset(&sess->sids[dir], 0, sizeof(struct sids)); +} + +void session_set_sids(struct session *sess, enum flow_direction dir, const struct sids *sids) +{ + sess->sids[dir] = *sids; +} + +const struct sids *session_get_sids(const struct session *sess, enum flow_direction dir) +{ + return &sess->sids[dir]; +} + +void session_clear_route_ctx(struct session *sess, enum flow_direction dir) +{ + memset(&sess->route_ctx[dir], 0, sizeof(struct route_ctx)); +} + +void session_set_route_ctx(struct session *sess, enum flow_direction dir, const struct route_ctx *ctx) +{ + sess->route_ctx[dir] = *ctx; +} + +const struct route_ctx *session_get_route_ctx(const struct session *sess, enum flow_direction dir) +{ + return &sess->route_ctx[dir]; +} + +void session_set_first_packet(struct session *sess, enum flow_direction dir, const struct packet *pkt) +{ + sess->first_pkt[dir] = pkt; +} + +const struct packet *session_get_first_packet(const struct session *sess, enum flow_direction dir) +{ + return sess->first_pkt[dir]; +} + +void session_set_current_packet(struct session *sess, const struct packet *pkt) +{ + sess->curr_pkt = pkt; +} + +const struct packet *session_get0_current_packet(const struct session *sess) +{ + return sess->curr_pkt; +} + +int session_is_symmetric(const struct session *sess, unsigned char *flag) +{ + int is_symmetric = 0; + if (sess->first_pkt[FLOW_DIRECTION_C2S] && sess->first_pkt[FLOW_DIRECTION_S2C]) + { + if (flag) + { + *flag = (SESSION_SEEN_C2S_FLOW | SESSION_SEEN_S2C_FLOW); + } + is_symmetric = 1; + } + else if (sess->first_pkt[FLOW_DIRECTION_C2S]) + { + if (flag) + { + *flag = SESSION_SEEN_C2S_FLOW; + } + } + else if (sess->first_pkt[FLOW_DIRECTION_S2C]) + { + if (flag) + { + *flag = SESSION_SEEN_S2C_FLOW; + } + } + return is_symmetric; +} + +void session_set_user_data(struct session *sess, void *user_data) +{ + sess->user_data = user_data; +} + +void *session_get_user_data(const struct session *sess) +{ + return sess->user_data; +} + +struct tcp_segment *session_get_tcp_segment(struct session *sess) +{ + enum flow_direction dir = session_get_current_flow_direction(sess); + struct tcp_half *half = &sess->tcp_halfs[dir]; + + if (half->in_order.data != NULL && half->in_order.len > 0 && half->in_order_ref == 0) + { + sess->mgr_stat->tcp_segs_consumed++; + half->in_order_ref++; + return &half->in_order; + } + else + { + struct tcp_segment *seg = tcp_reassembly_pop(half->assembler); + if (seg) + { + session_inc_stat(sess, dir, STAT_TCP_SEGMENTS_REORDERED, 1); + session_inc_stat(sess, dir, STAT_TCP_PAYLOADS_REORDERED, seg->len); + + // TODO + sess->mgr_stat->tcp_segs_consumed++; + sess->mgr_stat->tcp_segs_reordered++; + } + return seg; + } +} + +void session_free_tcp_segment(struct session *sess, struct tcp_segment *seg) +{ + if (seg == NULL) + { + return; + } + + enum flow_direction dir = session_get_current_flow_direction(sess); + struct tcp_half *half = &sess->tcp_halfs[dir]; + + if (seg == &half->in_order) + { + half->in_order.data = NULL; + half->in_order.len = 0; + return; + } + else + { + session_inc_stat(sess, dir, STAT_TCP_SEGMENTS_RELEASED, 1); + session_inc_stat(sess, dir, STAT_TCP_PAYLOADS_RELEASED, seg->len); + sess->mgr_stat->tcp_segs_freed++; + + tcp_segment_free(seg); + } +} + +const char *closing_reason_to_str(enum closing_reason reason) +{ + switch (reason) + { + case CLOSING_BY_TIMEOUT: + return "closing by timeout"; + case CLOSING_BY_LRU_EVICTED: + return "closing by lru evicted"; + case CLOSING_BY_PORT_REUSE_EVICTED: + return "closing by port reuse 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 *flow_direction_to_str(enum flow_direction dir) +{ + switch (dir) + { + case FLOW_DIRECTION_C2S: + return "C2S"; + case FLOW_DIRECTION_S2C: + return "S2C"; + default: + return "unknown"; + } +} + +static void tcp_flags_to_str(uint8_t flags, char *buffer, size_t len) +{ + int used = 0; + + if (flags & TH_SYN) + { + used += snprintf(buffer + used, len - used, "SYN "); + } + if (flags & TH_ACK) + { + used += snprintf(buffer + used, len - used, "ACK "); + } + if (flags & TH_FIN) + { + used += snprintf(buffer + used, len - used, "FIN "); + } + if (flags & TH_RST) + { + used += snprintf(buffer + used, len - used, "RST "); + } +} + +int session_to_str(const struct session *sess, int bref, char *buff, int size) +{ + memset(buff, 0, size); + char flags[64] = {0}; + int used = 0; + + if (bref) + { + used += snprintf(buff + used, size - used, "session id: %lu, addr: %s, type: %s, state: %s, dir: %s, c2s_rx_pkts: %lu, s2c_rx_pkts: %lu", + session_get_id(sess), + session_get0_readable_addr(sess), + session_type_to_str(session_get_type(sess)), + session_state_to_str(session_get_current_state(sess)), + flow_direction_to_str(session_get_current_flow_direction(sess)), + session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_RAW_PACKETS_RECEIVED), + session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_RAW_PACKETS_RECEIVED)); + } + else + { + used += snprintf(buff + used, size - used, "{"); + used += snprintf(buff + used, size - used, "\"id\":%" PRIu64 ",", session_get_id(sess)); + used += snprintf(buff + used, size - used, "\"start_timestamp_ms\":%" PRIu64 ",", session_get_timestamp(sess, SESSION_TIMESTAMP_START)); + used += snprintf(buff + used, size - used, "\"last_timestamp_ms\":%" PRIu64 ",", session_get_timestamp(sess, SESSION_TIMESTAMP_LAST)); + used += snprintf(buff + used, size - used, "\"tuple\":\"%s\",", session_get0_readable_addr(sess)); + used += snprintf(buff + used, size - used, "\"type\":\"%s\",", session_type_to_str(session_get_type(sess))); + used += snprintf(buff + used, size - used, "\"state\":\"%s\",", session_state_to_str(session_get_current_state(sess))); + used += snprintf(buff + used, size - used, "\"closing_reason\":\"%s\",", closing_reason_to_str(session_get_closing_reason(sess))); + used += snprintf(buff + used, size - used, "\"duplicate_traffic\":%d,", session_has_duplicate_traffic(sess)); + used += snprintf(buff + used, size - used, "\"current_packet\":\"%p\",", session_get0_current_packet(sess)); + + const char *str[] = {"c2s", "s2c"}; + enum flow_direction dir[] = {FLOW_DIRECTION_C2S, FLOW_DIRECTION_S2C}; + for (int i = 0; i < 2; i++) + { + // raw packets + used += snprintf(buff + used, size - used, "\"%s_raw_packets_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_PACKETS_RECEIVED)); + used += snprintf(buff + used, size - used, "\"%s_raw_bytes_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_BYTES_RECEIVED)); + + used += snprintf(buff + used, size - used, "\"%s_raw_packets_transmitted\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_PACKETS_TRANSMITTED)); + used += snprintf(buff + used, size - used, "\"%s_raw_bytes_transmitted\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_BYTES_TRANSMITTED)); + + used += snprintf(buff + used, size - used, "\"%s_raw_packets_dropped\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_PACKETS_DROPPED)); + used += snprintf(buff + used, size - used, "\"%s_raw_bytes_dropped\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_RAW_BYTES_DROPPED)); + + // duplicate packets + used += snprintf(buff + used, size - used, "\"%s_duplicate_packets_bypass\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_DUPLICATE_PACKETS_BYPASS)); + used += snprintf(buff + used, size - used, "\"%s_duplicate_bytes_bypass\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_DUPLICATE_BYTES_BYPASS)); + + // injected packets + used += snprintf(buff + used, size - used, "\"%s_injected_packets_failed\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_INJECTED_PACKETS_FAILED)); + used += snprintf(buff + used, size - used, "\"%s_injected_packets_success\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_INJECTED_PACKETS_SUCCESS)); + used += snprintf(buff + used, size - used, "\"%s_injected_bytes_success\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_INJECTED_BYTES_SUCCESS)); + + // control packets + used += snprintf(buff + used, size - used, "\"%s_control_packets_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_PACKETS_RECEIVED)); + used += snprintf(buff + used, size - used, "\"%s_control_bytes_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_BYTES_RECEIVED)); + + used += snprintf(buff + used, size - used, "\"%s_control_packets_transmitted\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_PACKETS_TRANSMITTED)); + used += snprintf(buff + used, size - used, "\"%s_control_bytes_transmitted\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_BYTES_TRANSMITTED)); + + used += snprintf(buff + used, size - used, "\"%s_control_packets_dropped\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_PACKETS_DROPPED)); + used += snprintf(buff + used, size - used, "\"%s_control_bytes_dropped\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_CONTROL_BYTES_DROPPED)); + + if (session_get_type(sess) == SESSION_TYPE_TCP) + { + used += snprintf(buff + used, size - used, "\"%s_tcp_last_seq\":%u,", str[i], sess->tcp_halfs[dir[i]].seq); + used += snprintf(buff + used, size - used, "\"%s_tcp_last_ack\":%u,", str[i], sess->tcp_halfs[dir[i]].ack); + memset(flags, 0, sizeof(flags)); + tcp_flags_to_str(sess->tcp_halfs[dir[i]].flags, flags, sizeof(flags)); + used += snprintf(buff + used, size - used, "\"%s_tcp_flags\":\"%s\",", str[i], flags); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_RECEIVED)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_received\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_RECEIVED)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_expired\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_EXPIRED)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_expired\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_EXPIRED)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_retransmit\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_RETRANSMIT)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_retransmit\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_RETRANSMIT)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_overlap\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_OVERLAP)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_overlap\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_OVERLAP)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_nospace\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_NOSPACE)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_nospace\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_NOSPACE)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_inorder\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_INORDER)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_inorder\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_INORDER)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_reordered\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_REORDERED)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_reordered\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_REORDERED)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_buffered\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_BUFFERED)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_buffered\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_BUFFERED)); + + used += snprintf(buff + used, size - used, "\"%s_tcp_segments_released\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_SEGMENTS_RELEASED)); + used += snprintf(buff + used, size - used, "\"%s_tcp_payloads_released\":%" PRIu64 ",", str[i], session_get_stat(sess, dir[i], STAT_TCP_PAYLOADS_RELEASED)); + } + + used += snprintf(buff + used, size - used, "\"%s_first_packet\":\"%p\"", str[i], session_get_first_packet(sess, dir[i])); + if (i == 0) + { + used += snprintf(buff + used, size - used, ","); + } + } + used += snprintf(buff + used, size - used, "}"); + } + + return used; +} + +void session_print(const struct session *sess) +{ + char buff[4096]; + session_to_str(sess, 0, buff, sizeof(buff)); + printf("%s\n", buff); +} |
