Add a -sctp option to s_server
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3286)
This commit is contained in:
parent
5114d8227e
commit
72d0bc84de
3 changed files with 80 additions and 21 deletions
|
@ -20,9 +20,9 @@
|
||||||
#define PORT "4433"
|
#define PORT "4433"
|
||||||
#define PROTOCOL "tcp"
|
#define PROTOCOL "tcp"
|
||||||
|
|
||||||
typedef int (*do_server_cb)(int s, int stype, unsigned char *context);
|
typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
|
||||||
int do_server(int *accept_sock, const char *host, const char *port,
|
int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
int family, int type,
|
int family, int type, int protocol,
|
||||||
do_server_cb cb,
|
do_server_cb cb,
|
||||||
unsigned char *context, int naccept);
|
unsigned char *context, int naccept);
|
||||||
#ifdef HEADER_X509_H
|
#ifdef HEADER_X509_H
|
||||||
|
|
|
@ -91,9 +91,9 @@ typedef unsigned int u_int;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
|
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
|
||||||
static int sv_body(int s, int stype, unsigned char *context);
|
static int sv_body(int s, int stype, int prot, unsigned char *context);
|
||||||
static int www_body(int s, int stype, unsigned char *context);
|
static int www_body(int s, int stype, int prot, unsigned char *context);
|
||||||
static int rev_body(int s, int stype, unsigned char *context);
|
static int rev_body(int s, int stype, int prot, unsigned char *context);
|
||||||
static void close_accept_socket(void);
|
static void close_accept_socket(void);
|
||||||
static int init_ssl_connection(SSL *s);
|
static int init_ssl_connection(SSL *s);
|
||||||
static void print_stats(BIO *bp, SSL_CTX *ctx);
|
static void print_stats(BIO *bp, SSL_CTX *ctx);
|
||||||
|
@ -719,7 +719,7 @@ typedef enum OPTION_choice {
|
||||||
OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
|
OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
|
||||||
OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
|
OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
|
||||||
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
|
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
|
||||||
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
|
OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
|
||||||
OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
|
OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
|
||||||
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
||||||
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
||||||
|
@ -903,6 +903,9 @@ const OPTIONS s_server_options[] = {
|
||||||
#ifndef OPENSSL_NO_DTLS1_2
|
#ifndef OPENSSL_NO_DTLS1_2
|
||||||
{"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
|
{"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
|
{"sctp", OPT_SCTP, '-', "Use SCTP"},
|
||||||
|
#endif
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
{"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
|
{"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
|
||||||
#endif
|
#endif
|
||||||
|
@ -960,7 +963,7 @@ int s_server_main(int argc, char *argv[])
|
||||||
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
|
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
|
||||||
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
|
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
|
||||||
int rev = 0, naccept = -1, sdebug = 0;
|
int rev = 0, naccept = -1, sdebug = 0;
|
||||||
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
|
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
|
||||||
int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
|
int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
|
||||||
char *host = NULL;
|
char *host = NULL;
|
||||||
char *port = BUF_strdup(PORT);
|
char *port = BUF_strdup(PORT);
|
||||||
|
@ -1429,6 +1432,11 @@ int s_server_main(int argc, char *argv[])
|
||||||
min_version = DTLS1_2_VERSION;
|
min_version = DTLS1_2_VERSION;
|
||||||
max_version = DTLS1_2_VERSION;
|
max_version = DTLS1_2_VERSION;
|
||||||
socket_type = SOCK_DGRAM;
|
socket_type = SOCK_DGRAM;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case OPT_SCTP:
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
|
protocol = IPPROTO_SCTP;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case OPT_TIMEOUT:
|
case OPT_TIMEOUT:
|
||||||
|
@ -1543,6 +1551,17 @@ int s_server_main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
|
if (protocol == IPPROTO_SCTP) {
|
||||||
|
if (socket_type != SOCK_DGRAM) {
|
||||||
|
BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
|
||||||
|
socket_type = SOCK_STREAM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
|
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
|
||||||
BIO_printf(bio_err, "Bad split send fragment size\n");
|
BIO_printf(bio_err, "Bad split send fragment size\n");
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -2018,7 +2037,7 @@ int s_server_main(int argc, char *argv[])
|
||||||
&& unlink_unix_path)
|
&& unlink_unix_path)
|
||||||
unlink(host);
|
unlink(host);
|
||||||
#endif
|
#endif
|
||||||
do_server(&accept_socket, host, port, socket_family, socket_type,
|
do_server(&accept_socket, host, port, socket_family, socket_type, protocol,
|
||||||
server_cb, context, naccept);
|
server_cb, context, naccept);
|
||||||
print_stats(bio_s_out, ctx);
|
print_stats(bio_s_out, ctx);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -2090,7 +2109,7 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
|
||||||
SSL_CTX_sess_get_cache_size(ssl_ctx));
|
SSL_CTX_sess_get_cache_size(ssl_ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sv_body(int s, int stype, unsigned char *context)
|
static int sv_body(int s, int stype, int prot, unsigned char *context)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
|
@ -2105,6 +2124,13 @@ static int sv_body(int s, int stype, unsigned char *context)
|
||||||
#else
|
#else
|
||||||
struct timeval *timeoutp;
|
struct timeval *timeoutp;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_DTLS
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
|
int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP);
|
||||||
|
#else
|
||||||
|
int isdtls = (stype == SOCK_DGRAM);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
buf = app_malloc(bufsize, "server buffer");
|
buf = app_malloc(bufsize, "server buffer");
|
||||||
if (s_nbio) {
|
if (s_nbio) {
|
||||||
|
@ -2136,9 +2162,13 @@ static int sv_body(int s, int stype, unsigned char *context)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#ifndef OPENSSL_NO_DTLS
|
#ifndef OPENSSL_NO_DTLS
|
||||||
if (stype == SOCK_DGRAM) {
|
if (isdtls) {
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
|
if (prot == IPPROTO_SCTP)
|
||||||
|
sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
|
||||||
|
|
||||||
if (enable_timeouts) {
|
if (enable_timeouts) {
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
|
@ -2169,12 +2199,20 @@ static int sv_body(int s, int stype, unsigned char *context)
|
||||||
/* want to do MTU discovery */
|
/* want to do MTU discovery */
|
||||||
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
|
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
|
||||||
|
|
||||||
/* turn on cookie exchange */
|
if (prot != IPPROTO_SCTP) {
|
||||||
SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
|
/* Turn on cookie exchange. Not necessary for SCTP */
|
||||||
|
SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
sbio = BIO_new_socket(s, BIO_NOCLOSE);
|
sbio = BIO_new_socket(s, BIO_NOCLOSE);
|
||||||
|
|
||||||
|
if (sbio == NULL) {
|
||||||
|
BIO_printf(bio_err, "Unable to create BIO\n");
|
||||||
|
ERR_print_errors(bio_err);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (s_nbio_test) {
|
if (s_nbio_test) {
|
||||||
BIO *test;
|
BIO *test;
|
||||||
|
|
||||||
|
@ -2767,7 +2805,7 @@ static DH *load_dh_param(const char *dhfile)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int www_body(int s, int stype, unsigned char *context)
|
static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
@ -3153,7 +3191,7 @@ static int www_body(int s, int stype, unsigned char *context)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rev_body(int s, int stype, unsigned char *context)
|
static int rev_body(int s, int stype, int prot, unsigned char *context)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -128,7 +128,7 @@ int init_client(int *sock, const char *host, const char *port,
|
||||||
* 0 on failure, something other on success.
|
* 0 on failure, something other on success.
|
||||||
*/
|
*/
|
||||||
int do_server(int *accept_sock, const char *host, const char *port,
|
int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
int family, int type, do_server_cb cb,
|
int family, int type, int protocol, do_server_cb cb,
|
||||||
unsigned char *context, int naccept)
|
unsigned char *context, int naccept)
|
||||||
{
|
{
|
||||||
int asock = 0;
|
int asock = 0;
|
||||||
|
@ -140,7 +140,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
if (!BIO_sock_init())
|
if (!BIO_sock_init())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
|
if (!BIO_lookup_ex(host, port, BIO_LOOKUP_SERVER, family, type, protocol,
|
||||||
|
&res)) {
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +149,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
/* Admittedly, these checks are quite paranoid, we should not get
|
/* Admittedly, these checks are quite paranoid, we should not get
|
||||||
* anything in the BIO_ADDRINFO chain that we haven't asked for */
|
* anything in the BIO_ADDRINFO chain that we haven't asked for */
|
||||||
OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
|
OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
|
||||||
&& (type == 0 || type == BIO_ADDRINFO_socktype(res)));
|
&& (type == 0 || type == BIO_ADDRINFO_socktype(res))
|
||||||
|
&& (protocol == 0 || protocol == BIO_ADDRINFO_protocol(res)));
|
||||||
|
|
||||||
asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
|
asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
|
||||||
BIO_ADDRINFO_protocol(res), 0);
|
BIO_ADDRINFO_protocol(res), 0);
|
||||||
|
@ -161,6 +163,25 @@ int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SCTP
|
||||||
|
if (protocol == IPPROTO_SCTP) {
|
||||||
|
/*
|
||||||
|
* For SCTP we have to set various options on the socket prior to
|
||||||
|
* accepting. This is done automatically by BIO_new_dgram_sctp().
|
||||||
|
* We don't actually need the created BIO though so we free it again
|
||||||
|
* immediately.
|
||||||
|
*/
|
||||||
|
BIO *tmpbio = BIO_new_dgram_sctp(asock, BIO_NOCLOSE);
|
||||||
|
|
||||||
|
if (tmpbio == NULL) {
|
||||||
|
BIO_closesocket(asock);
|
||||||
|
ERR_print_errors(bio_err);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
BIO_free(tmpbio);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BIO_ADDRINFO_free(res);
|
BIO_ADDRINFO_free(res);
|
||||||
res = NULL;
|
res = NULL;
|
||||||
|
|
||||||
|
@ -176,10 +197,10 @@ int do_server(int *accept_sock, const char *host, const char *port,
|
||||||
BIO_closesocket(asock);
|
BIO_closesocket(asock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i = (*cb)(sock, type, context);
|
i = (*cb)(sock, type, protocol, context);
|
||||||
BIO_closesocket(sock);
|
BIO_closesocket(sock);
|
||||||
} else {
|
} else {
|
||||||
i = (*cb)(asock, type, context);
|
i = (*cb)(asock, type, protocol, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (naccept != -1)
|
if (naccept != -1)
|
||||||
|
|
Loading…
Reference in a new issue