On Thu, Apr 16, 2009 at 10:41 PM, Markus Wiederkehr
<[email protected]> wrote:
> On Thu, Apr 16, 2009 at 11:05 PM, Robert Burrell Donkin
> <[email protected]> wrote:
>> On Thu, Apr 16, 2009 at 8:12 PM, Markus Wiederkehr
>> <[email protected]> wrote:
>>> On Thu, Apr 16, 2009 at 8:40 PM, Stefano Bagnara <[email protected]> wrote:
>>>> Robert Burrell Donkin ha scritto:
>>>>> On Thu, Apr 16, 2009 at 3:32 PM, Markus Wiederkehr
>>>>> <[email protected]> wrote:
>>>>>> I have a problem with a manufacturer of a certain anti-virus e-mail
>>>>>> gateway. This particular mail receiver closes the TCP connection after
>>>>>> receiving the terminating <CRLF>.<CRLF> indicator of the DATA command
>>>>>> without waiting for a QUIT command to be sent by the client (James in
>>>>>> this case).
>>>>>>
>>>>>> This is a clear violation of RFC 5321 which says that "the receiver
>>>>>> MUST NOT intentionally close the transmission channel until it
>>>>>> receives and replies to a QUIT command".
>>>>>>
>>>>>> Unfortunately the manufacturer is aware of this fact but still refuses
>>>>>> to change the behavior of the software. They claim that this behavior
>>>>>> is common for bigger providers in order to avoid DDOS attacks and save
>>>>>> port numbers (which is BS in my opinion).
>>>>>>
>>>>>> Anyway, RemoteDelivery uses the Java Mail API to send the message,
>>>>>> something like this:
>>>>>>
>>>>>> try { ...
>>>>>>  transport.sendMessage(message, addr);
>>>>>> } finally {
>>>>>>  transport.close();
>>>>>> }
>>>>>>
>>>>>> So sendMessage() succeeds but close() throws a MessagingException and
>>>>>> James (correctly) thinks it has to send the message again. As a
>>>>>> consequence the recipient receives the same message several times
>>>>>> until James gives up permanently.
>>>>>>
>>>>>> Now, I do not ask for a modification in James since the problem
>>>>>> clearly lies on the recipient's side...
>>>>>
>>>>> i'm not sure that an unchecked close is correct in this case. i would
>>>>> prefer to see an IO action in a finally wrapped in a exception
>>>>> handling block eg
>>>>>
>>>>>  try { ...
>>>>>    transport.sendMessage(message, addr);
>>>>>  } finally {
>>>>>    try {
>>>>>      transport.close();
>>>>>   } catch (Exception e) {
>>>>>     getLog().warn("Failed to cleanly close connection to remote server", 
>>>>> e);
>>>>>   }
>>>>> }
>>>>>
>>>>> if the action needs to be repeated then a boolean should be used. this
>>>>> should ensure that both exceptions are logging and the appropriate one
>>>>> processed.
>>>>>
>>>>> FWIW i would support altering the code without the additional boolean
>>>>
>>>> +1
>>>
>>> That would solve the problem but I think the behavior of James would
>>> then become non-standard compliant.
>>>
>>> See http://tools.ietf.org/html/rfc5321#section-3.8: "SMTP clients that
>>> experience a connection close, reset [...] SHOULD [...] treat the mail
>>> transaction as if a 451 response had been received and act
>>> accordingly."
>>
>> <blockquote cite='http://tools.ietf.org/html/rfc5321#section-3.8'>
>>   SMTP clients that experience a connection close, reset, or other
>>   communications failure due to circumstances not under their control
>>   (in violation of the intent of this specification but sometimes
>>   unavoidable) SHOULD, to maintain the robustness of the mail system,
>>   treat the mail transaction as if a 451 response had been received and
>>   act accordingly.
>> </blockquote>
>>
>> AIUI transport.close() sends a QUIT and then forcably closes the
>> socket. the client should assume that an exception means that 451
>> 'Requested action aborted: error in processing' has been returned by
>> the QUIT. in other words, that the QUIT failed and cannot be retried.
>
> Yes; Transport.sendMessage() sends DATA and the terminating dot and
> Transport.close() sends QUIT. In this particular case the client
> cannot send QUIT because the server has already closed the connection.

agreed

>> does this mean that the previous send should be assumed to be rolled back?
>
> The RFC speaks of the "mail transaction" so I'd say yes.  451 is a
> Transient Negative Completion reply so the client should retry later
> (exactly what James does).

i don't have a deep understanding of the RFC so hopefully someone who
does will jump in here

otherwise, maybe we need to ask on the IEFT list...

> In section 4.1.1.10. the RFC also says that "The receiver MUST NOT
> intentionally close the transmission channel until it receives and
> replies to a QUIT command".

yes

however, this behaviour is a real PITA for servers and enables DOS
attacks. i would expect most commercial SMTP servers to allow this
part of the specification to be ignored. i expect most servers just
set a timeout on the socket (AIUI james does this by default) so the
connection will timeout after a suitable period of inactivity. the
problem is that this server is particularly (and unusually) aggressive
in terminating the connection.

- robert

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to