struct event_base * rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, void (*accept_handler)(int, short, void *), gboolean load_lua) { struct event_base *ev_base; struct event *accept_events; GList *cur; struct rspamd_worker_listen_socket *ls; #ifdef WITH_PROFILER extern void _start (void), etext (void); monstartup ((u_long) & _start, (u_long) & etext); #endif gperf_profiler_init (worker->srv->cfg, name); worker->srv->pid = getpid (); worker->signal_events = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); ev_base = event_init (); rspamd_worker_init_signals (worker, ev_base); rspamd_control_worker_add_default_handler (worker, ev_base); #ifdef WITH_HIREDIS rspamd_redis_pool_config (worker->srv->cfg->redis_pool, worker->srv->cfg, ev_base); #endif /* Accept all sockets */ if (accept_handler) { cur = worker->cf->listen_socks; while (cur) { ls = cur->data; if (ls->fd != -1) { accept_events = g_slice_alloc0 (sizeof (struct event) * 2); event_set (&accept_events[0], ls->fd, EV_READ | EV_PERSIST, accept_handler, worker); event_base_set (ev_base, &accept_events[0]); event_add (&accept_events[0], NULL); worker->accept_events = g_list_prepend (worker->accept_events, accept_events); } cur = g_list_next (cur); } } if (load_lua) { struct rspamd_config *cfg = worker->srv->cfg; rspamd_lua_run_postloads (cfg->lua_state, cfg, ev_base, worker); } return ev_base; }
struct event_base * rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, void (*accept_handler)(int, short, void *)) { struct event_base *ev_base; struct event *accept_event; GList *cur; gint listen_socket; #ifdef WITH_PROFILER extern void _start (void), etext (void); monstartup ((u_long) & _start, (u_long) & etext); #endif gperf_profiler_init (worker->srv->cfg, name); worker->srv->pid = getpid (); worker->signal_events = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); ev_base = event_init (); rspamd_worker_init_signals (worker, ev_base); rspamd_control_worker_add_default_handler (worker, ev_base); /* Accept all sockets */ cur = worker->cf->listen_socks; while (cur) { listen_socket = GPOINTER_TO_INT (cur->data); if (listen_socket != -1) { accept_event = g_slice_alloc0 (sizeof (struct event)); event_set (accept_event, listen_socket, EV_READ | EV_PERSIST, accept_handler, worker); event_base_set (ev_base, accept_event); event_add (accept_event, NULL); worker->accept_events = g_list_prepend (worker->accept_events, accept_event); } cur = g_list_next (cur); } return ev_base; }
static void rspamd_http_start_servers (pid_t *sfd, rspamd_inet_addr_t *addr) { guint i; gint fd; fd = rspamd_inet_address_listen (addr, SOCK_STREAM, TRUE); g_assert (fd != -1); for (i = 0; i < nworkers; i++) { sfd[i] = fork (); g_assert (sfd[i] != -1); if (sfd[i] == 0) { gperf_profiler_init (NULL, "http-server"); rspamd_http_server_func (fd, addr); gperf_profiler_stop (); exit (EXIT_SUCCESS); } } close (fd); }
static void rspamd_http_start_servers (pid_t *sfd, rspamd_inet_addr_t *addr, struct rspamd_cryptobox_keypair *serv_key, struct rspamd_keypair_cache *c) { guint i; gint fd; g_assert ((fd = rspamd_inet_address_listen (addr, SOCK_STREAM, TRUE)) != -1); for (i = 0; i < nservers; i ++) { sfd[i] = fork (); g_assert (sfd[i] != -1); if (sfd[i] == 0) { gperf_profiler_init (NULL, "plain-http-server"); rspamd_http_server_func (fd, "/tmp/", addr, serv_key, c); gperf_profiler_stop (); exit (EXIT_SUCCESS); } } close (fd); }
gint main (gint argc, gchar **argv, gchar **env) { GError *error = NULL; GOptionContext *context; GOptionGroup *og; struct rspamd_config *cfg; GQuark process_quark; gchar **nargv, **targv; const gchar *cmd_name; const struct rspamadm_command *cmd; gint i, nargc, targc; ucl_vars = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, g_free); process_quark = g_quark_from_static_string ("rspamadm"); cfg = rspamd_config_new (); cfg->libs_ctx = rspamd_init_libs (); rspamd_main = g_malloc0 (sizeof (*rspamd_main)); rspamd_main->cfg = cfg; rspamd_main->pid = getpid (); rspamd_main->type = process_quark; rspamd_main->server_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "rspamadm"); cfg->log_level = G_LOG_LEVEL_WARNING; cfg->log_type = RSPAMD_LOG_CONSOLE; rspamd_set_logger (cfg, process_quark, rspamd_main); (void) rspamd_log_open (rspamd_main->logger); g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); g_set_printerr_handler (rspamd_glib_printerr_function); rspamd_config_post_load (cfg, FALSE); /* Setup logger */ if (verbose) { cfg->log_level = G_LOG_LEVEL_DEBUG; } else { cfg->log_level = G_LOG_LEVEL_INFO; } gperf_profiler_init (cfg, "rspamadm"); setproctitle ("rspamdadm"); /* Now read options and store everything till the first non-dash argument */ nargv = g_malloc0 (sizeof (gchar *) * (argc + 1)); nargv[0] = g_strdup (argv[0]); for (i = 1, nargc = 1; i < argc; i ++) { if (argv[i] && argv[i][0] == '-') { /* Copy to nargv */ nargv[nargc] = g_strdup (argv[i]); nargc ++; } else { break; } } context = g_option_context_new ("command - rspamd administration utility"); og = g_option_group_new ("global", "global options", "global options", NULL, NULL); g_option_context_set_help_enabled (context, FALSE); g_option_group_add_entries (og, entries); g_option_context_set_summary (context, "Summary:\n Rspamd administration utility version " RVERSION "\n Release id: " RID); g_option_context_set_main_group (context, og); targv = nargv; targc = nargc; if (!g_option_context_parse (context, &targc, &targv, &error)) { fprintf (stderr, "option parsing failed: %s\n", error->message); g_error_free (error); exit (1); } g_strfreev (nargv); if (show_version) { rspamadm_version (); exit (EXIT_SUCCESS); } if (show_help) { rspamadm_usage (context); exit (EXIT_SUCCESS); } if (list_commands) { rspamadm_commands (); exit (EXIT_SUCCESS); } cmd_name = argv[nargc]; if (cmd_name == NULL) { cmd_name = "help"; } cmd = rspamadm_search_command (cmd_name); if (cmd == NULL) { fprintf (stderr, "Invalid command name: %s\n", cmd_name); exit (EXIT_FAILURE); } if (nargc < argc) { nargv = g_malloc0 (sizeof (gchar *) * (argc - nargc + 1)); nargv[0] = g_strdup_printf ("%s %s", argv[0], cmd_name); for (i = 1; i < argc - nargc; i ++) { nargv[i] = g_strdup (argv[i + nargc]); } targc = argc - nargc; targv = nargv; cmd->run (targc, targv); g_strfreev (nargv); } else { cmd->run (0, NULL); } rspamd_log_close (rspamd_main->logger); REF_RELEASE (rspamd_main->cfg); g_free (rspamd_main); return 0; }
void rspamd_http_test_func (void) { struct event_base *ev_base = event_init (); rspamd_mempool_t *pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), NULL); struct rspamd_cryptobox_keypair *serv_key, *client_key; struct rspamd_cryptobox_pubkey *peer_key; struct rspamd_keypair_cache *c; rspamd_mempool_mutex_t *mtx; rspamd_inet_addr_t *addr; gdouble ts1, ts2; gchar filepath[PATH_MAX], *buf; gchar *env; gint fd; guint i, j; pid_t *sfd; GString *b32_key; double diff, total_diff = 0.0, *latency, mean, std; /* Read environment */ if ((env = getenv ("RSPAMD_HTTP_CONNS")) != NULL) { pconns = strtoul (env, NULL, 10); } else { return; } if ((env = getenv ("RSPAMD_HTTP_TESTS")) != NULL) { ntests = strtoul (env, NULL, 10); } if ((env = getenv ("RSPAMD_HTTP_SIZE")) != NULL) { file_size = strtoul (env, NULL, 10); } if ((env = getenv ("RSPAMD_HTTP_SERVERS")) != NULL) { nservers = strtoul (env, NULL, 10); } rspamd_cryptobox_init (); rspamd_snprintf (filepath, sizeof (filepath), "/tmp/http-test-XXXXXX"); g_assert ((fd = mkstemp (filepath)) != -1); sfd = g_alloca (sizeof (*sfd) * nservers); latency = g_malloc0 (pconns * ntests * sizeof (gdouble)); buf = g_malloc (file_size); memset (buf, 0, file_size); g_assert (write (fd, buf, file_size) == file_size); g_free (buf); mtx = rspamd_mempool_get_mutex (pool); rspamd_parse_inet_address (&addr, "127.0.0.1", 0); rspamd_inet_address_set_port (addr, 43898); serv_key = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_25519); client_key = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_25519); c = rspamd_keypair_cache_new (16); rspamd_http_start_servers (sfd, addr, serv_key, NULL); usleep (100000); /* Do client stuff */ gperf_profiler_init (NULL, "plain-http-client"); for (i = 0; i < ntests; i ++) { for (j = 0; j < pconns; j ++) { rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, addr, NULL, NULL, c, ev_base, &latency[i * pconns + j]); } ts1 = rspamd_get_ticks (); event_base_loop (ev_base, 0); ts2 = rspamd_get_ticks (); diff = (ts2 - ts1) * 1000.0; total_diff += diff; } gperf_profiler_stop (); msg_info ("Made %d connections of size %d in %.6f ms, %.6f cps", ntests * pconns, file_size, total_diff, ntests * pconns / total_diff * 1000.); mean = rspamd_http_calculate_mean (latency, &std); msg_info ("Latency: %.6f ms mean, %.6f dev", mean, std); rspamd_http_stop_servers (sfd); rspamd_http_start_servers (sfd, addr, serv_key, c); //rspamd_mempool_lock_mutex (mtx); usleep (100000); b32_key = rspamd_keypair_print (serv_key, RSPAMD_KEYPAIR_PUBKEY|RSPAMD_KEYPAIR_BASE32); g_assert (b32_key != NULL); peer_key = rspamd_pubkey_from_base32 (b32_key->str, b32_key->len, RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_25519); g_assert (peer_key != NULL); total_diff = 0.0; gperf_profiler_init (NULL, "cached-http-client"); for (i = 0; i < ntests; i ++) { for (j = 0; j < pconns; j ++) { rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, addr, client_key, peer_key, c, ev_base, &latency[i * pconns + j]); } ts1 = rspamd_get_ticks (); event_base_loop (ev_base, 0); ts2 = rspamd_get_ticks (); diff = (ts2 - ts1) * 1000.0; total_diff += diff; } gperf_profiler_stop (); msg_info ("Made %d encrypted connections of size %d in %.6f ms, %.6f cps", ntests * pconns, file_size, total_diff, ntests * pconns / total_diff * 1000.); mean = rspamd_http_calculate_mean (latency, &std); msg_info ("Latency: %.6f ms mean, %.6f dev", mean, std); /* Restart server */ rspamd_http_stop_servers (sfd); /* No keypairs cache */ rspamd_http_start_servers (sfd, addr, serv_key, NULL); usleep (100000); total_diff = 0.0; gperf_profiler_init (NULL, "fair-http-client"); for (i = 0; i < ntests; i ++) { for (j = 0; j < pconns; j ++) { rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, addr, client_key, peer_key, c, ev_base, &latency[i * pconns + j]); } ts1 = rspamd_get_ticks (); event_base_loop (ev_base, 0); ts2 = rspamd_get_ticks (); diff = (ts2 - ts1) * 1000.0; total_diff += diff; } gperf_profiler_stop (); msg_info ("Made %d uncached encrypted connections of size %d in %.6f ms, %.6f cps", ntests * pconns, file_size, total_diff, ntests * pconns / total_diff * 1000.); mean = rspamd_http_calculate_mean (latency, &std); msg_info ("Latency: %.6f ms mean, %.6f dev", mean, std); /* AES mode */ serv_key = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_NIST); client_key = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_NIST); c = rspamd_keypair_cache_new (16); /* Restart server */ rspamd_http_stop_servers (sfd); /* No keypairs cache */ rspamd_http_start_servers (sfd, addr, serv_key, c); //rspamd_mempool_lock_mutex (mtx); usleep (100000); b32_key = rspamd_keypair_print (serv_key, RSPAMD_KEYPAIR_PUBKEY | RSPAMD_KEYPAIR_BASE32); g_assert (b32_key != NULL); peer_key = rspamd_pubkey_from_base32 (b32_key->str, b32_key->len, RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_NIST); g_assert (peer_key != NULL); total_diff = 0.0; gperf_profiler_init (NULL, "cached-http-client-aes"); for (i = 0; i < ntests; i++) { for (j = 0; j < pconns; j++) { rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, addr, client_key, peer_key, NULL, ev_base, &latency[i * pconns + j]); } ts1 = rspamd_get_ticks (); event_base_loop (ev_base, 0); ts2 = rspamd_get_ticks (); diff = (ts2 - ts1) * 1000.0; total_diff += diff; } gperf_profiler_stop (); msg_info ( "Made %d aes encrypted connections of size %d in %.6f ms, %.6f cps", ntests * pconns, file_size, total_diff, ntests * pconns / total_diff * 1000.); mean = rspamd_http_calculate_mean (latency, &std); msg_info ("Latency: %.6f ms mean, %.6f dev", mean, std); /* Restart server */ rspamd_http_stop_servers (sfd); /* No keypairs cache */ rspamd_http_start_servers (sfd, addr, serv_key, NULL); //rspamd_mempool_lock_mutex (mtx); usleep (100000); total_diff = 0.0; gperf_profiler_init (NULL, "fair-http-client-aes"); for (i = 0; i < ntests; i++) { for (j = 0; j < pconns; j++) { rspamd_http_client_func (filepath + sizeof ("/tmp") - 1, addr, client_key, peer_key, c, ev_base, &latency[i * pconns + j]); } ts1 = rspamd_get_ticks (); event_base_loop (ev_base, 0); ts2 = rspamd_get_ticks (); diff = (ts2 - ts1) * 1000.0; total_diff += diff; } gperf_profiler_stop (); msg_info ( "Made %d uncached aes encrypted connections of size %d in %.6f ms, %.6f cps", ntests * pconns, file_size, total_diff, ntests * pconns / total_diff * 1000.); mean = rspamd_http_calculate_mean (latency, &std); msg_info ("Latency: %.6f ms mean, %.6f dev", mean, std); close (fd); unlink (filepath); rspamd_http_stop_servers (sfd); }