Exemple #1
0
/*%
 * Internal print routine used to print short form replies.
 */
static isc_result_t
say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) {
	isc_result_t result;
	isc_uint64_t diff;
	isc_time_t now;
	char store[sizeof("12345678901234567890")];

	if (query->lookup->trace || query->lookup->ns_search_only) {
		result = dns_rdatatype_totext(rdata->type, buf);
		if (result != ISC_R_SUCCESS)
			return (result);
		ADD_STRING(buf, " ");
	}
	result = dns_rdata_totext(rdata, NULL, buf);
	if (result == ISC_R_NOSPACE)
		return (result);
	check_result(result, "dns_rdata_totext");
	if (query->lookup->identify) {
		TIME_NOW(&now);
		diff = isc_time_microdiff(&now, &query->time_sent);
		ADD_STRING(buf, " from server ");
		ADD_STRING(buf, query->servname);
		snprintf(store, 19, " in %d ms.", (int)diff/1000);
		ADD_STRING(buf, store);
	}
	ADD_STRING(buf, "\n");
	return (ISC_R_SUCCESS);
}
Exemple #2
0
static isc_result_t
get(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
	isc_keyboard_t *kbd = (isc_keyboard_t *)arg;
	isc_result_t result;
	isc_time_t t;
	isc_uint32_t sample;
	isc_uint32_t extra;
	unsigned char c;

	if (!blocking)
		return (ISC_R_NOENTROPY);

	result = isc_keyboard_getchar(kbd, &c);
	if (result != ISC_R_SUCCESS)
		return (result);

	TIME_NOW(&t);

	sample = isc_time_nanoseconds(&t);
	extra = c;

	result = isc_entropy_addcallbacksample(source, sample, extra);
	if (result != ISC_R_SUCCESS) {
		printf("\r\n");
		return (result);
	}

	printf(".");
	fflush(stdout);

	return (result);
}
Exemple #3
0
void Player::setClient(NetPeer* client)
{
    assert(network_client == NULL);
    network_client = client;

    lastActivityTime = TIME_NOW();
}
Exemple #4
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_touch(isc_timer_t *timer0) {
	isc__timer_t *timer = (isc__timer_t *)timer0;
	isc_result_t result;
	isc_time_t now;

	/*
	 * Set the last-touched time of 'timer' to the current time.
	 */

	REQUIRE(VALID_TIMER(timer));

	LOCK(&timer->lock);

	/*
	 * We'd like to
	 *
	 *	REQUIRE(timer->type == isc_timertype_once);
	 *
	 * but we cannot without locking the manager lock too, which we
	 * don't want to do.
	 */

	TIME_NOW(&now);
	result = isc_time_add(&now, &timer->interval, &timer->idle);

	UNLOCK(&timer->lock);

	return (result);
}
Exemple #5
0
ATF_TC_BODY(zonemgr_unreachable, tc) {
	dns_zonemgr_t *zonemgr = NULL;
	dns_zone_t *zone = NULL;
	isc_sockaddr_t addr1, addr2;
	struct in_addr in;
	isc_result_t result;
	isc_time_t now;

	UNUSED(tc);

	TIME_NOW(&now);

	result = dns_test_begin(NULL, ISC_TRUE);

	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr,
				    &zonemgr);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_test_makezone("foo", &zone, NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_zonemgr_setsize(zonemgr, 1);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_zonemgr_managezone(zonemgr, zone);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	in.s_addr = inet_addr("10.53.0.1");
	isc_sockaddr_fromin(&addr1, &in, 2112);
	in.s_addr = inet_addr("10.53.0.2");
	isc_sockaddr_fromin(&addr2, &in, 5150);
	ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
	dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now);
	ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));

	in.s_addr = inet_addr("10.53.0.3");
	isc_sockaddr_fromin(&addr2, &in, 5150);
	ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
	dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now);
	ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));

	dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2);
	ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));

	in.s_addr = inet_addr("10.53.0.2");
	isc_sockaddr_fromin(&addr2, &in, 5150);
	ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
	dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2);
	ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));

	dns_zonemgr_releasezone(zonemgr, zone);
	dns_zone_detach(&zone);
	dns_zonemgr_shutdown(zonemgr);
	dns_zonemgr_detach(&zonemgr);
	ATF_REQUIRE_EQ(zonemgr, NULL);

	dns_test_end();
}
Exemple #6
0
void SMWServer::playerLeavesRoom(uint64_t playerID)
{
    if (!players.count(playerID))
        return;

    Player* player = &players[playerID];
    if (!player->currentRoomID || player->isPlaying)
        return;

    if (!rooms.count(player->currentRoomID))
        return;

    // Search for the room in which the player is
    Room* room = &rooms[player->currentRoomID];
    room->removePlayer(player);

    // If the room is now empty, delete it.
    if (room->playerCount == 0) {
        rooms.erase(player->currentRoomID);
        log("Room %u erased.", player->currentRoomID);
    }
    else
        room->sendRoomUpdate();

    player->currentRoomID = 0;
    player->isPlaying = false;
    player->lastActivityTime = TIME_NOW();
}
Exemple #7
0
void
isc__timermgr_dispatch(void) {
	isc_time_t now;
	if (timermgr == NULL)
		return;
	TIME_NOW(&now);
	dispatch(timermgr, &now);
}
Exemple #8
0
// Network stuff
bool Player::sendData(const void* data, size_t dataLength)
{
    assert(network_client);
    if (!network_client || !data || dataLength < 3)
        return false;

    lastActivityTime = TIME_NOW();
    return network_client->sendReliable(data, dataLength);
}
Exemple #9
0
void Player::setSkin(const void* data, size_t data_length)
{
    // Some basic package validation
    if (data_length <= sizeof(NetPkgs::MessageHeader) + 5 /* id 1B + un-/compressed size 2*2B */
        || data_length > SKINPKG_SIZE_LIMIT) {
        printf("[error] Corrupt skin arrived from %s\n", toString().c_str());
        return;
    }

    skinPackage.replace_with(data, data_length);
    lastActivityTime = TIME_NOW();
}
Exemple #10
0
Player::Player()
{
    currentRoomID = 0;
    isPlaying = false;
    playerNumberInRoom = 0;
    synchOK = false;

    name = "Anonymous";
    network_client = NULL;

    joinTime = TIME_NOW();
    lastActivityTime = joinTime;
}
Exemple #11
0
void
isc__timermgr_dispatch(isc_timermgr_t *manager0) {
	isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
	isc_time_t now;

#ifdef USE_SHARED_MANAGER
	if (manager == NULL)
		manager = timermgr;
#endif
	if (manager == NULL)
		return;
	TIME_NOW(&now);
	dispatch(manager, &now);
}
Exemple #12
0
/*%
 * Callback from dighost.c to print the received message.
 */
