Blob Blame History Raw
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;
 }