This is the fourth of several patches to limit the number of address verification requests in the Postfix mail queue.
This patch corrects mistakes in the third patch. - Dangling call-backs in post_mail_fclose_async() event handler. - The queue manager no longer recognized address verification requests. - The verify daemon now flags a request as pending before we have the final cleanup submission status, so that a report for a 1-to-many virtual alias will arrive when the pending count is non-zero. Wietse diff -cr /var/tmp/postfix-2.12-20140406-verify-3/src/cleanup/cleanup_envelope.c ./src/cleanup/cleanup_envelope.c *** /var/tmp/postfix-2.12-20140406-verify-3/src/cleanup/cleanup_envelope.c Sat Apr 26 17:46:26 2014 --- ./src/cleanup/cleanup_envelope.c Sun Apr 27 20:11:59 2014 *************** *** 435,445 **** cleanup_out(state, type, buf, len); return; } - if (mapped_type == REC_TYPE_TFLAGS) { - if (state->tflags == 0) - state->tflags = DEL_REQ_TRACE_FLAGS(atoi(mapped_buf)); - return; - } if (type == REC_TYPE_WARN) { /* First instance wins. */ if ((state->flags & CLEANUP_FLAG_WARN_SEEN) == 0) { --- 435,440 ---- *************** *** 485,490 **** --- 480,495 ---- return; } } + if (strcmp(attr_name, MAIL_ATTR_TRACE_FLAGS) == 0) { + if (!alldig(attr_value)) { + msg_warn("%s: message rejected: bad TFLAG record <%.200s>", + state->queue_id, buf); + state->errs |= CLEANUP_STAT_BAD; + return; + } + if (state->tflags == 0) + state->tflags = DEL_REQ_TRACE_FLAGS(atoi(attr_value)); + } nvtable_update(state->attr, attr_name, attr_value); cleanup_out(state, type, buf, len); return; diff -cr /var/tmp/postfix-2.12-20140406-verify-3/src/global/post_mail.c ./src/global/post_mail.c *** /var/tmp/postfix-2.12-20140406-verify-3/src/global/post_mail.c Sat Apr 26 20:13:33 2014 --- ./src/global/post_mail.c Sun Apr 27 20:23:01 2014 *************** *** 454,468 **** POST_MAIL_FCLOSE_STATE *state = (POST_MAIL_FCLOSE_STATE *) context; int status = state->status; ! if (status == 0) { ! if (vstream_ferror(state->stream) != 0 ! || attr_scan(state->stream, ATTR_FLAG_MISSING, ! ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ! ATTR_TYPE_END) != 1) ! status = CLEANUP_STAT_WRITE; } ! (void) vstream_fclose(state->stream); state->notify(status, state->context); myfree((char *) state); } --- 454,495 ---- POST_MAIL_FCLOSE_STATE *state = (POST_MAIL_FCLOSE_STATE *) context; int status = state->status; ! switch (event) { ! ! /* ! * Final server reply. Pick up the completion status. ! */ ! case EVENT_READ: ! if (status == 0) { ! if (vstream_ferror(state->stream) != 0 ! || attr_scan(state->stream, ATTR_FLAG_MISSING, ! ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ! ATTR_TYPE_END) != 1) ! status = CLEANUP_STAT_WRITE; ! } ! break; ! ! /* ! * No response or error. ! */ ! default: ! msg_warn("error talking to service: %s", var_cleanup_service); ! status = CLEANUP_STAT_WRITE; ! break; } ! ! /* ! * Stop the watchdog timer, and disable further read events that end up ! * calling this function. ! */ ! event_cancel_timer(post_mail_fclose_event, context); ! event_disable_readwrite(vstream_fileno(state->stream)); ! ! /* ! * Notify the requestor and clean up. ! */ state->notify(status, state->context); + (void) vstream_fclose(state->stream); myfree((char *) state); } diff -cr /var/tmp/postfix-2.12-20140406-verify-3/src/global/rec_attr_map.c ./src/global/rec_attr_map.c *** /var/tmp/postfix-2.12-20140406-verify-3/src/global/rec_attr_map.c Sat Apr 26 17:36:16 2014 --- ./src/global/rec_attr_map.c Sun Apr 27 20:12:43 2014 *************** *** 48,55 **** return (REC_TYPE_DSN_RET); } else if (strcmp(attr_name, MAIL_ATTR_CREATE_TIME) == 0) { return (REC_TYPE_CTIME); - } else if (strcmp(attr_name, MAIL_ATTR_TRACE_FLAGS) == 0) { - return (REC_TYPE_TFLAGS); } else { return (0); } --- 48,53 ---- diff -cr /var/tmp/postfix-2.12-20140406-verify-3/src/verify/verify.c ./src/verify/verify.c *** /var/tmp/postfix-2.12-20140406-verify-3/src/verify/verify.c Sat Apr 26 19:46:47 2014 --- ./src/verify/verify.c Sun Apr 27 20:09:50 2014 *************** *** 483,490 **** { char *addr = context; ! if (status == 0) ! verify_probe_queued(addr); myfree(addr); } --- 483,493 ---- { char *addr = context; ! /* ! * In case of trouble, count this request as not pending. ! */ ! if (status != 0) ! verify_probe_done(addr); myfree(addr); } *************** *** 497,506 **** /* * Probe messages need no body content, because they are never delivered, * deferred, or bounced. */ ! if (stream != 0) post_mail_fclose_async(stream, verify_post_mail_fclose_action, addr); ! else myfree(addr); } --- 500,513 ---- /* * Probe messages need no body content, because they are never delivered, * deferred, or bounced. + * + * Count this request as pending, so that we have non-zero pending count + * when the cleanup server reports a result for a 1-N virtual alias. */ ! if (stream != 0) { ! verify_probe_queued(addr); post_mail_fclose_async(stream, verify_post_mail_fclose_action, addr); ! } else myfree(addr); }