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]
