benchmark-openssl.cc revision b140ba61
1a98d478eSShuo Chen#include <openssl/aes.h> 2a98d478eSShuo Chen#include <openssl/conf.h> 3a98d478eSShuo Chen#include <openssl/err.h> 4a98d478eSShuo Chen#include <openssl/ssl.h> 5a98d478eSShuo Chen 6a98d478eSShuo Chen#include <muduo/net/Buffer.h> 7a98d478eSShuo Chen 8a98d478eSShuo Chen#include <stdio.h> 9a98d478eSShuo Chen 109acb42f4SShuo Chen#include "timer.h" 119acb42f4SShuo Chen 12a98d478eSShuo Chenmuduo::net::Buffer clientOut, serverOut; 13a98d478eSShuo Chen 14a98d478eSShuo Chenint bread(BIO *b, char *buf, int len) 15a98d478eSShuo Chen{ 16a98d478eSShuo Chen BIO_clear_retry_flags(b); 17a98d478eSShuo Chen muduo::net::Buffer* in = static_cast<muduo::net::Buffer*>(b->ptr); 18a98d478eSShuo Chen // printf("%s recv %d\n", in == &clientOut ? "server" : "client", len); 19a98d478eSShuo Chen if (in->readableBytes() > 0) 20a98d478eSShuo Chen { 21a98d478eSShuo Chen size_t n = std::min(in->readableBytes(), static_cast<size_t>(len)); 22a98d478eSShuo Chen memcpy(buf, in->peek(), n); 23a98d478eSShuo Chen in->retrieve(n); 24a98d478eSShuo Chen 25a98d478eSShuo Chen /* 26a98d478eSShuo Chen if (n < len) 27a98d478eSShuo Chen printf("got %zd\n", n); 28a98d478eSShuo Chen else 29a98d478eSShuo Chen printf("\n"); 30a98d478eSShuo Chen */ 31a98d478eSShuo Chen return n; 32a98d478eSShuo Chen } 33a98d478eSShuo Chen else 34a98d478eSShuo Chen { 35a98d478eSShuo Chen //printf("got 0\n"); 36a98d478eSShuo Chen BIO_set_retry_read(b); 37a98d478eSShuo Chen return -1; 38a98d478eSShuo Chen } 39a98d478eSShuo Chen} 40a98d478eSShuo Chen 41a98d478eSShuo Chenint bwrite(BIO *b, const char *buf, int len) 42a98d478eSShuo Chen{ 43a98d478eSShuo Chen BIO_clear_retry_flags(b); 44a98d478eSShuo Chen muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(b->ptr); 45a98d478eSShuo Chen // printf("%s send %d\n", out == &clientOut ? "client" : "server", len); 46a98d478eSShuo Chen out->append(buf, len); 47a98d478eSShuo Chen return len; 48a98d478eSShuo Chen} 49a98d478eSShuo Chen 50a98d478eSShuo Chenlong bctrl(BIO *, int cmd, long num, void *) 51a98d478eSShuo Chen{ 52a98d478eSShuo Chen //printf("ctrl %d\n", cmd); 53a98d478eSShuo Chen switch (cmd) { 54a98d478eSShuo Chen case BIO_CTRL_FLUSH: 55a98d478eSShuo Chen return 1; 56b140ba61SShuo Chen case BIO_CB_FREE: 57b140ba61SShuo Chen printf("ctrl BIO_CB_FREE %d\n", cmd); 58a98d478eSShuo Chen default: 59a98d478eSShuo Chen return 0; 60a98d478eSShuo Chen } 61a98d478eSShuo Chen} 62a98d478eSShuo Chen 63a98d478eSShuo Chenint main(int argc, char* argv[]) 64a98d478eSShuo Chen{ 65a98d478eSShuo Chen SSL_load_error_strings(); 66a98d478eSShuo Chen // ERR_load_BIO_strings(); 67a98d478eSShuo Chen SSL_library_init(); 68a98d478eSShuo Chen OPENSSL_config(NULL); 69a98d478eSShuo Chen 70b140ba61SShuo Chen SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method()); 71a98d478eSShuo Chen 72a98d478eSShuo Chen EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 73a98d478eSShuo Chen SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); 749acb42f4SShuo Chen if (argc > 3) 759acb42f4SShuo Chen SSL_CTX_set_tmp_ecdh(ctx, ecdh); 76a98d478eSShuo Chen EC_KEY_free(ecdh); 77a98d478eSShuo Chen 78b140ba61SShuo Chen const char* CertFile = "server.pem"; // argv[1]; 79b140ba61SShuo Chen const char* KeyFile = "server.pem"; // argv[2]; 80a98d478eSShuo Chen SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM); 81a98d478eSShuo Chen SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM); 82a98d478eSShuo Chen if (!SSL_CTX_check_private_key(ctx)) 83a98d478eSShuo Chen abort(); 84a98d478eSShuo Chen 85b140ba61SShuo Chen SSL_CTX* ctx_client = SSL_CTX_new(TLSv1_2_client_method()); 86a98d478eSShuo Chen 87a98d478eSShuo Chen BIO_METHOD method; 88a98d478eSShuo Chen bzero(&method, sizeof method); 89a98d478eSShuo Chen method.bread = bread; 90a98d478eSShuo Chen method.bwrite = bwrite; 91a98d478eSShuo Chen method.ctrl = bctrl; 92a98d478eSShuo Chen BIO client, server; 93a98d478eSShuo Chen bzero(&client, sizeof client); 94a98d478eSShuo Chen bzero(&server, sizeof server); 95a98d478eSShuo Chen BIO_set(&client, &method); 96a98d478eSShuo Chen BIO_set(&server, &method); 97a98d478eSShuo Chen client.ptr = &clientOut; 98a98d478eSShuo Chen client.init = 1; 99a98d478eSShuo Chen server.ptr = &serverOut; 100a98d478eSShuo Chen server.init = 1; 101a98d478eSShuo Chen 102a98d478eSShuo Chen 103a98d478eSShuo Chen double start = now(); 104a98d478eSShuo Chen const int N = 1000; 105a98d478eSShuo Chen SSL *ssl, *ssl_client; 1069acb42f4SShuo Chen Timer tc, ts; 107a98d478eSShuo Chen for (int i = 0; i < N; ++i) 108a98d478eSShuo Chen { 109a98d478eSShuo Chen ssl = SSL_new (ctx); 110a98d478eSShuo Chen ssl_client = SSL_new (ctx_client); 111a98d478eSShuo Chen SSL_set_bio(ssl, &client, &server); 112a98d478eSShuo Chen SSL_set_bio(ssl_client, &server, &client); 113a98d478eSShuo Chen 1149acb42f4SShuo Chen tc.start(); 115a98d478eSShuo Chen int ret = SSL_connect(ssl_client); 1169acb42f4SShuo Chen tc.stop(); 117a98d478eSShuo Chen //printf("%d %d\n", ret, BIO_retry_type(&server)); 1189acb42f4SShuo Chen ts.start(); 119a98d478eSShuo Chen int ret2 = SSL_accept(ssl); 1209acb42f4SShuo Chen ts.stop(); 121a98d478eSShuo Chen //printf("%d %d\n", ret2, BIO_retry_type(&client)); 122a98d478eSShuo Chen 123a98d478eSShuo Chen while (true) 124a98d478eSShuo Chen { 1259acb42f4SShuo Chen tc.start(); 1269acb42f4SShuo Chen ret = SSL_do_handshake(ssl_client); 1279acb42f4SShuo Chen tc.stop(); 128a98d478eSShuo Chen //printf("client handshake %d %d\n", ret, BIO_retry_type(&server)); 1299acb42f4SShuo Chen ts.start(); 1309acb42f4SShuo Chen ret2 = SSL_do_handshake(ssl); 1319acb42f4SShuo Chen ts.stop(); 132a98d478eSShuo Chen //printf("server handshake %d %d\n", ret2, BIO_retry_type(&client)); 133a98d478eSShuo Chen //if (ret == -1 && BIO_retry_type(&server) == 0) 134a98d478eSShuo Chen // break; 135a98d478eSShuo Chen //if (ret2 == -1 && BIO_retry_type(&client) == 0) 136a98d478eSShuo Chen // break; 137a98d478eSShuo Chen if (ret == 1 && ret2 == 1) 138a98d478eSShuo Chen break; 139a98d478eSShuo Chen } 140a98d478eSShuo Chen 141a98d478eSShuo Chen //printf ("SSL connection using %s %s\n", SSL_get_version(ssl), SSL_get_cipher (ssl)); 142a98d478eSShuo Chen if (i == 0) 143a98d478eSShuo Chen printf ("SSL connection using %s %s\n", SSL_get_version(ssl_client), SSL_get_cipher (ssl_client)); 144a98d478eSShuo Chen //SSL_clear(ssl); 145a98d478eSShuo Chen //SSL_clear(ssl_client); 146a98d478eSShuo Chen if (i != N-1) 147a98d478eSShuo Chen { 148a98d478eSShuo Chen SSL_free (ssl); 149a98d478eSShuo Chen SSL_free (ssl_client); 150a98d478eSShuo Chen } 151a98d478eSShuo Chen } 152a98d478eSShuo Chen double elapsed = now() - start; 153a98d478eSShuo Chen printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 1549acb42f4SShuo Chen printf("client %.3f %.1f\n", tc.seconds(), N / tc.seconds()); 1559acb42f4SShuo Chen printf("server %.3f %.1f\n", ts.seconds(), N / ts.seconds()); 1569acb42f4SShuo Chen printf("server/client %.2f\n", ts.seconds() / tc.seconds()); 1579acb42f4SShuo Chen 158a98d478eSShuo Chen 159a98d478eSShuo Chen double start2 = now(); 160a98d478eSShuo Chen const int M = 300; 161a98d478eSShuo Chen char buf[1024] = { 0 }; 162a98d478eSShuo Chen for (int i = 0; i < M*1024; ++i) 163a98d478eSShuo Chen { 164a98d478eSShuo Chen int n = SSL_write(ssl_client, buf, sizeof buf); 165a98d478eSShuo Chen if (n < 0) 166a98d478eSShuo Chen { 1679acb42f4SShuo Chen printf("%d\n", n); 168a98d478eSShuo Chen } 169a98d478eSShuo Chen clientOut.retrieveAll(); 170a98d478eSShuo Chen } 171a98d478eSShuo Chen elapsed = now() - start2; 172a98d478eSShuo Chen printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed); 173a98d478eSShuo Chen SSL_free (ssl); 174a98d478eSShuo Chen SSL_free (ssl_client); 175a98d478eSShuo Chen 176a98d478eSShuo Chen SSL_CTX_free (ctx); 177a98d478eSShuo Chen SSL_CTX_free (ctx_client); 178a98d478eSShuo Chen} 179