On Fri, Apr 17, 2009 at 12:43 PM, Markus Wiederkehr
<[email protected]> wrote:
> On Fri, Apr 17, 2009 at 10:22 AM, Stefano Bagnara <[email protected]> wrote:
>> Markus Wiederkehr ha scritto:
>>> 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.
>>>
>>>> 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).
>>
>> The rfc says that the time between "." and the reply to the "." should
>> be as short as possible to avoid duplicate send.
>>
>> The email is considered successfully SENT when the reply to "." is read.
>> What happen after this command is a new transaction.
>>
>> I have almost no doubts about this.
>
> Section 3.3. Mail Transactions seems to indicate that you are right
> about this. A mail transaction basically consists of MAIL, RCPT and
> DATA..
>
> So the current behaviour of RemoteDelivery indeed seems to be a bug.

want to open a JIRA and commit a fix?

(or shall i do it)

- robert

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

Reply via email to