* deadlock and livelock situations above.
*/
int rx_want, tx_want;
+
+ /* A few bytes of header data in case SSL negotation fails. */
+ uint8_t head[2];
+ short int n_head;
};
/* SSL context created by ssl_init(). */
sslv->ssl = ssl;
sslv->txbuf = NULL;
sslv->rx_want = sslv->tx_want = SSL_NOTHING;
+ sslv->n_head = 0;
*streamp = &sslv->stream;
return 0;
/* Fall through. */
case STATE_SSL_CONNECTING:
+ /* Capture the first few bytes of received data so that we can guess
+ * what kind of funny data we've been sent if SSL negotation fails. */
+ if (sslv->n_head <= 0) {
+ sslv->n_head = recv(sslv->fd, sslv->head, sizeof sslv->head,
+ MSG_PEEK);
+ }
+
retval = (sslv->type == CLIENT
? SSL_connect(sslv->ssl) : SSL_accept(sslv->ssl));
if (retval != 1) {
interpret_ssl_error((sslv->type == CLIENT ? "SSL_connect"
: "SSL_accept"), retval, error, &unused);
shutdown(sslv->fd, SHUT_RDWR);
+ stream_report_content(sslv->head, sslv->n_head, STREAM_SSL,
+ THIS_MODULE, stream_get_name(stream));
return EPROTO;
}
} else if (bootstrap_ca_cert) {
* background. */
SSL_shutdown(sslv->ssl);
+ /* SSL_shutdown() might have signaled an error, in which case we need to
+ * flush it out of the OpenSSL error queue or the next OpenSSL operation
+ * will falsely signal an error. */
+ ERR_clear_error();
+
SSL_free(sslv->ssl);
close(sslv->fd);
free(sslv);