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]
