/* * Copyright (c) 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: t-greyctl-1.c,v 1.4 2006/12/01 16:54:53 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/types.h" #include "sm/net.h" #include "sm/greyctl.h" #include "sm/io.h" #include "sm/test.h" #include "greyctl.h" static int Verbose = 0; static sm_ret_T grey_display1(DB *db, DB *sdb, sm_file_T *fp) { sm_ret_T ret; DBC *dbcp; DBT db_data, db_key; greyentry_T ge; bool first; ret = db->cursor(sdb, NULL, &dbcp, 0); if (ret != 0) return ret; first = true; do { sm_memzero(&db_key, sizeof(db_key)); sm_memzero(&db_data, sizeof(db_data)); db_data.flags = DB_DBT_USERMEM; db_data.data = ≥ db_data.ulen = sizeof(ge); ret = dbcp->c_get(dbcp, &db_key, &db_data, first ? DB_FIRST : DB_NEXT); if (ret == 0) { sm_io_fprintf(fp, "addr=%16A, time=%7ld, expire=%7ld, type=%s\n", (ipv4_T) ge.ge_key, (long) ge.ge_time, (long) ge.ge_expire, ge.ge_type == GREY_TYPE_GREY ? "grey" : ge.ge_type == GREY_TYPE_WHITE ? "white" : "oops"); } first = false; } while (ret == 0); ret = dbcp->c_close(dbcp); return ret; } static sm_ret_T grey_display(greyctx_P greyctx, sm_file_T *fp) { sm_ret_T ret; ret = grey_display1(greyctx->greyc_grey_db, greyctx->greyc_grey_sdb, fp); sm_io_putc(fp, '\n'); sm_io_flush(fp); return ret; } static void testg(uint entries, uint ips, bool display) { sm_ret_T ret; uint ht_size, ht_limit, ge_limit, u; ipv4_T addr; ipv4_T *addrs; time_t t; greyctx_P greyctx; time_t start, elapsed; uint greyr[2]; #define T_GREY_MIN_WAIT 60 #define T_GREY_MAX_WAIT 600 #define T_WHITE_EXP 6000 #define T_WHITE_TMO 12000 ht_size = 40000; ht_limit = 40000; ge_limit = 20000; addrs = (ipv4_T *) sm_malloc(ips * sizeof(*addrs)); if (addrs == NULL) return; ret = sm_greyctl_crt(&greyctx); SM_TEST(ret == SM_SUCCESS); if (ret != SM_SUCCESS) return; greyctx->greyc_cnf.greycnf_limit = ht_limit; greyctx->greyc_cnf.greycnf_min_grey_wait = T_GREY_MIN_WAIT; greyctx->greyc_cnf.greycnf_max_grey_wait = T_GREY_MAX_WAIT; greyctx->greyc_cnf.greycnf_white_expire = T_WHITE_EXP; greyctx->greyc_cnf.greycnf_white_reconfirm = T_WHITE_TMO; ret = sm_greyctl_open(greyctx, NULL); SM_TEST(ret == SM_SUCCESS); if (ret != SM_SUCCESS) return; srand(1); for (u = 0; u < ips; u++) addrs[u] = rand(); greyr[0] = 0; greyr[1] = 0; start = time((time_t *) 0); t = 1; for (u = 0; u < entries; u++) { addr = addrs[u % ips]; ret = sm_greyctl(greyctx, (uchar *)&addr, sizeof(addr), t + u); switch (ret) { case SM_GREY_AGAIN: case SM_GREY_FIRST: case SM_GREY_WAIT: ++greyr[1]; break; case SM_GREY_OK: ++greyr[0]; break; default: goto done; } } elapsed = time((time_t *) 0) - start; sm_io_fprintf(smioout, "elapsed time: %ld\n", (long) elapsed); if (elapsed > 0) sm_io_fprintf(smioout, "updates/s: %ld\n", (long) entries / elapsed); sm_io_fprintf(smioout, "wait=%u\nok= %u\n", greyr[1], greyr[0]); if (display) grey_display(greyctx, smioout); sm_io_flush(smioout); done: ret = sm_greyctl_free(greyctx); SM_TEST(ret == SM_SUCCESS); } int main(int argc, char *argv[]) { int c; bool rm, display; uint entries, ips; entries = 1000; ips = 100; rm = true; display = false; while ((c = getopt(argc, argv, "de:i:k:V")) != -1) { switch (c) { case 'd': display = true; break; case 'e': entries = strtoul(optarg, NULL, 0); break; case 'i': ips = strtoul(optarg, NULL, 0); break; case 'k': rm = false; break; case 'V': ++Verbose; break; default: return(1); } } if (rm) { (void) unlink("grey_grey_m.db"); (void) unlink("grey_grey_s.db"); } sm_test_begin(argc, argv, "test greylist"); testg(entries, ips, display); return sm_test_end(); }