summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorBoris Pismenny <borisp@mellanox.com>2019-04-13 17:20:35 +0300
committerMatt Caswell <matt@openssl.org>2019-05-07 14:24:16 +0100
commit7c3a7561b536264b282f604efc959edad18807d7 (patch)
tree7d66adca5bf7f54f8c944a58bef2abffec32102f /ssl
parent72fb59c72186c327e047cd29d8a66a4a323b9f3b (diff)
ssl: Add SSL_sendfile
This commit adds the SSL_sendfile call, which allows KTLS sockets to transmit file using zero-copy semantics. Signed-off-by: Boris Pismenny <borisp@mellanox.com> Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8727)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_err.c1
-rw-r--r--ssl/ssl_lib.c67
2 files changed, 68 insertions, 0 deletions
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index afe1b58214..daeee1ecc4 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -311,6 +311,7 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
"SSL_renegotiate_abbreviated"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SENDFILE, 0), "SSL_sendfile"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0),
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 89a410057b..910f82be43 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include "ssl_locl.h"
+#include "e_os.h"
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
@@ -2008,6 +2009,72 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
}
}
+ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags)
+{
+ ossl_ssize_t ret;
+
+ if (s->handshake_func == NULL) {
+ SSLerr(SSL_F_SSL_SENDFILE, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ if (s->shutdown & SSL_SENT_SHUTDOWN) {
+ s->rwstate = SSL_NOTHING;
+ SSLerr(SSL_F_SSL_SENDFILE, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ return -1;
+ }
+
+ if (!BIO_get_ktls_send(s->wbio)) {
+ SSLerr(SSL_F_SSL_SENDFILE, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ /* If we have an alert to send, lets send it */
+ if (s->s3.alert_dispatch) {
+ ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s);
+ if (ret <= 0) {
+ /* SSLfatal() already called if appropriate */
+ return ret;
+ }
+ /* if it went, fall through and send more stuff */
+ }
+
+ s->rwstate = SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0) {
+ if (!BIO_should_retry(s->wbio)) {
+ s->rwstate = SSL_NOTHING;
+ } else {
+#ifdef EAGAIN
+ set_sys_error(EAGAIN);
+#endif
+ }
+ return -1;
+ }
+
+#ifndef OPENSSL_NO_KTLS
+ ret = ktls_sendfile(SSL_get_wfd(s), fd, offset, size, flags);
+#else
+ ret = -1;
+#endif
+ if (ret < 0) {
+#if defined(EAGAIN) && defined(EINTR) && defined(EBUSY)
+ if ((get_last_sys_error() == EAGAIN) ||
+ (get_last_sys_error() == EINTR) ||
+ (get_last_sys_error() == EBUSY))
+ BIO_set_retry_write(s->wbio);
+ else
+#endif
+#ifdef OPENSSL_NO_KTLS
+ SYSerr(SYS_F_SENDFILE, get_last_sys_error());
+#else
+ SSLerr(SSL_F_SSL_SENDFILE, SSL_R_UNINITIALIZED);
+#endif
+ return ret;
+ }
+ s->rwstate = SSL_NOTHING;
+ return ret;
+}
+
int SSL_write(SSL *s, const void *buf, int num)
{
int ret;