[openssl] master update

kaishen.yy at antfin.com kaishen.yy at antfin.com
Wed Apr 1 11:14:25 UTC 2020


The branch master has been updated
       via  cd81ac7be309881b282ce517f902d211a26d8b42 (commit)
      from  96ebe52e897dea29664683e138877fb5eb995e4d (commit)


- Log -----------------------------------------------------------------
commit cd81ac7be309881b282ce517f902d211a26d8b42
Author: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
Date:   Fri Mar 13 11:24:05 2020 +0800

    apps: support sendfile in s_server when ktls enabled
    
    When the -WWW or -HTTP option is specified, s_server can choose
    to use SSL_sendfile to transmit the file requested by client
    with KTLS is enabled, taking full advantage of the performance
    advantages of Kernel TLS, and adding the '-sendfile' command
    line parameter to control this behavior.
    
    Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
    
    Reviewed-by: Paul Yang <kaishen.yy at antfin.com>
    Reviewed-by: Tim Hudson <tjh at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11318)

-----------------------------------------------------------------------

Summary of changes:
 apps/s_server.c                  | 107 ++++++++++++++++++++++++++++++---------
 doc/man1/openssl-s_server.pod.in |   9 ++++
 2 files changed, 92 insertions(+), 24 deletions(-)

diff --git a/apps/s_server.c b/apps/s_server.c
index 591c6c19c5..d2864bc689 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -103,6 +103,8 @@ static int keymatexportlen = 20;
 
 static int async = 0;
 
+static int use_sendfile = 0;
+
 static const char *session_id_prefix = NULL;
 
 #ifndef OPENSSL_NO_DTLS
@@ -749,7 +751,7 @@ typedef enum OPTION_choice {
     OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
     OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS,
     OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
-    OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
+    OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE,
     OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
     OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
     OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
@@ -981,6 +983,9 @@ const OPTIONS s_server_options[] = {
 #endif
     {"alpn", OPT_ALPN, 's',
      "Set the advertised protocols for the ALPN extension (comma-separated list)"},
+#ifndef OPENSSL_NO_KTLS
+    {"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
+#endif
 
     OPT_R_OPTIONS,
     OPT_S_OPTIONS,
@@ -1095,6 +1100,7 @@ int s_server_main(int argc, char *argv[])
     s_quiet = 0;
     s_brief = 0;
     async = 0;
+    use_sendfile = 0;
 
     cctx = SSL_CONF_CTX_new();
     vpm = X509_VERIFY_PARAM_new();
@@ -1643,6 +1649,11 @@ int s_server_main(int argc, char *argv[])
         case OPT_HTTP_SERVER_BINMODE:
             http_server_binmode = 1;
             break;
+        case OPT_SENDFILE:
+#ifndef OPENSSL_NO_KTLS
+            use_sendfile = 1;
+#endif
+            break;
         }
     }
     argc = opt_num_rest();
@@ -1695,6 +1706,13 @@ int s_server_main(int argc, char *argv[])
     }
 #endif
 
+#ifndef OPENSSL_NO_KTLS
+    if (use_sendfile && www <= 1) {
+        BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n");
+        goto end;
+    }
+#endif
+
     if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
         BIO_printf(bio_err, "Error getting password\n");
         goto end;
@@ -3336,38 +3354,79 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
                              "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
             }
             /* send the file */
