31 #define HOUR * 60 MINUTE 37 #define DEBUG_LEVEL 19 55 {
RATE_CONN,
"ze-conn.data",
"Connection Rate", 10
MINUTE, NULL, 1.0, NULL},
56 {
RATE_RCPT,
"ze-rcpt.data",
"Recipient Rate", 10
MINUTE, NULL, 1.0, NULL},
58 {
RATE_MSGS,
"ze-msgs.data",
"Message Rate", 10
MINUTE, NULL, 1.0, NULL},
61 {
RATE_SCORE,
"ze-score.data",
"Spam Score Rate", 10
MINUTE, NULL, 1.0, NULL},
66 {
RATE_FROM_CONN,
"ze-fromconn.data",
"Connection Rate by sender address",
67 20
MINUTE, NULL, 1.0, NULL},
68 {
RATE_FROM_MSGS,
"ze-frommsgs.data",
"Message Rate by sender address",
69 20
MINUTE, NULL, 1.0, NULL},
70 {
RATE_FROM_RCPT,
"ze-fromrcpt.data",
"Recipient Rate by sender address",
71 20
MINUTE, NULL, 1.0, NULL},
73 20
MINUTE, NULL, 1.0, NULL},
75 20
MINUTE, NULL, 1.0, NULL},
76 {
RATE_AUTH_RCPT,
"ze-authrcpt.data",
"Recipient Rate by AUTH login",
77 20
MINUTE, NULL, 1.0, NULL},
79 {-1, NULL, NULL, 0, NULL, 1., NULL}
94 static size_t DIM_HIST = 0x4000;
95 static size_t DIM_RES = 0x1000;
134 #define RATEHIST_INITIALIZER {NULL,0,0} 153 #define DATA_LOCK() MUTEX_LOCK(&hdata.mutex) 155 #define DATA_UNLOCK() MUTEX_UNLOCK(&hdata.mutex) 157 static int res_t_cmp_by_addr(
void *,
void *);
158 static int res_t_cmp_by_value(
void *,
void *);
159 static void update_res_t(
Res_T *, time_t);
166 res_t_cmp_by_addr(a, b)
175 if (ta == NULL || tb == NULL) {
183 return (strcmp(ta->
key, tb->
key));
187 res_t_cmp_by_value(a, b)
195 if (ta == NULL || tb == NULL) {
216 calc_bucket_rate(
bucket, which, now, wsz)
232 if (bucket[i].date *
SZ_BUCKET + wsz > now)
233 nb += bucket[i].nb[which];
240 update_res_t(res, now)
246 for (which = 0; which <
RATE_DIM; which++) {
247 if (rateDef[which].which < 0)
250 calc_bucket_rate(res->Srate, which, now, rateDef[which].
wsz);
251 res->nb[0][which] = calc_bucket_rate(res->Srate, which, now, 1
MINUTE);
252 res->nb[1][which] = calc_bucket_rate(res->Srate, which, now, 10
MINUTE);
253 res->nb[2][which] = calc_bucket_rate(res->Srate, which, now, 1
HOUR);
254 res->nb[3][which] = calc_bucket_rate(res->Srate, which, now, 2
HOUR);
277 memset(hdata.
hist, 0, sizeof (hdata.
hist));
278 memset(&hdata.
gres, 0, sizeof (hdata.
gres));
281 if ((sza != 0) && (szb != 0)) {
304 memset(&hdata.
gres, 0, sizeof (hdata.
gres));
334 memset(&hdata.
hist[i], 0, sizeof (hdata.
hist[i]));
392 if (which < 0 || which >= RATE_DIM)
395 if (rateDef[which].which < 0)
400 name =
STRNULL(name,
"UNKNOWN");
402 rptr = &hdata.
hist[which];
412 rptr->
ptr = (n + 1) % DIM_HIST;
413 if (rptr->
nb < DIM_HIST)
424 update_res_t(&hdata.
gres, t);
429 memset(&p, 0,
sizeof (p));
437 if (ptr->
Srate[ibucket].
date != tbucket) {
444 calc_bucket_rate(ptr->
Srate, which, t, rateDef[which].
wsz);
452 p.
rate[which] = calc_bucket_rate(p.
Srate, which, t, rateDef[which].
wsz);
464 n = calc_bucket_rate(hdata.
gres.
Srate, which, t, rateDef[which].
wsz);
487 time_t now = time(NULL);
492 memset(&p, 0,
sizeof (p));
500 if (which < 0 || which >= RATE_DIM)
503 if (rateDef[which].which < 0)
509 win = rateDef[which].
wsz;
510 if (strlen(key) > 0) {
512 res = calc_bucket_rate(t->
Srate, which, now, win);
514 res = calc_bucket_rate(hdata.
gres.
Srate, which, now, win);
527 static time_t cleanuptime = 0;
530 cleanup_select(vp, arg)
536 time_t *win = (time_t *) arg;
539 if (win != NULL && *win > 0)
543 if (p->
Srate[i].
date * SZ_BUCKET + nbb >= cleanuptime)
602 time_t now = time(NULL);
605 static bool save_it =
FALSE;
627 memset(&hdata.
gres, 0, sizeof (hdata.
gres));
629 for (which = 0; which <
RATE_DIM; which++) {
630 if (rateDef[which].which < 0)
636 for (i = 0; i < DIM_HIST; i++) {
639 if (h->
date == 0 || h->
nb == 0)
642 if (h->
date + w_width < now) {
647 if (strlen(h->
key) > 0) {
656 if (h->
date + rateDef[which].
wsz >= now) {
665 memset(&p, 0,
sizeof (p));
679 memset(&p, 0,
sizeof (p));
695 update_res_t(&hdata.
gres, now);
697 if (rateDef[which].which < 0)
700 if (rateDef[which].name == NULL)
704 rateDef[which].name, hdata.
gres.
rate[which]);
752 if (work_dir == NULL)
755 for (which = 0; which <
RATE_DIM; which++) {
756 if (rateDef[which].which < 0)
759 if (rateDef[which].fname == NULL || hdata.
hist[which].
data == NULL)
763 rateDef[which].name, rateDef[which].fname);
765 snprintf(fname,
sizeof (fname),
"%s/%s", work_dir, rateDef[which].fname);
766 if ((fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 00644)) >= 0) {
768 if (write(fd, hdata.
hist[which].
data, size) != size)
795 if (work_dir == NULL)
805 for (which = 0; which <
RATE_DIM; which++) {
806 if (rateDef[which].which < 0)
808 if (rateDef[which].fname == NULL)
810 if (rateDef[which].name == NULL)
816 rateDef[which].name, rateDef[which].fname);
818 snprintf(fname,
sizeof (fname),
"%s/%s", work_dir, rateDef[which].fname);
819 if ((fd = open(fname, O_RDONLY)) >= 0) {
821 if (read(fd, hdata.
hist[which].
data, size) != size)
827 for (i = 0, imax = 0, tmax = 0; i < DIM_HIST; i++) {
842 hdata.
hist[which].
ptr = imax + 1;
843 hdata.
hist[which].
ptr %= DIM_HIST;
864 for (i = 0; i < hdata.conn_nb; i++) {
865 if (hdata.rate_res[i].nb > 5)
867 hdata.rate_res[i].ip, hdata.rate_res[i].nb);
878 static int outfd = STDOUT_FILENO;
879 static pthread_mutex_t fdmutex = PTHREAD_MUTEX_INITIALIZER;
898 char nodename[256], *s;
900 time_t now = time(NULL);
904 if (p == NULL || sel == NULL)
913 memset(nodename, 0,
sizeof (nodename));
920 update_res_t(p, now);
923 if (rateDef[i].which < 0)
927 FD_PRINTF(outfd,
"- %4d %4d %4d ", p->
nb[0][i], p->
nb[1][i], p->
nb[2][i]);
944 time_t now = time(NULL);
951 if (rateDef[j].which < 0)
961 update_res_t(p, now);
982 time_t tmin = 0, tmax = 0, now;
983 unsigned long hh, mm, ss;
1000 FD_PRINTF(fd,
"*** THROTTLE TABLE (units each 10 minutes) at %s\n", s);
1002 for (which = 0; which <
RATE_DIM; which++) {
1003 if (rateDef[which].which < 0)
1006 if (rateDef[which].name == NULL)
1015 FD_PRINTF(fd,
"*** %-18s : %6ld/ 10 min (%ld entries)\n",
1016 rateDef[which].name, (
long int ) hdata.
gres.
nb[1][which],
1017 (
long int ) hdata.
hist[which].
nb);
1020 for (v = 0, i = 0; i < DIM_HIST; i++) {
1040 FD_PRINTF(fd,
" %-18s : %3ld:%02ld:%02ld (%ld/%ld entries)\n",
1041 "HISTORY", hh, mm, ss, (
long int ) v, (
long int ) DIM_HIST);
1056 memset(&sel, 0,
sizeof (sel));
1060 sel.
now = time(NULL);
1133 FD_PRINTF(fd,
"\n %d records handled \n\n", n);
1159 for (s = strtok_r(nstr,
",", &ptr); s != NULL;
1160 s = strtok_r(NULL,
",", &ptr)) {
1164 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1170 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1176 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1182 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1188 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1194 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1200 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1206 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1212 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1218 if (strncasecmp(s, tag, strlen(tag)) == 0) {
1224 if (strncasecmp(s, tag, strlen(tag)) == 0) {
bool zeBTree_Set_BTree_Size(ZEBT_T *, bool, int)
int smtprate_add_entry(int which, char *key, char *name, int nb, time_t t)
int smtprate_update_table(time_t w_width)
uint32_t smtprate_str2flags(char *str)
#define CACHE_GETHOSTNAMEBYADDR(ip, name, size, query)
void * zeBTree_Get(ZEBT_T *, void *)
bool zeBTree_Init(ZEBT_T *, size_t, ZEBT_CMP_F)
#define MUTEX_UNLOCK(mutex)
unsigned int smtprate_window
#define MUTEX_LOCK(mutex)
#define ZE_LogMsgInfo(level,...)
bool smtprate_cleanup_table(time_t now, time_t win)
bool zeBTree_Add(ZEBT_T *, void *)
#define ZE_LogMsgError(level,...)
struct Bucket_T bucket[K_MIN]
Bucket_T Srate[NB_BUCKET]
RateHist_T hist[RATE_DIM]
bool zeBTree_Destroy(ZEBT_T *)
#define FD_PRINTF(fdp,...)
bool smtprate_resize(size_t sza, size_t szb)
void add_throttle_entry(time_t)
int smtprate_read_table(char *filename)
unsigned int connrate_window
int zeBTree_Count(ZEBT_T *)
bool zeBTree_Clear(ZEBT_T *)
bool zeBTree_Cpy(ZEBT_T *, ZEBT_T *, ZEBT_SEL_F, void *)
#define ZE_MessageInfo(level,...)
#define ZE_LogSysError(...)
char * cf_get_str(int id)
#define ZE_LogMsgWarning(level,...)
int smtprate_check(int which, char *key, time_t win)
void update_throttle(time_t)
void smtprate_save_table(char *filename)
void smtprate_print_table(int fd, int allhosts, int verbose, bool hostnames, time_t win, uint32_t flags, int nbrecs)
struct HistEvt_T HistEvt_T
bool smtprate_init(size_t sza, size_t szb)
unsigned int smtprate_interval
void smtprate_log_table()
struct SmtpRate_T SmtpRate_T
bool zeBTree_Cleanup(ZEBT_T *, ZEBT_SEL_F, void *)
int zeBTree_Browse(ZEBT_T *, ZEBT_BROWSE_F, void *)