void
received(int bytes, isc_sockaddr_t *from, dig_query_t *query) {
	isc_uint64_t diff;
	isc_time_t now;
	time_t tnow;
	struct tm tmnow;
	char time_str[100];
	char fromtext[ISC_SOCKADDR_FORMATSIZE];

	isc_sockaddr_format(from, fromtext, sizeof(fromtext));

	TIME_NOW(&now);

	if (query->lookup->stats && !short_form) {
		diff = isc_time_microdiff(&now, &query->time_sent);
		printf(";; Query time: %ld msec\n", (long int)diff/1000);
		printf(";; SERVER: %s(%s)\n", fromtext, query->servname);
		time(&tnow);
		tmnow  = *localtime(&tnow);
		if (strftime(time_str, sizeof(time_str),
			     "%a %b %d %H:%M:%S %Z %Y", &tmnow) > 0U)
			printf(";; WHEN: %s\n", time_str);
		if (query->lookup->doing_xfr) {
			printf(";; XFR size: %u records (messages %u, "
			       "bytes %" ISC_PRINT_QUADFORMAT "u)\n",
			       query->rr_count, query->msg_count,
			       query->byte_count);
		} else {
			printf(";; MSG SIZE  rcvd: %u\n", bytes);
		}
		if (key != NULL) {
			if (!validated)
				puts(";; WARNING -- Some TSIG could not "
				     "be validated");
		}
		if ((key == NULL) && (keysecret[0] != 0)) {
			puts(";; WARNING -- TSIG key was not used.");
		}
		puts("");
	} else if (query->lookup->identify && !short_form) {
		diff = isc_time_microdiff(&now, &query->time_sent);
		printf(";; Received %" ISC_PRINT_QUADFORMAT "u bytes "
		       "from %s(%s) in %d ms\n\n",
		       query->lookup->doing_xfr ?
				query->byte_count : (isc_uint64_t)bytes,
		       fromtext, query->userarg,
		       (int)diff/1000);
	}
}
Exemple #13
0
void
dns_badcache_print(dns_badcache_t *bc, const char *cachename, FILE *fp) {
	char namebuf[DNS_NAME_FORMATSIZE];
	char typebuf[DNS_RDATATYPE_FORMATSIZE];
	dns_bcentry_t *bad, *next, *prev;
	isc_time_t now;
	unsigned int i;
	isc_uint64_t t;

	REQUIRE(VALID_BADCACHE(bc));
	REQUIRE(cachename != NULL);
	REQUIRE(fp != NULL);

	LOCK(&bc->lock);
	fprintf(fp, ";\n; %s\n;\n", cachename);

	TIME_NOW(&now);
	for (i = 0; bc->count > 0 && i < bc->size; i++) {
		prev = NULL;
		for (bad = bc->table[i]; bad != NULL; bad = next) {
			next = bad->next;
			if (isc_time_compare(&bad->expire, &now) < 0) {
				if (prev != NULL)
					prev->next = bad->next;
				else
					bc->table[i] = bad->next;

				isc_mem_put(bc->mctx, bad, sizeof(*bad) +
					    bad->name.length);
				bc->count--;
				continue;
			}
			prev = bad;
			dns_name_format(&bad->name, namebuf, sizeof(namebuf));
			dns_rdatatype_format(bad->type, typebuf,
					     sizeof(typebuf));
			t = isc_time_microdiff(&bad->expire, &now);
			t /= 1000;
			fprintf(fp, "; %s/%s [ttl "
				"%" ISC_PLATFORM_QUADFORMAT "u]\n",
				namebuf, typebuf, t);
		}
	}
	UNLOCK(&bc->lock);
}
Exemple #14
0
/*
 * Set up a DLZ zone as writeable
 */
isc_result_t
ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
				dns_rdataclass_t rdclass, dns_name_t *name)
{
	dns_db_t *db = NULL;
	isc_time_t now;
	isc_result_t result;

	TIME_NOW(&now);

	dns_zone_settype(zone, dns_zone_dlz);
	result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
	if (result != ISC_R_SUCCESS)
		return result;
	result = dns_zone_dlzpostload(zone, db);
	dns_db_detach(&db);
	return result;
}
Exemple #15
0
static isc_threadresult_t
#ifdef _WIN32			/* XXXDCL */
WINAPI
#endif
run(void *uap) {
	isc__timermgr_t *manager = uap;
	isc_time_t now;
	isc_result_t result;

	LOCK(&manager->lock);
	while (!manager->done) {
		TIME_NOW(&now);

		XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
					  ISC_MSG_RUNNING,
					  "running"), now);

		dispatch(manager, &now);

		if (manager->nscheduled > 0) {
			XTRACETIME2(isc_msgcat_get(isc_msgcat,
						   ISC_MSGSET_GENERAL,
						   ISC_MSG_WAITUNTIL,
						   "waituntil"),
				    manager->due, now);
			result = WAITUNTIL(&manager->wakeup, &manager->lock, &manager->due);
			INSIST(result == ISC_R_SUCCESS ||
			       result == ISC_R_TIMEDOUT);
		} else {
			XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						  ISC_MSG_WAIT, "wait"), now);
			WAIT(&manager->wakeup, &manager->lock);
		}
		XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
				      ISC_MSG_WAKEUP, "wakeup"));
	}
	UNLOCK(&manager->lock);

