Long living (e.g. keepalive, connection reuse) textproto client connections don't get an event when a remote server closes a connection causing CLOSE_WAIT half closed TCP connections on the client side.
See an example: https://gist.github.com/kayrus/31023f2a1cc30b1744b3c45cd3557d21
$ go run .
220 ESMTP Service Ready
EHLO client
250-Hello client
250-PIPELINING
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-CHUNKING
250-AUTH PLAIN
250 SIZE
MAIL FROM:<test@test.com> BODY=8BITMIME
250 2.0.0 Roger, accepting mail from <test@test.com>
RCPT TO:<test@test.com>
250 2.0.0 I'll make sure <test@test.com> gets this
DATA
354 2.0.0 Go ahead. End your data with <CR><LF>.<CR><LF>
test
.
250 2.0.0 OK: queued
221 2.4.2 Idle timeout, bye bye
2022/07/18 10:51:43 tcp 34 0 127.0.0.1:59336 127.0.0.1:1025 CLOSE_WAIT 22336/smtp-test
I see that for an HTTP client go lang has a workaround. IMHO this solution is too complicated and I wonder whether it's possible to implement something general and reuse it for HTTP/SMTP/etc.
see also emersion/go-smtp#185