176404edcSAsim Jamshed #include <stdio.h>
276404edcSAsim Jamshed #include <stdlib.h>
376404edcSAsim Jamshed #include <assert.h>
476404edcSAsim Jamshed #include <unistd.h>
576404edcSAsim Jamshed #include <time.h>
676404edcSAsim Jamshed
776404edcSAsim Jamshed #include "mtcp.h"
876404edcSAsim Jamshed #include "mos_api.h"
976404edcSAsim Jamshed #include "memory_mgt.h"
1076404edcSAsim Jamshed #include "scalable_event.h"
1176404edcSAsim Jamshed
1276404edcSAsim Jamshed #define PROFILE_ON
1376404edcSAsim Jamshed #include "profile.h"
1476404edcSAsim Jamshed
1576404edcSAsim Jamshed event_t g_first_ev = MOS_NULL_EVENT, g_last_ev = MOS_NULL_EVENT;
1676404edcSAsim Jamshed int g_depth = 0;
1776404edcSAsim Jamshed float g_prob = 0;
1876404edcSAsim Jamshed int g_threshold = 0;
1976404edcSAsim Jamshed
2076404edcSAsim Jamshed int ft_counter = 0, cb_counter = 0;
2176404edcSAsim Jamshed struct mtcp_manager mtcp;
2276404edcSAsim Jamshed
2376404edcSAsim Jamshed extern inline int
2476404edcSAsim Jamshed ModCb(kvs_t *store, stree_t **pstree, event_t ev, callback_t cb);
2576404edcSAsim Jamshed
2676404edcSAsim Jamshed extern void
2776404edcSAsim Jamshed HandleCb(mctx_t mctx, int sock, int side, stree_t *stree, event_t events);
2876404edcSAsim Jamshed
2976404edcSAsim Jamshed extern int
3076404edcSAsim Jamshed RaiseEv(kvs_t *store, event_t event);
3176404edcSAsim Jamshed
3276404edcSAsim Jamshed mtcp_manager_t
GetMTCPManager(mctx_t mctx)3376404edcSAsim Jamshed GetMTCPManager(mctx_t mctx)
3476404edcSAsim Jamshed {
3576404edcSAsim Jamshed return &mtcp;
3676404edcSAsim Jamshed }
3776404edcSAsim Jamshed
3876404edcSAsim Jamshed u_int
sfbpf_filter(const struct sfbpf_insn * pc,const u_char * p,u_int wirelen,u_int buflen)3976404edcSAsim Jamshed sfbpf_filter(const struct sfbpf_insn *pc, const u_char *p, u_int wirelen,
4076404edcSAsim Jamshed u_int buflen)
4176404edcSAsim Jamshed {
4276404edcSAsim Jamshed return 0;
4376404edcSAsim Jamshed }
4476404edcSAsim Jamshed
4576404edcSAsim Jamshed static void
cb(mctx_t mctx,int sock,int side,event_t ev,filter_arg_t * arg)4676404edcSAsim Jamshed cb(mctx_t mctx, int sock, int side, event_t ev, filter_arg_t *arg)
4776404edcSAsim Jamshed {
4876404edcSAsim Jamshed //printf("cb: %ld\n", ev);
4976404edcSAsim Jamshed cb_counter++;
5076404edcSAsim Jamshed }
5176404edcSAsim Jamshed
5276404edcSAsim Jamshed static bool
ft(mctx_t mctx,int sock,int side,event_t ev,filter_arg_t * arg)5376404edcSAsim Jamshed ft(mctx_t mctx, int sock, int side, event_t ev, filter_arg_t *arg)
5476404edcSAsim Jamshed {
5576404edcSAsim Jamshed //printf("ft: %ld\n", ev);
5676404edcSAsim Jamshed return true;
5776404edcSAsim Jamshed }
5876404edcSAsim Jamshed
5976404edcSAsim Jamshed static bool
ft_prob(mctx_t mctx,int sockid,int side,uint64_t events,filter_arg_t * arg)6076404edcSAsim Jamshed ft_prob(mctx_t mctx, int sockid, int side, uint64_t events, filter_arg_t *arg)
6176404edcSAsim Jamshed {
6276404edcSAsim Jamshed static __thread unsigned int seed = 0;
6376404edcSAsim Jamshed if (seed == 0)
6476404edcSAsim Jamshed seed = time(NULL) + getpid();
6576404edcSAsim Jamshed bool ret = rand_r(&seed) < g_threshold;
6676404edcSAsim Jamshed //printf("ft: %ld returns %s\n", events, ret ? "true" : "false");
6776404edcSAsim Jamshed ft_counter++;
6876404edcSAsim Jamshed return ret;
6976404edcSAsim Jamshed }
7076404edcSAsim Jamshed
7176404edcSAsim Jamshed static int
power(base,exponent)7276404edcSAsim Jamshed power(base, exponent)
7376404edcSAsim Jamshed {
7476404edcSAsim Jamshed int i, ret = 1;
7576404edcSAsim Jamshed
7676404edcSAsim Jamshed assert(exponent >= 0);
7776404edcSAsim Jamshed
7876404edcSAsim Jamshed for (i = 0; i < exponent; i++)
7976404edcSAsim Jamshed ret *= base;
8076404edcSAsim Jamshed
8176404edcSAsim Jamshed return ret;
8276404edcSAsim Jamshed }
8376404edcSAsim Jamshed
8476404edcSAsim Jamshed event_t g_ac_events[5000];
8576404edcSAsim Jamshed event_t g_r_events[5000];
8676404edcSAsim Jamshed
8776404edcSAsim Jamshed static bool
ft_ac_match(mctx_t mctx,int sock,int side,uint64_t ev,filter_arg_t * arg)8876404edcSAsim Jamshed ft_ac_match(mctx_t mctx, int sock, int side, uint64_t ev, filter_arg_t *arg)
8976404edcSAsim Jamshed {
9076404edcSAsim Jamshed event_t ev_matched;
9176404edcSAsim Jamshed static __thread unsigned int seed = 0;
9276404edcSAsim Jamshed if (seed == 0)
9376404edcSAsim Jamshed seed = time(NULL) + getpid();
9476404edcSAsim Jamshed ev_matched = g_ac_events[rand_r(&seed) % *((int *)arg->arg)];
9576404edcSAsim Jamshed
9676404edcSAsim Jamshed RaiseEv(mtcp.ev_store, ev_matched);
9776404edcSAsim Jamshed
9876404edcSAsim Jamshed return true;
9976404edcSAsim Jamshed }
10076404edcSAsim Jamshed
main(int argc,char ** argv)10176404edcSAsim Jamshed int main(int argc, char **argv)
10276404edcSAsim Jamshed {
10376404edcSAsim Jamshed stree_t *stree[10] = {NULL};
10476404edcSAsim Jamshed
10576404edcSAsim Jamshed GlobInitEvent();
10676404edcSAsim Jamshed InitEvent(&mtcp);
10776404edcSAsim Jamshed
10876404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[0], 1, cb);
10976404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[1], 1, cb);
11076404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[0], 2, cb);
11176404edcSAsim Jamshed
11276404edcSAsim Jamshed printf("HandleCb(0)\n");
11376404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[0], 3);
11476404edcSAsim Jamshed printf("HandleCb(1)\n");
11576404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[1], 3);
11676404edcSAsim Jamshed
11776404edcSAsim Jamshed event_t ude1 = mtcp_define_event(1, ft, NULL);
11876404edcSAsim Jamshed assert(ude1);
11976404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[2], ude1, cb);
12076404edcSAsim Jamshed
12176404edcSAsim Jamshed printf("HandleCb(2)\n");
12276404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[2], 3);
12376404edcSAsim Jamshed
12476404edcSAsim Jamshed event_t ude2 = mtcp_define_event(ude1, ft, NULL);
12576404edcSAsim Jamshed assert(ude2);
12676404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[1], ude2, cb);
12776404edcSAsim Jamshed
12876404edcSAsim Jamshed printf("HandleCb(1)\n");
12976404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[1], 1);
13076404edcSAsim Jamshed
13176404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[1], ude2, NULL);
13276404edcSAsim Jamshed
13376404edcSAsim Jamshed printf("HandleCb(1)\n");
13476404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[1], 1);
13576404edcSAsim Jamshed
13676404edcSAsim Jamshed /* Random tree test */
13776404edcSAsim Jamshed #define BEV4 4
13876404edcSAsim Jamshed event_t ev;
13976404edcSAsim Jamshed int opt, i;
14076404edcSAsim Jamshed float numcb = 1, numft = 0, p;
14176404edcSAsim Jamshed
14276404edcSAsim Jamshed while ((opt = getopt(argc, argv, "d:p:")) > 0) {
14376404edcSAsim Jamshed if (opt == 'd')
14476404edcSAsim Jamshed g_depth = atoi(optarg);
14576404edcSAsim Jamshed else if (opt == 'p')
14676404edcSAsim Jamshed sscanf(optarg, "%f", &g_prob);
14776404edcSAsim Jamshed else {
14876404edcSAsim Jamshed fprintf(stderr, "Unknown option '%c'\n", opt);
14976404edcSAsim Jamshed exit(0);
15076404edcSAsim Jamshed }
15176404edcSAsim Jamshed }
15276404edcSAsim Jamshed
15376404edcSAsim Jamshed g_threshold = (int)((float)RAND_MAX * g_prob);
15476404edcSAsim Jamshed
15576404edcSAsim Jamshed if (g_depth < 0)
15676404edcSAsim Jamshed return -1;
15776404edcSAsim Jamshed
15876404edcSAsim Jamshed PROFILE_INIT();
15976404edcSAsim Jamshed PROFILE_VAR(define_event);
16076404edcSAsim Jamshed PROFILE_VAR(register_event);
16176404edcSAsim Jamshed PROFILE_VAR(trigger_event);
16276404edcSAsim Jamshed
16376404edcSAsim Jamshed PROFILE_START();
16476404edcSAsim Jamshed
16576404edcSAsim Jamshed PROFILE_FROM(define_event);
16676404edcSAsim Jamshed
16776404edcSAsim Jamshed g_first_ev = mtcp_define_event(BEV4, ft_prob, NULL);
16876404edcSAsim Jamshed //printf("%d -> %ld\n", BEV4, g_first_ev);
16976404edcSAsim Jamshed ev = mtcp_define_event(BEV4, ft_prob, NULL);
17076404edcSAsim Jamshed //printf("%d -> %ld\n", BEV4, ev);
17176404edcSAsim Jamshed g_last_ev = g_first_ev + power(2, g_depth + 1) - 3;
17276404edcSAsim Jamshed
17376404edcSAsim Jamshed for (ev = g_first_ev; g_depth != 1 && ev != MOS_NULL_EVENT; ev++) {
17476404edcSAsim Jamshed event_t nev;
17576404edcSAsim Jamshed /* Call define_event() twice since it is full binary tree */
17676404edcSAsim Jamshed nev = mtcp_define_event(ev, ft_prob, NULL);
17776404edcSAsim Jamshed //printf("%ld -> %ld\n", ev, nev);
17876404edcSAsim Jamshed nev = mtcp_define_event(ev, ft_prob, NULL);
17976404edcSAsim Jamshed //printf("%ld -> %ld\n", ev, nev);
18076404edcSAsim Jamshed if (nev == g_last_ev)
18176404edcSAsim Jamshed break;
18276404edcSAsim Jamshed else if (nev == MOS_NULL_EVENT) {
18376404edcSAsim Jamshed fprintf(stderr, "Failed to define child event of event %ld\n", ev);
18476404edcSAsim Jamshed exit(0);
18576404edcSAsim Jamshed }
18676404edcSAsim Jamshed }
18776404edcSAsim Jamshed if (ev == MOS_NULL_EVENT) {
18876404edcSAsim Jamshed fprintf(stderr, "Failed to define child event of event %ld\n", ev);
18976404edcSAsim Jamshed exit(0);
19076404edcSAsim Jamshed }
19176404edcSAsim Jamshed
19276404edcSAsim Jamshed PROFILE_TO(define_event);
19376404edcSAsim Jamshed
19476404edcSAsim Jamshed for (p = g_prob, i = 0; i < g_depth; p *= g_prob, i++) {
19576404edcSAsim Jamshed numft = 2*numcb;
19676404edcSAsim Jamshed numcb += p * power(2, i+1);
19776404edcSAsim Jamshed }
19876404edcSAsim Jamshed
19976404edcSAsim Jamshed printf("\x1b[33m"
20076404edcSAsim Jamshed "Tree depth: %d, Defined total events: %d\n"
20176404edcSAsim Jamshed "Theoritical average function call: %.2f callbacks, %.2f filters"
20276404edcSAsim Jamshed "\x1b[0m\n",
20376404edcSAsim Jamshed g_depth, power(2, g_depth) + 1, numcb, numft);
20476404edcSAsim Jamshed
20576404edcSAsim Jamshed /* Test random tree */
20676404edcSAsim Jamshed
20776404edcSAsim Jamshed PROFILE_FROM(register_event);
20876404edcSAsim Jamshed
20976404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[3], BEV4, cb);
21076404edcSAsim Jamshed for (ev = g_first_ev; ev != g_last_ev; ev++)
21176404edcSAsim Jamshed ModCb(mtcp.ev_store, &stree[3], ev, cb);
21276404edcSAsim Jamshed
21376404edcSAsim Jamshed PROFILE_TO(register_event);
21476404edcSAsim Jamshed
21576404edcSAsim Jamshed #if 0
21676404edcSAsim Jamshed mtcp_register_callback(mctx, msock, BEV4, MOS_PRE_RCV, cb_void);
21776404edcSAsim Jamshed
21876404edcSAsim Jamshed for (ev = g_first_ev; ev != g_last_ev; ev++)
21976404edcSAsim Jamshed mtcp_register_callback(mctx, msock, ev, MOS_PRE_RCV, cb_void);
22076404edcSAsim Jamshed #endif
22176404edcSAsim Jamshed
22276404edcSAsim Jamshed PROFILE_FROM(trigger_event);
22376404edcSAsim Jamshed #define LCOUNT 1000000
22476404edcSAsim Jamshed int j;
22576404edcSAsim Jamshed for (j=0; j<LCOUNT;j++)
22676404edcSAsim Jamshed HandleCb(NULL, 0, 0, stree[3], BEV4);
22776404edcSAsim Jamshed
22876404edcSAsim Jamshed PROFILE_TO(trigger_event);
22976404edcSAsim Jamshed
23076404edcSAsim Jamshed PROFILE_END();
23176404edcSAsim Jamshed
23276404edcSAsim Jamshed PROFILE_PRINT(stdout);
23376404edcSAsim Jamshed printf("Avg CB %f Avg FT %f\n", cb_counter*1.000000/LCOUNT, ft_counter*1.0/LCOUNT);
23476404edcSAsim Jamshed
235*a14d6bd4SAsim Jamshed #ifdef DO_SNORT_SIM
23676404edcSAsim Jamshed /*--------------------------------------------------------------------*/
23776404edcSAsim Jamshed /* selective event invocation test */
23876404edcSAsim Jamshed /*--------------------------------------------------------------------*/
23976404edcSAsim Jamshed
24076404edcSAsim Jamshed /* 1. Snort simulation */
24176404edcSAsim Jamshed {
24276404edcSAsim Jamshed printf("SNORT SIMULATION TEST\n");
24376404edcSAsim Jamshed stree_t *s = NULL;
24476404edcSAsim Jamshed const event_t BEV8 = 8;
24576404edcSAsim Jamshed const int REPEAT = 10;
24676404edcSAsim Jamshed const int RULES = 4000;
24776404edcSAsim Jamshed const int RULE_CONDS = 4;
24876404edcSAsim Jamshed filter_arg_t arg = {&RULES, sizeof(RULES)};
24976404edcSAsim Jamshed int percent = 0;
25076404edcSAsim Jamshed
25176404edcSAsim Jamshed int i, j;
25276404edcSAsim Jamshed
25376404edcSAsim Jamshed const event_t EV_AC_MATCH = mtcp_define_event(BEV8, ft_ac_match, &arg);
25476404edcSAsim Jamshed
25576404edcSAsim Jamshed for (i = 0; i < RULES; i++) {
25676404edcSAsim Jamshed event_t e = g_ac_events[i] = mtcp_alloc_event(EV_AC_MATCH);
25776404edcSAsim Jamshed
25876404edcSAsim Jamshed for (j = 0; j < RULE_CONDS; j++)
25976404edcSAsim Jamshed e = mtcp_define_event(e, ft, NULL);
26076404edcSAsim Jamshed
26176404edcSAsim Jamshed g_r_events[i] = e;
26276404edcSAsim Jamshed
26376404edcSAsim Jamshed if ((i * 100) / RULES > percent) {
26476404edcSAsim Jamshed percent = (i * 100) / RULES;
26576404edcSAsim Jamshed printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
26676404edcSAsim Jamshed printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
26776404edcSAsim Jamshed printf(" %d%% (%d / %d)", percent, i, RULES);
26876404edcSAsim Jamshed }
26976404edcSAsim Jamshed }
27076404edcSAsim Jamshed printf("\n");
27176404edcSAsim Jamshed
27276404edcSAsim Jamshed percent = 0;
27376404edcSAsim Jamshed for (i = 0; i < RULES; i++) {
27476404edcSAsim Jamshed ModCb(mtcp.ev_store, &s, g_r_events[i], cb);
27576404edcSAsim Jamshed
27676404edcSAsim Jamshed if ((i * 100) / RULES > percent) {
27776404edcSAsim Jamshed percent = (i * 100) / RULES;
27876404edcSAsim Jamshed printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
27976404edcSAsim Jamshed printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
28076404edcSAsim Jamshed printf(" %d%% (%d / %d)", percent, i, RULES);
28176404edcSAsim Jamshed }
28276404edcSAsim Jamshed }
28376404edcSAsim Jamshed printf("\n");
28476404edcSAsim Jamshed
28576404edcSAsim Jamshed cb_counter = 0;
28676404edcSAsim Jamshed for (i = 0; i < REPEAT; i++)
28776404edcSAsim Jamshed HandleCb(NULL, 0, 0, s, BEV8);
28876404edcSAsim Jamshed printf("%d / %d callbacks are called; %s\n",
28976404edcSAsim Jamshed cb_counter, REPEAT, cb_counter == REPEAT ? "SUCCESS" : "FAILURE");
29076404edcSAsim Jamshed }
291*a14d6bd4SAsim Jamshed #endif
29276404edcSAsim Jamshed
29376404edcSAsim Jamshed return 0;
29476404edcSAsim Jamshed }
295