#ifdef OPENSSL_LEAKS
	ERR_remove_state(0);
#endif

	return ((isc_threadresult_t)0);
}
Exemple #16
0
void SMWServer::playerSendsChatMsg(uint64_t playerID, const void* data)
{
    if (!players.count(playerID))
        return;

    Player* player = &players[playerID];
    uint32_t roomID = player->currentRoomID;
    if (!roomID || player->isPlaying)
        return;

    if (!rooms.count(roomID))
        return;

    Net_RoomChatMsgPackage pkg;
    memcpy(&pkg, data, sizeof(Net_RoomChatMsgPackage));

    rooms[roomID].sendChatMessage(player, pkg.message);
    player->lastActivityTime = TIME_NOW();
}
Exemple #17
0
Room::Room(uint32_t roomID, const char* name, const char* password, Player* host)
    : roomID(roomID)
    , visible(true) // TODO
    , hostPlayerNumber(0)
    , playerCount(1)
    , gamemodeID(0) // Classic
    , gamemodeGoal(10) // 10 lives
{
    strncpy(this->name, name, NET_MAX_ROOM_NAME_LENGTH);
    this->name[NET_MAX_ROOM_NAME_LENGTH - 1] = '\0';
    strncpy(this->password, password, NET_MAX_ROOM_PASSWORD_LENGTH);
    this->password[NET_MAX_ROOM_PASSWORD_LENGTH - 1] = '\0';

    players[0] = host;
    host->skinPackage.setPlayerID(0);

    for (uint8_t p = 1; p < 4; p++)
        players[p] = NULL;

    createTime = TIME_NOW();
    lastActivityTime = createTime;
}
Exemple #18
0
void SMWServer::playerSendsChatMsg(uint64_t playerID, const void* data, size_t dataLength)
{
    if (!players.count(playerID))
        return;

    Player* player = &players[playerID];
    uint32_t roomID = player->currentRoomID;
    if (!roomID || player->isPlaying)
        return;

    if (!rooms.count(roomID))
        return;

    if (dataLength != sizeof(NetPkgs::RoomChatMsg)) {
        printf("[error] Corrupt package arrived from %lu\n", playerID);
        return;
    }

    NetPkgs::RoomChatMsg pkg;
    memcpy(&pkg, data, dataLength);

    rooms[roomID].sendChatMessage(player, pkg.message);
    player->lastActivityTime = TIME_NOW();
}
Exemple #19
0
void SMWServer::playerStartsRoom(uint64_t playerID)
{
    if (!players.count(playerID))
        return;

    Player* player = &players[playerID];
    uint32_t roomID = player->currentRoomID;
    if (!roomID || player->isPlaying)
        return;

    if (!rooms.count(roomID))
        return;

    Room* room = &rooms[roomID];
    assert(room->hostPlayerNumber < 4);

    // only host can start
    if (room->players[room->hostPlayerNumber] != player)
        return;

    rooms[roomID].sendStartSignal();
    player->lastActivityTime = TIME_NOW();
    log("[info] Room #%d starting.", roomID);
}
Exemple #20
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type,
		 isc_time_t *expires, isc_interval_t *interval,
		 isc_boolean_t purge)
{
	isc__timer_t *timer = (isc__timer_t *)timer0;
	isc_time_t now;
	isc__timermgr_t *manager;
	isc_result_t result;

	/*
	 * Change the timer's type, expires, and interval values to the given
	 * values.  If 'purge' is ISC_TRUE, any pending events from this timer
	 * are purged from its task's event queue.
	 */

	REQUIRE(VALID_TIMER(timer));
	manager = timer->manager;
	REQUIRE(VALID_MANAGER(manager));

	if (expires == NULL)
		expires = isc_time_epoch;
	if (interval == NULL)
		interval = isc_interval_zero;
	REQUIRE(type == isc_timertype_inactive ||
		!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
	REQUIRE(type != isc_timertype_limited ||
		!(isc_time_isepoch(expires) || isc_interval_iszero(interval)));

	/*
	 * Get current time.
	 */
	if (type != isc_timertype_inactive) {
		TIME_NOW(&now);
	} else {
		/*
		 * We don't have to do this, but it keeps the compiler from
		 * complaining about "now" possibly being used without being
		 * set, even though it will never actually happen.
		 */
		isc_time_settoepoch(&now);
	}

	LOCK(&manager->lock);
	LOCK(&timer->lock);

	if (purge)
		(void)isc_task_purgerange(timer->task,
					  timer,
					  ISC_TIMEREVENT_FIRSTEVENT,
					  ISC_TIMEREVENT_LASTEVENT,
					  NULL);
	timer->type = type;
	timer->expires = *expires;
	timer->interval = *interval;
	if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
		result = isc_time_add(&now, interval, &timer->idle);
	} else {
		isc_time_settoepoch(&timer->idle);
		result = ISC_R_SUCCESS;
	}

	if (result == ISC_R_SUCCESS) {
		if (type == isc_timertype_inactive) {
			deschedule(timer);
			result = ISC_R_SUCCESS;
		} else
			result = schedule(timer, &now, ISC_TRUE);
	}

	UNLOCK(&timer->lock);
	UNLOCK(&manager->lock);

	return (result);
}
Exemple #21
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
		  isc_time_t *expires, isc_interval_t *interval,
		  isc_task_t *task, isc_taskaction_t action, const void *arg,
		  isc_timer_t **timerp)
{
	isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
	isc__timer_t *timer;
	isc_result_t result;
	isc_time_t now;

	/*
	 * Create a new 'type' timer managed by 'manager'.  The timers
	 * parameters are specified by 'expires' and 'interval'.  Events
	 * will be posted to 'task' and when dispatched 'action' will be
	 * called with 'arg' as the arg value.  The new timer is returned
	 * in 'timerp'.
	 */

	REQUIRE(VALID_MANAGER(manager));
	REQUIRE(task != NULL);
	REQUIRE(action != NULL);
	if (expires == NULL)
		expires = isc_time_epoch;
	if (interval == NULL)
		interval = isc_interval_zero;
	REQUIRE(type == isc_timertype_inactive ||
		!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
	REQUIRE(timerp != NULL && *timerp == NULL);
	REQUIRE(type != isc_timertype_limited ||
		!(isc_time_isepoch(expires) || isc_interval_iszero(interval)));

	/*
	 * Get current time.
	 */
	if (type != isc_timertype_inactive) {
		TIME_NOW(&now);
	} else {
		/*
		 * We don't have to do this, but it keeps the compiler from
		 * complaining about "now" possibly being used without being
		 * set, even though it will never actually happen.
		 */
		isc_time_settoepoch(&now);
	}


	timer = isc_mem_get(manager->mctx, sizeof(*timer));
	if (timer == NULL)
		return (ISC_R_NOMEMORY);

	timer->manager = manager;
	timer->references = 1;

	if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
		result = isc_time_add(&now, interval, &timer->idle);
		if (result != ISC_R_SUCCESS) {
			isc_mem_put(manager->mctx, timer, sizeof(*timer));
			return (result);
		}
	} else
		isc_time_settoepoch(&timer->idle);

	timer->type = type;
	timer->expires = *expires;
	timer->interval = *interval;
	timer->task = NULL;
	isc_task_attach(task, &timer->task);
	timer->action = action;
	/*
	 * Removing the const attribute from "arg" is the best of two
	 * evils here.  If the timer->arg member is made const, then
	 * it affects a great many recipients of the timer event
	 * which did not pass in an "arg" that was truly const.
	 * Changing isc_timer_create() to not have "arg" prototyped as const,
	 * though, can cause compilers warnings for calls that *do*
	 * have a truly const arg.  The caller will have to carefully
	 * keep track of whether arg started as a true const.
	 */
	DE_CONST(arg, timer->arg);
	timer->index = 0;
	result = isc_mutex_init(&timer->lock);
	if (result != ISC_R_SUCCESS) {
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}
	ISC_LINK_INIT(timer, link);
	timer->common.impmagic = TIMER_MAGIC;
	timer->common.magic = ISCAPI_TIMER_MAGIC;
	timer->common.methods = (isc_timermethods_t *)&timermethods;

	LOCK(&manager->lock);

	/*
	 * Note we don't have to lock the timer like we normally would because
	 * there are no external references to it yet.
	 */

	if (type != isc_timertype_inactive)
		result = schedule(timer, &now, ISC_TRUE);
	else
		result = ISC_R_SUCCESS;
	if (result == ISC_R_SUCCESS)
		APPEND(manager->timers, timer, link);

	UNLOCK(&manager->lock);

	if (result != ISC_R_SUCCESS) {
		timer->common.impmagic = 0;
		timer->common.magic = 0;
		DESTROYLOCK(&timer->lock);
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}

	*timerp = (isc_timer_t *)timer;

	return (ISC_R_SUCCESS);
}
Exemple #22
0
void Player::setName(const std::string& name)
{
    this->name = name;

    lastActivityTime = TIME_NOW();
}
Exemple #23
0
/*!
 * Event loop for nonthreaded programs.
 */
