예제 #1
0
static void
is_broken(WF *wf)
{
	wf->broken = time(0) + WHITE_BROKEN_DELAY;

	/* This is racy, but the worst that can happen is that
	 * another process races to set the retry timer */
	if (!(wf->wf_flags & WF_RO) && wf->wtbl) {
		wf->wtbl->hdr.broken = wf->broken;
		sync_white(wf);
	}
}
예제 #2
0
static void
unmap_white_ht(WF *wf)
{
	if (!wf->wtbl)
		return;

	sync_white(wf);
#ifdef DCC_WIN32
	dcc_win32_unmap(&wf->ht_map, wf->wtbl, wf->ht_nm);
#else
	if (0 > munmap((void *)wf->wtbl, wf->wtbl_size))
		dcc_error_msg("munmap(%s,%d): %s",
			      wf->ht_nm, wf->wtbl_size, ERROR_STR());
#endif
	wf->wtbl = 0;
}
예제 #3
0
int
dbupdate(char *dbname, char *ip)
{
	HASHINFO	hashinfo;
	DBT		dbk, dbd;
	DB		*db;
	struct gdata	gd;
	time_t		now;
	int		r;
	struct in_addr	ia;

	now = time(NULL);
	memset(&hashinfo, 0, sizeof(hashinfo));
	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_HASH, &hashinfo);
	if (db == NULL) {
		logmsg(LOG_ERR, "Can not open db %s: %s", dbname,
		    strerror(errno));
		return (-1);
	}
	if (inet_pton(AF_INET, ip, &ia) != 1) {
		logmsg(LOG_NOTICE, "Invalid IP address %s", ip);
		goto bad;
	}
	memset(&dbk, 0, sizeof(dbk));
	dbk.size = strlen(ip);
	dbk.data = ip;
	memset(&dbd, 0, sizeof(dbd));

	/* add or update whitelist entry */
	r = db->get(db, &dbk, &dbd, 0);
	if (r == -1) {
		logmsg(LOG_NOTICE, "db->get failed (%m)");
		goto bad;
	}

	if (r) {
		/* new entry */
		memset(&gd, 0, sizeof(gd));
		gd.first = now;
		gd.bcount = 1;
		gd.pass = now;
		gd.expire = now + whiteexp;
		memset(&dbk, 0, sizeof(dbk));
		dbk.size = strlen(ip);
		dbk.data = ip;
		memset(&dbd, 0, sizeof(dbd));
		dbd.size = sizeof(gd);
		dbd.data = &gd;
		r = db->put(db, &dbk, &dbd, 0);
		if (r) {
			logmsg(LOG_NOTICE, "db->put failed (%m)");
			goto bad;
		}
	} else {
		if (dbd.size != sizeof(gd)) {
			/* whatever this is, it doesn't belong */
			db->del(db, &dbk, 0);
			goto bad;
		}
		memcpy(&gd, dbd.data, sizeof(gd));
		gd.pcount++;
		gd.expire = now + whiteexp;
		memset(&dbk, 0, sizeof(dbk));
		dbk.size = strlen(ip);
		dbk.data = ip;
		memset(&dbd, 0, sizeof(dbd));
		dbd.size = sizeof(gd);
		dbd.data = &gd;
		r = db->put(db, &dbk, &dbd, 0);
		if (r) {
			logmsg(LOG_NOTICE, "db->put failed (%m)");
			goto bad;
		}
	}
	db->close(db);
	db = NULL;
	if (syncsend)
		sync_white(now, now + whiteexp, ip);
	return (0);
 bad:
	db->close(db);
	db = NULL;
	return (-1);
}