2024-03-14 10:56:09 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
2024-09-19 16:23:12 +08:00
|
|
|
#include "log_internal.h"
|
2024-09-19 16:18:54 +08:00
|
|
|
#include "session_internal.h"
|
2024-03-14 10:56:09 +08:00
|
|
|
#include "session_transition.h"
|
|
|
|
|
|
2024-08-23 18:44:17 +08:00
|
|
|
#define SESSION_TRANSITION_LOG_INFO(format, ...) STELLAR_LOG_INFO(__thread_local_logger, "session transition", format, ##__VA_ARGS__)
|
2024-06-25 10:32:51 +08:00
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
#define MAX_TRANSITION_PER_STATE 8
|
2024-03-14 10:56:09 +08:00
|
|
|
|
|
|
|
|
struct session_transition
|
|
|
|
|
{
|
|
|
|
|
int inputs_mask;
|
|
|
|
|
enum session_state next_state;
|
|
|
|
|
} fsm[MAX_STATE][MAX_TRANSITION_PER_STATE];
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* session transition
|
|
|
|
|
*
|
|
|
|
|
* SESSION_STATE_INIT -> SESSION_STATE_INIT ( NONE )
|
|
|
|
|
* SESSION_STATE_INIT -> SESSION_STATE_OPENING ( TCP_SYN | TCP_SYN_ACK | UDP_DATA )
|
|
|
|
|
*
|
|
|
|
|
* SESSION_STATE_OPENING -> SESSION_STATE_OPENING ( NONE )
|
|
|
|
|
* SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA )
|
|
|
|
|
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
2024-03-15 15:36:26 +08:00
|
|
|
* SESSION_STATE_OPENING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
2024-05-17 17:38:08 +08:00
|
|
|
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT )
|
2024-03-14 10:56:09 +08:00
|
|
|
*
|
|
|
|
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE )
|
|
|
|
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
2024-03-15 15:36:26 +08:00
|
|
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
2024-05-17 17:38:08 +08:00
|
|
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT)
|
2024-03-14 10:56:09 +08:00
|
|
|
*
|
|
|
|
|
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE )
|
2024-03-15 15:36:26 +08:00
|
|
|
* SESSION_STATE_CLOSING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
2024-05-17 17:38:08 +08:00
|
|
|
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT )
|
2024-03-15 15:36:26 +08:00
|
|
|
*
|
|
|
|
|
* SESSION_STATE_DISCARD -> SESSION_STATE_DISCARD ( NONE )
|
2024-05-17 17:38:08 +08:00
|
|
|
* SESSION_STATE_DISCARD -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT )
|
2024-03-14 10:56:09 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void session_inputs_to_str(int inputs, char *buff, int len)
|
|
|
|
|
{
|
|
|
|
|
int nused = 0;
|
|
|
|
|
if (inputs & TCP_SYN)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TCP_SYN");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & TCP_SYN_ACK)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TCP_SYN_ACK");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & TCP_FIN)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TCP_FIN");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & TCP_RST)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TCP_RST");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & TCP_DATA)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TCP_DATA");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & UDP_DATA)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "UDP_DATA");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & TIMEOUT)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "TIMEOUT");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
if (inputs & LRU_EVICT)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "LRU_EVICT");
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
2024-05-16 19:13:36 +08:00
|
|
|
if (inputs & PORT_REUSE_EVICT)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "PORT_REUSE_EVICT");
|
2024-05-16 19:13:36 +08:00
|
|
|
}
|
2024-03-15 15:36:26 +08:00
|
|
|
if (inputs & USER_CLOSE)
|
|
|
|
|
{
|
2024-10-24 16:22:18 +08:00
|
|
|
nused += snprintf(buff + nused, len - nused, "USER_CLOSE");
|
2024-03-15 15:36:26 +08:00
|
|
|
}
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void session_transition_init()
|
|
|
|
|
{
|
|
|
|
|
fsm[SESSION_STATE_INIT][0].inputs_mask = TCP_SYN | TCP_SYN_ACK | UDP_DATA;
|
|
|
|
|
fsm[SESSION_STATE_INIT][0].next_state = SESSION_STATE_OPENING;
|
|
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_INIT][1].inputs_mask = NONE;
|
|
|
|
|
fsm[SESSION_STATE_INIT][1].next_state = SESSION_STATE_INIT;
|
|
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_OPENING][0].inputs_mask = TCP_DATA | UDP_DATA;
|
|
|
|
|
fsm[SESSION_STATE_OPENING][0].next_state = SESSION_STATE_ACTIVE;
|
|
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_OPENING][1].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT;
|
|
|
|
|
fsm[SESSION_STATE_OPENING][1].next_state = SESSION_STATE_CLOSING;
|
|
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_OPENING][2].inputs_mask = USER_CLOSE;
|
|
|
|
|
fsm[SESSION_STATE_OPENING][2].next_state = SESSION_STATE_DISCARD;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-05-16 19:13:36 +08:00
|
|
|
fsm[SESSION_STATE_OPENING][3].inputs_mask = LRU_EVICT | PORT_REUSE_EVICT;
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_OPENING][3].next_state = SESSION_STATE_CLOSED;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_OPENING][4].inputs_mask = NONE;
|
|
|
|
|
fsm[SESSION_STATE_OPENING][4].next_state = SESSION_STATE_OPENING;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_ACTIVE][0].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT;
|
|
|
|
|
fsm[SESSION_STATE_ACTIVE][0].next_state = SESSION_STATE_CLOSING;
|
|
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_ACTIVE][1].inputs_mask = USER_CLOSE;
|
|
|
|
|
fsm[SESSION_STATE_ACTIVE][1].next_state = SESSION_STATE_DISCARD;
|
|
|
|
|
|
2024-05-16 19:13:36 +08:00
|
|
|
fsm[SESSION_STATE_ACTIVE][2].inputs_mask = LRU_EVICT | PORT_REUSE_EVICT;
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_ACTIVE][2].next_state = SESSION_STATE_CLOSED;
|
|
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_ACTIVE][3].inputs_mask = NONE;
|
|
|
|
|
fsm[SESSION_STATE_ACTIVE][3].next_state = SESSION_STATE_ACTIVE;
|
|
|
|
|
|
|
|
|
|
fsm[SESSION_STATE_CLOSING][0].inputs_mask = USER_CLOSE;
|
|
|
|
|
fsm[SESSION_STATE_CLOSING][0].next_state = SESSION_STATE_DISCARD;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-05-16 19:13:36 +08:00
|
|
|
fsm[SESSION_STATE_CLOSING][1].inputs_mask = LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT;
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_CLOSING][1].next_state = SESSION_STATE_CLOSED;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_CLOSING][2].inputs_mask = NONE;
|
|
|
|
|
fsm[SESSION_STATE_CLOSING][2].next_state = SESSION_STATE_CLOSING;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-05-16 19:13:36 +08:00
|
|
|
fsm[SESSION_STATE_DISCARD][0].inputs_mask = LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT;
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_DISCARD][0].next_state = SESSION_STATE_CLOSED;
|
2024-03-14 10:56:09 +08:00
|
|
|
|
2024-03-15 15:36:26 +08:00
|
|
|
fsm[SESSION_STATE_DISCARD][1].inputs_mask = NONE;
|
|
|
|
|
fsm[SESSION_STATE_DISCARD][1].next_state = SESSION_STATE_DISCARD;
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum session_state session_transition_run(enum session_state curr_state, int inputs)
|
|
|
|
|
{
|
|
|
|
|
struct session_transition *list = fsm[curr_state];
|
|
|
|
|
for (int i = 0; i < MAX_TRANSITION_PER_STATE; i++)
|
|
|
|
|
{
|
|
|
|
|
int mask = list[i].inputs_mask;
|
|
|
|
|
if (mask & inputs)
|
|
|
|
|
{
|
|
|
|
|
return list[i].next_state;
|
|
|
|
|
}
|
|
|
|
|
if (mask == NONE)
|
|
|
|
|
{
|
|
|
|
|
return list[i].next_state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(0);
|
|
|
|
|
return curr_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void session_transition_log(struct session *sess, enum session_state curr_state, enum session_state next_state, int inputs)
|
|
|
|
|
{
|
|
|
|
|
if (curr_state == next_state)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char reason[128] = {0};
|
|
|
|
|
session_inputs_to_str(inputs, reason, sizeof(reason));
|
2024-03-27 17:11:38 +08:00
|
|
|
SESSION_TRANSITION_LOG_INFO("%s session %lu %s (%s) %s -> %s",
|
2024-04-10 11:40:26 +08:00
|
|
|
session_type_to_str(session_get_type(sess)),
|
2024-11-01 15:37:26 +08:00
|
|
|
session_get_id(sess), session_get_readable_addr(sess), reason,
|
2024-03-27 17:11:38 +08:00
|
|
|
session_state_to_str(curr_state), session_state_to_str(next_state));
|
2024-03-14 10:56:09 +08:00
|
|
|
}
|