The attached patch numbers all postscreen(8) DNSBL requests, so that delayed DNSBL results for an old session are not added to the score when the same remote SMTP client has reconnected in the mean time.
This error was rare enough that it should not affect real email. Use "postfix reload" after "make upgrade" on a running Postfix system. This is needed because the protocol between postscreen(8) and dnsblog(8) has changed. Wietse
20110313 Bugfix (introduced Postfix 2.8): number the postscreen DNSBL requests, so that delayed results for an old session are not added to the score when the same remote SMTP client has reconnected in the mean time. Files: postscreen/postscreen_dnsbl.c, dnsblog/dnsblog.c. diff --exclude=man --exclude=html --exclude=README_FILES --exclude=.indent.pro --exclude=Makefile.in -r -cr /var/tmp/postfix-2.9-20110228/src/dnsblog/dnsblog.c ./src/dnsblog/dnsblog.c *** /var/tmp/postfix-2.9-20110228/src/dnsblog/dnsblog.c Sun Jan 16 12:39:46 2011 --- ./src/dnsblog/dnsblog.c Sun Mar 13 14:41:05 2011 *************** *** 14,21 **** /* .ad /* .fi /* With each connection, the \fBdnsblog\fR(8) server receives ! /* a DNS white/blacklist domain name and an IP address. If the ! /* address is listed under the DNS white/blacklist, the /* \fBdnsblog\fR(8) server logs the match and replies with the /* query arguments plus a non-zero status. Otherwise it replies /* with the query arguments plus a zero status. Finally, The --- 14,21 ---- /* .ad /* .fi /* With each connection, the \fBdnsblog\fR(8) server receives ! /* a DNS white/blacklist domain name, IP address, and an ID. ! /* If the address is listed under the DNS white/blacklist, the /* \fBdnsblog\fR(8) server logs the match and replies with the /* query arguments plus a non-zero status. Otherwise it replies /* with the query arguments plus a zero status. Finally, The *************** *** 215,220 **** --- 215,221 ---- static void dnsblog_service(VSTREAM *client_stream, char *unused_service, char **argv) { + int request_id; /* * Sanity check. This service takes no command-line arguments. *************** *** 231,243 **** ATTR_FLAG_MORE | ATTR_FLAG_STRICT, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, rbl_domain, ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, addr, ! ATTR_TYPE_END) == 2) { (void) dnsblog_query(result, STR(rbl_domain), STR(addr)); if (var_dnsblog_delay > 0) sleep(var_dnsblog_delay); attr_print(client_stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, STR(rbl_domain), ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, STR(addr), ATTR_TYPE_STR, MAIL_ATTR_RBL_ADDR, STR(result), ATTR_TYPE_END); vstream_fflush(client_stream); --- 232,246 ---- ATTR_FLAG_MORE | ATTR_FLAG_STRICT, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, rbl_domain, ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, addr, ! ATTR_TYPE_INT, MAIL_ATTR_LABEL, &request_id, ! ATTR_TYPE_END) == 3) { (void) dnsblog_query(result, STR(rbl_domain), STR(addr)); if (var_dnsblog_delay > 0) sleep(var_dnsblog_delay); attr_print(client_stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, STR(rbl_domain), ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, STR(addr), + ATTR_TYPE_INT, MAIL_ATTR_LABEL, request_id, ATTR_TYPE_STR, MAIL_ATTR_RBL_ADDR, STR(result), ATTR_TYPE_END); vstream_fflush(client_stream); diff --exclude=man --exclude=html --exclude=README_FILES --exclude=.indent.pro --exclude=Makefile.in -r -cr /var/tmp/postfix-2.9-20110228/src/postscreen/postscreen_dnsbl.c ./src/postscreen/postscreen_dnsbl.c *** /var/tmp/postfix-2.9-20110228/src/postscreen/postscreen_dnsbl.c Sat Jan 15 18:09:25 2011 --- ./src/postscreen/postscreen_dnsbl.c Sun Mar 13 14:35:02 2011 *************** *** 143,148 **** --- 143,149 ---- int total; /* combined blocklist score */ int refcount; /* score reference count */ int pending_lookups; /* nr of DNS requests in flight */ + int request_id; /* duplicate suppression */ /* Call-back table support. */ int index; /* next table index */ int limit; /* last valid index */ *************** *** 344,349 **** --- 345,351 ---- PSC_DNSBL_HEAD *head; PSC_DNSBL_SITE *site; ARGV *reply_argv; + int request_id; PSC_CLEAR_EVENT_REQUEST(vstream_fileno(stream), psc_dnsbl_receive, context); *************** *** 367,376 **** ATTR_FLAG_STRICT, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, reply_dnsbl, ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, reply_client, ATTR_TYPE_STR, MAIL_ATTR_RBL_ADDR, reply_addr, ! ATTR_TYPE_END) == 3 && (score = (PSC_DNSBL_SCORE *) ! htable_find(dnsbl_score_cache, STR(reply_client))) != 0) { /* * Run this response past all applicable DNSBL filters and update the --- 369,380 ---- ATTR_FLAG_STRICT, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, reply_dnsbl, ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, reply_client, + ATTR_TYPE_INT, MAIL_ATTR_LABEL, &request_id, ATTR_TYPE_STR, MAIL_ATTR_RBL_ADDR, reply_addr, ! ATTR_TYPE_END) == 4 && (score = (PSC_DNSBL_SCORE *) ! htable_find(dnsbl_score_cache, STR(reply_client))) != 0 ! && score->request_id == request_id) { /* * Run this response past all applicable DNSBL filters and update the *************** *** 429,434 **** --- 433,439 ---- HTABLE_INFO **ht; PSC_DNSBL_SCORE *score; HTABLE_INFO *hash_node; + static int request_count; /* * Some spambots make several connections at nearly the same time, *************** *** 468,473 **** --- 473,479 ---- if (msg_verbose > 1) msg_info("%s: create blocklist score for %s", myname, client_addr); score = (PSC_DNSBL_SCORE *) mymalloc(sizeof(*score)); + score->request_id = request_count++; score->dnsbl = 0; score->total = 0; score->refcount = 1; *************** *** 492,497 **** --- 498,504 ---- attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, ht[0]->key, ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, client_addr, + ATTR_TYPE_INT, MAIL_ATTR_LABEL, score->request_id, ATTR_TYPE_END); if (vstream_fflush(stream) != 0) { msg_warn("%s: error sending to %s service: %m",