Ejemplo n.º 1
0
static void
cleanup()
{
    int rc;
    DB *db;
    DB_ENV *dbenv;
    rc = get_db(&db, 0);
    assert(! rc);
    rc = get_dbenv(&dbenv, 0);
    assert(! rc);
    if (dbkey.data)
	free(dbkey.data);
    if (db)
	call_db(db->close(db, 0), "DB close");
    if (dbenv) {
	rc = call_db(db_create(&db, dbenv, 0), "db_create");
	if (!rc)
	    if (! db->remove(db, "tls_stats.db", 0, 0))
		syslog(LOG_NOTICE, "Unused database tls_stats.db removed");
	call_db(dbenv->txn_checkpoint(dbenv, 100 * 1024, 24 * 60, 0),
		"txn_checkpoint");
	call_db(dbenv->log_archive(dbenv, NULL, DB_ARCH_REMOVE), "log_archive");
	call_db(dbenv->close(dbenv, 0), "DB_ENV close");
    }
    policy_cleanup();
}
Ejemplo n.º 2
0
/* Return the current Berkeley DB environment. If "force" is not zero
   then force creating the environment if it does not yet exist. Note
   that if "force" is zero then the function can not fail. */
static int
get_dbenv(DB_ENV **dbenv_ret, int force)
{
    static DB_ENV *dbenv = NULL;
    int rc = 0;
    if (dbenv == NULL && force) {
	rc = call_db(db_env_create(&dbenv, 0), "db_env_create");
	if (!rc) {
	    dbenv->set_errcall(dbenv, db_errcall_fcn);
	    rc = call_db(dbenv->set_lk_detect(dbenv, DB_LOCK_YOUNGEST),
			 "dbenv->set_lk_detect DB_LOCK_YOUNGEST, expired triplets will not be deleted");
	    if (!rc)
		deadlock_detect = 1;
	    rc = call_db(dbenv->open(dbenv, db_home,
#ifdef DB_REGISTER
				     /* DB_REGISTER appears in Berkeley DB 4.4 [#11511]
					http://docs.oracle.com/cd/E17076_02/html/upgrading/changelog_4_4_16.html#idp51982816 */
				     DB_REGISTER | DB_RECOVER |
#endif
				     DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_CREATE, 0),
			 "dbenv->open");
	    if (rc) {
		dbenv->close(dbenv, 0);
		dbenv = 0;
	    }
	}
    }
    if (dbenv_ret)
	*dbenv_ret = dbenv;
    return rc;
}
void uvm_ml_config_rsrc::process_bp_notification
(
    uvm_ml_resource_notify_action action,
    const char *                  item_scope,
    const char *                  item_name,
    unsigned int                  stream_size,
    uvm_ml_stream_t               stream,
    uvm_ml_time_unit              time_unit,
    double                        time_value,
    const char *                  cntxt
)
{
    unsigned int         data_size = stream_size - UVM_ML_BLOCK_SIZE;
    std::string          str_val;
    uvm_object *         obj_val;
    sc_dt::sc_bv_base    bv_val((int) data_size);
    std::vector<unsigned> vec;
    uvm_ml_packer_int  packer;

    bp_set_config = true;
    uvm_ml_stream_t stream_data = stream;

    uvm_ml_packed_obj&  packed_obj = uvm_ml_utils::get_static_mlupo();


    // ENTER_CO_SIMULATION_CONTEXT();

    switch (stream[0])
    {
    case UVM_ML_STREAM_STRING:
        stream_data++;
        uvm_ml_utils::fill_mlupo(packed_obj, data_size, stream_data);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        packer >> str_val;
        call_db(action, cntxt, item_scope, item_name, str_val);
        break;

    case UVM_ML_STREAM_TYPED_OBJECT:
        uvm_ml_utils::fill_mlupo(packed_obj, stream_size, stream);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        packer >> obj_val;
        call_db(action, cntxt, item_scope, item_name, obj_val);
        break;

    case UVM_ML_STREAM_RAW:
        stream_data++;
        uvm_ml_utils::fill_mlupo(packed_obj, data_size, stream_data);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        packer >> bv_val;
        call_db(action, cntxt, item_scope, item_name, bv_val);
        break;

    default:
        break;
    };

    //EXIT_CO_SIMULATION_CONTEXT();

}   // process_bp_notification()
Ejemplo n.º 4
0
void uvm_ml_config_rsrc::process_bp_notification
(
    uvm_ml_resource_notify_action action,
    const char *                  item_scope,
    const char *                  item_name,
    unsigned int                  stream_size,
    uvm_ml_stream_t               stream,
    uvm_ml_time_unit              time_unit,
    double                        time_value,
    const char *                  cntxt
)
{
    unsigned int         data_size = stream_size - UVM_ML_BLOCK_SIZE;
    std::string          str_val;
    uvm_object *         obj_val;
    sc_dt::sc_bv_base    bv_val((int) data_size);
    std::vector<unsigned> vec;
    uvm_ml_packer_int  packer;

    bp_set_config = true;
    uvm_ml_stream_t stream_data = stream;

    uvm_ml_packed_obj&  packed_obj = uvm_ml_utils::get_static_mlupo();

    switch (stream[0])
    {
    case UVM_ML_STREAM_STRING:
        stream_data++;
        uvm_ml_utils::fill_mlupo(packed_obj, data_size, stream_data);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        packer >> str_val;
        call_db(action, cntxt, item_scope, item_name, str_val);
        break;

    case UVM_ML_STREAM_TYPED_OBJECT:
      { uvm_ml_utils::fill_mlupo(packed_obj, stream_size, stream);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        if (packer.check_obj_header()) { // Else silently drop it (until tracing is not added) - probably not intended for SC
           packer >> obj_val;
           call_db(action, cntxt, item_scope, item_name, obj_val);
	}
        break;
      }
    case UVM_ML_STREAM_RAW:
        stream_data++;
        uvm_ml_utils::fill_mlupo(packed_obj, data_size, stream_data);
        packer.set_from_uvm_ml_packed_obj(&packed_obj);
        packer >> bv_val;
        call_db(action, cntxt, item_scope, item_name, bv_val);
        break;

    default:
        break;
    };
Ejemplo n.º 5
0
static int
get_db(DB **db_ret, int force)
{
    static DB *db = NULL;
    int rc = 0;
    if (db == NULL && force) {
	DB_ENV *dbenv;
	rc = get_dbenv(&dbenv, force);
	if (rc)
	    return rc;
	rc = call_db(db_create(&db, dbenv, 0), "db_create");
	if (!rc) {
	    /* XXX do not use call_db: it is normal for this call to
	       fail with ENOENT if the database has to be upgraded or
	       created from scratch */
	    rc = db_open(db, DB_FILE_NAME, NULL,
			 DB_BTREE, DB_AUTO_COMMIT, 0644);
	    if (rc == ENOENT) {
		/* Try and upgrade from an old version */
		rc = call_db(upgrade_from_v0(dbenv), "upgrade_from_v0");
		if (!rc)
		    rc = call_db(db_open(db, DB_FILE_NAME, NULL, DB_BTREE, DB_AUTO_COMMIT | DB_CREATE, 0644),
				 "db->open 2");
	    }
	    else if (rc)
		call_db(rc, "db->open");
	    if (rc) {
		db->close(db, 0);
		db = 0;
	    }
	}
    }
    if (db_ret)
	*db_ret = db;
    return rc;
}
Ejemplo n.º 6
0
static int
process_smtp_rcpt(int crypted)
{
    double delay;
    int rc;
    DB_ENV *dbenv;
    DB *db;
    DB_TXN *txn = NULL;
    if (setjmp(defect_jmp_buf)) {
	if (defect_msg) {
	    printf(STR_ACTION "WARN %s\n", defect_msg);
	    defect_msg = 0;
	}
	else
	    puts(STR_ACTION "WARN " PACKAGE_STRING " is not working properly");
	if (txn)
	    call_db(txn->abort(txn), "Failed to abort transaction");
	return 1;
    }
    rc = get_dbenv(&dbenv, 1);
    if (rc)
	jmperr("get_dbenv failed");
    rc = get_db(&db, 1);
    if (rc)
	jmperr("get_db failed");
    rc = call_db(dbenv->txn_begin(dbenv, NULL, &txn, 0),
		 "txn_begin failed in process_smtp_rcpt");
    if (rc)
	jmperr("txn_begin failed");
    get_grey_data(db, txn);
    if (triplet_data.crypted != crypted) {
      triplet_data.crypted = crypted;
      if (debug_me) syslog(LOG_DEBUG,"crypted field changed for some reason");
    }
    delay = difftime(triplet_data.access_time, triplet_data.create_time);
    /* Block inbound mail that is from a previously unknown (ip, from, to) triplet */
    /* However we want different behavior for crypted stuff
     */

    if(crypted > 0) {
      if(delay < cryptlist_delay) {
	triplet_data.block_count++;
	fputs(STR_ACTION, stdout);
	printf_action(reject_action_fmt, greylist_delay - delay);
	putchar('\n');
    }
    else if (triplet_data.pass_count++)
	puts(STR_ACTION "DUNNO");
      else {
        fputs(STR_ACTION, stdout);
        printf_action(cryptlisted_action_fmt, delay);
        putchar('\n');
      }
    } else {
      if(delay < greylist_delay || block_unencrypted) {
        triplet_data.block_count++;
        fputs(STR_ACTION, stdout);
        if(block_unencrypted == 1) {
          printf_action(reject_unencrypted_action_fmt, (3600*24)); // block it for a day
        } else {
          printf_action(reject_unencrypted_action_fmt, greylist_delay - delay);
        }
        putchar('\n');
      }
      else if (triplet_data.pass_count++)
        puts(STR_ACTION "DUNNO");
      else {
        fputs(STR_ACTION, stdout);
        printf_action(greylisted_action_fmt, delay);
        putchar('\n');
      }
    }
    rc = put_grey_data(db, txn);
    if (rc)
	call_db(txn->abort(txn), "abort failed");
    else
	call_db(txn->commit(txn, 0), "commit failed");
    return rc;
}
Ejemplo n.º 7
0
static int
put_grey_data(DB *db, DB_TXN *txn)
{
    return call_db(db->put(db, txn, &dbkey, &dbdata, 0), "put");
}
Ejemplo n.º 8
0
/* Upgrade the database from v0 format to the new format */
static int
upgrade_from_v0(DB_ENV *dbenv)
{
    DB *db0 = NULL, *db1 = NULL;
    DB_TXN *tid = NULL;
    DBC *cursor = NULL;
    DBT key = { 0 }, data = { 0 };
    int rc = call_db(dbenv->txn_begin(dbenv, NULL, &tid, 0),
		     "upgrade_from_v0 dbenv->txn_begin");
    if (!rc)
	rc = call_db(db_create(&db0, dbenv, 0), "upgrade_from_v0 db_create 0");
    if (!rc) {
	/* XXX do not use call_db: it is normal for this call to fail,
	   if there is no database to upgrade from. */
	rc = db0->open(db0, tid, DB_FILE_NAME_V0, NULL, DB_UNKNOWN, 0, 0644);
	if (rc == ENOENT) {
	    call_db(db0->close(db0, 0), "upgrade_from_v0 db0->close 0");
	    call_db(tid->commit(tid, 0), "upgrade_from_v0 tid->commit 0");
	    return 0;
	}
    }
    if (!rc) {
	syslog(LOG_WARNING, "Upgrading from database format v0");
	rc = call_db(db_create(&db1, dbenv, 0), "upgrade_from_v0 db_create 1");
    }
    if (!rc)
	rc = call_db(db1->open(db1, tid,
			       DB_FILE_NAME, NULL,
			       DB_BTREE, DB_CREATE | DB_EXCL, 0644),
		     "upgrade_from_v0 db1->open");
    if (!rc)
	rc = call_db(db0->cursor(db0, tid, &cursor, 0),
		     "upgrade_from_v0 db0->cursor");
    size_t buffer_size = 0;
    char *buffer = 0;
    while (!rc) {
	rc = cursor->get(cursor, &key, &data, DB_NEXT);
	if (rc == DB_NOTFOUND) {
	    /* this is expected result, do commit this transaction */
	    rc = 0;
	    break;
	}
	else if (rc) {
	    call_db(rc, "upgrade_from_v0 cursor->get");
	    break;
	}
	/* Convert this entry to new format */
	char *s, *ip, *from, *to;
	size_t iplen, fromlen, tolen;
	ip = key.data;
	iplen = strlen(ip);
	from = ip + iplen + 1;
	fromlen = strlen(from);
	to = from + fromlen + 1;
	tolen = key.size - fromlen - iplen - 2;
	int count = 0;
	for (s = strchr(ip, '.'); s != NULL; s = strchr(s + 1, '.'))
	    count++;
	s = ensure_dbkey_reserve(MAX(MAX(sizeof(struct in_addr),
					 sizeof(struct in6_addr)),
				     iplen + 1)
				 + fromlen + tolen + 2);
	if (count) {
	    /* This is supposedly an IPv4 address. Complete it with
	       trailing zeroes. A complete IPv4 address has 3 dots and
	       4 numbers. For each missing dot, add the dot and a 0. */
	    size_t needed = iplen + 2 * (3 - count) + 1;
	    if (buffer_size < needed) {
		buffer = xrealloc(buffer, needed);
		buffer_size = needed;
	    }
	    strcpy(buffer, ip);
	    while (count++ < 3)
		strcat(buffer, ".0");
	    *s++ = DBKEY_T_IP4;
	    rc = inet_pton(AF_INET, buffer, s);
	    s += sizeof(struct in_addr);
	    if (rc == -1)
		rc = errno;
	    else if (rc == 1)
		rc = 0;
	    else
		rc = EINVAL;
	    if (rc)
		break;		/* error */
	}
	else {
	    /* Try it as an IPv6 address. v0 format did not abbreviate
	       IPv6 addresses. */
	    *s++ = DBKEY_T_IP6;
	    if (inet_pton(AF_INET6, ip, s) == 1)
		s += sizeof(struct in6_addr);
	    else {
		/* Not IPv4 neither IPv6. Keep it in its raw form */
		*s++ = DBKEY_T_RAW;
		strcpy(s, ip);
		s += iplen + 1;
	    }
	}
	strcpy(s, from);
	s += fromlen + 1;
	memcpy(s, to, tolen);
	s += tolen;
	dbkey.size = s - (char*)dbkey.data;
	rc = call_db(db1->put(db1, tid, &dbkey, &data, DB_NOOVERWRITE),
		     "upgrade_from_v0 db1->put");
    }
    if (buffer != NULL)
	free(buffer);
    if (cursor != NULL)
	call_db(cursor->close(cursor), "upgrade_from_v0 cursor->close");
    if (db1 != NULL)
	call_db(db1->close(db1, 0), "upgrade_from_v0 db1->close");
    if (db0 != NULL)
	call_db(db0->close(db0, 0), "upgrade_from_v0 db0->close");
    if (!rc)
	rc = call_db(dbenv->dbremove(dbenv, tid, DB_FILE_NAME_V0, NULL, 0),
		     "upgrade_from_v0 dbenv->dbremove");
    if (tid != NULL) {
	if (rc)
	    call_db(tid->abort(tid), "upgrade_from_v0 tid->abort");
	else
	    call_db(tid->commit(tid, 0), "upgrade_from_v0 tid->commit");
    }
    return rc;
}
Ejemplo n.º 9
0
static void
run_expiry()
{
    DB_ENV *dbenv;
    DB *db;
    DB_TXN *txn;
    DBC *dbcp;
    int rc;
    time_t now;
    DBT key = { 0 };
    unsigned int count = 0;
    if (exit_requested)
	return;
    /* Cursor operations can hold several locks and therefore deadlock
       so don't run expiry if deadlock detection does not work
       http://docs.oracle.com/cd/E17076_02/html/programmer_reference/lock_notxn.html */
    rc = get_db(&db, 0);
    assert(! rc);
    if (db == 0 || deadlock_detect == 0)
	return;
    rc = get_dbenv(&dbenv, 0);
    assert(! rc && dbenv);
    if (time(&now) == (time_t)-1) {
	syslog(LOG_ERR, "time failed during run_expiry");
	return;
    }
    muffle_error++;
    rc = dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOWAIT);
    if (rc) {
	if (rc == DB_LOCK_DEADLOCK)
	    syslog(LOG_DEBUG, "skipping concurrent expiry avoids "
		   "deadlocks and unnecessary work");
	else
	    log_db_error("txn_begin failed during run_expiry", rc);
	goto out;
    }
#if DB_VERSION_MAJOR >= 5
    call_db(txn->set_priority(txn, 50), "TXN->set_priority");
#endif
    rc = call_db(db->cursor(db, txn, &dbcp, 0),
		 "db->cursor failed during expiry run");
    if (rc)
	goto txn_fail;
    while ((rc = dbcp->c_get(dbcp, &key, &dbdata, DB_NEXT | DB_RMW)) == 0) {
	time_t ref_time;
	double age_max, age;
	if (triplet_data.pass_count) {
	    ref_time = triplet_data.access_time;
	    age_max = pass_max_idle;
	}
	else {
	    ref_time = triplet_data.create_time;
	    age_max = bloc_max_idle;
	}
	age = difftime(now, ref_time);
	if (age > age_max) {
	    if (opt_verbose) {
		syslog(LOG_INFO, "Expiring %s %s after %.0f seconds idle",
		       db_key_ntop(key.data),
		       triplet_data.pass_count ? "pass" : "block", age);
	    }
	    rc = call_db(dbcp->c_del(dbcp, 0), "dbcp->c_del failed");
	    if (rc)
		goto cursor_fail;
	    count++;
	}
	if (exit_requested)
	    break;
    }
    if (rc && rc != DB_NOTFOUND) {
	if (rc == DB_LOCK_DEADLOCK)
	    syslog(LOG_NOTICE, "Aborting concurrent expiry due to deadlock");
	else
	    log_db_error("dbcp->c_get failed", rc);
	goto cursor_fail;
    }
    if (call_db(dbcp->c_close(dbcp), "dbcp->c_close failed"))
	goto txn_fail;
    call_db(txn->commit(txn, 0), "commit failed in run_expiry");
    if (count)
	syslog(LOG_NOTICE, "Expired %u triplets", count);
    goto out;

  cursor_fail:
    call_db(dbcp->c_close(dbcp), "dbcp->c_close failed");
  txn_fail:
    call_db(txn->abort(txn), "failed to abort");
  out:
    muffle_error--;
    return;
}