benchmark-libressl.cc revision b140ba61
12c01beb4SShuo Chen#include <muduo/net/Buffer.h>
22c01beb4SShuo Chen
32c01beb4SShuo Chen#include <stdio.h>
42c01beb4SShuo Chen
52c01beb4SShuo Chen#include <tls.h>
62c01beb4SShuo Chen
72c01beb4SShuo Chen#include "timer.h"
82c01beb4SShuo Chen
92c01beb4SShuo Chenmuduo::net::Buffer clientOut, serverOut;
10d9e55939SShuo Chenint64_t clientWrite, serverWrite;
112c01beb4SShuo Chen
122c01beb4SShuo Chenssize_t net_read(struct tls *ctx, void *buf, size_t len, void *arg)
132c01beb4SShuo Chen{
142c01beb4SShuo Chen  muduo::net::Buffer* in = ((arg == &clientOut) ? &serverOut : &clientOut);
152c01beb4SShuo Chen  if (in->readableBytes() > 0)
162c01beb4SShuo Chen  {
172c01beb4SShuo Chen    size_t n = std::min(in->readableBytes(), len);
182c01beb4SShuo Chen    memcpy(buf, in->peek(), n);
192c01beb4SShuo Chen    in->retrieve(n);
202c01beb4SShuo Chen    return n;
212c01beb4SShuo Chen  }
222c01beb4SShuo Chen  else
232c01beb4SShuo Chen  {
242c01beb4SShuo Chen    return TLS_WANT_POLLIN;
252c01beb4SShuo Chen  }
262c01beb4SShuo Chen}
272c01beb4SShuo Chen
282c01beb4SShuo Chenssize_t net_write(struct tls *ctx, const void *buf, size_t len, void *arg)
292c01beb4SShuo Chen{
302c01beb4SShuo Chen  muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(arg);
31d9e55939SShuo Chen  int64_t& wr = (out == &clientOut ? clientWrite : serverWrite);
32d9e55939SShuo Chen  wr += len;
332c01beb4SShuo Chen  out->append(buf, len);
342c01beb4SShuo Chen  return len;
352c01beb4SShuo Chen}
362c01beb4SShuo Chen
372c01beb4SShuo Chenstruct tls* client()
382c01beb4SShuo Chen{
392c01beb4SShuo Chen  struct tls_config* cfg = tls_config_new();
402c01beb4SShuo Chen  assert(cfg != NULL);
412c01beb4SShuo Chen
422c01beb4SShuo Chen  tls_config_set_ca_file(cfg, "ca.pem");
432c01beb4SShuo Chen  // tls_config_insecure_noverifycert(cfg);
442c01beb4SShuo Chen  // tls_config_insecure_noverifyname(cfg);
452c01beb4SShuo Chen
462c01beb4SShuo Chen  struct tls* ctx = tls_client();
472c01beb4SShuo Chen  assert(ctx != NULL);
482c01beb4SShuo Chen
492c01beb4SShuo Chen  int ret = tls_configure(ctx, cfg);
502c01beb4SShuo Chen  assert(ret == 0);
512c01beb4SShuo Chen
522c01beb4SShuo Chen  tls_connect_cbs(ctx, net_read, net_write, &clientOut, "Test Server Cert");
532c01beb4SShuo Chen
542c01beb4SShuo Chen  return ctx;
552c01beb4SShuo Chen}
562c01beb4SShuo Chen
572c01beb4SShuo Chenstruct tls* server()
582c01beb4SShuo Chen{
592c01beb4SShuo Chen  struct tls_config* cfg = tls_config_new();
602c01beb4SShuo Chen  assert(cfg != NULL);
612c01beb4SShuo Chen
622c01beb4SShuo Chen  int ret = tls_config_set_cert_file(cfg, "server.pem");
632c01beb4SShuo Chen  assert(ret == 0);
642c01beb4SShuo Chen
652c01beb4SShuo Chen  ret = tls_config_set_key_file(cfg, "server.pem");
662c01beb4SShuo Chen  assert(ret == 0);
672c01beb4SShuo Chen
68b140ba61SShuo Chen  ret = tls_config_set_ecdhecurve(cfg, "prime256v1");
69b140ba61SShuo Chen  assert(ret == 0);
70b140ba61SShuo Chen
712c01beb4SShuo Chen  // tls_config_verify_client_optional(cfg);
722c01beb4SShuo Chen  struct tls* ctx = tls_server();
732c01beb4SShuo Chen  assert(ctx != NULL);
742c01beb4SShuo Chen
752c01beb4SShuo Chen  ret = tls_configure(ctx, cfg);
762c01beb4SShuo Chen  assert(ret == 0);
772c01beb4SShuo Chen
782c01beb4SShuo Chen  struct tls* conn_ctx = NULL;
792c01beb4SShuo Chen  tls_accept_cbs(ctx, &conn_ctx, net_read, net_write, &serverOut);
802c01beb4SShuo Chen  return conn_ctx;
812c01beb4SShuo Chen}
822c01beb4SShuo Chen
832c01beb4SShuo ChenTimer tclient, tserver;
842c01beb4SShuo Chen
852c01beb4SShuo Chenvoid handshake(struct tls* cctx, struct tls* sctx)
862c01beb4SShuo Chen{
872c01beb4SShuo Chen  int client_done = false, server_done = false;
882c01beb4SShuo Chen  while (!(client_done && server_done))
892c01beb4SShuo Chen  {
902c01beb4SShuo Chen    if (!client_done)
912c01beb4SShuo Chen    {
922c01beb4SShuo Chen      tclient.start();
932c01beb4SShuo Chen      int ret = tls_handshake(cctx);
942c01beb4SShuo Chen      tclient.stop();
952c01beb4SShuo Chen      // printf("c %d\n", ret);
962c01beb4SShuo Chen      if (ret == 0)
972c01beb4SShuo Chen        client_done = true;
982c01beb4SShuo Chen      else if (ret == -1)
992c01beb4SShuo Chen        break;
1002c01beb4SShuo Chen    }
1012c01beb4SShuo Chen
1022c01beb4SShuo Chen    if (!server_done)
1032c01beb4SShuo Chen    {
1042c01beb4SShuo Chen      tserver.start();
1052c01beb4SShuo Chen      int ret = tls_handshake(sctx);
1062c01beb4SShuo Chen      tserver.stop();
1072c01beb4SShuo Chen      // printf("s %d\n", ret);
1082c01beb4SShuo Chen      if (ret == 0)
1092c01beb4SShuo Chen        server_done = true;
1102c01beb4SShuo Chen      else if (ret == -1)
1112c01beb4SShuo Chen        break;
1122c01beb4SShuo Chen    }
1132c01beb4SShuo Chen  }
1142c01beb4SShuo Chen}
1152c01beb4SShuo Chen
116d9e55939SShuo Chenvoid throughput(int block_size, struct tls* cctx, struct tls* sctx)
117d9e55939SShuo Chen{
118d9e55939SShuo Chen  double start = now();
119d9e55939SShuo Chen  int total = 0;
120d9e55939SShuo Chen  int batch = 1024;
121d9e55939SShuo Chen  char* message = new char[block_size];
122d9e55939SShuo Chen  bzero(message, block_size);
123d9e55939SShuo Chen  clientWrite = 0;
124d9e55939SShuo Chen  tclient.reset();
125d9e55939SShuo Chen  tserver.reset();
126d9e55939SShuo Chen  while (now() - start < 10)
127d9e55939SShuo Chen  {
128d9e55939SShuo Chen    for (int i = 0; i < batch; ++i)
129d9e55939SShuo Chen    {
130d9e55939SShuo Chen      tclient.start();
131d9e55939SShuo Chen      int nw = tls_write(cctx, message, block_size);
132d9e55939SShuo Chen      tclient.stop();
133d9e55939SShuo Chen      assert(nw == block_size);
134d9e55939SShuo Chen      tserver.start();
135d9e55939SShuo Chen      int nr = tls_read(sctx, message, block_size);
136d9e55939SShuo Chen      tserver.stop();
137d9e55939SShuo Chen      assert(nr == block_size);
138d9e55939SShuo Chen    }
139d9e55939SShuo Chen    total += batch;
140d9e55939SShuo Chen    batch *= 2;
141d9e55939SShuo Chen  }
142d9e55939SShuo Chen  double secs = now() - start;
143d9e55939SShuo Chen  // throughput is half of real value, because client and server share one core.
144d9e55939SShuo Chen  printf("bs %5d sec %.3f tot %d thr %.1fKB/s wr %.2fB client %.3f server %.3f\n", block_size, secs, total,
145d9e55939SShuo Chen         block_size / secs * total / 1024, clientWrite * 1.0 / total, tclient.seconds(), tserver.seconds());
146926c960eSShuo Chen  delete[] message;
147d9e55939SShuo Chen}
148d9e55939SShuo Chen
1492c01beb4SShuo Chenint main(int argc, char* argv[])
1502c01beb4SShuo Chen{
1512c01beb4SShuo Chen  int ret = tls_init();
1522c01beb4SShuo Chen  assert(ret == 0);
1532c01beb4SShuo Chen
1542c01beb4SShuo Chen  struct tls* cctx = client();
1552c01beb4SShuo Chen  struct tls* sctx = server();
1562c01beb4SShuo Chen
1572c01beb4SShuo Chen  const int N = 500;
1582c01beb4SShuo Chen  Timer all, client, server;
1592c01beb4SShuo Chen  all.start();
1602c01beb4SShuo Chen  for (int i = 0; i < N; ++i)
1612c01beb4SShuo Chen  {
1622c01beb4SShuo Chen    handshake(cctx, sctx);
1632c01beb4SShuo Chen
1642c01beb4SShuo Chen    if (i == 0)
1652c01beb4SShuo Chen      printf("cipher %s\n", tls_conn_cipher(cctx));
1662c01beb4SShuo Chen  }
1672c01beb4SShuo Chen  all.stop();
1682c01beb4SShuo Chen  printf("%f secs, %f handshakes/sec\n", all.seconds(), N / all.seconds());
1692c01beb4SShuo Chen  printf("client %f secs, server %f secs\n", tclient.seconds(), tserver.seconds());
170d9e55939SShuo Chen
171d9e55939SShuo Chen  for (int i = 1; i <= 1024 * 16; i *= 2)
172d9e55939SShuo Chen  {
173d9e55939SShuo Chen    throughput(i, cctx, sctx);
174d9e55939SShuo Chen  }
1752c01beb4SShuo Chen}
1762c01beb4SShuo Chen
177