У меня есть приложение, которое отправляет электронную почту smtp через локальный сервер Exchange у клиента. Все электронные письма отправляются нормально (они доходят до получателя), но некоторые электронные письма отправляются несколько раз, потому что мое приложение никогда не получает код ответа 221, чтобы сказать, что он работал нормально, и поэтому повторяет попытку. Мы могли бы отменить повторные попытки, но часто это необходимо для реальных проблем.
Это чаще всего происходит на определенных адресах электронной почты и будет повторяться на этом электронном письме, когда это произойдет.
Я записал TCP-поток, один из которых работает, а другой - нет. Очевидно, имена изменены, чтобы защитить виновных.
Did work:
220 SBS4S1.example.local Microsoft ESMTP MAIL Service ready at Thu, 16 Apr 2015 11:51:16 +0100
EHLO example-PC
250-SBS4S1.example.local Hello [192.168.111.15]
250-SIZE 10485760
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XSHADOW
RSET
250 2.0.0 Resetting
MAIL FROM:<yyyy@example.com>
250 2.1.0 Sender OK
RCPT TO:<zzz@example.com>
250 2.1.5 Recipient OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>
--DATA Here, identical other than MIME/Content IDs in both emails--
.
250 2.6.0 <ac8dcf01-0d61-4e76-a52e-3946e68bf3a1@SBS4S1.example.local> [InternalId=26602] Queued mail for delivery
QUIT
221 2.0.0 Service closing transmission channel
.
Did NOT work:
220 SBS4S1.example.local Microsoft ESMTP MAIL Service ready at Thu, 16 Apr 2015 11:43:39 +0100
EHLO example-PC
250-SBS4S1.example.local Hello [192.168.111.15]
250-SIZE 10485760
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XSHADOW
RSET
250 2.0.0 Resetting
MAIL FROM:<yyyy@example.com>
250 2.1.0 Sender OK
RCPT TO:<zzz@example.com>
250 2.1.5 Recipient OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>
--DATA Here, identical other than MIME/Content IDs in both emails--
.
QUIT
250 2.6.0 <96ac271e-5525-4d89-aefa-a7469bae04df@SBS4S1.example.local> [InternalId=26573] Queued mail for delivery
--This then times out but never gets the 221--
Единственное различие, которое я вижу, кроме отсутствующего 221, состоит в том, что 250 и QUIT - это наоборот в сообщении, которое «не работает». Это известная причуда Exchange, которую мы должны решить, что-то, что мы могли бы исправить или должны справиться в нашем приложении, или что-то, что мы можем попросить изменить на почтовом сервере? Мы не хотим ничего ломать для нормальной, обычной ситуации.
Обновление: я думал, что мы не сможем получить журналы Exchange (администраторы даже не знали, где они), но у меня есть! Итак, соответствующая строка:
Tarpit для '0.00: 00: 32.619' из-за 'DelayedAck', Expired; Timeout
Похоже, это могло быть связано с:
https://mikecrowley.wordpress.com/2010/07/24/delayed-smtp-acknowledgement/
Надо сначала попробовать и протестировать.
Кажется, что иногда ваше приложение отправляет QUIT
команда перед получение ответа на «последнюю точку» сообщения (250 для ОК).
Похоже, что MTA (MS Exchange) игнорирует команды, полученные до отправки ответа.
Предлагаемые исправления:
1) Увеличьте время ожидания ответа, не отправляйте QUIT до его получения (даже если объявляется расширение PIPELINING).
2) Не отправить повторно, если вы получите 250
ответьте на «последнюю точку». В таком случае MTA (MS Exchange) берет на себя ответственность за доставку сообщения.
Причиной проблемы была настройка «DelayedAck» на транспорте Exchange. Принимающий сервер на «другой стороне» ретранслятора слишком долго отвечал (более 30 секунд), поэтому время ожидания соединения истекло, а SMTP-диалог так и не завершился. (этот URL-адрес, который я добавил в вопросе).
Администратор Exchange отключил DelayedAck на внутреннем транспорте, и проблема исчезла.
Мы могли / должны были изменить наше приложение, чтобы обойти эту проблему, но у нас есть компонент третьей части, который усложняет эту задачу, и поэтому мы не можем проверить, будет ли это работать.