之前写的SSL的性能测试程序
2013-03-14 11:13
218 查看
client.c
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <sys/mman.h> #define MAXBUF 1024 #define MAX_THREADS 100 #define SUBTHREADNUM 2 int pkgSize = 1024; int threads = 10; int times = 10; int mode = 0; //0-handshake 1-throughput 2-full int sslversion = 1; //0-SSLv2 1-SSLv3 2-SSLv23 3-TLSv1 4-TLSv1_1 5-TLSv1_2 char *ip = "127.0.0.1"; int port = 8701; char *cipher = "AES128-SHA"; int debug = 0; int showTitle = 1; struct cpuinfo { char name[20]; unsigned int user; unsigned int nice; unsigned int system; unsigned int idle; unsigned int iowait; unsigned int irq; unsigned int softirq; unsigned int stealstolen; unsigned int guest; }; void throughputTest(); void handshakeTest(); void fullTest(); void apacheTest(); void getCpuInfo (struct cpuinfo *cpu); void calCpuUseRatio (struct cpuinfo *old, struct cpuinfo *new); int getCpuTotalUseRatio(); struct shm_layout { u_int64_t count[MAX_THREADS]; u_int64_t t1[MAX_THREADS]; u_int64_t t2[MAX_THREADS]; int ready[MAX_THREADS]; int done[MAX_THREADS]; volatile int start; volatile int exit; volatile int stop; }; struct subthread_layout { u_int64_t starttime[SUBTHREADNUM]; u_int64_t endtime[SUBTHREADNUM]; u_int64_t count[SUBTHREADNUM]; }; struct shm_layout *shared_region = NULL; struct subthread_layout subthread_region; u_int64_t total_count = 0ull; int thread_id = 0; u_int64_t min_t1 = 0ull, max_t2 = 0ull; u_int64_t total_throughput = 0; int pid[100]; struct sockaddr_in dest; char *buffer; SSL_CTX *ctx; void usage() { printf("Usage: Client \n\ -a IP Addr (127.0.0.1) \n\ -c Cipher (AES128-SHA) \n\ -p Port (8701)\n\ -s Package Size (1024)\n\ -t Times (10)\n\ -l Threads (10)\n\ -m Mode (0-handshake 1-throughput 2-full 3-apachessl default 0)\n\ -v SSLVersion (0-SSLv2 1-SSLv3 2-SSLv23 3-TLSv1 4-TLSv1_1 5-TLSv1_2 default 1)\n\ -d Debug Info\n\ -h Help\n"); exit(-1); } void min_max_times(int count, u_int64_t *t1, u_int64_t *t2, u_int64_t *min_t1, u_int64_t *max_t2) { int i = 0; *min_t1 = t1[0]; *max_t2 = t2[0]; for(i = 1; i < count; i++) { if(t1[i] < *min_t1) *min_t1 = t1[i]; if(t2[i] > *max_t2) *max_t2 = t2[i]; } } u_int64_t apiTimeUs() { struct timeval m_real1; u_int64_t temp; gettimeofday (&m_real1, 0); temp = m_real1.tv_sec; temp = (temp * 1000000) + m_real1.tv_usec; return temp; } char* randomStr() { char *tmp = malloc(pkgSize * sizeof(char) + 1); int i; srand(time(NULL)); for(i = 0; i < pkgSize; i++) { do { tmp[i] = rand() % 128; }while(!isprint(tmp[i])); } tmp[i] = '\0'; return tmp; } int main(int argc, char **argv) { char options[] = "a:c:m:t:s:p:v:l:hde"; int opt; while((opt = getopt(argc, argv, options)) != -1) { switch(opt) { case 't': times = atoi(optarg); //printf("times:%d\n", times); break; case 'c': cipher = optarg; break; case 's': pkgSize = atoi(optarg); //printf("pkgSize:%d\n", pkgSize); break; case 'l': threads = atoi(optarg); //printf("threads:%d\n", threads); break; case 'p': port = atoi(optarg); //printf("port:%d\n", port); break; case 'a': ip = optarg; //printf("IP:%s\n", ip); break; case 'm': mode = atoi(optarg); //printf("type:%d\n", mode); break; case 'v': sslversion = atoi(optarg); //printf("type:%d\n", sslversion); break; case 'd': debug = 1; break; case 'e': showTitle = 0; break; case 'h': default: usage(); break; } } if(showTitle) { char *title[4] = {"Handshake Test", "Throughput Test", "HS And TP Test", "Apache SSL Test"}; char *version[6] = {"SSLv2", "SSLv3", "SSLv23", "TLSv1", "TLSv1_1", "TLSv1_2"}; char tmpStr[200] = {0}; sprintf(tmpStr, "%s%s%s", "------------------------------------------------ ", title[mode], " ------------------------------------------------"); printf("%s\n", tmpStr); printf("Server IP Server Port Thread Number Times Package Size Cipher Version\n"); printf("%-20s %-20d %-15d %-16d %-12d %-16s %s\n", ip, port, threads, times, pkgSize, cipher, version[sslversion]); } int status[100]; shared_region = mmap(NULL, sizeof(struct shm_layout), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); if(shared_region == MAP_FAILED) { printf("\n ERROR mapping \n"); exit(1); } memset(shared_region, 0, sizeof(struct shm_layout)); //SSL 库初始化,参看 ssl-server.c 代码 SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); ctx = SSL_CTX_new(SSLv3_client_method()); if (ctx == NULL) { ERR_print_errors_fp(stdout); exit(1); } //初始化服务器端(对方)的地址和端口信息 bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(port); if (inet_aton(ip, (struct in_addr *) &dest.sin_addr.s_addr) == 0) { perror(argv[1]); exit(errno); } //printf("address created\n"); if(!SSL_CTX_set_cipher_list(ctx, cipher)) { SSL_CTX_free(ctx); exit(1); } buffer = randomStr(); if(debug) { printf("buffer:%s\n", buffer); } int i; for(i = 0; i < threads; i++) { int kid = fork(); if(kid < 0) { printf("Fork failed, Failed to create a new thread\n"); } if(kid == 0) { thread_id = i; if(mode == 0) { handshakeTest(); } else if(mode == 1) { throughputTest(); } else if(mode == 2) { fullTest(); } else if(mode == 3) { apacheTest(); } shared_region->done[thread_id] = 1; sync(); /* loop till all other threads are ready */ while ((volatile int)shared_region->exit == 0) { sleep(1); } exit(0); } else { pid[i] = kid; } } for(i = 0;i < threads; i++) { while((volatile int)shared_region->ready[i] == 0) { usleep(10); } } shared_region->start = 1; u_int64_t starttime, endtime; starttime = apiTimeUs(); sync(); sleep(2); endtime = apiTimeUs(); u_int64_t timeuse = endtime - starttime; while(timeuse < times * 1000000) { usleep(times * 1000000 - timeuse); endtime = apiTimeUs(); timeuse = endtime - starttime; continue; } shared_region->stop = 1; for(i = 0;i < threads; i++) { while((volatile int)shared_region->done[i] == 0) { usleep(10); } } shared_region->exit = 1; sync(); for(i = 0; i < threads; i++) { waitpid(pid[i], &status[i], 0); } for(i = 0;i < threads; i++) { total_count += shared_region->count[i]; } min_max_times(threads, shared_region->t1, shared_region->t2, &min_t1, &max_t2); total_throughput = (u_int64_t)((total_count) * 1000000) / (max_t2 - min_t1); if(showTitle) { printf(" --------------------------- Result ---------------------------\n"); } if(mode == 1) { total_throughput = total_throughput * pkgSize / 1024 / 1024 * 8; if(showTitle) { printf(" Package Size(Bytes) Operations Throughtput(Mbps)\n"); printf(" %-22d %-20llu %llu\n", pkgSize, (unsigned long long)total_count, (unsigned long long)total_throughput); } else { printf(" %-22d %-20llu %llu\n", pkgSize, (unsigned long long)total_count, (unsigned long long)total_throughput); } } else if(mode == 0) { if(showTitle) { printf(" Package Size(Bytes) Operations Operations/Sec\n"); printf(" %-23d %-20llu %llu\n", pkgSize, (unsigned long long)total_count, (unsigned long long)total_throughput); } else { printf(" %-23d %-20llu %llu\n", pkgSize, (unsigned long long)total_count, (unsigned long long)total_throughput); } } else if(mode == 2) { if(showTitle) { printf(" Module Size (Bytes) Operations Operations/Sec\n"); printf(" %-23d %-20llu %llu\n", 1024, (unsigned long long)total_count, (unsigned long long)total_throughput); } else { printf(" %-23d %-20llu %llu\n", 1024, (unsigned long long)total_count, (unsigned long long)total_throughput); } } else if(mode == 3) { if(showTitle) { printf(" Module Size (Bytes) Operations Operations/Sec\n"); printf(" %-23d %-20llu %llu\n", 1024, (unsigned long long)total_count, (unsigned long long)total_throughput); } else { printf(" %-23d %-20llu %llu\n", 1024, (unsigned long long)total_count, (unsigned long long)total_throughput); } } //printf ("%-8d %-8u %-8%llu %-dd8llu\n", buflen, total_throughput, total_count, max_t2-min_t1); munmap(shared_region, sizeof(struct shm_layout)); fflush(stdout); sleep(2); return 0; } void handshakeTest() { int sockfd, len; SSL *ssl; shared_region->ready[thread_id] = 1; sync(); while ((volatile int)shared_region->start == 0); u_int64_t count = 0; u_int64_t starttime, endtime; starttime = apiTimeUs(); while ((volatile int)shared_region->stop == 0) { //创建一个 socket 用于 tcp 通信 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); break; } //printf("socket created!\n"); //连接服务器 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); close(sockfd); break; } //printf("server connected!\n"); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); if(count % 2 == 0) { SSL_free(ssl); ssl = SSL_new(ctx); } SSL_set_fd(ssl, sockfd); //建立 SSL 连接 if (SSL_connect(ssl) == -1) { perror("SSL connect"); SSL_free(ssl); close(sockfd); break; } else { count++; if(debug) { if(count == 1) { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); } } } // 关闭连接 //SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); } endtime = apiTimeUs(); SSL_CTX_free(ctx); shared_region->count[thread_id] = count; shared_region->t1[thread_id] = starttime; shared_region->t2[thread_id] = endtime; sync(); } void *createThread(void *arg) { int sockfd, len; SSL *ssl; //创建一个 socket 用于 tcp 通信 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); SSL_CTX_free(ctx); return; } //printf("socket created!\n"); //连接服务器 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); close(sockfd); SSL_CTX_free(ctx); return; } //printf("server connected!\n"); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); SSL_set_fd(ssl, sockfd); //建立 SSL 连接 if (SSL_connect(ssl) == -1) { //ERR_print_errors_fp(stderr); perror("SSL connect"); SSL_free(ssl); close(sockfd); SSL_CTX_free(ctx); return; } else { if(debug) { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); } } u_int64_t count = 0; int threadNum = (int)(*((int*)arg)); subthread_region.starttime[threadNum] = apiTimeUs(); while ((volatile int)shared_region->stop == 0) { len = SSL_write(ssl, buffer, strlen(buffer)); if (len < 0) { printf("消息发送失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); break; } else { count++; //printf("消息'%s'发送成功,共发送了%d个字节!\n", buffer, len); } } subthread_region.endtime[threadNum] = apiTimeUs(); subthread_region.count[threadNum] = count; // 关闭连接 SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); return NULL; } void throughputTest() { shared_region->ready[thread_id] = 1; sync(); while ((volatile int)shared_region->start == 0); /* pthread_t thread[SUBTHREADNUM]; int i; for(i = 0; i < SUBTHREADNUM; i++) { if(pthread_create(&thread[i], NULL, createThread, (void *)&i) != 0)//创建子线程 { perror("pthread_create"); break; } } for(i = 0; i < SUBTHREADNUM; i++) { pthread_join(thread[i], NULL); } */ int sockfd, len; SSL *ssl; //创建一个 socket 用于 tcp 通信 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); SSL_CTX_free(ctx); return; } //printf("socket created!\n"); //连接服务器 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); close(sockfd); SSL_CTX_free(ctx); return; } //printf("server connected!\n"); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); if(thread_id >= threads / 2) { SSL_free(ssl); ssl = SSL_new(ctx); } SSL_set_fd(ssl, sockfd); //建立 SSL 连接 if (SSL_connect(ssl) == -1) { //ERR_print_errors_fp(stderr); perror("SSL connect"); SSL_free(ssl); close(sockfd); SSL_CTX_free(ctx); return; } else { if(debug) { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); } } u_int64_t count = 0; u_int64_t starttime, endtime; starttime = apiTimeUs(); while ((volatile int)shared_region->stop == 0) { len = SSL_write(ssl, buffer, strlen(buffer)); if (len < 0) { printf("消息发送失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); break; } else { count++; //printf("消息'%s'发送成功,共发送了%d个字节!\n", buffer, len); } } endtime = apiTimeUs(); // 关闭连接 //SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); SSL_CTX_free(ctx); //业务处理结束 /* u_int64_t starttime, endtime; min_max_times(SUBTHREADNUM, subthread_region.starttime, subthread_region.endtime, &starttime, &endtime); u_int64_t count = 0; for(i = 0; i < SUBTHREADNUM; i++) { count += subthread_region.count[i]; } */ shared_region->count[thread_id] = count; shared_region->t1[thread_id] = starttime; shared_region->t2[thread_id] = endtime; sync(); } void fullTest() { int sockfd, len; SSL *ssl; shared_region->ready[thread_id] = 1; sync(); while ((volatile int)shared_region->start == 0); u_int64_t count = 0; u_int64_t starttime, endtime; starttime = apiTimeUs(); while ((volatile int)shared_region->stop == 0) { //创建一个 socket 用于 tcp 通信 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); break; } //printf("socket created!\n"); //连接服务器 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); close(sockfd); break; } //printf("server connected!\n"); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); SSL_set_fd(ssl, sockfd); //建立 SSL 连接 if (SSL_connect(ssl) == -1) { perror("SSL connect"); SSL_free(ssl); close(sockfd); break; } else { len = SSL_write(ssl, buffer, strlen(buffer)); if (len < 0) { printf("消息发送失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); SSL_free(ssl); close(sockfd); break; } else { count++; //printf("消息'%s'发送成功,共发送了%d个字节!\n", buffer, len); } if(debug) { if(count == 1) { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); } } } // 关闭连接 //SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); } endtime = apiTimeUs(); SSL_CTX_free(ctx); shared_region->count[thread_id] = count; shared_region->t1[thread_id] = starttime; shared_region->t2[thread_id] = endtime; sync(); } void apacheTest() { int sockfd, len; SSL *ssl; shared_region->ready[thread_id] = 1; sync(); while ((volatile int)shared_region->start == 0); u_int64_t count = 0; u_int64_t starttime, endtime; starttime = apiTimeUs(); char readBuff[MAXBUF] = {0}; char writeData[200] = {0}; sprintf(writeData, "%s%s%s", "GET /index.html HTTP/1.1\r\nHost: ", ip, "\r\nConnection: Close\r\n"); while ((volatile int)shared_region->stop == 0) { //创建一个 socket 用于 tcp 通信 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); break; } //printf("socket created!\n"); //连接服务器 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); close(sockfd); break; } //printf("server connected!\n"); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); SSL_set_fd(ssl, sockfd); //建立 SSL 连接 if (SSL_connect(ssl) == -1) { perror("SSL connect"); SSL_free(ssl); close(sockfd); break; } else { len = SSL_write(ssl, writeData, strlen(writeData)); if (len < 0) { printf("消息发送失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); SSL_free(ssl); close(sockfd); break; } else { count++; printf("消息'%s'发送成功,共发送了%d个字节!\n", readBuff, len); } memset(readBuff, 0 , MAXBUF); len = SSL_read(ssl, readBuff, MAXBUF); if(len < 0) { printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); SSL_free(ssl); close(sockfd); break; } if(debug) { if(count == 1) { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); printf("The Apache data: %s\n", readBuff); } } } // 关闭连接 //SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); } endtime = apiTimeUs(); SSL_CTX_free(ctx); shared_region->count[thread_id] = count; shared_region->t1[thread_id] = starttime; shared_region->t2[thread_id] = endtime; sync(); } /** * 获取总的CPU利用率 */ int getCpuTotalUseRatio() { struct cpuinfo oldinfo; struct cpuinfo newinfo; getCpuInfo(&oldinfo); sleep(1); getCpuInfo(&newinfo); calCpuUseRatio(&oldinfo, &newinfo); } /** * 计算CPU利用率 */ void calCpuUseRatio (struct cpuinfo *old, struct cpuinfo *new) { double oldTotal, newTotal, total, idle, user, system, softirq, irq; float totalRatio, userRatio, systemRatio, softirqRatio, irqRatio; oldTotal = (double)(old->user + old->nice + old->system + old->idle + old->iowait + old->irq + old->softirq + old->stealstolen + old->guest); newTotal = (double)(new->user + new->nice + new->system + new->idle + new->iowait + new->irq + new->softirq + new->stealstolen + new->guest); total = newTotal - oldTotal; idle = new->idle - old->idle; user = new->user - old->user; system = new->system - old->system; softirq = new->softirq - old->softirq; irq = new->irq - old->irq; //CPU利用率 totalRatio = (total - idle) / total; //用户空间CPU利用率 userRatio = user / total; //内核空间CPU利用率 systemRatio = system / total; //软中断CPU利用率 softirqRatio = softirq / total; //硬中断CPU利用率 irqRatio = irq / total; //printf("total:%f, idle:%f, new->idle:%u, old->idle:%u\n", total, idle, new->idle, old->idle); printf("总的CPU利用率为:%f(%f + %f + %f + %f)\n", totalRatio, userRatio, systemRatio, softirqRatio, irqRatio); } /** * 获取当前CPU信息 */ void getCpuInfo (struct cpuinfo *cpu) { FILE *fd; char buff[1024]; fd = fopen ("/proc/stat", "r"); fgets (buff, sizeof(buff), fd); sscanf (buff, "%s %u %u %u %u %u %u %u %u %u", &cpu->name, &cpu->user, &cpu->nice, &cpu->system, &cpu->idle,&cpu->iowait, &cpu->irq, &cpu->softirq, &cpu->stealstolen, &cpu->guest); printf ("%s %u %u %u %u %u %u %u %u %u\n", cpu->name, cpu->user, cpu->nice, cpu->system, cpu->idle, cpu->iowait, cpu->irq, cpu->softirq, cpu->stealstolen, cpu->guest); fclose(fd); }
server.c
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <unistd.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <sys/mman.h> #define SUBTHREADNUM 2 #define MAX_THREADS 100 int pkgSize = 1024; int threads = 10; int mode = 0; //0-handshake 1-throughput int port = 8701; void handshakeTest(); void throughputTest(); SSL_CTX *ctx; char *buffer; int sockfd; int debug = 0; int thread_id = 0; int pid[100]; int showTitle = 1; int times = 10; struct cpuinfo { char name[20]; unsigned int user; unsigned int nice; unsigned int system; unsigned int idle; unsigned int iowait; unsigned int irq; unsigned int softirq; unsigned int stealstolen; unsigned int guest; }; void getCpuInfo (struct cpuinfo *cpu); void calCpuUseRatio (struct cpuinfo *old, struct cpuinfo *new); int getCpuTotalUseRatio(); struct shm_layout { int ready[MAX_THREADS]; int done[MAX_THREADS]; int failCount[MAX_THREADS]; }; struct shm_layout *shared_region = NULL; void usage() { printf("Usage: Client \n\ -p Port (8701)\n\ -s Package Size (1024)\n\ -l Threads (10)\n\ -m Type (0-handshake 1-throughput default 0)\n\ -d Debug Info\n\ -t Time\n\ -h Help\n"); exit(-1); } int main(int argc, char **argv) { char options[] = "a:s:p:m:l:t:hde"; int opt; while((opt = getopt(argc, argv, options)) != -1) { switch(opt) { case 's': pkgSize = atoi(optarg); //printf("pkgSize:%d\n", pkgSize); break; case 'l': threads = atoi(optarg); //printf("threads:%d\n", threads); break; case 'p': port = atoi(optarg); //printf("port:%d\n", port); break; case 'm': mode = atoi(optarg); //printf("type:%d\n", mode); break; case 'd': debug = 1; break; case 't': times = atoi(optarg); case 'e': showTitle = 0; break; case 'h': default: usage(); break; } } if(showTitle) { if(mode == 0) { printf("------------------- Handshake Test -------------------\n"); } else if(mode == 1) { printf("------------------- Throughput Test -------------------\n"); } printf("Server Port Thread Number Package Size\n"); } printf(" %-20d %-20d %-18d\n", port, threads, pkgSize); shared_region = mmap(NULL, sizeof(struct shm_layout), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); if(shared_region == MAP_FAILED) { printf("\n ERROR mapping \n"); exit(1); } memset(shared_region, 0, sizeof(struct shm_layout)); struct sockaddr_in my_addr; unsigned int lisnum; lisnum = 20; buffer = malloc(pkgSize + 1); memset(buffer, 0 , pkgSize + 1); //SSL 库初始化 SSL_library_init(); //载入所有 SSL 算法 OpenSSL_add_all_algorithms(); //载入所有 SSL 错误消息 SSL_load_error_strings(); //以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text ctx = SSL_CTX_new(SSLv3_server_method()); //也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 if (ctx == NULL) { printf("SSLContext failed!\n"); exit(1); } //载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 if (SSL_CTX_use_certificate_file(ctx, "cacert.pem", SSL_FILETYPE_PEM) <= 0) { printf("Certificate load failed!\n"); exit(1); } //载入用户私钥 if (SSL_CTX_use_PrivateKey_file(ctx, "privkey.pem", SSL_FILETYPE_PEM) <= 0) { printf("PrivateKey load failed!\n"); exit(1); } //检查用户私钥是否正确 if (!SSL_CTX_check_private_key(ctx)) { printf("PrivateKey check failed!\n"); exit(1); } //开启一个 socket 监听 if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } else { if(debug) { printf("socket created\n"); } } bzero(&my_addr, sizeof(my_addr)); my_addr.sin_family = PF_INET; my_addr.sin_port = htons(port); my_addr.sin_addr.s_addr = INADDR_ANY; if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } else { if(debug) { printf("binded\n"); } } if (listen(sockfd, lisnum) == -1) { perror("listen"); exit(1); } else { if(debug) { printf("begin listen\n"); } } int i; for(i = 0; i < threads; i++) { int kid = fork(); if(kid < 0) { printf("Fork failed, Failed to create a new thread\n"); } if(kid == 0) { thread_id = i; if(mode == 0) { handshakeTest(); } else if(mode == 1) { throughputTest(); } shared_region->done[thread_id] = 1; exit(0); } else { pid[i] = kid; } } for(i = 0;i < threads; i++) { while((volatile int)shared_region->ready[i] == 0) { usleep(10); } } getCpuTotalUseRatio(); for(i = 0;i < threads; i++) { while((volatile int)shared_region->done[i] == 0) { usleep(1000); } } int total_fail_count = 0; for(i = 0;i < threads; i++) { total_fail_count += shared_region->failCount[i]; } if(total_fail_count != threads) { printf("-------------------------------- Warning: failed count is %d --------------------------------\n", total_fail_count); } // 关闭监听的 socket close(sockfd); } void handshakeTest() { SSL *ssl; int new_fd; int i = 0; int count = 0; while(1) { //等待客户端连上来 if ((new_fd = accept(sockfd, NULL, NULL)) == -1) { if(count == 0) { shared_region->ready[thread_id] = 1; sync(); } perror("accept"); exit(errno); } else { //printf("Accepted success!\n"); } //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); if(count % 2 == 0) { SSL_free(ssl); ssl = SSL_new(ctx); } //将连接用户的 socket 加入到 SSL SSL_set_fd(ssl, new_fd); //建立 SSL 连接 if (SSL_accept(ssl) == -1) { perror("accept"); SSL_free(ssl); close(new_fd); break; } count++; //SSL_shutdown(ssl); //释放 SSL SSL_shutdown(ssl); SSL_free(ssl); //关闭 socket close(new_fd); } SSL_CTX_free(ctx); } void *createThread(void *arg) { SSL *ssl; int new_fd; int len; /* 等待客户端连上来 */ if ((new_fd = accept(sockfd, NULL, NULL)) == -1) { perror("accept"); exit(errno); } else { if(debug) { printf("Accepted success!\n"); } } //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); //将连接用户的 socket 加入到 SSL SSL_set_fd(ssl, new_fd); //建立 SSL 连接 if (SSL_accept(ssl) == -1) { perror("accept"); close(new_fd); exit(0); } int i = 0; while(1) { bzero(buffer, pkgSize + 1); //接收客户端的消息 len = SSL_read(ssl, buffer, pkgSize); if (len > 0) { if(debug) { i++; if(i == 1) { printf("接收消息成功:'%s',共%d个字节的数据\n", buffer, len); } } } else { printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); break; } } //SSL_shutdown(ssl); //释放 SSL SSL_free(ssl); //关闭 socket close(new_fd); return NULL; } void throughputTest() { /* pthread_t thread[SUBTHREADNUM]; int i; for(i = 0; i < SUBTHREADNUM; i++) { if(pthread_create(&thread[i], NULL, createThread, NULL) != 0)//创建子线程 { perror("pthread_create"); break; } } for(i = 0; i < SUBTHREADNUM; i++) { pthread_join(thread[i], NULL); } */ SSL *ssl; int new_fd; int len; /* 等待客户端连上来 */ if ((new_fd = accept(sockfd, NULL, NULL)) == -1) { perror("accept"); exit(errno); } else { if(debug) { printf("Accepted success!\n"); } } shared_region->ready[thread_id] = 1; sync(); //基于 ctx 产生一个新的 SSL ssl = SSL_new(ctx); if(thread_id >= threads / 2) { SSL_free(ssl); ssl = SSL_new(ctx); } //将连接用户的 socket 加入到 SSL SSL_set_fd(ssl, new_fd); //建立 SSL 连接 if (SSL_accept(ssl) == -1) { perror("accept"); close(new_fd); exit(0); } int i = 0; while(1) { bzero(buffer, pkgSize + 1); //接收客户端的消息 len = SSL_read(ssl, buffer, pkgSize); if (len > 0) { if(debug) { i++; if(i == 1) { printf("接收消息成功:'%s',共%d个字节的数据\n", buffer, len); } } } else { if(debug) { printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); } shared_region->failCount[thread_id]++; break; } } sync(); //SSL_shutdown(ssl); //释放 SSL SSL_free(ssl); //关闭 socket close(new_fd); SSL_CTX_free(ctx); } /** * 获取总的CPU利用率 */ int getCpuTotalUseRatio() { struct cpuinfo oldinfo; struct cpuinfo newinfo; getCpuInfo(&oldinfo); sleep(times - 1); getCpuInfo(&newinfo); calCpuUseRatio(&oldinfo, &newinfo); } /** * 计算CPU利用率 */ void calCpuUseRatio (struct cpuinfo *old, struct cpuinfo *new) { double oldTotal, newTotal, total, idle, user, system, softirq, irq; float totalRatio, userRatio, systemRatio, softirqRatio, irqRatio; oldTotal = (double)(old->user + old->nice + old->system + old->idle + old->iowait + old->irq + old->softirq + old->stealstolen + old->guest); newTotal = (double)(new->user + new->nice + new->system + new->idle + new->iowait + new->irq + new->softirq + new->stealstolen + new->guest); total = newTotal - oldTotal; idle = new->idle - old->idle; user = new->user - old->user; system = new->system - old->system; softirq = new->softirq - old->softirq; irq = new->irq - old->irq; //CPU利用率 totalRatio = (total - idle) / total; //用户空间CPU利用率 userRatio = user / total; //内核空间CPU利用率 systemRatio = system / total; //软中断CPU利用率 softirqRatio = softirq / total; //硬中断CPU利用率 irqRatio = irq / total; //printf("total:%f, idle:%f, new->idle:%u, old->idle:%u\n", total, idle, new->idle, old->idle); printf("%f(%f + %f + %f + %f)\n", totalRatio, userRatio, systemRatio, softirqRatio, irqRatio); } /** * 获取当前CPU信息 */ void getCpuInfo (struct cpuinfo *cpu) { FILE *fd; char buff[1024]; fd = fopen ("/proc/stat", "r"); fgets (buff, sizeof(buff), fd); sscanf (buff, "%s %u %u %u %u %u %u %u %u %u", &cpu->name, &cpu->user, &cpu->nice, &cpu->system, &cpu->idle,&cpu->iowait, &cpu->irq, &cpu->softirq, &cpu->stealstolen, &cpu->guest); //printf ("%s %u %u %u %u %u %u %u %u %u\n", cpu->name, cpu->user, cpu->nice, cpu->system, //cpu->idle, cpu->iowait, cpu->irq, cpu->softirq, cpu->stealstolen, cpu->guest); fclose(fd); }
Makefile
CIPHER = AES128-SHA #AES128-SHA AES256-SHA RC4-SHA RC4-MD5 PKT_SIZES = 256 512 1024 1500 2048 RSA = RSA_CRT RSA_NOCRT MODEXP HANDSHAKE = RSASERVERFULL NUM_THREADS = 40 #MAX 100 NUM_THREADSHS = 60 #MAX 100 NB_TEST_DURATION = 5 HANDSHAKEIP = 168.1.1.10 THROUGHPUTIP = 169.1.1.10 TIME = 10 LOOP = 1 2 3 4 5 6 PORT = 8701 CFLAGS = -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl CC = gcc OBJS_SERVER = server.o OBJS_CLIENT = client.o all:server client server: $(OBJS_SERVER) $(CC) -o $@ $^ ${CFLAGS} client: $(OBJS_CLIENT) $(CC) -o $@ $^ ${CFLAGS} handshake_client: for pktsize in ${PKT_SIZES}; do \ ./client -a ${THROUGHPUTIP} -l ${NUM_THREADSHS} -s $$pktsize -c AES128-SHA -t ${TIME};\ done throughput_AES128-SHA: @echo "------------------------------------- Throughput Test -------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} AES128-SHA SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c AES128-SHA -t ${TIME} -e;\ done throughput_AES256-SHA: @echo "-------------------------------------------------------------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} AES256-SHA SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c AES256-SHA -t ${TIME} -e;\ done throughput_RC4-SHA: @echo "-------------------------------------------------------------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} RC4-SHA SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c RC4-SHA -t ${TIME} -e;\ done throughput_RC4-MD5: @echo "-------------------------------------------------------------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} RC4-MD5 SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c RC4-MD5 -t ${TIME} -e;\ done throughput_DES-CBC-SHA: @echo "-------------------------------------------------------------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} DES-CBC-SHA SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c DES-CBC-SHA -t ${TIME} -e;\ done throughput_DES-CBC3-SHA: @echo "-------------------------------------------------------------------------------------------"; @echo "Server IP Server Port Thread Number Times Cipher Version"; @echo "${THROUGHPUTIP} ${PORT} ${NUM_THREADS} ${TIME} DES-CBC3-SHA SSLv3"; @echo " Package Size(Bytes) Operations Throughtput(Mbps)"; for pktsize in ${PKT_SIZES}; do \ ./client -m 1 -a ${THROUGHPUTIP} -l ${NUM_THREADS} -s $$pktsize -c DES-CBC3-SHA -t ${TIME} -e;\ done handshake_server: ./server -l ${NUM_THREADSHS}; throughput_server: @echo "------------------ Throughput Test ------------------"; @echo "Server Port Thread Number Package Size"; for var in ${LOOP}; do \ for pktsize in ${PKT_SIZES}; do \ ./server -m 1 -l ${NUM_THREADS} -s $$pktsize -e;\ done \ done run_client: throughput_AES128-SHA throughput_AES256-SHA throughput_RC4-SHA throughput_RC4-MD5 throughput_DES-CBC-SHA throughput_DES-CBC3-SHA handshake_client run_server: throughput_server handshake_server clean: rm -f *.o server client
make_key.sh
#!/bin/sh openssl genrsa -out privkey.pem 2048 openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
相关文章推荐
- 对上述png服务器性能测试的程序
- opcache提升php程序性能测试
- NET程序内存分析工具CLRProfiler的使用(性能测试)
- Intel MIC性能测试程序
- Java程序性能测试
- LoadRunner调用Java程序—性能测试
- 程序性能分析及性能测试
- LoadRunner调用Java程序—性能测试
- 程序压力测试、性能测试AB、Webbench、Tsung
- Go语言HTTP测试及程序性能调优
- ASP.NET权限组件,生成10万条测试数据检测程序的大数据性能改进
- 127168420条记录的SQL2005数据库性能测试,程序人生的一次飞跃(上亿条记录的查询测试、查询优化)
- 性能测试培训:通用互联网服务端程序
- C# 性能测试程序及编写要点
- Linux下用JMap对Java程序进行性能测试检查内存泄露问题
- 测试我们的程序性能
- Smark.Net.Tcp.XmlService性能测试程序
- 测试工具:用性能监视器查看程序的性能
- 一个简单的redis性能测试程序和性能测试结果
- TPTP(Java Profiling Tools插件)对Java程序进行性能测试