Add test case: inject IPv4 based TCP payload packet after recv C2S first payload
This commit is contained in:
@@ -17,10 +17,8 @@
|
||||
#include "stellar/tuple.h"
|
||||
#include "stellar/session_mq.h"
|
||||
|
||||
#define MOCK_PLUGIN_LOG_DEBUG(format, ...) LOG_DEBUG("mock plugin", format, ##__VA_ARGS__)
|
||||
|
||||
/******************************************************************************
|
||||
* gmock plugin manager
|
||||
* packet_injector
|
||||
******************************************************************************/
|
||||
|
||||
enum condition
|
||||
@@ -50,157 +48,7 @@ struct inject_rule
|
||||
uint64_t count_num;
|
||||
} rule;
|
||||
|
||||
static void inject_packet_plugin(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
|
||||
{
|
||||
char buffer[1024] = {0};
|
||||
struct inject_rule *p_rule = &rule;
|
||||
// struct packet *pkt = (struct packet *)msg;
|
||||
const struct tuple6 *tuple = session_get_tuple6(sess);
|
||||
if (p_rule->ip_type == 4 &&
|
||||
memcmp(&tuple->src_addr.v4, &p_rule->v4, sizeof(struct in_addr)) &&
|
||||
memcmp(&tuple->dst_addr.v4, &p_rule->v4, sizeof(struct in_addr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->ip_type == 6 &&
|
||||
memcmp(&tuple->src_addr.v6, &p_rule->v6, sizeof(struct in6_addr)) &&
|
||||
memcmp(&tuple->dst_addr.v6, &p_rule->v6, sizeof(struct in6_addr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->port != 0 && tuple->src_port != p_rule->port && tuple->dst_port != p_rule->port)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->count_dir == AFTER_RECV_C2S_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->count_dir == AFTER_RECV_S2C_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (p_rule->inject_type)
|
||||
{
|
||||
case INJECT_TYPE_TCP_RST:
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0);
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_TCP_FIN:
|
||||
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_C2S) > 0);
|
||||
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_TCP_PAYLOAD:
|
||||
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); // inject payload to client
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0); // inject RST to client
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_UDP_PAYLOAD:
|
||||
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
|
||||
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "Hello Client", 12) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_CTRL_MSG:
|
||||
// TOOD
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* mock plugin manager
|
||||
******************************************************************************/
|
||||
|
||||
void *plugin_manager_new_ctx(struct session *sess, void *plugin_env)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void plugin_manager_free_ctx(struct session *sess, void *ctx, void *plugin_env)
|
||||
{
|
||||
char buff[4096] = {0};
|
||||
session_to_json(sess, buff, sizeof(buff));
|
||||
MOCK_PLUGIN_LOG_DEBUG("=> session: %s", buff);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* main
|
||||
******************************************************************************/
|
||||
|
||||
// curl -v http://http.badssl.selftest.gdnt-cloud.website --resolve "http.badssl.selftest.gdnt-cloud.website:80:192.0.2.110"
|
||||
|
||||
static const char *log_config_file = "./conf/log.toml";
|
||||
static const char *stellar_config_file = "./conf/stellar.toml";
|
||||
|
||||
static void signal_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGINT received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGQUIT)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGQUIT received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGTERM)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGTERM received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGHUP)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGHUP received, reload log level !!!");
|
||||
log_reload_level(log_config_file);
|
||||
}
|
||||
}
|
||||
|
||||
static int all_session_have_freed(void)
|
||||
{
|
||||
for (int i = 0; i < config->io_opts.nr_threads; i++)
|
||||
{
|
||||
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
|
||||
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->curr_nr_tcp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->curr_nr_udp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int all_stat_have_output(void)
|
||||
{
|
||||
static int count = 0;
|
||||
if (runtime->stat_last_output_ts == stellar_get_monotonic_time_msec())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
return count == 2;
|
||||
}
|
||||
#define INJECT_PACKET_PLUGIN_LOG_DEBUG(format, ...) LOG_DEBUG("inject packet plugin", format, ##__VA_ARGS__)
|
||||
|
||||
static void usage(char *cmd)
|
||||
{
|
||||
@@ -219,7 +67,7 @@ static void usage(char *cmd)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static int parse_cmdline(int argc, char **argv, struct inject_rule *rule)
|
||||
static int packet_injector_on_init(int argc, char **argv, struct inject_rule *rule)
|
||||
{
|
||||
memset(rule, 0, sizeof(struct inject_rule));
|
||||
|
||||
@@ -342,9 +190,155 @@ static int parse_cmdline(int argc, char **argv, struct inject_rule *rule)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inject_packet_main(int argc, char **argv)
|
||||
static void packet_injector_on_msg(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
|
||||
{
|
||||
if (parse_cmdline(argc, argv, &rule) != 0)
|
||||
char buffer[1024] = {0};
|
||||
struct inject_rule *p_rule = &rule;
|
||||
// struct packet *pkt = (struct packet *)msg;
|
||||
const struct tuple6 *tuple = session_get_tuple6(sess);
|
||||
if (p_rule->ip_type == 4 &&
|
||||
memcmp(&tuple->src_addr.v4, &p_rule->v4, sizeof(struct in_addr)) &&
|
||||
memcmp(&tuple->dst_addr.v4, &p_rule->v4, sizeof(struct in_addr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->ip_type == 6 &&
|
||||
memcmp(&tuple->src_addr.v6, &p_rule->v6, sizeof(struct in6_addr)) &&
|
||||
memcmp(&tuple->dst_addr.v6, &p_rule->v6, sizeof(struct in6_addr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->port != 0 && tuple->src_port != p_rule->port && tuple->dst_port != p_rule->port)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->count_dir == AFTER_RECV_C2S_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (p_rule->count_dir == AFTER_RECV_S2C_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (p_rule->inject_type)
|
||||
{
|
||||
case INJECT_TYPE_TCP_RST:
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0);
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_TCP_FIN:
|
||||
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_C2S) > 0);
|
||||
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_TCP_PAYLOAD:
|
||||
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); // inject payload to client
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0); // inject RST to client
|
||||
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_UDP_PAYLOAD:
|
||||
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
|
||||
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "Hello Client", 12) > 0);
|
||||
session_set_discard(sess);
|
||||
break;
|
||||
case INJECT_TYPE_CTRL_MSG:
|
||||
// TOOD
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void *packet_injector_on_sess_new(struct session *sess, void *plugin_env)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void packet_injector_on_sess_free(struct session *sess, void *ctx, void *plugin_env)
|
||||
{
|
||||
char buff[4096] = {0};
|
||||
session_to_json(sess, buff, sizeof(buff));
|
||||
INJECT_PACKET_PLUGIN_LOG_DEBUG("=> session: %s", buff);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* main
|
||||
******************************************************************************/
|
||||
|
||||
static const char *log_config_file = "./conf/log.toml";
|
||||
static const char *stellar_config_file = "./conf/stellar.toml";
|
||||
|
||||
static void signal_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGINT received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGQUIT)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGQUIT received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGTERM)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGTERM received, notify threads to exit !!!");
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
|
||||
if (signo == SIGHUP)
|
||||
{
|
||||
STELLAR_LOG_STATE("SIGHUP received, reload log level !!!");
|
||||
log_reload_level(log_config_file);
|
||||
}
|
||||
}
|
||||
|
||||
static int all_session_have_freed(void)
|
||||
{
|
||||
for (int i = 0; i < config->io_opts.nr_threads; i++)
|
||||
{
|
||||
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
|
||||
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->curr_nr_tcp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->curr_nr_udp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int all_stat_have_output(void)
|
||||
{
|
||||
static int count = 0;
|
||||
if (runtime->stat_last_output_ts == stellar_get_monotonic_time_msec())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
return count == 2;
|
||||
}
|
||||
|
||||
int packet_injector_main(int argc, char **argv)
|
||||
{
|
||||
if (packet_injector_on_init(argc, argv, &rule) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -400,12 +394,12 @@ int inject_packet_main(int argc, char **argv)
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
sess_plug_id = stellar_session_plugin_register(&st, plugin_manager_new_ctx, plugin_manager_free_ctx, NULL);
|
||||
sess_plug_id = stellar_session_plugin_register(&st, packet_injector_on_sess_new, packet_injector_on_sess_free, NULL);
|
||||
tcp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_TCP);
|
||||
udp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_UDP);
|
||||
|
||||
stellar_session_mq_subscribe(&st, tcp_topic_id, inject_packet_plugin, sess_plug_id);
|
||||
stellar_session_mq_subscribe(&st, udp_topic_id, inject_packet_plugin, sess_plug_id);
|
||||
stellar_session_mq_subscribe(&st, tcp_topic_id, packet_injector_on_msg, sess_plug_id);
|
||||
stellar_session_mq_subscribe(&st, udp_topic_id, packet_injector_on_msg, sess_plug_id);
|
||||
|
||||
if (stellar_thread_init(runtime, config) != 0)
|
||||
{
|
||||
@@ -452,5 +446,5 @@ error_out:
|
||||
|
||||
int __attribute__((weak)) main(int argc, char **argv)
|
||||
{
|
||||
return inject_packet_main(argc, argv);
|
||||
return packet_injector_main(argc, argv);
|
||||
}
|
||||
Reference in New Issue
Block a user