From 74fa3f6f62728cab1597bca5deea6ee758157e24 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Wed, 23 Oct 2024 21:54:06 +0200 Subject: [PATCH] Fix Quit handling when initial HELO fails Ensure QUIT command can be sent even if initial HELO fails. Added a check to skip retrying HELO if it already failed, allowing for proper closing of the connection. This prevents potential hangs or errors during connection termination. --- smtp/smtp.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/smtp/smtp.go b/smtp/smtp.go index 77b5fb0..208677f 100644 --- a/smtp/smtp.go +++ b/smtp/smtp.go @@ -554,8 +554,19 @@ func (c *Client) Noop() error { // Quit sends the QUIT command and closes the connection to the server. func (c *Client) Quit() error { - if err := c.hello(); err != nil { - return err + // If we did already tried to send a EHLO/HELO but it failed, we still need to be able to send + // a QUIT to close the connection. + // c.hello() will return the global helloErr of the Client, which will always be set if the HELO + // failed before. Therefore if we already sent a HELO and the error is not nil, we skip another + // EHLO/HELO try + c.mutex.RLock() + didHello := c.didHello + helloErr := c.helloError + c.mutex.RUnlock() + if !didHello || helloErr == nil { + if err := c.hello(); err != nil { + return err + } } _, _, err := c.cmd(221, "QUIT") if err != nil {