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. Thanks, Markus > >> 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". >>>> Maybe a switch would be in order? But if nobody else ever had this >>>> problem I can also write a workaround locally without affecting the >>>> code base. >>> possibly >>> >>>>>>> But has anyone ever experienced something like this? And maybe is >>>>>>> there a workaround? >>>>>> (hopefully stefano or norman will jump in here) >>>>> I'm using a custom RemoteDelivery but (if I remember correctly) that >>>>> case should be handled the same. I never had a "duplicate delivery" >>>>> issue reported. >>>>> >>>>> I deliver a lot of mail nowadays, but mainly to italian recipients: >>>>> maybe the antivirus gateway Markus talks about is not so used in italy. >>>>> Markus, can you name the product? >>>> I would rather not; or at least not until I have spoken to my >>>> co-workers. The company is located in Austria but I have no idea how >>>> widely the product has been adopted. >>> you may want to take this off list to stefano directly or perhaps hook up >>> on IRC >> >> Good idea, thanks. >> >> Markus > > I'm often on #ja...@freenode, icq uin 16554317, skype bagovoip, aim > instantbago . > > Stefano > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
