提交 8ccc2377 编写于 作者: M Matt Caswell

Add a -sctp option to s_client

Reviewed-by: NRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3286)
上级 72d0bc84
...@@ -38,7 +38,7 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared); ...@@ -38,7 +38,7 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared);
#endif #endif
int ssl_print_tmp_key(BIO *out, SSL *s); int ssl_print_tmp_key(BIO *out, SSL *s);
int init_client(int *sock, const char *host, const char *port, int init_client(int *sock, const char *host, const char *port,
int family, int type); int family, int type, int protocol);
int should_retry(int i); int should_retry(int i);
long bio_dump_callback(BIO *bio, int cmd, const char *argp, long bio_dump_callback(BIO *bio, int cmd, const char *argp,
......
...@@ -539,7 +539,7 @@ typedef enum OPTION_choice { ...@@ -539,7 +539,7 @@ typedef enum OPTION_choice {
#endif #endif
OPT_SSL3, OPT_SSL_CONFIG, OPT_SSL3, OPT_SSL_CONFIG,
OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH,
OPT_VERIFYCAPATH, OPT_VERIFYCAPATH,
OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE,
...@@ -699,6 +699,9 @@ const OPTIONS s_client_options[] = { ...@@ -699,6 +699,9 @@ const OPTIONS s_client_options[] = {
#ifndef OPENSSL_NO_DTLS1_2 #ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"}, {"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"},
#endif #endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
#endif
#ifndef OPENSSL_NO_SSL_TRACE #ifndef OPENSSL_NO_SSL_TRACE
{"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"},
#endif #endif
...@@ -847,7 +850,7 @@ int s_client_main(int argc, char **argv) ...@@ -847,7 +850,7 @@ int s_client_main(int argc, char **argv)
int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0; int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0;
int sbuf_len, sbuf_off, cmdletters = 1; int sbuf_len, sbuf_off, cmdletters = 1;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
...@@ -900,6 +903,7 @@ int s_client_main(int argc, char **argv) ...@@ -900,6 +903,7 @@ int s_client_main(int argc, char **argv)
#endif #endif
BIO *bio_c_msg = NULL; BIO *bio_c_msg = NULL;
const char *keylog_file = NULL, *early_data_file = NULL; const char *keylog_file = NULL, *early_data_file = NULL;
int isdtls = 0;
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_ZERO(&writefds); FD_ZERO(&writefds);
...@@ -1217,6 +1221,7 @@ int s_client_main(int argc, char **argv) ...@@ -1217,6 +1221,7 @@ int s_client_main(int argc, char **argv)
#ifndef OPENSSL_NO_DTLS #ifndef OPENSSL_NO_DTLS
meth = DTLS_client_method(); meth = DTLS_client_method();
socket_type = SOCK_DGRAM; socket_type = SOCK_DGRAM;
isdtls = 1;
#endif #endif
break; break;
case OPT_DTLS1: case OPT_DTLS1:
...@@ -1225,6 +1230,7 @@ int s_client_main(int argc, char **argv) ...@@ -1225,6 +1230,7 @@ int s_client_main(int argc, char **argv)
min_version = DTLS1_VERSION; min_version = DTLS1_VERSION;
max_version = DTLS1_VERSION; max_version = DTLS1_VERSION;
socket_type = SOCK_DGRAM; socket_type = SOCK_DGRAM;
isdtls = 1;
#endif #endif
break; break;
case OPT_DTLS1_2: case OPT_DTLS1_2:
...@@ -1233,6 +1239,12 @@ int s_client_main(int argc, char **argv) ...@@ -1233,6 +1239,12 @@ int s_client_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;
isdtls = 1;
#endif
break;
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
#endif #endif
break; break;
case OPT_TIMEOUT: case OPT_TIMEOUT:
...@@ -1432,6 +1444,17 @@ int s_client_main(int argc, char **argv) ...@@ -1432,6 +1444,17 @@ int s_client_main(int argc, char **argv)
goto end; goto end;
} }
#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;
...@@ -1804,7 +1827,8 @@ int s_client_main(int argc, char **argv) ...@@ -1804,7 +1827,8 @@ int s_client_main(int argc, char **argv)
} }
re_start: re_start:
if (init_client(&s, host, port, socket_family, socket_type) == 0) { if (init_client(&s, host, port, socket_family, socket_type, protocol)
== 0) {
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
BIO_closesocket(s); BIO_closesocket(s);
goto end; goto end;
...@@ -1819,10 +1843,16 @@ int s_client_main(int argc, char **argv) ...@@ -1819,10 +1843,16 @@ int s_client_main(int argc, char **argv)
BIO_printf(bio_c_out, "Turned on non blocking io\n"); BIO_printf(bio_c_out, "Turned on non blocking io\n");
} }
#ifndef OPENSSL_NO_DTLS #ifndef OPENSSL_NO_DTLS
if (socket_type == SOCK_DGRAM) { if (isdtls) {
union BIO_sock_info_u peer_info; union BIO_sock_info_u peer_info;
sbio = BIO_new_dgram(s, BIO_NOCLOSE); #ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP)
sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
else
#endif
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
if ((peer_info.addr = BIO_ADDR_new()) == NULL) { if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "memory allocation failure\n"); BIO_printf(bio_err, "memory allocation failure\n");
BIO_closesocket(s); BIO_closesocket(s);
......
...@@ -44,6 +44,7 @@ typedef unsigned int u_int; ...@@ -44,6 +44,7 @@ typedef unsigned int u_int;
* @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
* AF_UNSPEC * AF_UNSPEC
* @type: socket type, must be SOCK_STREAM or SOCK_DGRAM * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
* @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
* *
* This will create a socket and use it to connect to a host:port, or if * This will create a socket and use it to connect to a host:port, or if
* family == AF_UNIX, to the path found in host. * family == AF_UNIX, to the path found in host.
...@@ -55,7 +56,7 @@ typedef unsigned int u_int; ...@@ -55,7 +56,7 @@ typedef unsigned int u_int;
* Returns 1 on success, 0 on failure. * Returns 1 on success, 0 on failure.
*/ */
int init_client(int *sock, const char *host, const char *port, int init_client(int *sock, const char *host, const char *port,
int family, int type) int family, int type, int protocol)
{ {
BIO_ADDRINFO *res = NULL; BIO_ADDRINFO *res = NULL;
const BIO_ADDRINFO *ai = NULL; const BIO_ADDRINFO *ai = NULL;
...@@ -64,7 +65,8 @@ int init_client(int *sock, const char *host, const char *port, ...@@ -64,7 +65,8 @@ int init_client(int *sock, const char *host, const char *port,
if (!BIO_sock_init()) if (!BIO_sock_init())
return 0; return 0;
ret = BIO_lookup(host, port, BIO_LOOKUP_CLIENT, family, type, &res); ret = BIO_lookup_ex(host, port, BIO_LOOKUP_CLIENT, family, type, protocol,
&res);
if (ret == 0) { if (ret == 0) {
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
return 0; return 0;
...@@ -76,7 +78,9 @@ int init_client(int *sock, const char *host, const char *port, ...@@ -76,7 +78,9 @@ int init_client(int *sock, const char *host, const char *port,
* anything in the BIO_ADDRINFO chain that we haven't * anything in the BIO_ADDRINFO chain that we haven't
* asked for. */ * 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)));
*sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai), *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
BIO_ADDRINFO_protocol(res), 0); BIO_ADDRINFO_protocol(res), 0);
...@@ -86,6 +90,25 @@ int init_client(int *sock, const char *host, const char *port, ...@@ -86,6 +90,25 @@ int init_client(int *sock, const char *host, const char *port,
*/ */
continue; continue;
} }
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP) {
/*
* For SCTP we have to set various options on the socket prior to
* connecting. 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(*sock, BIO_NOCLOSE);
if (tmpbio == NULL) {
ERR_print_errors(bio_err);
return 0;
}
BIO_free(tmpbio);
}
#endif
if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) { if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) {
BIO_closesocket(*sock); BIO_closesocket(*sock);
*sock = INVALID_SOCKET; *sock = INVALID_SOCKET;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册