-            for (;;) {
-                i = BIO_read(file, buf, bufsize);
-                if (i <= 0)
-                    break;
+#ifndef OPENSSL_NO_KTLS
+            if (use_sendfile) {
+                FILE *fp = NULL;
+                int fd;
+                struct stat st;
+                off_t offset = 0;
+                size_t filesize;
+
+                BIO_get_fp(file, &fp);
+                fd = fileno(fp);
+                if (fstat(fd, &st) < 0) {
+                    BIO_printf(io, "Error fstat '%s'\r\n", p);
+                    ERR_print_errors(io);
+                    goto write_error;
+                }
 
-#ifdef RENEG
-                total_bytes += i;
-                BIO_printf(bio_err, "%d\n", i);
-                if (total_bytes > 3 * 1024) {
-                    total_bytes = 0;
-                    BIO_printf(bio_err, "RENEGOTIATE\n");
-                    SSL_renegotiate(con);
+                filesize = st.st_size;
+                if (((int)BIO_flush(io)) < 0)
+                    goto write_error;
+
+                for (;;) {
+                    i = SSL_sendfile(con, fd, offset, filesize, 0);
+                    if (i < 0) {
+                        BIO_printf(io, "Error SSL_sendfile '%s'\r\n", p);
+                        ERR_print_errors(io);
+                        break;
+                    } else {
+                        offset += i;
+                        filesize -= i;
+                    }
+
+                    if (filesize <= 0) {
+                        if (!s_quiet)
+                            BIO_printf(bio_err, "KTLS SENDFILE '%s' OK\n", p);
+
+                        break;
+                    }
                 }
+            } else
 #endif
+            {
+                for (;;) {
+                    i = BIO_read(file, buf, bufsize);
+                    if (i <= 0)
+                        break;
 
-                for (j = 0; j < i;) {
 #ifdef RENEG
-                    static count = 0;
-                    if (++count == 13) {
+                    total_bytes += i;
+                    BIO_printf(bio_err, "%d\n", i);
+                    if (total_bytes > 3 * 1024) {
+                        total_bytes = 0;
+                        BIO_printf(bio_err, "RENEGOTIATE\n");
                         SSL_renegotiate(con);
                     }
 #endif
-                    k = BIO_write(io, &(buf[j]), i - j);
-                    if (k <= 0) {
-                        if (!BIO_should_retry(io)
-                            && !SSL_waiting_for_async(con))
-                            goto write_error;
-                        else {
-                            BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+
+                    for (j = 0; j < i;) {
+#ifdef RENEG
+                        static count = 0;
+                        if (++count == 13)
+                            SSL_renegotiate(con);
+#endif
+                        k = BIO_write(io, &(buf[j]), i - j);
+                        if (k <= 0) {
+                            if (!BIO_should_retry(io)
+                                && !SSL_waiting_for_async(con)) {
+                                goto write_error;
+                            } else {
+                                BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+                            }
+                        } else {
+                            j += k;
                         }
-                    } else {
-                        j += k;
                     }
                 }
             }
diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in
index 9a5ef10d0a..0fd22d4689 100644
--- a/doc/man1/openssl-s_server.pod.in
+++ b/doc/man1/openssl-s_server.pod.in
@@ -124,6 +124,7 @@ B<openssl> B<s_server>
 [B<-nextprotoneg> I<val>]
 [B<-use_srtp> I<val>]
 [B<-alpn> I<val>]
+[B<-sendfile>]
 [B<-keylogfile> I<outfile>]
 [B<-recv_max_early_data> I<int>]
 [B<-max_early_data> I<int>]
@@ -152,6 +153,8 @@ B<openssl> B<s_server>
 
 =for openssl ifdef ssl3 tls1 tls1_1 tls1_2 tls1_3 dtls mtu dtls1 dtls1_2
 
+=for openssl ifdef sendfile
+
 =head1 DESCRIPTION
 
 This command implements a generic SSL/TLS server which
@@ -613,6 +616,12 @@ Protocol names are printable ASCII strings, for example "http/1.1" or
 "spdy/3".
 The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used.
 
+=item B<-sendfile>
+
+If this option is set and KTLS is enabled, SSL_sendfile() will be used
+instead of BIO_write() to send the HTTP response requested by a client.
+This option is only valid if B<-WWW> or B<-HTTP> is specified.
+
 =item B<-keylogfile> I<outfile>
 
 Appends TLS secrets to the specified keylog file such that external programs


More information about the openssl-commits mailing list