diff options
author | Boris Pismenny <borisp@mellanox.com> | 2019-04-13 17:20:35 +0300 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2019-05-07 14:24:16 +0100 |
commit | 7c3a7561b536264b282f604efc959edad18807d7 (patch) | |
tree | 7d66adca5bf7f54f8c944a58bef2abffec32102f /ssl | |
parent | 72fb59c72186c327e047cd29d8a66a4a323b9f3b (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.c | 1 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 67 |
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; |