static isc_result_t
evloop(isc__appctx_t *ctx) {
	isc_result_t result;

	while (!ctx->want_shutdown) {
		int n;
		isc_time_t when, now;
		struct timeval tv, *tvp;
		isc_socketwait_t *swait;
		isc_boolean_t readytasks;
		isc_boolean_t call_timer_dispatch = ISC_FALSE;

		/*
		 * Check the reload (or suspend) case first for exiting the
		 * loop as fast as possible in case:
		 *   - the direct call to isc__taskmgr_dispatch() in
		 *     isc__app_ctxrun() completes all the tasks so far,
		 *   - there is thus currently no active task, and
		 *   - there is a timer event
		 */
		if (ctx->want_reload) {
			ctx->want_reload = ISC_FALSE;
			return (ISC_R_RELOAD);
		}

		readytasks = isc__taskmgr_ready(ctx->taskmgr);
		if (readytasks) {
			tv.tv_sec = 0;
			tv.tv_usec = 0;
			tvp = &tv;
			call_timer_dispatch = ISC_TRUE;
		} else {
			result = isc__timermgr_nextevent(ctx->timermgr, &when);
			if (result != ISC_R_SUCCESS)
				tvp = NULL;
			else {
				isc_uint64_t us;

				TIME_NOW(&now);
				us = isc_time_microdiff(&when, &now);
				if (us == 0)
					call_timer_dispatch = ISC_TRUE;
				tv.tv_sec = us / 1000000;
				tv.tv_usec = us % 1000000;
				tvp = &tv;
			}
		}

		swait = NULL;
		n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait);

		if (n == 0 || call_timer_dispatch) {
			/*
			 * We call isc__timermgr_dispatch() only when
			 * necessary, in order to reduce overhead.  If the
			 * select() call indicates a timeout, we need the
			 * dispatch.  Even if not, if we set the 0-timeout
			 * for the select() call, we need to check the timer
			 * events.  In the 'readytasks' case, there may be no
			 * timeout event actually, but there is no other way
			 * to reduce the overhead.
			 * Note that we do not have to worry about the case
			 * where a new timer is inserted during the select()
			 * call, since this loop only runs in the non-thread
			 * mode.
			 */
			isc__timermgr_dispatch(ctx->timermgr);
		}
		if (n > 0)
			(void)isc__socketmgr_dispatch(ctx->socketmgr, swait);
		(void)isc__taskmgr_dispatch(ctx->taskmgr);
	}
	return (ISC_R_SUCCESS);
}
Exemple #24
0
int
main(int argc, char *argv[]) {
	dns_db_t *db;
	dns_dbnode_t *node;
	isc_result_t result;
	dns_name_t name;
	dns_offsets_t offsets;
	size_t len;
	isc_buffer_t source, target;
	char s[1000];
	char b[255];
	dns_rdataset_t rdataset, sigrdataset;
	int ch;
	dns_rdatatype_t type = 1;
	isc_boolean_t printnode = ISC_FALSE;
	isc_boolean_t addmode = ISC_FALSE;
	isc_boolean_t delmode = ISC_FALSE;
	isc_boolean_t holdmode = ISC_FALSE;
	isc_boolean_t verbose = ISC_FALSE;
	isc_boolean_t done = ISC_FALSE;
	isc_boolean_t quiet = ISC_FALSE;
	isc_boolean_t time_lookups = ISC_FALSE;
	isc_boolean_t found_as;
	isc_boolean_t find_zonecut = ISC_FALSE;
	isc_boolean_t noexact_zonecut = ISC_FALSE;
	int i, v;
	dns_rdatasetiter_t *rdsiter;
	char t1[256];
	char t2[256];
	isc_buffer_t tb1, tb2;
	isc_region_t r1, r2;
	dns_fixedname_t foundname;
	dns_name_t *fname;
	unsigned int options = 0, zcoptions;
	isc_time_t start, finish;
	char *origintext;
	dbinfo *dbi;
	dns_dbversion_t *version;
	dns_name_t *origin;
	size_t memory_quota = 0;
	dns_trust_t trust = 0;
	unsigned int addopts;
	isc_log_t *lctx = NULL;
	size_t n;

	dns_result_register();

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) ==
		      ISC_R_SUCCESS);



	strcpy(dbtype, "rbt");
	while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT"))
	       != -1) {
		switch (ch) {
		case 'c':
			result = load(isc_commandline_argument, ".", ISC_TRUE);
			if (result != ISC_R_SUCCESS)
				printf("cache load(%s) %08x: %s\n",
				       isc_commandline_argument, result,
				       isc_result_totext(result));
			break;
		case 'd':
			n = strlcpy(dbtype, isc_commandline_argument,
				    sizeof(dbtype));
			if (n >= sizeof(dbtype)) {
				fprintf(stderr, "bad db type '%s'\n",
					isc_commandline_argument);
				exit(1);
			}
			break;
		case 'g':
			options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE);
			break;
		case 'l':
			RUNTIME_CHECK(isc_log_create(mctx, &lctx,
						     NULL) == ISC_R_SUCCESS);
			isc_log_setcontext(lctx);
			dns_log_init(lctx);
			dns_log_setcontext(lctx);
			break;
		case 'q':
			quiet = ISC_TRUE;
			verbose = ISC_FALSE;
			break;
		case 'p':
			printnode = ISC_TRUE;
			break;
		case 'P':
			pause_every = atoi(isc_commandline_argument);
			break;
		case 'Q':
			memory_quota = atoi(isc_commandline_argument);
			isc_mem_setquota(mctx, memory_quota);
			break;
		case 't':
			type = atoi(isc_commandline_argument);
			break;
		case 'T':
			time_lookups = ISC_TRUE;
			break;
		case 'v':
			verbose = ISC_TRUE;
			break;
		case 'z':
			origintext = strrchr(isc_commandline_argument, '/');
			if (origintext == NULL)
				origintext = isc_commandline_argument;
			else
				origintext++;	/* Skip '/'. */
			result = load(isc_commandline_argument, origintext,
				      ISC_FALSE);
			if (result != ISC_R_SUCCESS)
				printf("zone load(%s) %08x: %s\n",
				       isc_commandline_argument, result,
				       isc_result_totext(result));
			break;
		}
	}

	argc -= isc_commandline_index;
	argv += isc_commandline_index;
	POST(argv);

	if (argc != 0)
		printf("ignoring trailing arguments\n");

	/*
	 * Some final initialization...
	 */
	dns_fixedname_init(&foundname);
	fname = dns_fixedname_name(&foundname);
	dbi = NULL;
	origin = dns_rootname;
	version = NULL;

	if (time_lookups) {
		TIME_NOW(&start);
	}

	while (!done) {
		if (!quiet)
			printf("\n");
		if (fgets(s, sizeof(s), stdin) == NULL) {
			done = ISC_TRUE;
			continue;
		}
		len = strlen(s);
		if (len > 0U && s[len - 1] == '\n') {
			s[len - 1] = '\0';
			len--;
		}
		if (verbose && dbi != NULL) {
			if (dbi->wversion != NULL)
				printf("future version (%p)\n", dbi->wversion);
			for (i = 0; i < dbi->rcount; i++)
				if (dbi->rversions[i] != NULL)
					printf("open version %d (%p)\n", i,
					       dbi->rversions[i]);
		}
		dns_name_init(&name, offsets);
		if (strcmp(s, "!R") == 0) {
			DBI_CHECK(dbi);
			if (dbi->rcount == MAXVERSIONS) {
				printf("too many open versions\n");
				continue;
			}
			dns_db_currentversion(dbi->db,
					      &dbi->rversions[dbi->rcount]);
			printf("opened version %d\n", dbi->rcount);
			dbi->version = dbi->rversions[dbi->rcount];
			version = dbi->version;
			dbi->rcount++;
			continue;
		} else if (strcmp(s, "!W") == 0) {
			DBI_CHECK(dbi);
			if (dbi->wversion != NULL) {
				printf("using existing future version\n");
				dbi->version = dbi->wversion;
				version = dbi->version;
				continue;
			}
			result = dns_db_newversion(dbi->db, &dbi->wversion);
			if (result != ISC_R_SUCCESS)
				print_result("", result);
			else
				printf("newversion\n");
			dbi->version = dbi->wversion;
			version = dbi->version;
			continue;
		} else if (strcmp(s, "!C") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			delmode = ISC_FALSE;
			if (dbi->version == NULL)
				continue;
			if (dbi->version == dbi->wversion) {
				printf("closing future version\n");
				dbi->wversion = NULL;
			} else {
				for (i = 0; i < dbi->rcount; i++) {
					if (dbi->version ==
					    dbi->rversions[i]) {
						dbi->rversions[i] = NULL;
					  printf("closing open version %d\n",
						 i);
						break;
					}
				}
			}
			dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE);
			version = NULL;
			continue;
		} else if (strcmp(s, "!X") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			delmode = ISC_FALSE;
			if (dbi->version == NULL)
				continue;
			if (dbi->version == dbi->wversion) {
				printf("aborting future version\n");
				dbi->wversion = NULL;
			} else {
				for (i = 0; i < dbi->rcount; i++) {
					if (dbi->version ==
					    dbi->rversions[i]) {
						dbi->rversions[i] = NULL;
					  printf("closing open version %d\n",
						 i);
						break;
					}
				}
			}
			dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE);
			version = NULL;
			continue;
		} else if (strcmp(s, "!A") == 0) {
			DBI_CHECK(dbi);
			delmode = ISC_FALSE;
			if (addmode)
				addmode = ISC_FALSE;
			else
				addmode = ISC_TRUE;
			printf("addmode = %s\n", addmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!D") == 0) {
			DBI_CHECK(dbi);
			addmode = ISC_FALSE;
			if (delmode)
				delmode = ISC_FALSE;
			else
				delmode = ISC_TRUE;
			printf("delmode = %s\n", delmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!H") == 0) {
			DBI_CHECK(dbi);
			if (holdmode)
				holdmode = ISC_FALSE;
			else
				holdmode = ISC_TRUE;
			printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!HR") == 0) {
			DBI_CHECK(dbi);
			for (i = 0; i < dbi->hold_count; i++)
				dns_db_detachnode(dbi->db,
						  &dbi->hold_nodes[i]);
			dbi->hold_count = 0;
			holdmode = ISC_FALSE;
			printf("held nodes have been detached\n");
			continue;
		} else if (strcmp(s, "!VC") == 0) {
			DBI_CHECK(dbi);
			printf("switching to current version\n");
			dbi->version = NULL;
			version = NULL;
			continue;
		} else if (strstr(s, "!V") == s) {
			DBI_CHECK(dbi);
			v = atoi(&s[2]);
			if (v >= dbi->rcount || v < 0) {
				printf("unknown open version %d\n", v);
				continue;
			}
			if (dbi->rversions[v] == NULL) {
				printf("version %d is not open\n", v);
				continue;
			}
			printf("switching to open version %d\n", v);
			dbi->version = dbi->rversions[v];
			version = dbi->version;
			continue;
		} else if (strstr(s, "!TR") == s) {
			trust = (unsigned int)atoi(&s[3]);
			printf("trust level is now %u\n", (unsigned int)trust);
			continue;
		} else if (strstr(s, "!T") == s) {
			type = (unsigned int)atoi(&s[2]);
			printf("now searching for type %u\n", type);
			continue;
		} else if (strcmp(s, "!G") == 0) {
			if ((options & DNS_DBFIND_GLUEOK) != 0)
				options &= ~DNS_DBFIND_GLUEOK;
			else
				options |= DNS_DBFIND_GLUEOK;
			printf("glue ok = %s\n",
			       ((options & DNS_DBFIND_GLUEOK) != 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!GV") == 0) {
			if ((options & DNS_DBFIND_VALIDATEGLUE) != 0)
				options &= ~DNS_DBFIND_VALIDATEGLUE;
			else
				options |= DNS_DBFIND_VALIDATEGLUE;
			printf("validate glue = %s\n",
			       ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!WC") == 0) {
			if ((options & DNS_DBFIND_NOWILD) != 0)
				options &= ~DNS_DBFIND_NOWILD;
			else
				options |= DNS_DBFIND_NOWILD;
			printf("wildcard matching = %s\n",
			       ((options & DNS_DBFIND_NOWILD) == 0) ?
			       "TRUE" : "FALSE");
			continue;
		} else if (strstr(s, "!LS ") == s) {
			DBI_CHECK(dbi);
			list(dbi, &s[4]);
			continue;
		} else if (strcmp(s, "!LS") == 0) {
			DBI_CHECK(dbi);
			list(dbi, NULL);
			continue;
		} else if (strstr(s, "!DU ") == s) {
			DBI_CHECK(dbi);
			result = dns_db_dump(dbi->db, dbi->version, s+4);
			if (result != ISC_R_SUCCESS) {
				printf("\n");
				print_result("", result);
			}
			continue;
		} else if (strcmp(s, "!PN") == 0) {
			if (printnode)
				printnode = ISC_FALSE;
			else
				printnode = ISC_TRUE;
			printf("printnode = %s\n",
			       printnode ? "TRUE" : "FALSE");
			continue;
		} else if (strstr(s, "!P") == s) {
			DBI_CHECK(dbi);
			v = atoi(&s[2]);
			dbi->pause_every = v;
			continue;
		} else if (strcmp(s, "!+") == 0) {
			DBI_CHECK(dbi);
			dbi->ascending = ISC_TRUE;
			continue;
		} else if (strcmp(s, "!-") == 0) {
			DBI_CHECK(dbi);
			dbi->ascending = ISC_FALSE;
			continue;
		} else if (strcmp(s, "!DB") == 0) {
			dbi = NULL;
			origin = dns_rootname;
			version = NULL;
			printf("now searching all databases\n");
			continue;
		} else if (strncmp(s, "!DB ", 4) == 0) {
			dbi = select_db(s+4);
			if (dbi != NULL) {
				db = dbi->db;
				origin = dns_db_origin(dbi->db);
				version = dbi->version;
				addmode = ISC_FALSE;
				delmode = ISC_FALSE;
				holdmode = ISC_FALSE;
			} else {
				db = NULL;
				version = NULL;
				origin = dns_rootname;
				printf("database not found; "
				       "now searching all databases\n");
			}
			continue;
		} else if (strcmp(s, "!ZC") == 0) {
			if (find_zonecut)
				find_zonecut = ISC_FALSE;
			else
				find_zonecut = ISC_TRUE;
			printf("find_zonecut = %s\n",
			       find_zonecut ? "TRUE" : "FALSE");
			continue;
		} else if (strcmp(s, "!NZ") == 0) {
			if (noexact_zonecut)
				noexact_zonecut = ISC_FALSE;
			else
				noexact_zonecut = ISC_TRUE;
			printf("noexact_zonecut = %s\n",
			       noexact_zonecut ? "TRUE" : "FALSE");
			continue;
		}

		isc_buffer_init(&source, s, len);
		isc_buffer_add(&source, len);
		isc_buffer_init(&target, b, sizeof(b));
		result = dns_name_fromtext(&name, &source, origin, 0, &target);
		if (result != ISC_R_SUCCESS) {
			print_result("bad name: ", result);
			continue;
		}

		if (dbi == NULL) {
			zcoptions = 0;
			if (noexact_zonecut)
				zcoptions |= DNS_DBTABLEFIND_NOEXACT;
			db = NULL;
			result = dns_dbtable_find(dbtable, &name, zcoptions,
						  &db);
			if (result != ISC_R_SUCCESS &&
			    result != DNS_R_PARTIALMATCH) {
				if (!quiet) {
					printf("\n");
					print_result("", result);
				}
				continue;
			}
			isc_buffer_init(&tb1, t1, sizeof(t1));
			result = dns_name_totext(dns_db_origin(db), ISC_FALSE,
						 &tb1);
			if (result != ISC_R_SUCCESS) {
				printf("\n");
				print_result("", result);
				dns_db_detach(&db);
				continue;
			}
			isc_buffer_usedregion(&tb1, &r1);
			printf("\ndatabase = %.*s (%s)\n",
			       (int)r1.length, r1.base,
			       (dns_db_iszone(db)) ? "zone" : "cache");
		}
		node = NULL;
		dns_rdataset_init(&rdataset);
		dns_rdataset_init(&sigrdataset);

		if (find_zonecut && dns_db_iscache(db)) {
			zcoptions = options;
			if (noexact_zonecut)
				zcoptions |= DNS_DBFIND_NOEXACT;
			result = dns_db_findzonecut(db, &name, zcoptions,
						    0, &node, fname,
						    &rdataset, &sigrdataset);
		} else {
			result = dns_db_find(db, &name, version, type,
					     options, 0, &node, fname,
					     &rdataset, &sigrdataset);
		}

		if (!quiet) {
			if (dbi != NULL)
				printf("\n");
			print_result("", result);
		}

		found_as = ISC_FALSE;
		switch (result) {
		case ISC_R_SUCCESS:
		case DNS_R_GLUE:
		case DNS_R_CNAME:
		case DNS_R_ZONECUT:
			break;
		case DNS_R_DNAME:
		case DNS_R_DELEGATION:
			found_as = ISC_TRUE;
			break;
		case DNS_R_NXRRSET:
			if (dns_rdataset_isassociated(&rdataset))
				break;
			if (dbi != NULL) {
				if (holdmode) {
					RUNTIME_CHECK(dbi->hold_count <
						      MAXHOLD);
					dbi->hold_nodes[dbi->hold_count++] =
						node;
					node = NULL;
				} else
					dns_db_detachnode(db, &node);
			} else {
				dns_db_detachnode(db, &node);
				dns_db_detach(&db);
			}
			continue;
		case DNS_R_NXDOMAIN:
			if (dns_rdataset_isassociated(&rdataset))
				break;
			/* FALLTHROUGH */
		default:
			if (dbi == NULL)
				dns_db_detach(&db);
			if (quiet)
				print_result("", result);
			continue;
		}
		if (found_as && !quiet) {
			isc_buffer_init(&tb1, t1, sizeof(t1));
			isc_buffer_init(&tb2, t2, sizeof(t2));
			result = dns_name_totext(&name, ISC_FALSE, &tb1);
			if (result != ISC_R_SUCCESS) {
				print_result("", result);
				dns_db_detachnode(db, &node);
				if (dbi == NULL)
					dns_db_detach(&db);
				continue;
			}
			result = dns_name_totext(fname, ISC_FALSE, &tb2);
			if (result != ISC_R_SUCCESS) {
				print_result("", result);
				dns_db_detachnode(db, &node);
				if (dbi == NULL)
					dns_db_detach(&db);
				continue;
			}
			isc_buffer_usedregion(&tb1, &r1);
			isc_buffer_usedregion(&tb2, &r2);
			printf("found %.*s as %.*s\n",
			       (int)r1.length, r1.base,
			       (int)r2.length, r2.base);
		}

		if (printnode)
			dns_db_printnode(db, node, stdout);

		if (!found_as && type == dns_rdatatype_any) {
			rdsiter = NULL;
			result = dns_db_allrdatasets(db, node, version, 0,
						     &rdsiter);
			if (result == ISC_R_SUCCESS) {
				if (!quiet)
					print_rdatasets(fname, rdsiter);
				dns_rdatasetiter_destroy(&rdsiter);
			} else
				print_result("", result);
		} else {
			if (!quiet)
				print_rdataset(fname, &rdataset);
			if (dns_rdataset_isassociated(&sigrdataset)) {
				if (!quiet)
					print_rdataset(fname, &sigrdataset);
				dns_rdataset_disassociate(&sigrdataset);
			}
			if (dbi != NULL && addmode && !found_as) {
				rdataset.ttl++;
				rdataset.trust = trust;
				if (dns_db_iszone(db))
					addopts = DNS_DBADD_MERGE;
				else
					addopts = 0;
				result = dns_db_addrdataset(db, node, version,
							    0, &rdataset,
							    addopts, NULL);
				if (result != ISC_R_SUCCESS)
					print_result("", result);
				if (printnode)
					dns_db_printnode(db, node, stdout);
			} else if (dbi != NULL && delmode && !found_as) {
				result = dns_db_deleterdataset(db, node,
							       version, type,
							       0);
				if (result != ISC_R_SUCCESS)
					print_result("", result);
				if (printnode)
					dns_db_printnode(db, node, stdout);
			}
			dns_rdataset_disassociate(&rdataset);
		}

		if (dbi != NULL) {
			if (holdmode) {
				RUNTIME_CHECK(dbi->hold_count < MAXHOLD);
				dbi->hold_nodes[dbi->hold_count++] = node;
				node = NULL;
			} else
				dns_db_detachnode(db, &node);
		} else {
			dns_db_detachnode(db, &node);
			dns_db_detach(&db);
		}
	}

	if (time_lookups) {
		isc_uint64_t usec;

		TIME_NOW(&finish);

		usec = isc_time_microdiff(&finish, &start);

		printf("elapsed time: %lu.%06lu seconds\n",
		       (unsigned long)(usec / 1000000),
		       (unsigned long)(usec % 1000000));
	}

	unload_all();

	dns_dbtable_detach(&dbtable);

	if (lctx != NULL)
		isc_log_destroy(&lctx);

	if (!quiet)
		isc_mem_stats(mctx, stdout);

	return (0);
}
Exemple #25
0
/*!
 * Event loop for nonthreaded programs.
 */
static isc_result_t
evloop() {
	isc_result_t result;
	while (!want_shutdown) {
		int n;
		isc_time_t when, now;
		struct timeval tv, *tvp;
		fd_set *readfds, *writefds;
		int maxfd;
		isc_boolean_t readytasks;
		isc_boolean_t call_timer_dispatch = ISC_FALSE;

		readytasks = isc__taskmgr_ready();
		if (readytasks) {
			tv.tv_sec = 0;
			tv.tv_usec = 0;
			tvp = &tv;
			call_timer_dispatch = ISC_TRUE;
		} else {
			result = isc__timermgr_nextevent(&when);
			if (result != ISC_R_SUCCESS)
				tvp = NULL;
			else {
				isc_uint64_t us;

				TIME_NOW(&now);
				us = isc_time_microdiff(&when, &now);
				if (us == 0)
					call_timer_dispatch = ISC_TRUE;
				tv.tv_sec = us / 1000000;
				tv.tv_usec = us % 1000000;
				tvp = &tv;
			}
		}

		isc__socketmgr_getfdsets(&readfds, &writefds, &maxfd);
		n = select(maxfd, readfds, writefds, NULL, tvp);

		if (n == 0 || call_timer_dispatch) {
			/*
			 * We call isc__timermgr_dispatch() only when
			 * necessary, in order to reduce overhead.  If the
			 * select() call indicates a timeout, we need the
			 * dispatch.  Even if not, if we set the 0-timeout 
			 * for the select() call, we need to check the timer
			 * events.  In the 'readytasks' case, there may be no
			 * timeout event actually, but there is no other way
			 * to reduce the overhead.
			 * Note that we do not have to worry about the case
			 * where a new timer is inserted during the select()
			 * call, since this loop only runs in the non-thread
			 * mode.
			 */
			isc__timermgr_dispatch();
		}
		if (n > 0)
			(void)isc__socketmgr_dispatch(readfds, writefds,
						      maxfd);
		(void)isc__taskmgr_dispatch();

		if (want_reload) {
			want_reload = ISC_FALSE;
			return (ISC_R_RELOAD);
		}
	}
	return (ISC_R_SUCCESS);
}
Exemple #26
0
int main (int argc, char *argv[])
{
    isc_taskmgr_t *manager = NULL;

    isc_timermgr_t *timgr = NULL;

    unsigned int workers;

    isc_time_t expires, now;

    isc_interval_t interval;

    if (argc > 1)
        workers = atoi (argv[1]);
    else
        workers = 2;
    printf ("%d workers\n", workers);

    RUNTIME_CHECK (isc_mem_create (0, 0, &mctx1) == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_taskmgr_create (mctx1, workers, 0, &manager) == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_timermgr_create (mctx1, &timgr) == ISC_R_SUCCESS);

    RUNTIME_CHECK (isc_task_create (manager, 0, &t1) == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_task_create (manager, 0, &t2) == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_task_create (manager, 0, &t3) == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_task_onshutdown (t1, shutdown_task, "1") == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_task_onshutdown (t2, shutdown_task, "2") == ISC_R_SUCCESS);
    RUNTIME_CHECK (isc_task_onshutdown (t3, shutdown_task, "3") == ISC_R_SUCCESS);

    printf ("task 1: %p\n", t1);
    printf ("task 2: %p\n", t2);
    printf ("task 3: %p\n", t3);

    TIME_NOW (&now);

    isc_interval_set (&interval, 2, 0);
    RUNTIME_CHECK (isc_timer_create (timgr, isc_timertype_once, NULL,
                                     &interval, t2, timeout, "2", &ti2) == ISC_R_SUCCESS);

    isc_interval_set (&interval, 1, 0);
    RUNTIME_CHECK (isc_timer_create (timgr, isc_timertype_ticker, NULL,
                                     &interval, t1, tick, "1", &ti1) == ISC_R_SUCCESS);

    isc_interval_set (&interval, 10, 0);
    RUNTIME_CHECK (isc_time_add (&now, &interval, &expires) == ISC_R_SUCCESS);
    isc_interval_set (&interval, 2, 0);
    RUNTIME_CHECK (isc_timer_create (timgr, isc_timertype_once, &expires,
                                     &interval, t3, timeout, "3", &ti3) == ISC_R_SUCCESS);

    isc_task_detach (&t1);
    isc_task_detach (&t2);
    isc_task_detach (&t3);

    sleep (15);
    printf ("destroy\n");
    isc_timer_detach (&ti1);
    isc_timer_detach (&ti2);
    isc_timer_detach (&ti3);
    sleep (2);
    isc_timermgr_destroy (&timgr);
    isc_taskmgr_destroy (&manager);
    printf ("destroyed\n");

    printf ("Statistics for mctx1:\n");
    isc_mem_stats (mctx1, stdout);
    isc_mem_destroy (&mctx1);

    return (0);
}