loop-libressl.cc revision 926c960e
1926c960eSShuo Chen#include "timer.h" 2926c960eSShuo Chen#include "thread/Thread.h" 3926c960eSShuo Chen#include <boost/bind.hpp> 4926c960eSShuo Chen 542b85340SShuo Chen#include <assert.h> 6926c960eSShuo Chen#include <fcntl.h> 742b85340SShuo Chen#include <stdio.h> 842b85340SShuo Chen#include <sys/types.h> 942b85340SShuo Chen#include <sys/socket.h> 1042b85340SShuo Chen 1142b85340SShuo Chen#include <tls.h> 1242b85340SShuo Chen 1323a62999SShuo Chenstruct tls* client(int sockfd) 1442b85340SShuo Chen{ 1542b85340SShuo Chen struct tls_config* cfg = tls_config_new(); 1642b85340SShuo Chen assert(cfg != NULL); 1742b85340SShuo Chen 1842b85340SShuo Chen tls_config_set_ca_file(cfg, "ca.pem"); 1942b85340SShuo Chen // tls_config_insecure_noverifycert(cfg); 2042b85340SShuo Chen // tls_config_insecure_noverifyname(cfg); 2142b85340SShuo Chen 2242b85340SShuo Chen struct tls* ctx = tls_client(); 2342b85340SShuo Chen assert(ctx != NULL); 2442b85340SShuo Chen 2542b85340SShuo Chen int ret = tls_configure(ctx, cfg); 2642b85340SShuo Chen assert(ret == 0); 2742b85340SShuo Chen 2823a62999SShuo Chen ret = tls_connect_socket(ctx, sockfd, "Test Server Cert"); 2923a62999SShuo Chen assert(ret == 0); 3023a62999SShuo Chen 3142b85340SShuo Chen return ctx; 3242b85340SShuo Chen} 3342b85340SShuo Chen 3423a62999SShuo Chenstruct tls* server(int sockfd) 3542b85340SShuo Chen{ 3642b85340SShuo Chen struct tls_config* cfg = tls_config_new(); 3742b85340SShuo Chen assert(cfg != NULL); 3842b85340SShuo Chen 3923a62999SShuo Chen int ret = tls_config_set_cert_file(cfg, "server.pem"); 4042b85340SShuo Chen assert(ret == 0); 4142b85340SShuo Chen 4223a62999SShuo Chen ret = tls_config_set_key_file(cfg, "server.pem"); 4342b85340SShuo Chen assert(ret == 0); 4442b85340SShuo Chen 4542b85340SShuo Chen tls_config_verify_client_optional(cfg); 4642b85340SShuo Chen struct tls* ctx = tls_server(); 4742b85340SShuo Chen assert(ctx != NULL); 4842b85340SShuo Chen 4942b85340SShuo Chen ret = tls_configure(ctx, cfg); 5042b85340SShuo Chen assert(ret == 0); 5142b85340SShuo Chen 5242b85340SShuo Chen struct tls* sctx = NULL; 5323a62999SShuo Chen ret = tls_accept_socket(ctx, &sctx, sockfd); 5423a62999SShuo Chen assert(ret == 0 && sctx != NULL); 5542b85340SShuo Chen 5623a62999SShuo Chen return sctx; 5723a62999SShuo Chen} 5823a62999SShuo Chen 59926c960eSShuo Chen// only works for non-blocking sockets 6023a62999SShuo Chenbool handshake(struct tls* cctx, struct tls* sctx) 6123a62999SShuo Chen{ 6223a62999SShuo Chen int client_done = false, server_done = false; 6323a62999SShuo Chen 6423a62999SShuo Chen while (!(client_done && server_done)) 6523a62999SShuo Chen { 6623a62999SShuo Chen if (!client_done) 6723a62999SShuo Chen { 6823a62999SShuo Chen int ret = tls_handshake(cctx); 69926c960eSShuo Chen // printf("c %d\n", ret); 7023a62999SShuo Chen if (ret == 0) 7123a62999SShuo Chen client_done = true; 7223a62999SShuo Chen else if (ret == -1) 7323a62999SShuo Chen { 7423a62999SShuo Chen printf("client handshake failed: %s\n", tls_error(cctx)); 7523a62999SShuo Chen break; 7623a62999SShuo Chen } 7723a62999SShuo Chen } 7823a62999SShuo Chen 7923a62999SShuo Chen if (!server_done) 8023a62999SShuo Chen { 8123a62999SShuo Chen int ret = tls_handshake(sctx); 82926c960eSShuo Chen // printf("s %d\n", ret); 8323a62999SShuo Chen if (ret == 0) 8423a62999SShuo Chen server_done = true; 8523a62999SShuo Chen else if (ret == -1) 8623a62999SShuo Chen { 8723a62999SShuo Chen printf("server handshake failed: %s\n", tls_error(cctx)); 8823a62999SShuo Chen break; 8923a62999SShuo Chen } 9023a62999SShuo Chen } 9123a62999SShuo Chen } 9223a62999SShuo Chen 9323a62999SShuo Chen return client_done && server_done; 9423a62999SShuo Chen} 9523a62999SShuo Chen 96926c960eSShuo Chenvoid setBlockingIO(int fd) 97926c960eSShuo Chen{ 98926c960eSShuo Chen int flags = fcntl(fd, F_GETFL, 0); 99926c960eSShuo Chen if (flags > 0) 100926c960eSShuo Chen { 101926c960eSShuo Chen printf("set blocking IO for %d\n", fd); 102926c960eSShuo Chen fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 103926c960eSShuo Chen } 104926c960eSShuo Chen} 105926c960eSShuo Chen 106926c960eSShuo Chenconst int N = 500; 107926c960eSShuo Chen 108926c960eSShuo Chenstruct Trial 109926c960eSShuo Chen{ 110926c960eSShuo Chen int blocks, block_size; 111926c960eSShuo Chen}; 112926c960eSShuo Chen 113926c960eSShuo Chenvoid client_thread(struct tls* ctx) 114926c960eSShuo Chen{ 115926c960eSShuo Chen Timer t; 116926c960eSShuo Chen t.start(); 117926c960eSShuo Chen for (int i = 0; i < N; ++i) 118926c960eSShuo Chen { 119926c960eSShuo Chen int ret = tls_handshake(ctx); 120926c960eSShuo Chen if (ret != 0) 121926c960eSShuo Chen printf("client err = %d\n", ret); 122926c960eSShuo Chen } 123926c960eSShuo Chen t.stop(); 124926c960eSShuo Chen printf("client %f secs, %f handshakes/sec\n", t.seconds(), N / t.seconds()); 125926c960eSShuo Chen while (true) 126926c960eSShuo Chen { 127926c960eSShuo Chen Trial trial = { 0, 0 }; 128926c960eSShuo Chen 129926c960eSShuo Chen int nr = tls_read(ctx, &trial, sizeof trial); 130926c960eSShuo Chen if (nr == 0) 131926c960eSShuo Chen break; 132926c960eSShuo Chen assert(nr == sizeof trial); 133926c960eSShuo Chen // printf("client read bs %d nb %d\n", trial.block_size, trial.blocks); 134926c960eSShuo Chen if (trial.block_size == 0) 135926c960eSShuo Chen break; 136926c960eSShuo Chen char* buf = new char[trial.block_size]; 137926c960eSShuo Chen for (int i = 0; i < trial.blocks; ++i) 138926c960eSShuo Chen { 139926c960eSShuo Chen nr = tls_read(ctx, buf, trial.block_size); 140926c960eSShuo Chen assert(nr == trial.block_size); 141926c960eSShuo Chen } 142926c960eSShuo Chen int64_t ack = static_cast<int64_t>(trial.blocks) * trial.block_size; 143926c960eSShuo Chen int nw = tls_write(ctx, &ack, sizeof ack); 144926c960eSShuo Chen assert(nw == sizeof ack); 145926c960eSShuo Chen delete[] buf; 146926c960eSShuo Chen } 147926c960eSShuo Chen printf("client done\n"); 148926c960eSShuo Chen tls_close(ctx); 149926c960eSShuo Chen tls_free(ctx); 150926c960eSShuo Chen} 151926c960eSShuo Chen 152926c960eSShuo Chenvoid send(int block_size, struct tls* ctx) 153926c960eSShuo Chen{ 154926c960eSShuo Chen double start = now(); 155926c960eSShuo Chen int total = 0; 156926c960eSShuo Chen int blocks = 1024; 157926c960eSShuo Chen char* message = new char[block_size]; 158926c960eSShuo Chen bzero(message, block_size); 159926c960eSShuo Chen Timer t; 160926c960eSShuo Chen while (now() - start < 10) 161926c960eSShuo Chen { 162926c960eSShuo Chen Trial trial = { blocks, block_size }; 163926c960eSShuo Chen int nw = tls_write(ctx, &trial, sizeof trial); 164926c960eSShuo Chen assert(nw == sizeof trial); 165926c960eSShuo Chen t.start(); 166926c960eSShuo Chen for (int i = 0; i < blocks; ++i) 167926c960eSShuo Chen { 168926c960eSShuo Chen nw = tls_write(ctx, message, block_size); 169926c960eSShuo Chen if (nw != block_size) 170926c960eSShuo Chen printf("bs %d nw %d\n", block_size, nw); 171926c960eSShuo Chen assert(nw == block_size); 172926c960eSShuo Chen } 173926c960eSShuo Chen t.stop(); 174926c960eSShuo Chen int64_t ack = 0; 175926c960eSShuo Chen int nr = tls_read(ctx, &ack, sizeof ack); 176926c960eSShuo Chen assert(nr == sizeof ack); 177926c960eSShuo Chen assert(ack == static_cast<int64_t>(blocks) * block_size); 178926c960eSShuo Chen total += blocks; 179926c960eSShuo Chen blocks *= 2; 180926c960eSShuo Chen } 181926c960eSShuo Chen double secs = now() - start; 182926c960eSShuo Chen printf("bs %5d sec %.3f tot %d thr %.1fKB/s wr cpu %.3f\n", block_size, secs, total, 183926c960eSShuo Chen block_size / secs * total / 1024, t.seconds()); 184926c960eSShuo Chen delete[] message; 185926c960eSShuo Chen} 186926c960eSShuo Chen 18723a62999SShuo Chenint main(int argc, char* argv[]) 18823a62999SShuo Chen{ 18923a62999SShuo Chen int ret = tls_init(); 19042b85340SShuo Chen assert(ret == 0); 19142b85340SShuo Chen 19223a62999SShuo Chen int fds[2]; 19323a62999SShuo Chen socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds); 19423a62999SShuo Chen 19523a62999SShuo Chen struct tls* cctx = client(fds[0]); 19623a62999SShuo Chen struct tls* sctx = server(fds[1]); 19742b85340SShuo Chen 19823a62999SShuo Chen if (handshake(cctx, sctx)) 19923a62999SShuo Chen printf("cipher %s\n", tls_conn_cipher(cctx)); 200926c960eSShuo Chen 201926c960eSShuo Chen setBlockingIO(fds[0]); 202926c960eSShuo Chen setBlockingIO(fds[1]); 203926c960eSShuo Chen muduo::Thread thr(boost::bind(client_thread, cctx), "clientThread"); 204926c960eSShuo Chen thr.start(); 205926c960eSShuo Chen 206926c960eSShuo Chen { 207926c960eSShuo Chen Timer t; 208926c960eSShuo Chen t.start(); 209926c960eSShuo Chen for (int i = 0; i < N; ++i) 210926c960eSShuo Chen { 211926c960eSShuo Chen int ret = tls_handshake(sctx); 212926c960eSShuo Chen if (ret != 0) 213926c960eSShuo Chen printf("server err = %d\n", ret); 214926c960eSShuo Chen } 215926c960eSShuo Chen t.stop(); 216926c960eSShuo Chen printf("server %f secs, %f handshakes/sec\n", t.seconds(), N / t.seconds()); 217926c960eSShuo Chen } 218926c960eSShuo Chen 219926c960eSShuo Chen for (int i = 1; i <= 1024 * 16; i *= 2) 220926c960eSShuo Chen { 221926c960eSShuo Chen send(i, sctx); 222926c960eSShuo Chen } 223926c960eSShuo Chen tls_close(sctx); 224926c960eSShuo Chen shutdown(fds[1], SHUT_RDWR); 225926c960eSShuo Chen tls_free(sctx); 226926c960eSShuo Chen 227926c960eSShuo Chen thr.join(); 22842b85340SShuo Chen} 229