diff --git a/examples/client/client.c b/examples/client/client.c index f814c0d4e..67ae69cd8 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -156,8 +156,10 @@ static void ShowVersions(void) printf("3\n"); } -int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int benchmark, int resumeSession) +/* Measures average time to create, connect and disconnect a connection (TPS). +Benchmark = number of connections. */ +static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, + int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession) { /* time passed in number of connects give average */ int times = benchmark; @@ -180,7 +182,7 @@ int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, if (ssl == NULL) err_sys("unable to get SSL object"); - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); #ifndef NO_SESSION_CACHE if (benchResume) @@ -215,8 +217,9 @@ int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, return EXIT_SUCCESS; } -int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int throughput) +/* Measures throughput in kbps. Throughput = number of bytes */ +static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, + int dtlsUDP, int dtlsSCTP, int throughput) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd; @@ -227,7 +230,7 @@ int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } @@ -343,7 +346,8 @@ const char* starttlsCmd[6] = { "QUIT\r\n", }; -int StartTLS_Init(SOCKET_T* sockfd) +/* Initiates the STARTTLS command sequence over TCP */ +static int StartTLS_Init(SOCKET_T* sockfd) { char tmpBuf[256]; @@ -399,7 +403,8 @@ int StartTLS_Init(SOCKET_T* sockfd) return SSL_SUCCESS; } -int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) +/* Closes down the SMTP connection */ +static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) { int ret; char tmpBuf[256]; @@ -461,6 +466,10 @@ static void Usage(void) printf("-g Send server HTTP GET\n"); printf("-u Use UDP DTLS," " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#ifdef WOLFSSL_SCTP + printf("-G Use SCTP DTLS," + " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#endif printf("-m Match domain name in cert\n"); printf("-N Use Non-blocking sockets\n"); printf("-r Resume session\n"); @@ -551,6 +560,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int benchmark = 0; int throughput = 0; int doDTLS = 0; + int dtlsUDP = 0; + int dtlsSCTP = 0; int matchName = 0; int doPeerCheck = 1; int nonBlocking = 0; @@ -640,7 +651,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef WOLFSSL_VXWORKS while ((ch = mygetopt(argc, argv, - "?gdeDusmNrwRitfxXUPCVh:p:v:l:A:c:k:Z:b:zS:F:L:ToO:aB:W:E:M:q:")) + "?gdeDuGsmNrwRitfxXUPCVh:p:v:l:A:c:k:Z:b:zS:F:L:ToO:aB:W:E:M:q:")) != -1) { switch (ch) { case '?' : @@ -670,7 +681,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) break; case 'u' : - doDTLS = 1; + doDTLS = 1; + dtlsUDP = 1; + break; + + case 'G' : + #ifdef WOLFSSL_SCTP + doDTLS = 1; + dtlsSCTP = 1; + #endif break; case 's' : @@ -1212,14 +1231,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (benchmark) { ((func_args*)args)->return_code = - ClientBenchmarkConnections(ctx, host, port, doDTLS, benchmark, resumeSession); + ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP, + benchmark, resumeSession); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } if(throughput) { ((func_args*)args)->return_code = - ClientBenchmarkThroughput(ctx, host, port, doDTLS, throughput); + ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP, + throughput); wolfSSL_CTX_free(ctx); exit(EXIT_SUCCESS); } @@ -1305,7 +1326,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - tcp_connect(&sockfd, host, port, doDTLS, ssl); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } @@ -1484,7 +1505,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - if (doDTLS == 0) { /* don't send alert after "break" command */ + if (dtlsUDP == 0) { /* don't send alert after "break" command */ ret = wolfSSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) wolfSSL_shutdown(ssl); /* bidirectional shutdown */ @@ -1498,7 +1519,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_SESSION_CACHE if (resumeSession) { - if (doDTLS) { + if (dtlsUDP) { #ifdef USE_WINDOWS_API Sleep(500); #elif defined(WOLFSSL_TIRTOS) @@ -1507,7 +1528,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) sleep(1); #endif } - tcp_connect(&sockfd, host, port, doDTLS, sslResume); + tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, sslResume); if (wolfSSL_set_fd(sslResume, sockfd) != SSL_SUCCESS) { err_sys("error in setting fd"); } diff --git a/examples/client/client.h b/examples/client/client.h index 913339ac0..39456a4f5 100644 --- a/examples/client/client.h +++ b/examples/client/client.h @@ -26,21 +26,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args); -/* Measures average time to create, connect and disconnect a connection (TPS). -Benchmark = number of connections. */ -int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int benchmark, int resumeSession); - -/* Measures throughput in kbps. Throughput = number of bytes */ -int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int doDTLS, int throughput); - -/* Initiates the STARTTLS command sequence over TCP */ -int StartTLS_Init(SOCKET_T* sockfd); - -/* Closes down the SMTP connection */ -int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown); - #endif /* WOLFSSL_CLIENT_H */ diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index 6cb836e6a..1c06efa83 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -180,7 +180,7 @@ void echoclient_test(void* args) #endif /* WOLFSSL_ASYNC_CRYPT */ ssl = SSL_new(ctx); - tcp_connect(&sockfd, yasslIP, port, doDTLS, ssl); + tcp_connect(&sockfd, yasslIP, port, doDTLS, 0, ssl); SSL_set_fd(ssl, sockfd); #if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index d917c946b..432525806 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -136,7 +136,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) fdOpenSession(Task_self()); #endif - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0); #if defined(CYASSL_DTLS) method = CyaDTLSv1_2_server_method(); @@ -373,7 +373,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) CyaSSL_free(ssl); CloseSocket(clientfd); #ifdef CYASSL_DTLS - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0); SignalReady(args, port); #endif } diff --git a/examples/server/server.c b/examples/server/server.c index 74feccc0b..3dd98554e 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -219,6 +219,10 @@ static void Usage(void) printf("-t Track wolfSSL memory use\n"); printf("-u Use UDP DTLS," " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#ifdef WOLFSSL_SCTP + printf("-G Use SCTP DTLS," + " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n"); +#endif printf("-f Fewer packets/group messages\n"); printf("-r Allow one client Resumption\n"); printf("-N Use Non-blocking sockets\n"); @@ -275,6 +279,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) int usePskPlus = 0; int useAnon = 0; int doDTLS = 0; + int dtlsUDP = 0; + int dtlsSCTP = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; @@ -370,7 +376,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) useAnyAddr = 1; #else while ((ch = mygetopt(argc, argv, - "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) { + "?jdbstnNuGfrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) { switch (ch) { case '?' : Usage(); @@ -404,6 +410,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) case 'u' : doDTLS = 1; + dtlsUDP = 1; + break; + + case 'G' : + #ifdef WOLFSSL_SCTP + doDTLS = 1; + dtlsSCTP = 1; + #endif break; case 'f' : @@ -563,6 +577,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) myoptind = 0; /* reset for test cases */ #endif /* !WOLFSSL_VXWORKS */ + /* Can only use DTLS over UDP or SCTP, can't do both. */ + if (dtlsUDP && dtlsSCTP) { + err_sys("Cannot use DTLS with both UDP and SCTP."); + } + /* sort out DTLS versus TLS versions */ if (version == CLIENT_INVALID_VERSION) { if (doDTLS) @@ -689,6 +708,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) if (fewerPackets) CyaSSL_CTX_set_group_messages(ctx); +#ifdef WOLFSSL_SCTP + if (dtlsSCTP) + wolfSSL_CTX_dtls_set_sctp(ctx); +#endif + #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); #endif @@ -821,13 +845,13 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) while (1) { /* allow resume option */ if(resumeCount > 1) { - if (doDTLS == 0) { + if (dtlsUDP == 0) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); clientfd = accept(sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); } else { - tcp_listen(&sockfd, &port, useAnyAddr, doDTLS); + tcp_listen(&sockfd, &port, useAnyAddr, dtlsUDP, dtlsSCTP); clientfd = sockfd; } if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) { @@ -908,7 +932,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) readySignal->srfName = serverReadyFile; } tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, - doDTLS, serverReadyFile ? 1 : 0, doListen); + dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen); doListen = 0; /* Don't listen next time */ if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { @@ -923,7 +947,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #ifdef WOLFSSL_DTLS - if (doDTLS) { + if (doDTLS && dtlsUDP) { SOCKADDR_IN_T cliaddr; byte b[1500]; int n; @@ -1039,7 +1063,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) Task_yield(); #endif - if (doDTLS == 0) { + if (dtlsUDP == 0) { ret = SSL_shutdown(ssl); if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) SSL_shutdown(ssl); /* bidirectional shutdown */ diff --git a/tests/api.c b/tests/api.c index a24941698..11605d1ce 100644 --- a/tests/api.c +++ b/tests/api.c @@ -672,7 +672,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) } ssl = wolfSSL_new(ctx); - tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 1); + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1); CloseSocket(sockfd); if (wolfSSL_set_fd(ssl, clientfd) != SSL_SUCCESS) { @@ -800,7 +800,8 @@ static void test_client_nofail(void* args) } ssl = wolfSSL_new(ctx); - tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl); + tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, + 0, 0, ssl); if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) { /*err_sys("SSL_set_fd failed");*/ goto done2; @@ -919,14 +920,14 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) socklen_t cliLen; cliLen = sizeof(cliAddr); - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0); idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK, (struct sockaddr*)&cliAddr, &cliLen); AssertIntGT(idx, 0); wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen); } else { - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 1); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1); CloseSocket(sfd); } @@ -1051,10 +1052,12 @@ static void run_wolfssl_client(void* args) ssl = wolfSSL_new(ctx); if (wolfSSL_dtls(ssl)) { - tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 1, ssl); + tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, + 1, 0, ssl); } else { - tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl); + tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, + 0, 0, ssl); } AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, sfd)); diff --git a/wolfssl/test.h b/wolfssl/test.h index f23748ee4..c0197d590 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -564,11 +564,12 @@ static INLINE void showPeer(WOLFSSL* ssl) static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, - word16 port, int udp) + word16 port, int udp, int sctp) { int useLookup = 0; (void)useLookup; (void)udp; + (void)sctp; if (addr == NULL) err_sys("invalid argument to build_addr, addr is NULL"); @@ -628,8 +629,17 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET_V; - hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; + if (udp) { + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + } else if (sctp) { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_SCTP; + } + else { + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } SNPRINTF(strPort, sizeof(strPort), "%d", port); strPort[79] = '\0'; @@ -649,10 +659,12 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, } -static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) +static INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) { if (udp) *sockfd = socket(AF_INET_V, SOCK_DGRAM, 0); + else if (sctp) + *sockfd = socket(AF_INET_V, SOCK_STREAM, 0); else *sockfd = socket(AF_INET_V, SOCK_STREAM, 0); @@ -677,7 +689,7 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) #endif /* S_NOSIGPIPE */ #if defined(TCP_NODELAY) - if (!udp) + if (!udp && !sctp) { int on = 1; socklen_t len = sizeof(on); @@ -690,14 +702,14 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, int udp) } static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, - int udp, WOLFSSL* ssl) + int udp, int sctp, WOLFSSL* ssl) { SOCKADDR_IN_T addr; - build_addr(&addr, ip, port, udp); - if(udp) { + build_addr(&addr, ip, port, udp, sctp); + if (udp) { wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); } - tcp_socket(sockfd, udp); + tcp_socket(sockfd, udp, sctp); if (!udp) { if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) @@ -757,14 +769,14 @@ static INLINE int tcp_select(SOCKET_T socketfd, int to_sec) static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, - int udp) + int udp, int sctp) { SOCKADDR_IN_T addr; /* don't use INADDR_ANY by default, firewall may block, make user switch on */ - build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp); - tcp_socket(sockfd, udp); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp, sctp); + tcp_socket(sockfd, udp, sctp); #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ && !defined(WOLFSSL_KEIL_TCP_NET) @@ -826,8 +838,8 @@ static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, SOCKADDR_IN_T addr; (void)args; - build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1); - tcp_socket(sockfd, 1); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), port, 1, 0); + tcp_socket(sockfd, 1, 0); #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \ @@ -879,7 +891,7 @@ static INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, func_args* args, word16 port, int useAnyAddr, - int udp, int ready_file, int do_listen) + int udp, int sctp, int ready_file, int do_listen) { SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); @@ -893,7 +905,7 @@ static INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, } if(do_listen) { - tcp_listen(sockfd, &port, useAnyAddr, udp); + tcp_listen(sockfd, &port, useAnyAddr, udp, sctp); #if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__) /* signal ready to tcp_accept */