/* Close an active connection. * * ctx The SSL/TLS connection data. * threadData The SSL/TLS connection data for the thread. * sslConn The SSL connection data object. */ static void SSLConn_Close(SSLConn_CTX* ctx, ThreadData* threadData, SSLConn* sslConn) { int ret; if (sslConn->state == CLOSED) return; pthread_mutex_lock(&sslConnMutex); ret = (ctx->numConnections == 0); ctx->numConnections++; if (wolfSSL_session_reused(sslConn->ssl)) ctx->numResumed++; pthread_mutex_unlock(&sslConnMutex); if (ret) { WOLFSSL_CIPHER* cipher; cipher = wolfSSL_get_current_cipher(sslConn->ssl); printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); } sslConn->state = CLOSED; /* Take it out of the double-linked list. */ if (threadData->sslConn == sslConn) threadData->sslConn = sslConn->next; if (sslConn->next != NULL) sslConn->next->prev = sslConn->prev; if (sslConn->prev != NULL) sslConn->prev->next = sslConn->next; /* Put object at head of free list */ sslConn->next = threadData->freeSSLConn; sslConn->prev = NULL; threadData->freeSSLConn = sslConn; threadData->cnt--; }
int main() { int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (sd < 0) err_sys("sctp socket error"); struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(12345); int ret = bind(sd, (struct sockaddr*)&sa, sizeof(sa)); if (ret < 0) err_sys("sctp bind error"); listen(sd, 3); int client_sd = accept(sd, NULL, NULL); if (client_sd < 0) err_sys("sctp accept error"); const char* response = "well hello to you"; char buffer[80]; WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()); if (ctx == NULL) err_sys("ctx new dtls server failed"); ret = wolfSSL_CTX_dtls_set_sctp(ctx); if (ret != SSL_SUCCESS) err_sys("set sctp mode failed"); ret = wolfSSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM); if (ret != SSL_SUCCESS) err_sys("use private key error"); ret = wolfSSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM); if (ret != SSL_SUCCESS) err_sys("use cert error"); WOLFSSL* ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("ssl new dtls server failed"); wolfSSL_set_fd(ssl, client_sd); ret = wolfSSL_accept(ssl); if (ret != SSL_SUCCESS) err_sys("ssl accept failed"); printf("TLS version is %s\n", wolfSSL_get_version(ssl)); printf("Cipher Suite is %s\n", wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl))); int got = wolfSSL_read(ssl, buffer, sizeof(buffer)); if (got > 0) { buffer[got] = 0; printf("client said: %s\n", buffer); } wolfSSL_write(ssl, response, (int)strlen(response)); unsigned char bigBuf[4096]; wolfSSL_read(ssl, bigBuf, sizeof(bigBuf)); wolfSSL_write(ssl, bigBuf, sizeof(bigBuf)); wolfSSL_shutdown(ssl); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); close(sd); return 0; }
/* Main entry point for the program. * * argc The count of command line arguments. * argv The command line arguments. * returns 0 on success and 1 otherwise. */ int main(int argc, char* argv[]) { socklen_t socketfd = -1; int ch; WOLFSSL_CTX* ctx = NULL; SSLConn_CTX* sslConnCtx; word16 port = wolfSSLPort; int resumeSession = 0; char* cipherList = NULL; char* ourCert = CLI_CERT; char* ourKey = CLI_KEY; char* verifyCert = CA_CERT; int version = SERVER_DEFAULT_VERSION; int numConns = SSL_NUM_CONN; int numBytesRead = NUM_READ_BYTES; int numBytesWrite = NUM_WRITE_BYTES; int maxBytes = MAX_BYTES; int maxConns = MAX_CONNECTIONS; int i; /* Parse the command line arguments. */ while ((ch = mygetopt(argc, argv, OPTIONS)) != -1) { switch (ch) { /* Help with command line options. */ case '?': Usage(); exit(EXIT_SUCCESS); /* Port number to connect to. */ case 'p': port = (word16)atoi(myoptarg); break; /* Version of SSL/TLS to use. */ case 'v': version = atoi(myoptarg); if (version < 0 || version > 3) { Usage(); exit(MY_EX_USAGE); } break; /* List of cipher suites to use. */ case 'l': cipherList = myoptarg; break; /* File name of client certificate for client authentication. */ case 'c': ourCert = myoptarg; break; /* File name of client private key for client authentication. */ case 'k': ourKey = myoptarg; break; /* File name of server certificate/CA for peer verification. */ case 'A': verifyCert = myoptarg; break; /* Resume sessions. */ case 'r': resumeSession = 1; break; /* Number of connections to make. */ case 'n': maxConns = atoi(myoptarg); if (maxConns < 0 || maxConns > 1000000) { Usage(); exit(MY_EX_USAGE); } maxBytes = 0; break; /* Number of conncurrent connections to use. */ case 'N': numConns = atoi(myoptarg); if (numConns < 0 || numConns > 1000000) { Usage(); exit(MY_EX_USAGE); } break; /* Number of bytes to read each call. */ case 'R': numBytesRead = atoi(myoptarg); if (numBytesRead <= 0) { Usage(); exit(MY_EX_USAGE); } break; /* Number of bytes to write each call. */ case 'W': numBytesWrite = atoi(myoptarg); if (numBytesWrite <= 0) { Usage(); exit(MY_EX_USAGE); } break; /* Maximum number of read and write bytes (separate counts). */ case 'B': maxBytes = atoi(myoptarg); if (maxBytes <= 0) { Usage(); exit(MY_EX_USAGE); } maxConns = 0; break; /* Unrecognized command line argument. */ default: Usage(); exit(MY_EX_USAGE); } } #ifdef DEBUG_WOLFSSL wolfSSL_Debugging_ON(); #endif /* Initialize wolfSSL */ wolfSSL_Init(); /* Initialize wolfSSL and create a context object. */ if (WolfSSLCtx_Init(version, ourCert, ourKey, verifyCert, cipherList, &ctx) == EXIT_FAILURE) exit(EXIT_FAILURE); /* Create SSL/TLS connection data object. */ sslConnCtx = SSLConn_New(numConns, numBytesRead, numBytesWrite, maxConns, maxBytes, resumeSession); if (sslConnCtx == NULL) exit(EXIT_FAILURE); /* Keep handling connections until all done. */ for (i = 0; !SSLConn_Done(sslConnCtx); i = (i + 1) % numConns) { SSLConn* sslConn = &sslConnCtx->sslConn[i]; /* Perform close if in CLOSE state. */ if (sslConn->state == CLOSE) { if (sslConnCtx->numConnections == 0) { WOLFSSL_CIPHER* cipher; cipher = wolfSSL_get_current_cipher(sslConn->ssl); printf("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); } SSLConn_Close(sslConnCtx, sslConn); } /* Create TCP connection and connect if in INIT state. */ if ((sslConn->state == INIT) && ((sslConnCtx->maxConnections <= 0) || (sslConnCtx->numCreated < sslConnCtx->maxConnections))) { if (CreateSocketConnect(port, &socketfd) == EXIT_FAILURE) { printf("ERROR: failed to connect to server\n"); exit(EXIT_FAILURE); } SSLConn_Connect(sslConnCtx, ctx, socketfd, sslConn); } #ifdef WOLFSSL_ASYNC_CRYPT if (sslConn->err == 4) { int ret; double start; start = current_time(1); ret = wolfSSL_AsyncPoll(sslConn->ssl, WOLF_POLL_FLAG_CHECK_HW); sslConnCtx->asyncTime += current_time(0) - start; if (ret < 0) { printf("ERROR: failed in async polling\n"); break; } if (ret == 0) continue; } sslConn->err = 0; #endif /* Handle other SSL states. */ if (sslConnCtx->totalTime == 0) sslConnCtx->totalTime = current_time(1); if (SSLConn_ReadWrite(sslConnCtx, sslConn) == EXIT_FAILURE) { if (sslConnCtx->maxConnections > 0) sslConn->state = CLOSE; } } sslConnCtx->totalTime = current_time(0) - sslConnCtx->totalTime; SSLConn_PrintStats(sslConnCtx); SSLConn_Free(sslConnCtx); WolfSSLCtx_Final(ctx); wolfSSL_Cleanup(); exit(EXIT_SUCCESS); }