int delay;
int retry_window;
int client_awl;
+ int max_age;
TCBDB *awl_db;
TCBDB *obj_db;
.delay = 300, \
.retry_window = 2 * 24 * 3600, \
.client_awl = 5, \
+ .max_age = 35 * 3600, \
.awl_db = NULL, \
.obj_db = NULL }
return cnet;
}
+static inline bool greylist_check_awlentry(const greylist_config_t *config,
+ struct awl_entry *aent, time_t now)
+{
+ return !(now - aent->last > config->max_age);
+}
+
+static inline bool greylist_check_object(const greylist_config_t *config,
+ const struct obj_entry *oent, time_t now)
+{
+ return !(now - oent->last > config->max_age
+ || (oent->last - oent->first < config->delay
+ && now - oent->last > config->retry_window));
+}
+
static bool try_greylist(const greylist_config_t *config,
const char *sender, const char *c_addr,
const char *c_name, const char *rcpt)
memcpy(&aent, res, len);
}
+ if (!greylist_check_awlentry(config, &aent, now)) {
+ aent.count = 0;
+ aent.last = 0;
+ }
+
/* Whitelist if count is enough.
*/
if (aent.count >= config->client_awl) {
res = tcbdbget3(config->obj_db, key, klen, &len);
if (res && len == sizeof(oent)) {
memcpy(&oent, res, len);
+ greylist_check_object(config, &oent, now);
}
/* Discard stored first-seen if it is the first retrial and
- * it is beyong the retry window.
+ * it is beyong the retry window and too old entries.
*/
- if (oent.last - oent.first < config->delay
- && now - oent.first > config->retry_window) {
+ if (!greylist_check_object(config, &oent, now)) {
oent.first = now;
}
FILTER_PARAM_PARSE_INT(RETRY_WINDOW, config->retry_window);
FILTER_PARAM_PARSE_INT(CLIENT_AWL, config->client_awl);
FILTER_PARAM_PARSE_INT(DELAY, config->delay);
+ FILTER_PARAM_PARSE_INT(MAX_AGE, config->max_age);
default: break;
}
(void)filter_param_register(type, "delay");
(void)filter_param_register(type, "retry_window");
(void)filter_param_register(type, "client_awl");
+ (void)filter_param_register(type, "max_age");
(void)filter_param_register(type, "path");
(void)filter_param_register(type, "prefix");
return 0;