diff --git a/src/main/tls_listen.c b/src/main/tls_listen.c
index 32cf564..45e7641 100644
--- a/src/main/tls_listen.c
+++ b/src/main/tls_listen.c
@@ -189,6 +189,18 @@ static int tls_socket_recv(rad_listen_t *listener)
RDEBUG3("Reading from socket %d", request->packet->sockfd);
PTHREAD_MUTEX_LOCK(&sock->mutex);
+
+ /*
+ * If there is pending application data, as set up by
+ * SSL_peek(), read that before reading more data from
+ * the socket.
+ */
+ if (SSL_pending(sock->ssn->ssl)) {
+ RDEBUG3("Reading pending buffered data");
+ sock->ssn->dirty_in.used = 0;
+ goto get_application_data;
+ }
+
rcode = read(request->packet->sockfd,
sock->ssn->dirty_in.data,
sizeof(sock->ssn->dirty_in.data));
@@ -250,6 +262,7 @@ static int tls_socket_recv(rad_listen_t *listener)
/*
* Try to get application data.
*/
+get_application_data:
status = tls_application_data(sock->ssn, request);
RDEBUG("Application data status %d", status);
@@ -333,9 +346,11 @@ int dual_tls_recv(rad_listen_t *listener)
RAD_REQUEST_FUNP fun = NULL;
listen_socket_t *sock = listener->data;
RADCLIENT *client = sock->client;
+ BIO *rbio;
if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
+redo:
if (!tls_socket_recv(listener)) {
return 0;
}
@@ -403,6 +418,26 @@ int dual_tls_recv(rad_listen_t *listener)
return 0;
}
+ /*
+ * Check for more application data.
+ *
+ * If there is pending SSL data, "peek" at the
+ * application data. If we get at least one byte of
+ * application data, go back to tls_socket_recv().
+ * SSL_peek() will set SSL_pending(), and
+ * tls_socket_recv() will read another packet.
+ */
+ rbio = SSL_get_rbio(sock->ssn->ssl);
+ if (BIO_ctrl_pending(rbio)) {
+ char buf[1];
+ int peek = SSL_peek(sock->ssn->ssl, buf, 1);
+
+ if (peek > 0) {
+ DEBUG("more TLS records after dual_tls_recv");
+ goto redo;
+ }
+ }
+
return 1;
}