forked from wolfSSL/wolfssl
4
.gitignore
vendored
4
.gitignore
vendored
@@ -51,6 +51,10 @@ examples/client/client
|
||||
examples/echoclient/echoclient
|
||||
examples/echoserver/echoserver
|
||||
examples/server/server
|
||||
examples/sctp/sctp-server
|
||||
examples/sctp/sctp-server-dtls
|
||||
examples/sctp/sctp-client
|
||||
examples/sctp/sctp-client-dtls
|
||||
server_ready
|
||||
snifftest
|
||||
output
|
||||
|
33
configure.ac
33
configure.ac
@@ -221,6 +221,29 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# DTLS-SCTP
|
||||
AC_ARG_ENABLE([sctp],
|
||||
[AS_HELP_STRING([--enable-sctp],[Enable wolfSSL DTLS-SCTP support (default: disabled)])],
|
||||
[ENABLED_SCTP=$enableval],
|
||||
[ENABLED_SCTP=no])
|
||||
|
||||
AM_CONDITIONAL([BUILD_SCTP], [test "x$ENABLED_SCTP" = "xyes"])
|
||||
|
||||
AS_IF([test "x$ENABLED_SCTP" = "xyes"],
|
||||
[AC_MSG_CHECKING([for SCTP])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
]],
|
||||
[[int s = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); if (s == -1) return 1;]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([SCTP not available, remove enable-sctp from configure])])
|
||||
])
|
||||
|
||||
|
||||
# OpenSSH compatibility Build
|
||||
AC_ARG_ENABLE([openssh],
|
||||
[AS_HELP_STRING([--enable-openssh],[Enable OpenSSH compatibility build (default: disabled)])],
|
||||
@@ -2886,6 +2909,15 @@ AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes" && \
|
||||
test "x$ENABLED_SSLV3" = "xyes"],
|
||||
[AC_MSG_ERROR([Cannot use Max Strength and SSLv3 at the same time.])])
|
||||
|
||||
AS_IF([test "x$ENABLED_SCTP" = "xyes"],
|
||||
[AM_CFLAGS="-DWOLFSSL_SCTP $AM_CFLAGS"])
|
||||
|
||||
# SCTP requires DTLS
|
||||
AS_IF([test "x$ENABLED_DTLS" = "xno" && \
|
||||
test "x$ENABLED_SCTP" = "xyes"],
|
||||
[AM_CFLAGS="-DWOLFSSL_DTLS $AM_CFLAGS"
|
||||
ENABLED_DTLS=yes])
|
||||
|
||||
################################################################################
|
||||
|
||||
# OPTIMIZE FLAGS
|
||||
@@ -3147,6 +3179,7 @@ echo " * LIGHTY: $ENABLED_LIGHTY"
|
||||
echo " * STUNNEL: $ENABLED_STUNNEL"
|
||||
echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS"
|
||||
echo " * DTLS: $ENABLED_DTLS"
|
||||
echo " * SCTP: $ENABLED_SCTP"
|
||||
echo " * Old TLS Versions: $ENABLED_OLD_TLS"
|
||||
echo " * SSL version 3.0: $ENABLED_SSLV3"
|
||||
echo " * OCSP: $ENABLED_OCSP"
|
||||
|
@@ -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' :
|
||||
@@ -1112,6 +1131,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SCTP
|
||||
if (dtlsSCTP)
|
||||
wolfSSL_CTX_dtls_set_sctp(ctx);
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
|
||||
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
||||
#endif
|
||||
@@ -1212,14 +1236,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 +1331,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 +1510,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 +1524,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 +1533,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");
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -5,3 +5,4 @@ include examples/client/include.am
|
||||
include examples/echoclient/include.am
|
||||
include examples/echoserver/include.am
|
||||
include examples/server/include.am
|
||||
include examples/sctp/include.am
|
||||
|
38
examples/sctp/include.am
Normal file
38
examples/sctp/include.am
Normal file
@@ -0,0 +1,38 @@
|
||||
# vim:ft=automake
|
||||
# included from Top Level Makefile.am
|
||||
# All paths should be given relative to the root
|
||||
|
||||
|
||||
if BUILD_SCTP
|
||||
if BUILD_EXAMPLE_SERVERS
|
||||
noinst_PROGRAMS += \
|
||||
examples/sctp/sctp-server \
|
||||
examples/sctp/sctp-server-dtls
|
||||
examples_sctp_sctp_server_SOURCES = examples/sctp/sctp-server.c
|
||||
examples_sctp_sctp_server_LDADD = $(LIB_STATIC_ADD)
|
||||
examples_sctp_sctp_server_dtls_SOURCES = examples/sctp/sctp-server-dtls.c
|
||||
examples_sctp_sctp_server_dtls_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD)
|
||||
examples_sctp_sctp_server_dtls_DEPENDENCIES = src/libwolfssl.la
|
||||
endif
|
||||
if BUILD_EXAMPLE_CLIENTS
|
||||
noinst_PROGRAMS += \
|
||||
examples/sctp/sctp-client \
|
||||
examples/sctp/sctp-client-dtls
|
||||
examples_sctp_sctp_client_SOURCES = examples/sctp/sctp-client.c
|
||||
examples_sctp_sctp_client_LDADD = $(LIB_STATIC_ADD)
|
||||
examples_sctp_sctp_client_dtls_SOURCES = examples/sctp/sctp-client-dtls.c
|
||||
examples_sctp_sctp_client_dtls_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD)
|
||||
examples_sctp_sctp_client_dtls_DEPENDENCIES = src/libwolfssl.la
|
||||
endif
|
||||
endif
|
||||
|
||||
dist_example_DATA += \
|
||||
examples/sctp/sctp-server.c \
|
||||
examples/sctp/sctp-server-dtls.c \
|
||||
examples/sctp/sctp-client.c \
|
||||
examples/sctp/sctp-client-dtls.c
|
||||
DISTCLEANFILES += \
|
||||
examples/sctp/.libs/sctp-server \
|
||||
examples/sctp/.libs/sctp-server-dtls \
|
||||
examples/sctp/.libs/sctp-client \
|
||||
examples/sctp/.libs/sctp-client-dtls
|
125
examples/sctp/sctp-client-dtls.c
Normal file
125
examples/sctp/sctp-client-dtls.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* sctp-client-dtls.c
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* sctp */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* std */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* wolfssl */
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
|
||||
|
||||
#define cacert "./certs/ca-cert.pem"
|
||||
|
||||
static int err_sys(const char* msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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 = inet_addr("127.0.0.1");
|
||||
sa.sin_port = htons(12345);
|
||||
|
||||
int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa));
|
||||
if (ret < 0)
|
||||
err_sys("sctp connect error");
|
||||
|
||||
const char* response = "hello there";
|
||||
char buffer[80];
|
||||
|
||||
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
|
||||
if (ctx == NULL)
|
||||
err_sys("ctx new dtls client failed");
|
||||
|
||||
ret = wolfSSL_CTX_dtls_set_sctp(ctx);
|
||||
if (ret != SSL_SUCCESS)
|
||||
err_sys("set sctp mode failed");
|
||||
|
||||
ret = wolfSSL_CTX_load_verify_locations(ctx, cacert, NULL);
|
||||
if (ret != SSL_SUCCESS)
|
||||
err_sys("ca cert error");
|
||||
|
||||
WOLFSSL* ssl = wolfSSL_new(ctx);
|
||||
if (ssl == NULL)
|
||||
err_sys("ssl new dtls client failed");
|
||||
|
||||
wolfSSL_set_fd(ssl, sd);
|
||||
|
||||
ret = wolfSSL_connect(ssl);
|
||||
if (ret != SSL_SUCCESS)
|
||||
err_sys("ssl connect 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)));
|
||||
|
||||
wolfSSL_write(ssl, response, (int)strlen(response));
|
||||
int got = wolfSSL_read(ssl, buffer, sizeof(buffer));
|
||||
if (got > 0) {
|
||||
buffer[got] = 0;
|
||||
printf("server said: %s\n", buffer);
|
||||
}
|
||||
|
||||
unsigned char bigBuf[4096];
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < (int)sizeof(bigBuf); i++)
|
||||
bigBuf[i] = (unsigned char)(i & 0xFF);
|
||||
wolfSSL_write(ssl, bigBuf, sizeof(bigBuf));
|
||||
memset(bigBuf, 0, sizeof(bigBuf));
|
||||
|
||||
wolfSSL_read(ssl, bigBuf, sizeof(bigBuf));
|
||||
for (i = 0; i < sizeof(bigBuf); i++) {
|
||||
if (bigBuf[i] != (unsigned char)(i & 0xFF)) {
|
||||
printf("big message check fail\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
||||
close(sd);
|
||||
|
||||
return 0;
|
||||
}
|
64
examples/sctp/sctp-client.c
Normal file
64
examples/sctp/sctp-client.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* sctp-client.c
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* sctp */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* std */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
|
||||
|
||||
if (sd < 0)
|
||||
perror("sctp socket error");
|
||||
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
sa.sin_port = htons(12345);
|
||||
|
||||
int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa));
|
||||
if (ret < 0)
|
||||
perror("sctp connect error");
|
||||
|
||||
const char* msg = "hello sctp";
|
||||
char buffer[80];
|
||||
|
||||
send(sd, msg, strlen(msg), 0);
|
||||
int got = (int)recv(sd, buffer, sizeof(buffer), 0);
|
||||
if (got > 0) {
|
||||
buffer[got] = 0;
|
||||
printf("server said: %s\n", buffer);
|
||||
}
|
||||
|
||||
close(sd);
|
||||
|
||||
return 0;
|
||||
}
|
124
examples/sctp/sctp-server-dtls.c
Normal file
124
examples/sctp/sctp-server-dtls.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/* sctp-server-dtls.c
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* sctp */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* std */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* wolfssl */
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
|
||||
|
||||
#define key "./certs/server-key.pem"
|
||||
#define cert "./certs/server-cert.pem"
|
||||
|
||||
static int err_sys(const char* msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
70
examples/sctp/sctp-server.c
Normal file
70
examples/sctp/sctp-server.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* sctp-server.c
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* sctp */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* std */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
|
||||
|
||||
if (sd < 0)
|
||||
perror("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)
|
||||
perror("sctp bind error");
|
||||
|
||||
listen(sd, 3);
|
||||
|
||||
int client_sd = accept(sd, NULL, NULL);
|
||||
if (client_sd < 0)
|
||||
perror("sctp accept error");
|
||||
|
||||
const char* response = "hi there";
|
||||
char buffer[80];
|
||||
|
||||
int got = (int)recv(client_sd, buffer, sizeof(buffer), 0);
|
||||
if (got > 0) {
|
||||
buffer[got] = 0;
|
||||
printf("client said: %s\n", buffer);
|
||||
}
|
||||
send(client_sd, response, strlen(response), 0);
|
||||
|
||||
|
||||
close(sd);
|
||||
|
||||
return 0;
|
||||
}
|
@@ -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 */
|
||||
|
123
src/internal.c
123
src/internal.c
@@ -195,6 +195,22 @@ static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
|
||||
}
|
||||
|
||||
|
||||
/* If SCTP is not enabled returns the state of the dtls option.
|
||||
* If SCTP is enabled returns dtls && !sctp. */
|
||||
static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
|
||||
{
|
||||
int result = ssl->options.dtls;
|
||||
|
||||
if (result) {
|
||||
#ifdef WOLFSSL_SCTP
|
||||
result = !ssl->options.dtlsSctp;
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_QSH
|
||||
/* free all structs that where used with QSH */
|
||||
static int QSH_FreeAll(WOLFSSL* ssl)
|
||||
@@ -1373,6 +1389,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
|
||||
|
||||
ctx->devId = INVALID_DEVID;
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP)
|
||||
ctx->dtlsMtuSz = MAX_RECORD_SIZE;
|
||||
#endif
|
||||
|
||||
#ifndef NO_CERTS
|
||||
ctx->cm = wolfSSL_CertManagerNew_ex(heap);
|
||||
if (ctx->cm == NULL) {
|
||||
@@ -3324,9 +3344,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
|
||||
ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */
|
||||
ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
ssl->dtls_expected_rx = MAX_MTU;
|
||||
#endif
|
||||
|
||||
ssl->options.serverState = NULL_STATE;
|
||||
ssl->options.clientState = NULL_STATE;
|
||||
@@ -3336,9 +3353,17 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
|
||||
ssl->options.processReply = doProcessInit;
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifdef WOLFSSL_SCTP
|
||||
ssl->options.dtlsSctp = ctx->dtlsSctp;
|
||||
ssl->dtlsMtuSz = ctx->dtlsMtuSz;
|
||||
ssl->dtls_expected_rx = ssl->dtlsMtuSz;
|
||||
#else
|
||||
ssl->dtls_expected_rx = MAX_MTU;
|
||||
#endif
|
||||
ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT;
|
||||
ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX;
|
||||
ssl->dtls_timeout = ssl->dtls_timeout_init;
|
||||
ssl->buffers.dtlsCtx.fd = -1;
|
||||
#endif
|
||||
|
||||
#ifndef NO_OLD_TLS
|
||||
@@ -3348,10 +3373,6 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
ssl->buffers.dtlsCtx.fd = -1;
|
||||
#endif
|
||||
|
||||
ssl->cipher.ssl = ssl;
|
||||
|
||||
#ifdef HAVE_TLS_EXTENSIONS
|
||||
@@ -4779,16 +4800,15 @@ retry:
|
||||
return -1;
|
||||
|
||||
case WOLFSSL_CBIO_ERR_TIMEOUT:
|
||||
if (ssl->options.dtls) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (!ssl->options.handShakeDone &&
|
||||
DtlsPoolTimeout(ssl) == 0 &&
|
||||
DtlsPoolSend(ssl) == 0) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
!ssl->options.handShakeDone &&
|
||||
DtlsPoolTimeout(ssl) == 0 &&
|
||||
DtlsPoolSend(ssl) == 0) {
|
||||
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
default:
|
||||
@@ -5055,7 +5075,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls &&
|
||||
if (IsDtlsNotSctpMode(ssl) &&
|
||||
(!DtlsCheckWindow(&ssl->keys.dtls_state) ||
|
||||
(ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) {
|
||||
return SEQUENCE_ERROR;
|
||||
@@ -7427,7 +7447,8 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
/* hello_request not hashed */
|
||||
/* Also, skip hashing the client_hello message here for DTLS. It will be
|
||||
* hashed later if the DTLS cookie is correct. */
|
||||
if (type != hello_request && !(ssl->options.dtls && type == client_hello) &&
|
||||
if (type != hello_request &&
|
||||
!(IsDtlsNotSctpMode(ssl) && type == client_hello) &&
|
||||
ssl->error != WC_PENDING_E) {
|
||||
ret = HashInput(ssl, input + *inOutIdx, size);
|
||||
if (ret != 0) return ret;
|
||||
@@ -7790,7 +7811,8 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
}
|
||||
*inOutIdx += ssl->keys.padSz;
|
||||
}
|
||||
ret = DtlsPoolSend(ssl);
|
||||
if (IsDtlsNotSctpMode(ssl))
|
||||
ret = DtlsPoolSend(ssl);
|
||||
}
|
||||
else if (fragSz < size) {
|
||||
/* Since this branch is in order, but fragmented, dtls_msg_list will be
|
||||
@@ -9180,7 +9202,7 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
ssl->buffers.inputBuffer.length = 0;
|
||||
ssl->buffers.inputBuffer.idx = 0;
|
||||
|
||||
if (ssl->options.dtlsHsRetain) {
|
||||
if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) {
|
||||
ret = DtlsPoolSend(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
@@ -9282,11 +9304,11 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
ssl->keys.decryptedCur = 1;
|
||||
}
|
||||
|
||||
if (ssl->options.dtls) {
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
DtlsUpdateWindow(&ssl->keys.dtls_state);
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
WOLFSSL_MSG("received record layer msg");
|
||||
|
||||
@@ -9339,9 +9361,11 @@ int ProcessReply(WOLFSSL* ssl)
|
||||
if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E)
|
||||
return ret;
|
||||
|
||||
ret = DtlsPoolSend(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
ret = DtlsPoolSend(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ssl->curSize != 1) {
|
||||
WOLFSSL_MSG("Malicious or corrupted"
|
||||
@@ -9532,7 +9556,7 @@ int SendChangeCipher(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -9971,7 +9995,7 @@ int SendFinished(WOLFSSL* ssl)
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, input, headerSz + finishedSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -10217,7 +10241,7 @@ int SendCertificate(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -10312,7 +10336,7 @@ int SendCertificateRequest(WOLFSSL* ssl)
|
||||
i += REQ_HEADER_SZ; */
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -10411,7 +10435,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
|
||||
ret = HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ret == 0 && ssl->options.dtls)
|
||||
if (ret == 0 && IsDtlsNotSctpMode(ssl))
|
||||
ret = DtlsPoolSave(ssl, output, sendSz);
|
||||
#endif
|
||||
|
||||
@@ -10810,14 +10834,10 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
#ifdef HAVE_MAX_FRAGMENT
|
||||
int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
|
||||
#else
|
||||
int len = min(sz - sent, OUTPUT_RECORD_SIZE);
|
||||
#endif
|
||||
int len;
|
||||
byte* out;
|
||||
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
|
||||
int buffSz = len; /* may switch on comp */
|
||||
int buffSz; /* may switch on comp */
|
||||
int outputSz;
|
||||
#ifdef HAVE_LIBZ
|
||||
byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
|
||||
@@ -10825,12 +10845,17 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
|
||||
|
||||
if (sent == sz) break;
|
||||
|
||||
len = min(sz - sent, OUTPUT_RECORD_SIZE);
|
||||
#ifdef HAVE_MAX_FRAGMENT
|
||||
len = min(len, ssl->max_fragment);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
len = min(len, MAX_UDP_SIZE);
|
||||
buffSz = len;
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
len = min(len, MAX_UDP_SIZE);
|
||||
}
|
||||
#endif
|
||||
buffSz = len;
|
||||
|
||||
/* check for available size */
|
||||
outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
|
||||
@@ -12818,7 +12843,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl,
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -15274,7 +15299,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
|
||||
goto exit_scke;
|
||||
}
|
||||
@@ -15751,7 +15776,7 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
ret = DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
@@ -16028,7 +16053,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
ssl->buffers.outputBuffer.length += sendSz;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -17352,7 +17377,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
@@ -17819,7 +17844,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
XMEMCPY(&pv, input + i, OPAQUE16_LEN);
|
||||
ssl->chVersion = pv; /* store */
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
int ret;
|
||||
#if defined(NO_SHA) && defined(NO_SHA256)
|
||||
#error "DTLS needs either SHA or SHA-256"
|
||||
@@ -17896,7 +17921,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
/* random */
|
||||
XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
|
||||
if (ret != 0) return ret;
|
||||
}
|
||||
@@ -17929,7 +17954,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
XMEMCPY(ssl->arrays->sessionID, input + i, b);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
|
||||
if (ret != 0) return ret;
|
||||
}
|
||||
@@ -17983,7 +18008,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
int ret = wc_HmacUpdate(&cookieHmac,
|
||||
input + i - OPAQUE16_LEN,
|
||||
clSuites.suiteSz + OPAQUE16_LEN);
|
||||
@@ -18000,7 +18025,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return BUFFER_ERROR;
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
byte newCookie[MAX_COOKIE_LEN];
|
||||
int ret;
|
||||
|
||||
@@ -18535,7 +18560,7 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
AddHeaders(output, 0, server_hello_done, ssl);
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||
return 0;
|
||||
}
|
||||
|
93
src/ssl.c
93
src/ssl.c
@@ -547,6 +547,61 @@ int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
|
||||
return SSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
|
||||
|
||||
int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ctx->dtlsSctp = 1;
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
|
||||
|
||||
if (ssl == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ssl->options.dtlsSctp = 1;
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
|
||||
{
|
||||
if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ctx->dtlsMtuSz = newMtu;
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
|
||||
{
|
||||
if (ssl == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (newMtu > MAX_RECORD_SIZE) {
|
||||
ssl->error = BAD_FUNC_ARG;
|
||||
return SSL_FAILURE;
|
||||
}
|
||||
|
||||
ssl->dtlsMtuSz = newMtu;
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
|
||||
|
||||
#endif /* WOLFSSL_LEANPSK */
|
||||
|
||||
|
||||
@@ -1020,17 +1075,22 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
|
||||
#ifdef HAVE_ERRNO_H
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
if (ssl->options.dtls) {
|
||||
ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
|
||||
#ifdef WOLFSSL_SCTP
|
||||
if (ssl->options.dtlsSctp)
|
||||
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
sz = min(sz, OUTPUT_RECORD_SIZE);
|
||||
#ifdef HAVE_MAX_FRAGMENT
|
||||
ret = ReceiveData(ssl, (byte*)data,
|
||||
min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)),peek);
|
||||
#else
|
||||
ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
|
||||
sz = min(sz, ssl->max_fragment);
|
||||
#endif
|
||||
ret = ReceiveData(ssl, (byte*)data, sz, peek);
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
|
||||
|
||||
@@ -6753,6 +6813,21 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If SCTP is not enabled returns the state of the dtls option.
|
||||
* If SCTP is enabled returns dtls && !sctp. */
|
||||
static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
|
||||
{
|
||||
int result = ssl->options.dtls;
|
||||
|
||||
if (result) {
|
||||
#ifdef WOLFSSL_SCTP
|
||||
result = !ssl->options.dtlsSctp;
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* please see note at top of README if you get an error from connect */
|
||||
int wolfSSL_connect(WOLFSSL* ssl)
|
||||
{
|
||||
@@ -6822,7 +6897,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
/* In DTLS, when resuming, we can go straight to FINISHED,
|
||||
* or do a cookie exchange and then skip to FINISHED, assume
|
||||
* we need the cookie exchange first. */
|
||||
if (ssl->options.dtls)
|
||||
if (IsDtlsNotSctpMode(ssl))
|
||||
neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
|
||||
#endif
|
||||
/* get response */
|
||||
@@ -6834,7 +6909,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
/* if resumption failed, reset needed state */
|
||||
else if (neededState == SERVER_FINISHED_COMPLETE)
|
||||
if (!ssl->options.resuming) {
|
||||
if (!ssl->options.dtls)
|
||||
if (!IsDtlsNotSctpMode(ssl))
|
||||
neededState = SERVER_HELLODONE_COMPLETE;
|
||||
else
|
||||
neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
|
||||
@@ -6849,7 +6924,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
return SSL_SUCCESS;
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
/* re-init hashes, exclude first hello and verify request */
|
||||
#ifndef NO_OLD_TLS
|
||||
wc_InitMd5(&ssl->hsHashes->hashMd5);
|
||||
@@ -6894,7 +6969,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||
|
||||
case HELLO_AGAIN_REPLY :
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
if (IsDtlsNotSctpMode(ssl)) {
|
||||
neededState = ssl->options.resuming ?
|
||||
SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
|
||||
|
||||
|
15
tests/api.c
15
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));
|
||||
|
||||
|
@@ -513,6 +513,16 @@ int SuiteTest(void)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SCTP
|
||||
/* add dtls-sctp extra suites */
|
||||
strcpy(argv0[1], "tests/test-sctp.conf");
|
||||
printf("starting dtls-sctp extra cipher suite tests\n");
|
||||
test_harness(&args);
|
||||
if (args.return_code != 0) {
|
||||
printf("error from script %d\n", args.return_code);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
#ifndef WC_STRICT_SIG
|
||||
#if !defined(NO_RSA) && defined(HAVE_ECC) /* testing mixed ECC/RSA cert */
|
||||
/* add extra signature test suites */
|
||||
|
1111
tests/test-sctp.conf
Normal file
1111
tests/test-sctp.conf
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1936,6 +1936,10 @@ struct WOLFSSL_CTX {
|
||||
byte quietShutdown; /* don't send close notify */
|
||||
byte groupMessages; /* group handshake messages before sending */
|
||||
byte minDowngrade; /* minimum downgrade version */
|
||||
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
|
||||
byte dtlsSctp; /* DTLS-over-SCTP mode */
|
||||
word16 dtlsMtuSz; /* DTLS MTU size */
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
word16 minDhKeySz; /* minimum DH key size */
|
||||
#endif
|
||||
@@ -2401,6 +2405,9 @@ typedef struct Options {
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
word16 dtlsHsRetain:1; /* DTLS retaining HS data */
|
||||
#ifdef WOLFSSL_SCTP
|
||||
word16 dtlsSctp:1; /* DTLS-over-SCTP mode */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* need full byte values for this section */
|
||||
@@ -2740,6 +2747,9 @@ struct WOLFSSL {
|
||||
void* IOCB_CookieCtx; /* gen cookie ctx */
|
||||
word32 dtls_expected_rx;
|
||||
wc_dtls_export dtls_export; /* export function for session */
|
||||
#ifdef WOLFSSL_SCTP
|
||||
word16 dtlsMtuSz;
|
||||
#endif /* WOLFSSL_SCTP */
|
||||
#endif
|
||||
#ifdef WOLFSSL_CALLBACKS
|
||||
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
||||
|
@@ -409,6 +409,11 @@ WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int);
|
||||
WOLFSSL_API int wolfSSL_dtls_get_peer(WOLFSSL*, void*, unsigned int*);
|
||||
|
||||
WOLFSSL_API int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX*);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_sctp(WOLFSSL*);
|
||||
WOLFSSL_API int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX*, unsigned short);
|
||||
WOLFSSL_API int wolfSSL_dtls_set_mtu(WOLFSSL*, unsigned short);
|
||||
|
||||
WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err);
|
||||
WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*);
|
||||
WOLFSSL_API void wolfSSL_ERR_error_string_n(unsigned long e, char* buf,
|
||||
|
@@ -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,12 +659,14 @@ 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);
|
||||
*sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
|
||||
else if (sctp)
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
|
||||
else
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
|
||||
err_sys("socket failed\n");
|
||||
@@ -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 */
|
||||
|
Reference in New Issue
Block a user