/* */ #include "sm/generic.h" SM_RCSID("@(#)$Id: t-greyctl-2.c,v 1.2 2007/02/14 03:34:24 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; #define KEYLEN GL_KEYLEN static DBC *DBcursor; 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; ipv4_T addr; 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_TEST_E(ge.ge_len > 4); sm_memcpy(&addr, ge.ge_key, sizeof(addr)); sm_io_fprintf(fp, "addr=%16A, mail/rcpt=%*s time=%7ld, expire=%7ld, type=%s\n", addr, (int) ge.ge_len - 4, ge.ge_key + 4, (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); error: 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 sm_ret_T sm_grey_findprefix(DB *db, void *key, uint len, greyentry_P ge) { sm_ret_T ret; DBT db_data, db_key; uchar mykey[KEYLEN]; sm_memzero(&db_key, sizeof(db_key)); sm_memzero(&db_data, sizeof(db_data)); SM_REQUIRE(len < sizeof(mykey)); sm_memcpy(mykey, key, len); db_key.data = mykey; db_key.size = len; db_key.ulen = sizeof(mykey); db_data.flags = DB_DBT_USERMEM; db_data.data = ge; db_data.ulen = sizeof(*ge); /* ret = db->get(db, NULL, &db_key, &db_data, DB_SET_RANGE); */ ret = DBcursor->c_get(DBcursor,&db_key, &db_data, DB_SET_RANGE); SM_TEST(0 == ret); sm_io_fprintf(smioerr, "get_prefix=%d\n", ret); return ret; } static void testg(uint entries, uint ips, bool display) { sm_ret_T ret; uint ht_size, ht_limit, ge_limit, u; int r; uchar **keys, *key; uint *keylens; time_t t; greyctx_P greyctx; time_t start, elapsed; uint greyr[2]; greyentry_T ges; greyentry_P ge; #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; keys = (uchar **) sm_malloc(ips * sizeof(*keys)); SM_TEST_E(keys != NULL); keylens = (uint *) sm_malloc(ips * sizeof(*keylens)); SM_TEST_E(keylens != NULL); ret = sm_greyctl_crt(&greyctx); SM_TEST(SM_SUCCESS == ret); 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(SM_SUCCESS == ret); if (ret != SM_SUCCESS) return; srand(1); for (u = 0; u < ips; u++) { key = (uchar *) sm_malloc(KEYLEN); SM_TEST_E(key != NULL); r = sm_snprintf((char *)key, KEYLEN, "%c%c%c%c" , (char) rand(), (char) rand(), (char) rand(), (char) rand() , rand(), rand(), rand(), rand()); SM_TEST_E(r < KEYLEN); keys[u] = key; keylens[u] = r; if (Verbose > 2) { sm_io_fprintf(smioerr, "key[%d], len=%u, %s\n", u, r, key + 4); } } greyr[0] = 0; greyr[1] = 0; start = time((time_t *) 0); t = 1; for (u = 0; u < entries; u++) { key = keys[u % ips]; ret = sm_greyctl(greyctx, key, keylens[u % ips], t + u); if (Verbose > 1) { sm_io_fprintf(smioerr, "key[%d] %s, ret=%#x\n", u % ips, key + 4, ret); } 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); ge = ⩾ key = keys[0]; ret = greyctx->greyc_grey_db->cursor(greyctx->greyc_grey_db, NULL, &DBcursor, 0); SM_TEST_E(0 == ret); ret = sm_grey_findprefix(greyctx->greyc_grey_db, key, 4, ge); SM_TEST_E(0 == ret); done: ret = sm_greyctl_free(greyctx); greyctx = NULL; SM_TEST(SM_SUCCESS == ret); error: if (greyctx != NULL) sm_greyctl_free(greyctx); return; } 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(); }