static void do_fork_stuff(gnutls_session_t session) { pid_t pid; int ret; char buf[64]; /* separate sending from receiving */ pid = fork(); if (pid == -1) { exit(1); } else if (pid != 0) { if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); sec_sleep(1); /* the server should reflect our messages */ ret = gnutls_record_recv(session, buf, sizeof(buf)); if (ret != sizeof(MSG)-1 || memcmp(buf, MSG, sizeof(MSG)-1) != 0) { fail("client: recv failed: %s\n", gnutls_strerror(ret)); exit(1); } if (debug) { fprintf(stderr, "client received: %.*s\n", ret, buf); } ret = gnutls_record_recv(session, buf, sizeof(buf)); if (ret != sizeof(MSG2)-1 || memcmp(buf, MSG2, sizeof(MSG2)-1) != 0) { fail("client: recv2 failed: %s\n", gnutls_strerror(ret)); exit(1); } if (debug) { fprintf(stderr, "client received: %.*s\n", ret, buf); } ret = gnutls_record_recv(session, buf, sizeof(buf)); if (ret != 0) { fail("client: recv3 failed: %s\n", gnutls_strerror(ret)); exit(1); } } else if (pid == 0) { /* child */ ret = gnutls_record_send(session, MSG, sizeof(MSG)-1); if (ret != sizeof(MSG)-1) { fail("client: send failed: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_record_send(session, MSG2, sizeof(MSG2)-1); if (ret != sizeof(MSG2)-1) { fail("client: send2 failed: %s\n", gnutls_strerror(ret)); exit(1); } sec_sleep(2); gnutls_bye(session, GNUTLS_SHUT_WR); } }
static void server(int fd, const char *prio) { int ret; uint8_t id[255]; uint8_t buffer[] = "\x16\x03\x00\x01\x25" "\x02\x00\x01\x21" "\x03\x00"/*Server Version */ /*Random*/"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00" /*SessionID*/"\xfe"; ret = read(fd, id, sizeof(id)); if (ret < 0) { abort(); } ret = write(fd, buffer, sizeof(buffer)); if (ret < 0) { return; } memset(id, 0xff, sizeof(id)); ret = write(fd, id, sizeof(id)); if (ret < 0) { return; } memset(id, 0xff, sizeof(id)); ret = write(fd, id, sizeof(id)); if (ret < 0) { return; } sec_sleep(3); return; }
/** * If the mode option was set, we need to sleep some * time between transfers. **/ static void lm_iothr_wait(io_t *io, int mp) { clock_t now = clock(); clock_t done; if (mp) done = io->timer_last+io->timer_wait_mp; else done = io->timer_last+io->timer_wait; if (now < done && done-now > CLOCKS_PER_SEC) sec_sleep((done-now)/CLOCKS_PER_SEC); }
static void client(int fd, int server_init) { int ret; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, 1500); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, push); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (!server_init) { sec_sleep(60); if (debug) success("Initiating client rehandshake\n"); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("2nd client gnutls_handshake: %s\n", gnutls_strerror(ret)); terminate(); } } else { do { ret = gnutls_record_recv(session, buffer, MAX_BUF); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); } if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { if (server_init && ret == GNUTLS_E_REHANDSHAKE) { if (debug) success ("Initiating rehandshake due to server request\n"); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); } if (ret != 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } } do { ret = gnutls_record_send(session, MSG, strlen(MSG)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
int main(int argc, char *argv[], char *env[]) { int opt; int nthreads = 1; // 默认一个线程 int nsec = 5; // 默认运行5秒 int nport = 0; char const *srv_name = NULL; pthread_t *pids; struct sockaddr_in si; if (1 == argc) { (void)fprintf(stderr, USAGE, argv[0]); return EXIT_SUCCESS; } (void)memset(&si, 0, sizeof(si)); si.sin_family = AF_INET; while ((opt = getopt(argc, argv, "s:p:c:t:")) != -1) { switch (opt) { case 's': { srv_name = optarg; if (! inet_aton(srv_name, &si.sin_addr)) { (void)fprintf(stderr, "invalid argument for -s\n"); return EXIT_FAILURE; } break; } case 'p': { nport = atoi(optarg); if ((nport < 1) || (nport > 65535)) { (void)fprintf(stderr, "invalid argument for -p\n"); return EXIT_FAILURE; } si.sin_port = htons(nport); break; } case 'c': { nthreads = atoi(optarg); if ((nthreads < 1) || (nthreads > MAX_THREADS)) { (void)fprintf(stderr, "invalid argument for -c\n"); return EXIT_FAILURE; } break; } case 't': { nsec = atoi(optarg); if ((nsec < 1) || (nsec > 99999)) { (void)fprintf(stderr, "invalid argument for -t\n"); return EXIT_FAILURE; } break; } case '?': { break; } default: { abort(); break; } } } if (NULL == srv_name) { (void)fprintf(stderr, "need to provide valid -s option\n"); return EXIT_FAILURE; } if (0 == nport) { (void)fprintf(stderr, "need to provide valid -p option\n"); return EXIT_FAILURE; } // 打印执行配置 (void)fprintf(stderr, "target: %s:%d\n", srv_name, nport); (void)fprintf(stderr, "threads: %d\n", nthreads); (void)fprintf(stderr, "duration of time: %ds\n", nsec); // 创建线程组 if (-1 == pthread_spin_init(&lock_success_count, PTHREAD_PROCESS_PRIVATE)) { abort(); } if (-1 == pthread_spin_init(&lock_failed_count, PTHREAD_PROCESS_PRIVATE)) { abort(); } pids = (pthread_t *)malloc(sizeof(pthread_t) * nthreads); for (int i = 0; i < nthreads; ++i) { switch (pthread_create(&pids[i], NULL, thread_proc_long, &si)) { case 0: { break; } case LTS_E_AGAIN: { break; } case LTS_E_INVAL: { break; } case LTS_E_PERM: { break; } default: { abort(); break; } } } // 计时 sec_sleep(nsec); keep_running = 0; // 等待线程组退出 for (int i = 0; i < nthreads; ++i) { switch(pthread_join(pids[i], NULL)) { case 0: { break; } case LTS_E_INVAL: { break; } case LTS_E_SRCH: { break; } default: { abort(); break; } } } free(pids); (void)pthread_spin_destroy(&lock_failed_count); (void)pthread_spin_destroy(&lock_success_count); // 打印统计结果 (void)fprintf(stderr, "********************\n"); (void)fprintf(stderr, "success: %Zd\n", success_count); (void)fprintf(stderr, "failed: %Zd\n", failed_count); (void)fprintf(stderr, "TPS: %Zd/sec\n", success_count/nsec); return EXIT_SUCCESS; }