static void
rspamd_ssl_shutdown (struct rspamd_ssl_connection *conn)
{
- gint ret;
+ gint ret = 0, retries;
+ static const gint max_retries = 5;
+
+ /*
+ * Fucking openssl...
+ * From the manual, 0 means: "The shutdown is not yet finished.
+ * Call SSL_shutdown() for a second time,
+ * if a bidirectional shutdown shall be performed.
+ * The output of SSL_get_error(3) may be misleading,
+ * as an erroneous SSL_ERROR_SYSCALL may be flagged
+ * even though no error occurred."
+ *
+ * What is `second`, what if `second` also returns 0?
+ * What a retarded behaviour!
+ */
+ for (retries = 0; retries < max_retries; retries ++) {
+ ret = SSL_shutdown (conn->ssl);
+
+ if (ret != 0) {
+ break;
+ }
+ }
- if ((ret = SSL_shutdown (conn->ssl)) == 1) {
+ if (ret == 1) {
/* All done */
msg_debug_ssl ("ssl shutdown: all done");
rspamd_ssl_connection_dtor (conn);
}
- else {
+ else if (ret < 0) {
short what;
ret = SSL_get_error (conn->ssl, ret);
what = EV_READ;
}
else if (ret == SSL_ERROR_WANT_WRITE) {
- msg_debug_ssl ("ssl shutdown: need read");
+ msg_debug_ssl ("ssl shutdown: need write");
what = EV_WRITE;
}
else {
conn->state = ssl_next_shutdown;
}
+ else if (ret == 0) {
+ /* What can we do here?? */
+ msg_debug_ssl ("ssl shutdown: openssl failed to initiate shutdown after "
+ "%d attempts!", max_retries);
+ rspamd_ssl_connection_dtor (conn);
+ }
}
static void