benchmark-openssl.cc revision a98d478e
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 10a98d478eSShuo Chenmuduo::net::Buffer clientOut, serverOut; 11a98d478eSShuo Chen 12a98d478eSShuo Chendouble now() 13a98d478eSShuo Chen{ 14a98d478eSShuo Chen struct timeval tv; 15a98d478eSShuo Chen gettimeofday(&tv, NULL); 16a98d478eSShuo Chen return tv.tv_sec + tv.tv_usec / 1000000.0; 17a98d478eSShuo Chen} 18a98d478eSShuo Chen 19a98d478eSShuo Chenint bread(BIO *b, char *buf, int len) 20a98d478eSShuo Chen{ 21a98d478eSShuo Chen BIO_clear_retry_flags(b); 22a98d478eSShuo Chen muduo::net::Buffer* in = static_cast<muduo::net::Buffer*>(b->ptr); 23a98d478eSShuo Chen // printf("%s recv %d\n", in == &clientOut ? "server" : "client", len); 24a98d478eSShuo Chen if (in->readableBytes() > 0) 25a98d478eSShuo Chen { 26a98d478eSShuo Chen size_t n = std::min(in->readableBytes(), static_cast<size_t>(len)); 27a98d478eSShuo Chen memcpy(buf, in->peek(), n); 28a98d478eSShuo Chen in->retrieve(n); 29a98d478eSShuo Chen 30a98d478eSShuo Chen /* 31a98d478eSShuo Chen if (n < len) 32a98d478eSShuo Chen printf("got %zd\n", n); 33a98d478eSShuo Chen else 34a98d478eSShuo Chen printf("\n"); 35a98d478eSShuo Chen */ 36a98d478eSShuo Chen return n; 37a98d478eSShuo Chen } 38a98d478eSShuo Chen else 39a98d478eSShuo Chen { 40a98d478eSShuo Chen //printf("got 0\n"); 41a98d478eSShuo Chen BIO_set_retry_read(b); 42a98d478eSShuo Chen return -1; 43a98d478eSShuo Chen } 44a98d478eSShuo Chen} 45a98d478eSShuo Chen 46a98d478eSShuo Chenint bwrite(BIO *b, const char *buf, int len) 47a98d478eSShuo Chen{ 48a98d478eSShuo Chen BIO_clear_retry_flags(b); 49a98d478eSShuo Chen muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(b->ptr); 50a98d478eSShuo Chen // printf("%s send %d\n", out == &clientOut ? "client" : "server", len); 51a98d478eSShuo Chen out->append(buf, len); 52a98d478eSShuo Chen return len; 53a98d478eSShuo Chen} 54a98d478eSShuo Chen 55a98d478eSShuo Chenlong bctrl(BIO *, int cmd, long num, void *) 56a98d478eSShuo Chen{ 57a98d478eSShuo Chen //printf("ctrl %d\n", cmd); 58a98d478eSShuo Chen switch (cmd) { 59a98d478eSShuo Chen case BIO_CTRL_FLUSH: 60a98d478eSShuo Chen return 1; 61a98d478eSShuo Chen default: 62a98d478eSShuo Chen return 0; 63a98d478eSShuo Chen } 64a98d478eSShuo Chen} 65a98d478eSShuo Chen 66a98d478eSShuo Chenint main(int argc, char* argv[]) 67a98d478eSShuo Chen{ 68a98d478eSShuo Chen SSL_load_error_strings(); 69a98d478eSShuo Chen // ERR_load_BIO_strings(); 70a98d478eSShuo Chen SSL_library_init(); 71a98d478eSShuo Chen OPENSSL_config(NULL); 72a98d478eSShuo Chen 73a98d478eSShuo Chen SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_server_method()); 74a98d478eSShuo Chen 75a98d478eSShuo Chen EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 76a98d478eSShuo Chen SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); 77a98d478eSShuo Chen SSL_CTX_set_tmp_ecdh(ctx, ecdh); 78a98d478eSShuo Chen EC_KEY_free(ecdh); 79a98d478eSShuo Chen 80a98d478eSShuo Chen const char* CertFile = argv[1]; 81a98d478eSShuo Chen const char* KeyFile = argv[2]; 82a98d478eSShuo Chen SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM); 83a98d478eSShuo Chen SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM); 84a98d478eSShuo Chen if (!SSL_CTX_check_private_key(ctx)) 85a98d478eSShuo Chen abort(); 86a98d478eSShuo Chen 87a98d478eSShuo Chen SSL_CTX* ctx_client = SSL_CTX_new(TLSv1_1_client_method()); 88a98d478eSShuo Chen 89a98d478eSShuo Chen BIO_METHOD method; 90a98d478eSShuo Chen bzero(&method, sizeof method); 91a98d478eSShuo Chen method.bread = bread; 92a98d478eSShuo Chen method.bwrite = bwrite; 93a98d478eSShuo Chen method.ctrl = bctrl; 94a98d478eSShuo Chen BIO client, server; 95a98d478eSShuo Chen bzero(&client, sizeof client); 96a98d478eSShuo Chen bzero(&server, sizeof server); 97a98d478eSShuo Chen BIO_set(&client, &method); 98a98d478eSShuo Chen BIO_set(&server, &method); 99a98d478eSShuo Chen client.ptr = &clientOut; 100a98d478eSShuo Chen client.init = 1; 101a98d478eSShuo Chen server.ptr = &serverOut; 102a98d478eSShuo Chen server.init = 1; 103a98d478eSShuo Chen 104a98d478eSShuo Chen 105a98d478eSShuo Chen double start = now(); 106a98d478eSShuo Chen const int N = 1000; 107a98d478eSShuo Chen SSL *ssl, *ssl_client; 108a98d478eSShuo Chen for (int i = 0; i < N; ++i) 109a98d478eSShuo Chen { 110a98d478eSShuo Chen ssl = SSL_new (ctx); 111a98d478eSShuo Chen ssl_client = SSL_new (ctx_client); 112a98d478eSShuo Chen SSL_set_bio(ssl, &client, &server); 113a98d478eSShuo Chen SSL_set_bio(ssl_client, &server, &client); 114a98d478eSShuo Chen 115a98d478eSShuo Chen int ret = SSL_connect(ssl_client); 116a98d478eSShuo Chen //printf("%d %d\n", ret, BIO_retry_type(&server)); 117a98d478eSShuo Chen int ret2 = SSL_accept(ssl); 118a98d478eSShuo Chen //printf("%d %d\n", ret2, BIO_retry_type(&client)); 119a98d478eSShuo Chen 120a98d478eSShuo Chen while (true) 121a98d478eSShuo Chen { 122a98d478eSShuo Chen int ret = SSL_do_handshake(ssl_client); 123a98d478eSShuo Chen //printf("client handshake %d %d\n", ret, BIO_retry_type(&server)); 124a98d478eSShuo Chen int ret2 = SSL_do_handshake(ssl); 125a98d478eSShuo Chen //printf("server handshake %d %d\n", ret2, BIO_retry_type(&client)); 126a98d478eSShuo Chen //if (ret == -1 && BIO_retry_type(&server) == 0) 127a98d478eSShuo Chen // break; 128a98d478eSShuo Chen //if (ret2 == -1 && BIO_retry_type(&client) == 0) 129a98d478eSShuo Chen // break; 130a98d478eSShuo Chen if (ret == 1 && ret2 == 1) 131a98d478eSShuo Chen break; 132a98d478eSShuo Chen } 133a98d478eSShuo Chen 134a98d478eSShuo Chen //printf ("SSL connection using %s %s\n", SSL_get_version(ssl), SSL_get_cipher (ssl)); 135a98d478eSShuo Chen if (i == 0) 136a98d478eSShuo Chen printf ("SSL connection using %s %s\n", SSL_get_version(ssl_client), SSL_get_cipher (ssl_client)); 137a98d478eSShuo Chen //SSL_clear(ssl); 138a98d478eSShuo Chen //SSL_clear(ssl_client); 139a98d478eSShuo Chen if (i != N-1) 140a98d478eSShuo Chen { 141a98d478eSShuo Chen SSL_free (ssl); 142a98d478eSShuo Chen SSL_free (ssl_client); 143a98d478eSShuo Chen } 144a98d478eSShuo Chen } 145a98d478eSShuo Chen double elapsed = now() - start; 146a98d478eSShuo Chen printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 147a98d478eSShuo Chen 148a98d478eSShuo Chen double start2 = now(); 149a98d478eSShuo Chen const int M = 300; 150a98d478eSShuo Chen char buf[1024] = { 0 }; 151a98d478eSShuo Chen for (int i = 0; i < M*1024; ++i) 152a98d478eSShuo Chen { 153a98d478eSShuo Chen int n = SSL_write(ssl_client, buf, sizeof buf); 154a98d478eSShuo Chen if (n < 0) 155a98d478eSShuo Chen { 156a98d478eSShuo Chen //char errbuf[512]; 157a98d478eSShuo Chen //polarssl_strerror(n, errbuf, sizeof errbuf); 158a98d478eSShuo Chen //printf("%s\n", errbuf); 159a98d478eSShuo Chen } 160a98d478eSShuo Chen /* 161a98d478eSShuo Chen n = ssl_read(&ssl_server, buf, 8192); 162a98d478eSShuo Chen if (n != 1024) 163a98d478eSShuo Chen break; 164a98d478eSShuo Chen if (n < 0) 165a98d478eSShuo Chen { 166a98d478eSShuo Chen char errbuf[512]; 167a98d478eSShuo Chen polarssl_strerror(n, errbuf, sizeof errbuf); 168a98d478eSShuo Chen printf("%s\n", errbuf); 169a98d478eSShuo Chen } 170a98d478eSShuo Chen */ 171a98d478eSShuo Chen clientOut.retrieveAll(); 172a98d478eSShuo Chen } 173a98d478eSShuo Chen elapsed = now() - start2; 174a98d478eSShuo Chen printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed); 175a98d478eSShuo Chen SSL_free (ssl); 176a98d478eSShuo Chen SSL_free (ssl_client); 177a98d478eSShuo Chen 178a98d478eSShuo Chen SSL_CTX_free (ctx); 179a98d478eSShuo Chen SSL_CTX_free (ctx_client); 180a98d478eSShuo Chen} 181