view thrlib/totals.c @ 4:d329bb5c36d0

Changes making it compile the new upstream release
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 14:57:12 +0100
parents c7f6b056b673
children
line wrap: on
line source

/* Distributed Checksum Clearinghouse
 *
 * count work
 *
 * Copyright (c) 2008 by Rhyolite Software, LLC
 *
 * This agreement is not applicable to any entity which sells anti-spam
 * solutions to others or provides an anti-spam solution as part of a
 * security solution sold to other entities, or to a private network
 * which employs the DCC or uses data provided by operation of the DCC
 * but does not provide corresponding data to other users.
 *
 * Permission to use, copy, modify, and distribute this software without
 * changes for any purpose with or without fee is hereby granted, provided
 * that the above copyright notice and this permission notice appear in all
 * copies and any distributed versions or copies are either unchanged
 * or not called anything similar to "DCC" or "Distributed Checksum
 * Clearinghouse".
 *
 * Parties not eligible to receive a license under this agreement can
 * obtain a commercial license to use DCC by contacting Rhyolite Software
 * at sales@rhyolite.com.
 *
 * A commercial license would be for Distributed Checksum and Reputation
 * Clearinghouse software.  That software includes additional features.  This
 * free license for Distributed ChecksumClearinghouse Software does not in any
 * way grant permision to use Distributed Checksum and Reputation Clearinghouse
 * software
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * Rhyolite Software DCC 1.3.103-1.19 $Revision$
 */


#include "cmn_defs.h"
#include "helper.h"
#include <signal.h>


TOTALS totals;
static time_t signaled;
static pthread_t totals_tid;
static u_char stopping;

static void totals_msg_signal(int);
static void *totals_msg_thread(void *);



static void
totals_msg_signal(int sig UATTRIB)
{
	time_t now;

	signal(SIGUSR1, totals_msg_signal);

	now = time(0);
	/* ignore signals faster than 60 seconds */
	if (!signaled || now > signaled+60) {
		signaled = now;
		totals.msg_next = signaled;
	}
}



static void * NRATTRIB
totals_msg_thread(void *ign UATTRIB)
{
	time_t now, next, last_clean;
	struct tm tm, signaled_tm;
	int secs;

	clnt_sigs_off(0);

	last_clean = time(0);
	for (;;) {
		if (stopping)
			pthread_exit(0);

		reap_helpers(0);

		now = time(0);
		next = totals.msg_next;
		if (now >= next && next != 0) {
			totals_msg();
			next = 0;
		}

		if (!next) {
			/* make a note to announce totals at midnight
			 * or 24 hours after the signal */
			dcc_localtime(totals.msg_prev, &tm);
			if (signaled != 0) {
				dcc_localtime(signaled, &signaled_tm);
				tm.tm_hour = signaled_tm.tm_hour;
				tm.tm_min = signaled_tm.tm_min;
			} else {
				tm.tm_hour = 0;
				tm.tm_min = 0;
			}
			tm.tm_sec = 0;
			++tm.tm_mday;
			next = mktime(&tm);
			if (next == -1) {
				dcc_error_msg("mktime() failed");
				next = now + 24*60*60;
			}
			totals.msg_next = next;

		}

		/* tell dccifd or dccm to close old sockets to recover
		 * from dictionary attacks */
		if (last_clean > now || last_clean+5*60 < now) {
			last_clean = now;
			work_clean();
		}

		secs = next - now;
		if (secs > 0) {
			/* reap helpers regularly */
			if (secs > HELPER_AUTO_REAP)
				secs = HELPER_AUTO_REAP;
			sleep(secs);
		}
	}
}



void
totals_init(void)
{
	int i;

	signal(SIGUSR1, totals_msg_signal);
	totals.msg_prev = time(0);

	i = pthread_create(&totals_tid, 0, totals_msg_thread, 0);
	if (i)
		dcc_logbad(EX_SOFTWARE, "pthread_create(totals msg): %s",
			   ERROR_STR1(i));
	i = pthread_detach(totals_tid);
	if (i)
		dcc_error_msg("pthread_detach(totals msg): %s",
			      ERROR_STR1(i));
}



void
totals_stop(void)
{
	stopping = 1;
	totals_msg();
}



/* brag about our accomplishments */
void
totals_msg(void)
{
	time_t now;
	char tbuf[20];
	char gbuf[80];
	sigset_t sigsold;
	int error;

	clnt_sigs_off(&sigsold);

	lock_work();
	now = time(0);

	if (grey_on)
		snprintf(gbuf, sizeof(gbuf),
			 " greylist embargoed %d messages to %d targets;",
			 totals.msgs_embargoed, totals.tgts_embargoed);
	else
		gbuf[0] = '\0';

	dcc_trace_msg(DCC_VERSION
		      "%s detected %d spam, ignored for %d, rejected for %d,"
		      " and discarded for %d targets among"
		      " %d total messages for %d targets since %s",
		      gbuf,
		      totals.msgs_spam, totals.tgts_ignored,
		      totals.tgts_rejected, totals.tgts_discarded,
		      totals.msgs, totals.tgts,
		      dcc_time2str(tbuf, sizeof(tbuf), "%x %X",
				   totals.msg_prev));

	memset(&totals, 0, sizeof(totals));
	totals.msg_prev = now;
	unlock_work();

	error = pthread_sigmask(SIG_SETMASK, &sigsold, 0);
	if (error)
		dcc_logbad(EX_SOFTWARE, "pthread_sigmask(totals): %s",
			   ERROR_STR1(error));
}