recv SYN after FIN or RST is considered to be TCP port reuse
This commit is contained in:
@@ -658,7 +658,8 @@ static struct session *session_manager_lookup_tcp_session(struct session_manager
|
|||||||
|
|
||||||
enum flow_direction dir = identify_direction_by_history(sess, key);
|
enum flow_direction dir = identify_direction_by_history(sess, key);
|
||||||
struct tcp_half *half = &sess->tcp_halfs[dir];
|
struct tcp_half *half = &sess->tcp_halfs[dir];
|
||||||
if (half->isn && half->isn != tcp_hdr_get_seq(hdr))
|
if ((half->isn && half->isn != tcp_hdr_get_seq(hdr)) || // recv SYN with different ISN
|
||||||
|
((half->history & TH_FIN) || (half->history & TH_RST))) // recv SYN after FIN or RST
|
||||||
{
|
{
|
||||||
// TCP port reuse, evict old session
|
// TCP port reuse, evict old session
|
||||||
session_manager_evicte_session(mgr, sess, now, PORT_REUSE_EVICT);
|
session_manager_evicte_session(mgr, sess, now, PORT_REUSE_EVICT);
|
||||||
|
|||||||
@@ -24,15 +24,16 @@ extern "C"
|
|||||||
struct tcp_half
|
struct tcp_half
|
||||||
{
|
{
|
||||||
struct tcp_reassembly *assembler;
|
struct tcp_reassembly *assembler;
|
||||||
struct tcp_segment in_order;
|
struct tcp_segment in_order; // current packet in order segment
|
||||||
uint32_t in_order_ref;
|
uint32_t in_order_ref; // reference count of current packet in order segment
|
||||||
|
|
||||||
uint32_t isn;
|
uint32_t seq; // current packet sequence number
|
||||||
uint32_t seq;
|
uint32_t ack; // current packet ack number
|
||||||
uint32_t ack;
|
uint16_t len; // current packet payload length
|
||||||
uint16_t len;
|
uint8_t flags; // current packet flags
|
||||||
uint8_t flags;
|
|
||||||
uint8_t history;
|
uint32_t isn; // current direction initial sequence number
|
||||||
|
uint8_t history; // current direction received flags
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -21,19 +21,19 @@ struct session_transition
|
|||||||
* SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA )
|
* SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA )
|
||||||
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
||||||
* SESSION_STATE_OPENING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
* SESSION_STATE_OPENING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
||||||
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT )
|
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT )
|
||||||
*
|
*
|
||||||
* SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE )
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE )
|
||||||
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
|
||||||
* SESSION_STATE_ACTIVE -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
||||||
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT )
|
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT)
|
||||||
*
|
*
|
||||||
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE )
|
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE )
|
||||||
* SESSION_STATE_CLOSING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
* SESSION_STATE_CLOSING -> SESSION_STATE_DISCARD ( USER_CLOSE )
|
||||||
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( LRU_EVICT | TIMEOUT )
|
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT )
|
||||||
*
|
*
|
||||||
* SESSION_STATE_DISCARD -> SESSION_STATE_DISCARD ( NONE )
|
* SESSION_STATE_DISCARD -> SESSION_STATE_DISCARD ( NONE )
|
||||||
* SESSION_STATE_DISCARD -> SESSION_STATE_CLOSED ( LRU_EVICT | TIMEOUT )
|
* SESSION_STATE_DISCARD -> SESSION_STATE_CLOSED ( LRU_EVICT | PORT_REUSE_EVICT | TIMEOUT )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void session_inputs_to_str(int inputs, char *buff, int len)
|
static void session_inputs_to_str(int inputs, char *buff, int len)
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ int build_tcp_packet(const struct packet *first, uint16_t ip_id, uint8_t ip_ttl,
|
|||||||
switch (curr->type)
|
switch (curr->type)
|
||||||
{
|
{
|
||||||
case LAYER_TYPE_TCP:
|
case LAYER_TYPE_TCP:
|
||||||
trim = curr->hdr_len + curr->pld_len - sizeof(struct tcphdr) + pld_len;
|
trim = curr->hdr_len + curr->pld_len - sizeof(struct tcphdr) - pld_len;
|
||||||
if (len - trim > buff_size)
|
if (len - trim > buff_size)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -330,7 +330,7 @@ int build_udp_packet(const struct packet *first, const char *udp_pld, int pld_le
|
|||||||
switch (curr->type)
|
switch (curr->type)
|
||||||
{
|
{
|
||||||
case LAYER_TYPE_UDP:
|
case LAYER_TYPE_UDP:
|
||||||
trim = curr->hdr_len + curr->pld_len - sizeof(struct udphdr) + pld_len;
|
trim = curr->hdr_len + curr->pld_len - sizeof(struct udphdr) - pld_len;
|
||||||
if (len - trim > buff_size)
|
if (len - trim > buff_size)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
@@ -51,16 +51,23 @@ struct inject_rule
|
|||||||
|
|
||||||
static void inject_packet_plugin(struct session *sess, struct packet *pkt, struct inject_rule *rule)
|
static void inject_packet_plugin(struct session *sess, struct packet *pkt, struct inject_rule *rule)
|
||||||
{
|
{
|
||||||
|
char buffer[1024] = {0};
|
||||||
const struct tuple6 *tuple = session_get_tuple6(sess);
|
const struct tuple6 *tuple = session_get_tuple6(sess);
|
||||||
if (rule->ip_type == 4 && memcmp(&tuple->src_addr.v4, &rule->v4, sizeof(struct in_addr)) && memcmp(&tuple->dst_addr.v4, &rule->v4, sizeof(struct in_addr)))
|
if (rule->ip_type == 4 &&
|
||||||
|
memcmp(&tuple->src_addr.v4, &rule->v4, sizeof(struct in_addr)) &&
|
||||||
|
memcmp(&tuple->dst_addr.v4, &rule->v4, sizeof(struct in_addr)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rule->ip_type == 6 && memcmp(&tuple->src_addr.v6, &rule->v6, sizeof(struct in6_addr)) && memcmp(&tuple->dst_addr.v6, &rule->v6, sizeof(struct in6_addr)))
|
if (rule->ip_type == 6 &&
|
||||||
|
memcmp(&tuple->src_addr.v6, &rule->v6, sizeof(struct in6_addr)) &&
|
||||||
|
memcmp(&tuple->dst_addr.v6, &rule->v6, sizeof(struct in6_addr)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rule->port != 0 && tuple->src_port != rule->port && tuple->dst_port != rule->port)
|
if (rule->port != 0 &&
|
||||||
|
tuple->src_port != rule->port &&
|
||||||
|
tuple->dst_port != rule->port)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -72,7 +79,8 @@ static void inject_packet_plugin(struct session *sess, struct packet *pkt, struc
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_INJECTED_PACKETS_SUCCESS) > 0 && session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_INJECTED_PACKETS_SUCCESS) > 0)
|
if (session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_INJECTED_PACKETS_SUCCESS) > 0 ||
|
||||||
|
session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_INJECTED_PACKETS_SUCCESS) > 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,6 +97,13 @@ static void inject_packet_plugin(struct session *sess, struct packet *pkt, struc
|
|||||||
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
|
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
|
||||||
break;
|
break;
|
||||||
case INJECT_TYPE_TCP_PAYLOAD:
|
case INJECT_TYPE_TCP_PAYLOAD:
|
||||||
|
packet_set_action(pkt, PACKET_ACTION_DROP);
|
||||||
|
snprintf(buffer, sizeof(buffer), "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s", 5 + 5 + 2, "Hello");
|
||||||
|
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, buffer, strlen(buffer)) > 0); // inject payload to client
|
||||||
|
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "World\r\n", 7) > 0);
|
||||||
|
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0); // inject FIN to client
|
||||||
|
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server
|
||||||
|
break;
|
||||||
case INJECT_TYPE_UDP_PAYLOAD:
|
case INJECT_TYPE_UDP_PAYLOAD:
|
||||||
packet_set_action(pkt, PACKET_ACTION_DROP);
|
packet_set_action(pkt, PACKET_ACTION_DROP);
|
||||||
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
|
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user