diff --git a/postfix/HISTORY b/postfix/HISTORY index 600cb0f54..e6d3ed82a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -9389,3 +9389,20 @@ Apologies for any names omitted. Bugfix: space in HELO commands could end up in XFORWARD commands. File: smtpd/smtpd.c. + +20040619 + + Bugfix: more missing resets in the SMTP client when it + switches to an alternate SMTP server. In this case the + error_mask that controls whether an SMTP session transcript + is mailed to the postmaster, and the size_limit that controls + how large a message Postfix will send. Found during code + maintenance. File: smtp/smtp_connect.c. + +20040622 + + Safety: when mail is delivered to a transport with per-delivery + recipient limit of 1, split the recipient address on the + recipient delimiter if one is defined, so that extended + addresses don't get extra delivery concurrency slots. + Files: *qmgr/qmgr_message.c. diff --git a/postfix/html/regexp_table.5.html b/postfix/html/regexp_table.5.html index 024f2add1..9dbf93cdb 100644 --- a/postfix/html/regexp_table.5.html +++ b/postfix/html/regexp_table.5.html @@ -68,7 +68,7 @@ REGEXP_TABLE(5) REGEXP_TABLE(5) Each pattern is a POSIX regular expression enclosed by a pair of delimiters. The regular expression syntax is docu- - mented in re_format(7) with 4.4BSD, in regcomp(3C) with + mented in re_format(7) with 4.4BSD, in regex(5) with Solaris, and in regex(7) with Linux. Other systems may use other document names. diff --git a/postfix/man/man5/regexp_table.5 b/postfix/man/man5/regexp_table.5 index 4f7907d9d..cb43347e7 100644 --- a/postfix/man/man5/regexp_table.5 +++ b/postfix/man/man5/regexp_table.5 @@ -62,7 +62,7 @@ starts with whitespace continues a logical line. .PP Each pattern is a POSIX regular expression enclosed by a pair of delimiters. The regular expression syntax is documented in -re_format(7) with 4.4BSD, in regcomp(3C) with Solaris, and in +re_format(7) with 4.4BSD, in regex(5) with Solaris, and in regex(7) with Linux. Other systems may use other document names. The expression delimiter can be any character, except whitespace diff --git a/postfix/proto/regexp_table b/postfix/proto/regexp_table index 92c8d7820..3dcd43b26 100644 --- a/postfix/proto/regexp_table +++ b/postfix/proto/regexp_table @@ -54,7 +54,7 @@ # .PP # Each pattern is a POSIX regular expression enclosed by a pair of # delimiters. The regular expression syntax is documented in -# re_format(7) with 4.4BSD, in regcomp(3C) with Solaris, and in +# re_format(7) with 4.4BSD, in regex(5) with Solaris, and in # regex(7) with Linux. Other systems may use other document names. # # The expression delimiter can be any character, except whitespace diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a540c0e17..6351e321b 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,8 +20,8 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only. */ -#define MAIL_RELEASE_DATE "20040616" -#define MAIL_VERSION_NUMBER "2.1.3" +#define MAIL_RELEASE_DATE "20040628" +#define MAIL_VERSION_NUMBER "2.1.4" #define VAR_MAIL_VERSION "mail_version" #ifdef SNAPSHOT diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index a722d0908..658d1d74e 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -936,10 +936,9 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * agent resources. We use recipient@nexthop as queue name rather * than the actual recipient domain name, so that one recipient in * multiple equivalent domains cannot evade the per-recipient - * concurrency limit. XXX Should split the address on the recipient - * delimiter if one is defined, but doing a proper job requires - * knowledge of local aliases. Yuck! I don't want to duplicate - * delivery-agent specific knowledge in the queue manager. + * concurrency limit. Split the address on the recipient delimiter if + * one is defined, so that extended addresses don't get extra + * delivery slots. * * Fold the result to lower case so that we don't have multiple queues * for the same name. @@ -947,18 +946,32 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * Important! All recipients in a queue must have the same nexthop * value. It is OK to have multiple queues with the same nexthop * value, but only when those queues are named after recipients. + * + * The single-recipient code below was written for local(8) like + * delivery agents, and assumes that all domains that deliver to the + * same (transport + nexthop) are aliases for $nexthop. Delivery + * concurrency is changed from per-domain into per-recipient, by + * changing the queue name from nexthop into localpart@nexthop. + * + * XXX This assumption is incorrect when different destinations share + * the same (transport + nexthop). In reality, such transports are + * rarely configured to use single-recipient deliveries. The fix is + * to decouple the per-destination recipient limit from the + * per-destination concurrency. */ vstring_strcpy(queue_name, STR(reply.nexthop)); if (strcmp(transport->name, MAIL_SERVICE_ERROR) != 0 && transport->recipient_limit == 1) { + /* Copy the recipient localpart. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); - VSTRING_SPACE(queue_name, len + 2); - memmove(STR(queue_name) + len + 1, STR(queue_name), - LEN(queue_name) + 1); - memcpy(STR(queue_name), STR(reply.recipient), len); - STR(queue_name)[len] = '@'; + vstring_strncpy(queue_name, STR(reply.recipient), len); + /* Remove the address extension from the recipient localpart. */ + if (*var_rcpt_delim && split_addr(STR(queue_name), *var_rcpt_delim)) + vstring_truncate(queue_name, strlen(STR(queue_name))); + /* Assume the recipient domain is equivalent to nexthop. */ + vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop)); } lowercase(STR(queue_name)); diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 708f48923..724cbd1ab 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -980,10 +980,9 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * agent resources. We use recipient@nexthop as queue name rather * than the actual recipient domain name, so that one recipient in * multiple equivalent domains cannot evade the per-recipient - * concurrency limit. XXX Should split the address on the recipient - * delimiter if one is defined, but doing a proper job requires - * knowledge of local aliases. Yuck! I don't want to duplicate - * delivery-agent specific knowledge in the queue manager. + * concurrency limit. Split the address on the recipient delimiter if + * one is defined, so that extended addresses don't get extra + * delivery slots. * * Fold the result to lower case so that we don't have multiple queues * for the same name. @@ -991,18 +990,32 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) * Important! All recipients in a queue must have the same nexthop * value. It is OK to have multiple queues with the same nexthop * value, but only when those queues are named after recipients. + * + * The single-recipient code below was written for local(8) like + * delivery agents, and assumes that all domains that deliver to the + * same (transport + nexthop) are aliases for $nexthop. Delivery + * concurrency is changed from per-domain into per-recipient, by + * changing the queue name from nexthop into localpart@nexthop. + * + * XXX This assumption is incorrect when different destinations share + * the same (transport + nexthop). In reality, such transports are + * rarely configured to use single-recipient deliveries. The fix is + * to decouple the per-destination recipient limit from the + * per-destination concurrency. */ vstring_strcpy(queue_name, STR(reply.nexthop)); if (strcmp(transport->name, MAIL_SERVICE_ERROR) != 0 && transport->recipient_limit == 1) { + /* Copy the recipient localpart. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); - VSTRING_SPACE(queue_name, len + 2); - memmove(STR(queue_name) + len + 1, STR(queue_name), - LEN(queue_name) + 1); - memcpy(STR(queue_name), STR(reply.recipient), len); - STR(queue_name)[len] = '@'; + vstring_strncpy(queue_name, STR(reply.recipient), len); + /* Remove the address extension from the recipient localpart. */ + if (*var_rcpt_delim && split_addr(STR(queue_name), *var_rcpt_delim)) + vstring_truncate(queue_name, strlen(STR(queue_name))); + /* Assume the recipient domain is equivalent to nexthop. */ + vstring_sprintf_append(queue_name, "@%s", STR(reply.nexthop)); } lowercase(STR(queue_name)); diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 604c90c64..79733b230 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -363,6 +363,8 @@ int smtp_connect(SMTP_STATE *state) smtp_chat_notify(state); smtp_chat_reset(state); } + state->error_mask = 0; + state->size_limit = 0; /* XXX smtp_xfer() may abort in the middle of DATA. */ smtp_session_free(state->session); state->session = 0;