mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
DTLS over UDP
This commit is contained in:
parent
ff8de6c5cd
commit
d1b809b4ab
14 changed files with 537 additions and 126 deletions
9
CHANGES
9
CHANGES
|
@ -50,6 +50,15 @@ Corrections:
|
||||||
address if you want to avoid data loss.
|
address if you want to avoid data loss.
|
||||||
Thanks to Chunmei Xu for reporting this issue and proving the patch.
|
Thanks to Chunmei Xu for reporting this issue and proving the patch.
|
||||||
|
|
||||||
|
Socats DTLS implementation has been reworked and appears to work now
|
||||||
|
reasonably over UDP.
|
||||||
|
New addresses: OPENSSL-DTLS-SERVER (DTLS-L),
|
||||||
|
OPENSSL-DTLS-CLIENT (DTLS)
|
||||||
|
Tests: OPENSSL_DTLS_CLIENT OPENSSL_DTLS_SERVER
|
||||||
|
OPENSSL_METHOD_DTLS1 OPENSSL_METHOD_DTLS1.2
|
||||||
|
Thanks to Brandon Carpenter, Qing Wan, and Pavel Nakonechnyi for
|
||||||
|
sending patches.
|
||||||
|
|
||||||
Porting:
|
Porting:
|
||||||
In gcc version 10 the default changed from -fcommon to -fno-common.
|
In gcc version 10 the default changed from -fcommon to -fno-common.
|
||||||
Consequently, linking filan and procan failed with error
|
Consequently, linking filan and procan failed with error
|
||||||
|
|
2
compat.h
2
compat.h
|
@ -681,7 +681,7 @@ typedef int sig_atomic_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* sigset_t printing - not an exact solution yet */
|
/* sigset_t printing - not an exact solution yet */
|
||||||
#define F_sigset "0x%4lx"
|
#define F_sigset "0x%06lx"
|
||||||
typedef unsigned long T_sigset;
|
typedef unsigned long T_sigset;
|
||||||
|
|
||||||
/* default: socklen_t */
|
/* default: socklen_t */
|
||||||
|
|
|
@ -466,6 +466,10 @@
|
||||||
#undef HAVE_TLSv1_2_client_method
|
#undef HAVE_TLSv1_2_client_method
|
||||||
#undef HAVE_TLSv1_2_server_method
|
#undef HAVE_TLSv1_2_server_method
|
||||||
|
|
||||||
|
/* Define if you have the DTLS client and server method functions */
|
||||||
|
#undef HAVE_DTLS_client_method
|
||||||
|
#undef HAVE_DTLS_server_method
|
||||||
|
|
||||||
/* Define if you have the DTLSv1 client and server method functions */
|
/* Define if you have the DTLSv1 client and server method functions */
|
||||||
#undef HAVE_DTLSv1_client_method
|
#undef HAVE_DTLSv1_client_method
|
||||||
#undef HAVE_DTLSv1_server_method
|
#undef HAVE_DTLSv1_server_method
|
||||||
|
@ -476,6 +480,10 @@
|
||||||
/* Define if you have the SSL_CTX_set_max_proto_version function/macro */
|
/* Define if you have the SSL_CTX_set_max_proto_version function/macro */
|
||||||
#undef HAVE_SSL_CTX_set_max_proto_version
|
#undef HAVE_SSL_CTX_set_max_proto_version
|
||||||
|
|
||||||
|
/* Define if you have the DTLSv1_2 client and server method functions */
|
||||||
|
#undef HAVE_DTLSv1_2_client_method
|
||||||
|
#undef HAVE_DTLSv1_2_server_method
|
||||||
|
|
||||||
/* Define if you have the EC_KEY type */
|
/* Define if you have the EC_KEY type */
|
||||||
#undef HAVE_TYPE_EC_KEY
|
#undef HAVE_TYPE_EC_KEY
|
||||||
|
|
||||||
|
|
|
@ -1454,6 +1454,8 @@ AC_CHECK_FUNC(SSL_CTX_set_min_proto_version, AC_DEFINE(HAVE_SSL_CTX_set_min_prot
|
||||||
AC_CHECK_FUNC(SSL_CTX_set_max_proto_version, AC_DEFINE(HAVE_SSL_CTX_set_max_proto_version))
|
AC_CHECK_FUNC(SSL_CTX_set_max_proto_version, AC_DEFINE(HAVE_SSL_CTX_set_max_proto_version))
|
||||||
AC_CHECK_FUNC(TLS_client_method, AC_DEFINE(HAVE_TLS_client_method) ac_cv_have_tls_client_method=yes, AC_CHECK_LIB(crypt, TLS_client_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(TLS_client_method, AC_DEFINE(HAVE_TLS_client_method) ac_cv_have_tls_client_method=yes, AC_CHECK_LIB(crypt, TLS_client_method, [LIBS=-lcrypt $LIBS]))
|
||||||
AC_CHECK_FUNC(TLS_server_method, AC_DEFINE(HAVE_TLS_server_method) ac_cv_have_tls_server_method=yes, AC_CHECK_LIB(crypt, TLS_server_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(TLS_server_method, AC_DEFINE(HAVE_TLS_server_method) ac_cv_have_tls_server_method=yes, AC_CHECK_LIB(crypt, TLS_server_method, [LIBS=-lcrypt $LIBS]))
|
||||||
|
AC_CHECK_FUNC(DTLS_client_method, AC_DEFINE(HAVE_DTLS_client_method), AC_CHECK_LIB(crypt, DTLS_client_method, [LIBS=-lcrypt $LIBS]))
|
||||||
|
AC_CHECK_FUNC(DTLS_server_method, AC_DEFINE(HAVE_DTLS_server_method), AC_CHECK_LIB(crypt, DTLS_server_method, [LIBS=-lcrypt $LIBS]))
|
||||||
if test -n "$WITH_OPENSSL_METHOD" -o -z "$ac_cv_have_tls_client_method" -o -z "$ac_cv_have_tls_server_method" ; then
|
if test -n "$WITH_OPENSSL_METHOD" -o -z "$ac_cv_have_tls_client_method" -o -z "$ac_cv_have_tls_server_method" ; then
|
||||||
dnl Search for SSLv2_client_method, SSLv2_server_method
|
dnl Search for SSLv2_client_method, SSLv2_server_method
|
||||||
AC_CHECK_FUNC(SSLv2_client_method, AC_DEFINE(HAVE_SSLv2_client_method), AC_CHECK_LIB(crypt, SSLv2_client_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(SSLv2_client_method, AC_DEFINE(HAVE_SSLv2_client_method), AC_CHECK_LIB(crypt, SSLv2_client_method, [LIBS=-lcrypt $LIBS]))
|
||||||
|
@ -1471,6 +1473,8 @@ AC_CHECK_FUNC(TLSv1_2_client_method, AC_DEFINE(HAVE_TLSv1_2_client_method), AC_C
|
||||||
AC_CHECK_FUNC(TLSv1_2_server_method, AC_DEFINE(HAVE_TLSv1_2_server_method), AC_CHECK_LIB(crypt, TLSv1_2_server_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(TLSv1_2_server_method, AC_DEFINE(HAVE_TLSv1_2_server_method), AC_CHECK_LIB(crypt, TLSv1_2_server_method, [LIBS=-lcrypt $LIBS]))
|
||||||
AC_CHECK_FUNC(DTLSv1_client_method, AC_DEFINE(HAVE_DTLSv1_client_method), AC_CHECK_LIB(crypt, DTLSv1_client_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(DTLSv1_client_method, AC_DEFINE(HAVE_DTLSv1_client_method), AC_CHECK_LIB(crypt, DTLSv1_client_method, [LIBS=-lcrypt $LIBS]))
|
||||||
AC_CHECK_FUNC(DTLSv1_server_method, AC_DEFINE(HAVE_DTLSv1_server_method), AC_CHECK_LIB(crypt, DTLSv1_server_method, [LIBS=-lcrypt $LIBS]))
|
AC_CHECK_FUNC(DTLSv1_server_method, AC_DEFINE(HAVE_DTLSv1_server_method), AC_CHECK_LIB(crypt, DTLSv1_server_method, [LIBS=-lcrypt $LIBS]))
|
||||||
|
AC_CHECK_FUNC(DTLSv1_2_client_method, AC_DEFINE(HAVE_DTLSv1_2_client_method), AC_CHECK_LIB(crypt, DTLSv1_2_client_method, [LIBS=-lcrypt $LIBS]))
|
||||||
|
AC_CHECK_FUNC(DTLSv1_2_server_method, AC_DEFINE(HAVE_DTLSv1_2_server_method), AC_CHECK_LIB(crypt, DTLSv1_2_server_method, [LIBS=-lcrypt $LIBS]))
|
||||||
fi # $WITH_OPENSSL_METHOD
|
fi # $WITH_OPENSSL_METHOD
|
||||||
|
|
||||||
AC_CHECK_FUNC(SSL_CTX_set_default_verify_paths, AC_DEFINE(HAVE_SSL_CTX_set_default_verify_paths))
|
AC_CHECK_FUNC(SSL_CTX_set_default_verify_paths, AC_DEFINE(HAVE_SSL_CTX_set_default_verify_paths))
|
||||||
|
|
69
doc/socat.yo
69
doc/socat.yo
|
@ -487,6 +487,7 @@ label(ADDRESS_OPEN)dit(bf(tt(OPEN:<filename>)))
|
||||||
link(CREATE)(ADDRESS_CREAT),
|
link(CREATE)(ADDRESS_CREAT),
|
||||||
link(GOPEN)(ADDRESS_GOPEN),
|
link(GOPEN)(ADDRESS_GOPEN),
|
||||||
link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT)
|
link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT)
|
||||||
|
|
||||||
label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
|
label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
|
||||||
Tries to establish a SSL connection to <port> [link(TCP
|
Tries to establish a SSL connection to <port> [link(TCP
|
||||||
service)(TYPE_TCP_SERVICE)] on
|
service)(TYPE_TCP_SERVICE)] on
|
||||||
|
@ -502,7 +503,7 @@ label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
|
||||||
<host> parameter or the value of the
|
<host> parameter or the value of the
|
||||||
link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option.
|
link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) option.
|
||||||
Socat tries to match it against the certificates subject commonName,
|
Socat tries to match it against the certificates subject commonName,
|
||||||
and the certifications extension subjectAltName DNS names. Wildcards in the
|
and the certificates extension subjectAltName DNS names. Wildcards in the
|
||||||
certificate are supported.nl()
|
certificate are supported.nl()
|
||||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl()
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl()
|
||||||
Useful options:
|
Useful options:
|
||||||
|
@ -522,6 +523,7 @@ label(ADDRESS_OPENSSL_CONNECT)dit(bf(tt(OPENSSL:<host>:<port>)))
|
||||||
See also:
|
See also:
|
||||||
link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN),
|
link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN),
|
||||||
link(TCP)(ADDRESS_TCP_CONNECT)
|
link(TCP)(ADDRESS_TCP_CONNECT)
|
||||||
|
|
||||||
label(ADDRESS_OPENSSL_LISTEN)dit(bf(tt(OPENSSL-LISTEN:<port>)))
|
label(ADDRESS_OPENSSL_LISTEN)dit(bf(tt(OPENSSL-LISTEN:<port>)))
|
||||||
Listens on tcp <port> [link(TCP service)(TYPE_TCP_SERVICE)].
|
Listens on tcp <port> [link(TCP service)(TYPE_TCP_SERVICE)].
|
||||||
The IP version is 4 or the one specified with
|
The IP version is 4 or the one specified with
|
||||||
|
@ -552,6 +554,71 @@ label(ADDRESS_OPENSSL_LISTEN)dit(bf(tt(OPENSSL-LISTEN:<port>)))
|
||||||
See also:
|
See also:
|
||||||
link(OPENSSL)(ADDRESS_OPENSSL_CONNECT),
|
link(OPENSSL)(ADDRESS_OPENSSL_CONNECT),
|
||||||
link(TCP-LISTEN)(ADDRESS_TCP_LISTEN)
|
link(TCP-LISTEN)(ADDRESS_TCP_LISTEN)
|
||||||
|
|
||||||
|
label(ADDRESS_OPENSSL_DTLS_CLIENT)dit(bf(tt(OPENSSL-DTLS-CLIENT:<host>:<port>)))
|
||||||
|
Tries to establish a DTLS connection to <port> [link(UDP
|
||||||
|
service)(TYPE_UDP_SERVICE)] on
|
||||||
|
<host> [link(IP address)(TYPE_IP_ADDRESS)] using UDP/IP version 4 or 6
|
||||||
|
depending on address specification, name resolution, or option
|
||||||
|
link(pf)(OPTION_PROTOCOL_FAMILY).nl()
|
||||||
|
Socat() checks the peer certificates subjectAltName or commonName against the addresses
|
||||||
|
option link(openssl-commonname)(OPTION_OPENSSL_COMMONNAME) or the host name.
|
||||||
|
Wildcards in the certificate are supported.nl()
|
||||||
|
Use socat() option link(-b)(option_b) to make datagrams small enough to fit with overhead
|
||||||
|
on the network. Use option link(-T)(option_T) to prevent indefinite hanging when peer went down quietly.nl()
|
||||||
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),COMMENT(link(UDP)(GROUP_UDP),)link(OPENSSL)(GROUP_OPENSSL),link(RETRY)(GROUP_RETRY) nl()
|
||||||
|
Useful options:
|
||||||
|
link(cipher)(OPTION_OPENSSL_CIPHERLIST),
|
||||||
|
link(verify)(OPTION_OPENSSL_VERIFY),
|
||||||
|
link(commonname)(OPTION_OPENSSL_COMMONNAME),
|
||||||
|
link(cafile)(OPTION_OPENSSL_CAFILE),
|
||||||
|
link(capath)(OPTION_OPENSSL_CAPATH),
|
||||||
|
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
|
||||||
|
link(key)(OPTION_OPENSSL_KEY),
|
||||||
|
link(compress)(OPTION_OPENSSL_COMPRESS),
|
||||||
|
link(bind)(OPTION_BIND),
|
||||||
|
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||||
|
link(sourceport)(OPTION_SOURCEPORT),
|
||||||
|
link(retry)(OPTION_RETRY)nl()
|
||||||
|
See also:
|
||||||
|
link(OPENSSL-DTLS-SERVER)(ADDRESS_OPENSSL_DTLS_SERVER),
|
||||||
|
link(OPENSSL-CONNECT)(ADDRESS_OPENSSL_CONNECT),
|
||||||
|
link(UDP-CONNECT)(ADDRESS_UDP_CONNECT)
|
||||||
|
|
||||||
|
label(ADDRESS_OPENSSL_DTLS_SERVER)dit(bf(tt(OPENSSL-DTLS-SERVER:<port>)))
|
||||||
|
Listens on UDP <port> [link(UDP service)(TYPE_UDP_SERVICE)].
|
||||||
|
The IP version is 4 or the one specified with
|
||||||
|
link(pf)(OPTION_PROTOCOL_FAMILY). When a
|
||||||
|
connection is accepted, this address behaves as DTLS server.nl()
|
||||||
|
Note: You probably want to use the link(certificate)(OPTION_OPENSSL_CERTIFICATE) option with this address.nl()
|
||||||
|
NOTE: The client certificate is only checked for validity against
|
||||||
|
link(cafile)(OPTION_OPENSSL_CAFILE) or link(capath)(OPTION_OPENSSL_CAPATH),
|
||||||
|
but not for match with the client's name or its IP address!
|
||||||
|
Use socat() option link(-b)(option_b) to make datagrams small enough to fit with overhead on the network.
|
||||||
|
Use option link(-T)(option_T) to prevent indefinite hanging when peer went down quietly.nl()
|
||||||
|
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),COMMENT(link(UDP)(GROUP_UDP),)link(LISTEN)(GROUP_LISTEN),link(OPENSSL)(GROUP_OPENSSL),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(RETRY)(GROUP_RETRY) nl()
|
||||||
|
Useful options:
|
||||||
|
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||||
|
link(cipher)(OPTION_OPENSSL_CIPHERLIST),
|
||||||
|
link(verify)(OPTION_OPENSSL_VERIFY),
|
||||||
|
link(commonname)(OPTION_OPENSSL_COMMONNAME),
|
||||||
|
link(cafile)(OPTION_OPENSSL_CAFILE),
|
||||||
|
link(capath)(OPTION_OPENSSL_CAPATH),
|
||||||
|
link(certificate)(OPTION_OPENSSL_CERTIFICATE),
|
||||||
|
link(key)(OPTION_OPENSSL_KEY),
|
||||||
|
link(compress)(OPTION_OPENSSL_COMPRESS),
|
||||||
|
link(fork)(OPTION_FORK),
|
||||||
|
link(bind)(OPTION_BIND),
|
||||||
|
link(range)(OPTION_RANGE),
|
||||||
|
link(tcpwrap)(OPTION_TCPWRAPPERS),
|
||||||
|
link(su)(OPTION_SUBSTUSER),
|
||||||
|
link(reuseaddr)(OPTION_REUSEADDR),
|
||||||
|
link(retry)(OPTION_RETRY)nl()
|
||||||
|
See also:
|
||||||
|
link(OPENSSL-DTLS-CLIENT)(ADDRESS_OPENSSL_DTLS_CLIENT),
|
||||||
|
link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN),
|
||||||
|
link(UDP-LISTEN)(ADDRESS_UDP_LISTEN)
|
||||||
|
|
||||||
label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>)))
|
label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>)))
|
||||||
If link(<filename>)(TYPE_FILENAME) already exists, it is opened.
|
If link(<filename>)(TYPE_FILENAME) already exists, it is opened.
|
||||||
If it does not exist, a named pipe is created and opened. Beginning with
|
If it does not exist, a named pipe is created and opened. Beginning with
|
||||||
|
|
60
sslcls.c
60
sslcls.c
|
@ -35,6 +35,26 @@ int sycSSL_library_init(void) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_TLS_client_method
|
||||||
|
const SSL_METHOD *sycTLS_client_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("TLS_client_method()");
|
||||||
|
result = TLS_client_method();
|
||||||
|
Debug1("TLS_client_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TLS_server_method
|
||||||
|
const SSL_METHOD *sycTLS_server_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("TLS_server_method()");
|
||||||
|
result = TLS_server_method();
|
||||||
|
Debug1("TLS_server_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSLv2_client_method
|
#if HAVE_SSLv2_client_method
|
||||||
const SSL_METHOD *sycSSLv2_client_method(void) {
|
const SSL_METHOD *sycSSLv2_client_method(void) {
|
||||||
const SSL_METHOD *result;
|
const SSL_METHOD *result;
|
||||||
|
@ -151,6 +171,26 @@ const SSL_METHOD *sycTLSv1_2_server_method(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DTLS_client_method
|
||||||
|
const SSL_METHOD *sycDTLS_client_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("DTLS_client_method()");
|
||||||
|
result = DTLS_client_method();
|
||||||
|
Debug1("DTLS_client_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DTLS_server_method
|
||||||
|
const SSL_METHOD *sycDTLS_server_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("DTLS_server_method()");
|
||||||
|
result = DTLS_server_method();
|
||||||
|
Debug1("DTLS_server_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_DTLSv1_client_method
|
#if HAVE_DTLSv1_client_method
|
||||||
const SSL_METHOD *sycDTLSv1_client_method(void) {
|
const SSL_METHOD *sycDTLSv1_client_method(void) {
|
||||||
const SSL_METHOD *result;
|
const SSL_METHOD *result;
|
||||||
|
@ -171,6 +211,26 @@ const SSL_METHOD *sycDTLSv1_server_method(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DTLSv1_2_client_method
|
||||||
|
const SSL_METHOD *sycDTLSv1_2_client_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("DTLSv1_2_client_method()");
|
||||||
|
result = DTLSv1_2_client_method();
|
||||||
|
Debug1("DTLSv1_2_client_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DTLSv1_2_server_method
|
||||||
|
const SSL_METHOD *sycDTLSv1_2_server_method(void) {
|
||||||
|
const SSL_METHOD *result;
|
||||||
|
Debug("DTLSv1_2_server_method()");
|
||||||
|
result = DTLSv1_2_server_method();
|
||||||
|
Debug1("DTLSv1_2_server_method() -> %p", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method) {
|
SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method) {
|
||||||
SSL_CTX *result;
|
SSL_CTX *result;
|
||||||
Debug1("SSL_CTX_new(%p)", method);
|
Debug1("SSL_CTX_new(%p)", method);
|
||||||
|
|
12
sslcls.h
12
sslcls.h
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
void sycSSL_load_error_strings(void);
|
void sycSSL_load_error_strings(void);
|
||||||
int sycSSL_library_init(void);
|
int sycSSL_library_init(void);
|
||||||
|
const SSL_METHOD *sycTLS_client_method(void);
|
||||||
|
const SSL_METHOD *sycTLS_server_method(void);
|
||||||
const SSL_METHOD *sycSSLv2_client_method(void);
|
const SSL_METHOD *sycSSLv2_client_method(void);
|
||||||
const SSL_METHOD *sycSSLv2_server_method(void);
|
const SSL_METHOD *sycSSLv2_server_method(void);
|
||||||
const SSL_METHOD *sycSSLv3_client_method(void);
|
const SSL_METHOD *sycSSLv3_client_method(void);
|
||||||
|
@ -22,8 +24,12 @@ const SSL_METHOD *sycTLSv1_1_client_method(void);
|
||||||
const SSL_METHOD *sycTLSv1_1_server_method(void);
|
const SSL_METHOD *sycTLSv1_1_server_method(void);
|
||||||
const SSL_METHOD *sycTLSv1_2_client_method(void);
|
const SSL_METHOD *sycTLSv1_2_client_method(void);
|
||||||
const SSL_METHOD *sycTLSv1_2_server_method(void);
|
const SSL_METHOD *sycTLSv1_2_server_method(void);
|
||||||
|
const SSL_METHOD *sycDTLS_client_method(void);
|
||||||
|
const SSL_METHOD *sycDTLS_server_method(void);
|
||||||
const SSL_METHOD *sycDTLSv1_client_method(void);
|
const SSL_METHOD *sycDTLSv1_client_method(void);
|
||||||
const SSL_METHOD *sycDTLSv1_server_method(void);
|
const SSL_METHOD *sycDTLSv1_server_method(void);
|
||||||
|
const SSL_METHOD *sycDTLSv1_2_client_method(void);
|
||||||
|
const SSL_METHOD *sycDTLSv1_2_server_method(void);
|
||||||
SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method);
|
SSL_CTX *sycSSL_CTX_new(const SSL_METHOD *method);
|
||||||
SSL *sycSSL_new(SSL_CTX *ctx);
|
SSL *sycSSL_new(SSL_CTX *ctx);
|
||||||
int sycSSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
int sycSSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
||||||
|
@ -69,6 +75,8 @@ const char *sycSSL_COMP_get_name(const COMP_METHOD *comp);
|
||||||
|
|
||||||
#define sycSSL_load_error_strings() SSL_load_error_strings()
|
#define sycSSL_load_error_strings() SSL_load_error_strings()
|
||||||
#define sycSSL_library_init() SSL_library_init()
|
#define sycSSL_library_init() SSL_library_init()
|
||||||
|
#define sycTLS_client_method() TLS_client_method()
|
||||||
|
#define sycTLS_server_method() TLS_server_method()
|
||||||
#define sycSSLv2_client_method() SSLv2_client_method()
|
#define sycSSLv2_client_method() SSLv2_client_method()
|
||||||
#define sycSSLv2_server_method() SSLv2_server_method()
|
#define sycSSLv2_server_method() SSLv2_server_method()
|
||||||
#define sycSSLv3_client_method() SSLv3_client_method()
|
#define sycSSLv3_client_method() SSLv3_client_method()
|
||||||
|
@ -81,8 +89,12 @@ const char *sycSSL_COMP_get_name(const COMP_METHOD *comp);
|
||||||
#define sycTLSv1_1_server_method() TLSv1_1_server_method()
|
#define sycTLSv1_1_server_method() TLSv1_1_server_method()
|
||||||
#define sycTLSv1_2_client_method() TLSv1_2_client_method()
|
#define sycTLSv1_2_client_method() TLSv1_2_client_method()
|
||||||
#define sycTLSv1_2_server_method() TLSv1_2_server_method()
|
#define sycTLSv1_2_server_method() TLSv1_2_server_method()
|
||||||
|
#define sycDTLS_client_method() DTLS_client_method()
|
||||||
|
#define sycDTLS_server_method() DTLS_server_method()
|
||||||
#define sycDTLSv1_client_method() DTLSv1_client_method()
|
#define sycDTLSv1_client_method() DTLSv1_client_method()
|
||||||
#define sycDTLSv1_server_method() DTLSv1_server_method()
|
#define sycDTLSv1_server_method() DTLSv1_server_method()
|
||||||
|
#define sycDTLSv1_2_client_method() DTLSv1_2_client_method()
|
||||||
|
#define sycDTLSv1_2_server_method() DTLSv1_2_server_method()
|
||||||
#define sycSSL_CTX_new(m) SSL_CTX_new(m)
|
#define sycSSL_CTX_new(m) SSL_CTX_new(m)
|
||||||
#define sycSSL_new(c) SSL_new(c)
|
#define sycSSL_new(c) SSL_new(c)
|
||||||
#define sycSSL_CTX_load_verify_locations(c,f,p) SSL_CTX_load_verify_locations(c,f,p)
|
#define sycSSL_CTX_load_verify_locations(c,f,p) SSL_CTX_load_verify_locations(c,f,p)
|
||||||
|
|
8
sycls.c
8
sycls.c
|
@ -960,8 +960,14 @@ int Sigaction(int signum, const struct sigaction *act,
|
||||||
|
|
||||||
int Sigprocmask(int how, const sigset_t *set, sigset_t *oset) {
|
int Sigprocmask(int how, const sigset_t *set, sigset_t *oset) {
|
||||||
int retval;
|
int retval;
|
||||||
Debug3("sigprocmask(%d, %p, %p)", how, set, oset);
|
if (set)
|
||||||
|
Debug3("sigprocmask(%d, "F_sigset", %p)", how, *(T_sigset *)set, oset);
|
||||||
|
else
|
||||||
|
Debug2("sigprocmask(%d, NULL, %p)", how, oset);
|
||||||
retval = sigprocmask(how, set, oset);
|
retval = sigprocmask(how, set, oset);
|
||||||
|
if (oset)
|
||||||
|
Debug2("sigprocmask() -> {,, "F_sigset"} %d", *(T_sigset *)oset, retval);
|
||||||
|
else
|
||||||
Debug1("sigprocmask() -> %d", retval);
|
Debug1("sigprocmask() -> %d", retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
147
test.sh
147
test.sh
|
@ -12907,7 +12907,7 @@ N=$((N+1))
|
||||||
|
|
||||||
# tests of various SSL methods; from TLS1.3 this method is not avail in OpenSSL:
|
# tests of various SSL methods; from TLS1.3 this method is not avail in OpenSSL:
|
||||||
OPENSSL_METHODS_OBSOLETE="SSL3 SSL23"
|
OPENSSL_METHODS_OBSOLETE="SSL3 SSL23"
|
||||||
OPENSSL_METHODS_EXPECTED="TLS1 TLS1.1 TLS1.2 DTLS1"
|
OPENSSL_METHODS_EXPECTED="TLS1 TLS1.1 TLS1.2 DTLS1 DTLS1.2"
|
||||||
|
|
||||||
# the OPENSSL_METHOD_DTLS1 test hangs sometimes, probably depending on the openssl version.
|
# the OPENSSL_METHOD_DTLS1 test hangs sometimes, probably depending on the openssl version.
|
||||||
OPENSSL_VERSION="$(openssl version)"
|
OPENSSL_VERSION="$(openssl version)"
|
||||||
|
@ -13015,7 +13015,11 @@ if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)
|
||||||
else
|
else
|
||||||
$CMD0 >/dev/null 2>"${te}0" &
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
pid0=$!
|
pid0=$!
|
||||||
|
if [[ "$method" =~ DTLS* ]]; then
|
||||||
|
waitudp4port $PORT 1
|
||||||
|
else
|
||||||
waittcp4port $PORT 1
|
waittcp4port $PORT 1
|
||||||
|
fi
|
||||||
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
||||||
rc1=$?
|
rc1=$?
|
||||||
kill $pid0 2>/dev/null; wait
|
kill $pid0 2>/dev/null; wait
|
||||||
|
@ -13924,6 +13928,147 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# test the DTLS client feature
|
||||||
|
NAME=OPENSSL_DTLS_CLIENT
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: OpenSSL DTLS client"
|
||||||
|
# Run openssl s_server in DTLS mode, wrapped into a simple Socat echoing command.
|
||||||
|
# Start a Socat DTLS client, send data to server and check if reply is received.
|
||||||
|
if ! eval $NUMCOND; then :;
|
||||||
|
elif ! a=$(testfeats ip4 udp openssl); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! a=$(testaddrs openssl-dtls-client); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! runsip4 >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! type openssl >/dev/null 2>&1; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
gentestcert testsrv
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
#set -vx
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
S_SERVER_4=
|
||||||
|
if openssl s_server -help 2>&1 | grep -q ' -4 '; then
|
||||||
|
S_SERVER_4="-4"
|
||||||
|
fi
|
||||||
|
if openssl s_server -help 2>&1 | grep -q ' -dtls '; then
|
||||||
|
S_SERVER_DTLS=-dtls
|
||||||
|
else
|
||||||
|
S_SERVER_DTLS=-dtls1
|
||||||
|
fi
|
||||||
|
if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then
|
||||||
|
S_SERVER_NO_IGN_EOF=-no-ign_eof
|
||||||
|
else
|
||||||
|
S_SERVER_NO_IGN_EOF=
|
||||||
|
fi
|
||||||
|
CMD1="$TRACE openssl s_server $S_SERVER_4 $S_SERVER_DTLS -accept $PORT -quiet $S_SERVER_NO_IGN_EOF -cert testsrv.pem"
|
||||||
|
CMD="$TRACE $SOCAT $opts -T 1 - OPENSSL-DTLS-CLIENT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
( sleep 2; echo "$da"; sleep 1 ) |$CMD1 2>"${te}1" &
|
||||||
|
pid1=$! # background process id
|
||||||
|
waitudp4port $PORT
|
||||||
|
$CMD >$tf 2>"$te"
|
||||||
|
kill $pid1 2>/dev/null; wait 2>/dev/null
|
||||||
|
if ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||||
|
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||||
|
echo "$CMD1 &"
|
||||||
|
cat "${te}1"
|
||||||
|
echo "$CMD"
|
||||||
|
cat "$te"
|
||||||
|
cat "$tdiff"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ -n "$debug" ]; then cat "${te}1" "$te"; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
fi
|
||||||
|
fi ;; # NUMCOND, feats
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
set +vx
|
||||||
|
|
||||||
|
# test the DTLS server feature
|
||||||
|
NAME=OPENSSL_DTLS_SERVER
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%socket%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: OpenSSL DTLS server"
|
||||||
|
# Run a socat OpenSSL DTLS server with echo function
|
||||||
|
# Start an OpenSSL s_client, send data and check if repley is received.
|
||||||
|
if ! eval $NUMCOND; then :;
|
||||||
|
elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! a=$(testaddrs openssl-dtls-server); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! runsip4 >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! type openssl >/dev/null 2>&1; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
gentestcert testsrv
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
if openssl s_server -help 2>&1 | grep -q ' -dtls '; then
|
||||||
|
S_SERVER_DTLS=-dtls
|
||||||
|
else
|
||||||
|
S_SERVER_DTLS=-dtls1
|
||||||
|
fi
|
||||||
|
CMD1="$TRACE $SOCAT $opts OPENSSL-DTLS-SERVER:$PORT,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
|
||||||
|
CMD="openssl s_client -host $LOCALHOST -port $PORT $S_SERVER_DTLS"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD1 >/dev/null 2>"${te}1" &
|
||||||
|
pid1=$!
|
||||||
|
waitudp4port $PORT 1
|
||||||
|
( echo "$da"; sleep 0.1 ) |$CMD 2>"$te" |grep "$da" >"$tf"
|
||||||
|
rc=$?
|
||||||
|
kill $pid1 2>/dev/null; wait
|
||||||
|
if echo "$da" |diff - $tf >"$tdiff"; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD1 &"
|
||||||
|
cat "${te}1"
|
||||||
|
echo "$CMD"
|
||||||
|
cat "$te"
|
||||||
|
cat "$tdiff"
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
#=================================================================================
|
#=================================================================================
|
||||||
# here come tests that might affect your systems integrity. Put normal tests
|
# here come tests that might affect your systems integrity. Put normal tests
|
||||||
|
|
108
xio-openssl.c
108
xio-openssl.c
|
@ -14,6 +14,7 @@
|
||||||
#include "xio-fd.h"
|
#include "xio-fd.h"
|
||||||
#include "xio-socket.h" /* _xioopen_connect() */
|
#include "xio-socket.h" /* _xioopen_connect() */
|
||||||
#include "xio-listen.h"
|
#include "xio-listen.h"
|
||||||
|
#include "xio-udp.h"
|
||||||
#include "xio-ipapp.h"
|
#include "xio-ipapp.h"
|
||||||
#include "xio-openssl.h"
|
#include "xio-openssl.h"
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ static int openssl_delete_cert_info(void);
|
||||||
|
|
||||||
|
|
||||||
/* description record for ssl connect */
|
/* description record for ssl connect */
|
||||||
const struct addrdesc addr_openssl = {
|
const struct addrdesc xioaddr_openssl = {
|
||||||
"openssl", /* keyword for selecting this address type in xioopen calls
|
"openssl", /* keyword for selecting this address type in xioopen calls
|
||||||
(canonical or main name) */
|
(canonical or main name) */
|
||||||
3, /* data flow directions this address supports on API layer:
|
3, /* data flow directions this address supports on API layer:
|
||||||
|
@ -67,7 +68,7 @@ const struct addrdesc addr_openssl = {
|
||||||
GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to.
|
GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to.
|
||||||
You might have to specify a new group in xioopts.h */
|
You might have to specify a new group in xioopts.h */
|
||||||
0, /* an integer passed to xioopen_openssl; makes it possible to
|
0, /* an integer passed to xioopen_openssl; makes it possible to
|
||||||
use the same xioopen_openssl function for slightly different
|
use the xioopen_openssl_connect function for slightly different
|
||||||
address types. */
|
address types. */
|
||||||
0, /* like previous argument */
|
0, /* like previous argument */
|
||||||
0 /* like previous arguments, but pointer type.
|
0 /* like previous arguments, but pointer type.
|
||||||
|
@ -79,7 +80,7 @@ const struct addrdesc addr_openssl = {
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
/* description record for ssl listen */
|
/* description record for ssl listen */
|
||||||
const struct addrdesc addr_openssl_listen = {
|
const struct addrdesc xioaddr_openssl_listen = {
|
||||||
"openssl-listen", /* keyword for selecting this address type in xioopen calls
|
"openssl-listen", /* keyword for selecting this address type in xioopen calls
|
||||||
(canonical or main name) */
|
(canonical or main name) */
|
||||||
3, /* data flow directions this address supports on API layer:
|
3, /* data flow directions this address supports on API layer:
|
||||||
|
@ -88,7 +89,7 @@ const struct addrdesc addr_openssl_listen = {
|
||||||
GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to.
|
GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_OPENSSL|GROUP_RETRY, /* bitwise OR of address groups this address belongs to.
|
||||||
You might have to specify a new group in xioopts.h */
|
You might have to specify a new group in xioopts.h */
|
||||||
0, /* an integer passed to xioopen_openssl_listen; makes it possible to
|
0, /* an integer passed to xioopen_openssl_listen; makes it possible to
|
||||||
use the same xioopen_openssl_listen function for slightly different
|
use the xioopen_openssl_listen function for slightly different
|
||||||
address types. */
|
address types. */
|
||||||
0, /* like previous argument */
|
0, /* like previous argument */
|
||||||
0 /* like previous arguments, but pointer type.
|
0 /* like previous arguments, but pointer type.
|
||||||
|
@ -99,6 +100,9 @@ const struct addrdesc addr_openssl_listen = {
|
||||||
} ;
|
} ;
|
||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
|
||||||
|
const struct addrdesc xioaddr_openssl_dtls_client = { "openssl-dtls-client", 3, xioopen_openssl_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_OPENSSL|GROUP_RETRY, 1, 0, 0 HELP(":<host>:<port>") } ;
|
||||||
|
const struct addrdesc xioaddr_openssl_dtls_server = { "openssl-dtls-server", 3, xioopen_openssl_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_OPENSSL|GROUP_RETRY, 1, 0, 0 HELP(":<port>") } ;
|
||||||
|
|
||||||
/* both client and server */
|
/* both client and server */
|
||||||
const struct optdesc opt_openssl_cipherlist = { "openssl-cipherlist", "ciphers", OPT_OPENSSL_CIPHERLIST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_openssl_cipherlist = { "openssl-cipherlist", "ciphers", OPT_OPENSSL_CIPHERLIST, GROUP_OPENSSL, PH_SPEC, TYPE_STRING, OFUNC_SPEC };
|
||||||
#if WITH_OPENSSL_METHOD
|
#if WITH_OPENSSL_METHOD
|
||||||
|
@ -188,7 +192,7 @@ static int
|
||||||
xiofile_t *xxfd, /* a xio file descriptor structure,
|
xiofile_t *xxfd, /* a xio file descriptor structure,
|
||||||
already allocated */
|
already allocated */
|
||||||
unsigned groups, /* the matching address groups... */
|
unsigned groups, /* the matching address groups... */
|
||||||
int dummy1, /* first transparent integer value from
|
int protogrp, /* first transparent integer value from
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
int dummy2, /* second transparent integer value from
|
int dummy2, /* second transparent integer value from
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
|
@ -199,8 +203,9 @@ static int
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
const char *hostname, *portname;
|
const char *hostname, *portname;
|
||||||
int pf = PF_UNSPEC;
|
int pf = PF_UNSPEC;
|
||||||
int ipproto = IPPROTO_TCP;
|
bool use_dtls = (protogrp != 0);
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
|
int ipproto = IPPROTO_TCP;
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
union sockaddr_union them_sa, *them = &them_sa;
|
union sockaddr_union them_sa, *them = &them_sa;
|
||||||
|
@ -248,9 +253,16 @@ static int
|
||||||
}
|
}
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx);
|
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls);
|
||||||
if (result != STAT_OK) return STAT_NORETRY;
|
if (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
|
||||||
|
if (use_dtls) {
|
||||||
|
socktype = SOCK_DGRAM;
|
||||||
|
ipproto = IPPROTO_UDP;
|
||||||
|
}
|
||||||
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
|
@ -428,7 +440,7 @@ static int
|
||||||
xiofile_t *xxfd, /* a xio file descriptor structure,
|
xiofile_t *xxfd, /* a xio file descriptor structure,
|
||||||
already allocated */
|
already allocated */
|
||||||
unsigned groups, /* the matching address groups... */
|
unsigned groups, /* the matching address groups... */
|
||||||
int dummy1, /* first transparent integer value from
|
int protogrp, /* first transparent integer value from
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
int dummy2, /* second transparent integer value from
|
int dummy2, /* second transparent integer value from
|
||||||
addr_openssl */
|
addr_openssl */
|
||||||
|
@ -441,6 +453,7 @@ static int
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
socklen_t uslen = sizeof(us_sa);
|
socklen_t uslen = sizeof(us_sa);
|
||||||
int pf;
|
int pf;
|
||||||
|
bool use_dtls = (protogrp != 0);
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
int ipproto = IPPROTO_TCP;
|
int ipproto = IPPROTO_TCP;
|
||||||
/*! lowport? */
|
/*! lowport? */
|
||||||
|
@ -486,9 +499,16 @@ static int
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx);
|
_xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx, &use_dtls);
|
||||||
if (result != STAT_OK) return STAT_NORETRY;
|
if (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
|
||||||
|
if (use_dtls) {
|
||||||
|
socktype = SOCK_DGRAM;
|
||||||
|
ipproto = IPPROTO_UDP;
|
||||||
|
}
|
||||||
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||||
|
|
||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
|
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
|
||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
|
@ -497,7 +517,7 @@ static int
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->addr = &addr_openssl_listen;
|
xfd->addr = &xioaddr_openssl_listen;
|
||||||
xfd->dtype = XIODATA_OPENSSL;
|
xfd->dtype = XIODATA_OPENSSL;
|
||||||
|
|
||||||
while (true) { /* loop over failed attempts */
|
while (true) { /* loop over failed attempts */
|
||||||
|
@ -509,17 +529,22 @@ static int
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
|
|
||||||
/* tcp listen; this can fork() for us; it only returns on error or on
|
/* this can fork() for us; it only returns on error or on
|
||||||
successful establishment of tcp connection */
|
successful establishment of connection */
|
||||||
|
if (ipproto == IPPROTO_TCP) {
|
||||||
result = _xioopen_listen(xfd, xioflags,
|
result = _xioopen_listen(xfd, xioflags,
|
||||||
(struct sockaddr *)us, uslen,
|
(struct sockaddr *)us, uslen,
|
||||||
opts, pf, socktype, IPPROTO_TCP,
|
opts, pf, socktype, ipproto,
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
(xfd->retry||xfd->forever)?E_INFO:E_ERROR
|
(xfd->retry||xfd->forever)?E_INFO:E_ERROR
|
||||||
#else
|
#else
|
||||||
E_ERROR
|
E_ERROR
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
result = _xioopen_ipdgram_listen(xfd, xioflags,
|
||||||
|
us, uslen, opts, pf, socktype, ipproto);
|
||||||
|
}
|
||||||
/*! not sure if we should try again on retry/forever */
|
/*! not sure if we should try again on retry/forever */
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
|
@ -838,7 +863,8 @@ int
|
||||||
bool server, /* SSL client: false */
|
bool server, /* SSL client: false */
|
||||||
bool *opt_ver,
|
bool *opt_ver,
|
||||||
const char *opt_cert,
|
const char *opt_cert,
|
||||||
SSL_CTX **ctxp)
|
SSL_CTX **ctxp,
|
||||||
|
bool *use_dtls) /* checked,overwritten with true if DTLS-method */
|
||||||
{
|
{
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
bool opt_fips = false;
|
bool opt_fips = false;
|
||||||
|
@ -857,7 +883,9 @@ int
|
||||||
unsigned long err;
|
unsigned long err;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
xfd->addr = &addr_openssl;
|
//*ipproto = IPPROTO_TCP;
|
||||||
|
|
||||||
|
xfd->addr = &xioaddr_openssl;
|
||||||
xfd->dtype = XIODATA_OPENSSL;
|
xfd->dtype = XIODATA_OPENSSL;
|
||||||
|
|
||||||
retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips);
|
retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips);
|
||||||
|
@ -926,15 +954,21 @@ int
|
||||||
method = sycTLSv1_2_client_method();
|
method = sycTLSv1_2_client_method();
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_DTLSv1_client_method
|
#if HAVE_DTLSv1_client_method
|
||||||
} else if (!strcasecmp(me_str, "DTLS") || !strcasecmp(me_str, "DTLS1")) {
|
} else if (!strcasecmp(me_str, "DTLS1") || !strcasecmp(me_str, "DTLS1.0")) {
|
||||||
method = sycDTLSv1_client_method();
|
method = sycDTLSv1_client_method();
|
||||||
|
*use_dtls = true;
|
||||||
|
#endif
|
||||||
|
#if HAVE_DTLSv1_2_client_method
|
||||||
|
} else if (!strcasecmp(me_str, "DTLS1.2")) {
|
||||||
|
method = sycDTLSv1_2_client_method();
|
||||||
|
*use_dtls = true;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str);
|
Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!*use_dtls) {
|
||||||
#if HAVE_TLS_client_method
|
#if HAVE_TLS_client_method
|
||||||
method = TLS_client_method();
|
method = sycTLS_client_method();
|
||||||
#elif HAVE_SSLv23_client_method
|
#elif HAVE_SSLv23_client_method
|
||||||
method = sycSSLv23_client_method();
|
method = sycSSLv23_client_method();
|
||||||
#elif HAVE_TLSv1_2_client_method
|
#elif HAVE_TLSv1_2_client_method
|
||||||
|
@ -948,8 +982,19 @@ int
|
||||||
#elif HAVE_SSLv2_client_method
|
#elif HAVE_SSLv2_client_method
|
||||||
method = sycSSLv2_client_method();
|
method = sycSSLv2_client_method();
|
||||||
#else
|
#else
|
||||||
# error "OpenSSL does not seem to provide client methods"
|
# error "OpenSSL does not seem to provide SSL/TLS client methods"
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
#if HAVE_DTLS_client_method
|
||||||
|
method = sycDTLS_client_method();
|
||||||
|
#elif HAVE_DTLSv1_2_client_method
|
||||||
|
method = sycDTLSv1_2_client_method();
|
||||||
|
#elif HAVE_DTLSv1_client_method
|
||||||
|
method = sycDTLSv1_client_method();
|
||||||
|
#else
|
||||||
|
# error "OpenSSL does not seem to provide DTLS client methods"
|
||||||
|
#endif
|
||||||
|
*use_dtls = true;
|
||||||
}
|
}
|
||||||
} else /* server */ {
|
} else /* server */ {
|
||||||
if (me_str != 0) {
|
if (me_str != 0) {
|
||||||
|
@ -980,15 +1025,21 @@ int
|
||||||
method = sycTLSv1_2_server_method();
|
method = sycTLSv1_2_server_method();
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_DTLSv1_server_method
|
#if HAVE_DTLSv1_server_method
|
||||||
} else if (!strcasecmp(me_str, "DTLS") || !strcasecmp(me_str, "DTLS1")) {
|
} else if (!strcasecmp(me_str, "DTLS1") || !strcasecmp(me_str, "DTLS1.0")) {
|
||||||
method = sycDTLSv1_server_method();
|
method = sycDTLSv1_server_method();
|
||||||
|
*use_dtls = true;
|
||||||
|
#endif
|
||||||
|
#if HAVE_DTLSv1_2_server_method
|
||||||
|
} else if (!strcasecmp(me_str, "DTLS1.2")) {
|
||||||
|
method = sycDTLSv1_2_server_method();
|
||||||
|
*use_dtls = true;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str);
|
Error1("openssl-method=\"%s\": method unknown or not provided by library", me_str);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!*use_dtls) {
|
||||||
#if HAVE_TLS_server_method
|
#if HAVE_TLS_server_method
|
||||||
method = TLS_server_method();
|
method = sycTLS_server_method();
|
||||||
#elif HAVE_SSLv23_server_method
|
#elif HAVE_SSLv23_server_method
|
||||||
method = sycSSLv23_server_method();
|
method = sycSSLv23_server_method();
|
||||||
#elif HAVE_TLSv1_2_server_method
|
#elif HAVE_TLSv1_2_server_method
|
||||||
|
@ -1002,8 +1053,19 @@ int
|
||||||
#elif HAVE_SSLv2_server_method
|
#elif HAVE_SSLv2_server_method
|
||||||
method = sycSSLv2_server_method();
|
method = sycSSLv2_server_method();
|
||||||
#else
|
#else
|
||||||
# error "OpenSSL does not seem to provide client methods"
|
# error "OpenSSL does not seem to provide SSL/TLS server methods"
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
#if HAVE_DTLS_server_method
|
||||||
|
method = sycDTLS_server_method();
|
||||||
|
#elif HAVE_DTLSv1_2_server_method
|
||||||
|
method = sycDTLSv1_2_server_method();
|
||||||
|
#elif HAVE_DTLSv1_server_method
|
||||||
|
method = sycDTLSv1_server_method();
|
||||||
|
#else
|
||||||
|
# error "OpenSSL does not seem to provide DTLS server methods"
|
||||||
|
#endif
|
||||||
|
*use_dtls = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@
|
||||||
#define SSLIO_BASE 0x53530000 /* "SSxx" */
|
#define SSLIO_BASE 0x53530000 /* "SSxx" */
|
||||||
#define SSLIO_MASK 0xffff0000
|
#define SSLIO_MASK 0xffff0000
|
||||||
|
|
||||||
extern const struct addrdesc addr_openssl;
|
extern const struct addrdesc xioaddr_openssl;
|
||||||
extern const struct addrdesc addr_openssl_listen;
|
extern const struct addrdesc xioaddr_openssl_listen;
|
||||||
|
extern const struct addrdesc xioaddr_openssl_dtls_client;
|
||||||
|
extern const struct addrdesc xioaddr_openssl_dtls_server;
|
||||||
|
|
||||||
extern const struct optdesc opt_openssl_cipherlist;
|
extern const struct optdesc opt_openssl_cipherlist;
|
||||||
extern const struct optdesc opt_openssl_method;
|
extern const struct optdesc opt_openssl_method;
|
||||||
|
@ -36,7 +38,7 @@ extern const struct optdesc opt_openssl_commonname;
|
||||||
extern int
|
extern int
|
||||||
_xioopen_openssl_prepare(struct opt *opts, struct single *xfd,
|
_xioopen_openssl_prepare(struct opt *opts, struct single *xfd,
|
||||||
bool server, bool *opt_ver, const char *opt_cert,
|
bool server, bool *opt_ver, const char *opt_cert,
|
||||||
SSL_CTX **ctx);
|
SSL_CTX **ctx, bool *use_dtls);
|
||||||
extern int
|
extern int
|
||||||
_xioopen_openssl_connect(struct single *xfd, bool opt_ver,
|
_xioopen_openssl_connect(struct single *xfd, bool opt_ver,
|
||||||
const char *opt_commonname,
|
const char *opt_commonname,
|
||||||
|
|
191
xio-udp.c
191
xio-udp.c
|
@ -74,16 +74,11 @@ const struct addrdesc addr_udp6_recv = { "udp6-recv", 1, xioopen_udp_re
|
||||||
#endif /* WITH_IP6 */
|
#endif /* WITH_IP6 */
|
||||||
|
|
||||||
|
|
||||||
/* we expect the form: port */
|
int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
int xioflags, union sockaddr_union *us, socklen_t uslen,
|
||||||
int xioflags, xiofile_t *fd,
|
struct opt *opts, int pf, int socktype, int ipproto) {
|
||||||
unsigned groups, int pf, int ipproto,
|
|
||||||
int protname) {
|
|
||||||
const char *portname = argv[1];
|
|
||||||
union sockaddr_union us;
|
|
||||||
union sockaddr_union themunion;
|
union sockaddr_union themunion;
|
||||||
union sockaddr_union *them = &themunion;
|
union sockaddr_union *them = &themunion;
|
||||||
int socktype = SOCK_DGRAM;
|
|
||||||
struct pollfd readfd;
|
struct pollfd readfd;
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
int maxchildren = 0;
|
int maxchildren = 0;
|
||||||
|
@ -91,49 +86,9 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
char *rangename;
|
char *rangename;
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
unsigned char buff1[1];
|
unsigned char buff1[1];
|
||||||
socklen_t uslen;
|
|
||||||
socklen_t themlen;
|
socklen_t themlen;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pf == PF_UNSPEC) {
|
|
||||||
#if WITH_IP4 && WITH_IP6
|
|
||||||
pf = xioopts.default_ip=='6'?PF_INET6:PF_INET;
|
|
||||||
#elif WITH_IP6
|
|
||||||
pf = PF_INET6;
|
|
||||||
#else
|
|
||||||
pf = PF_INET;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
|
||||||
|
|
||||||
if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
|
||||||
retropt_bind(opts, pf, socktype, IPPROTO_UDP,
|
|
||||||
(struct sockaddr *)&us, &uslen, 1,
|
|
||||||
fd->stream.para.socket.ip.res_opts[1],
|
|
||||||
fd->stream.para.socket.ip.res_opts[0]);
|
|
||||||
|
|
||||||
if (false) {
|
|
||||||
;
|
|
||||||
#if WITH_IP4
|
|
||||||
} else if (pf == PF_INET) {
|
|
||||||
us.ip4.sin_port = parseport(portname, ipproto);
|
|
||||||
#endif
|
|
||||||
#if WITH_IP6
|
|
||||||
} else if (pf == PF_INET6) {
|
|
||||||
us.ip6.sin6_port = parseport(portname, ipproto);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
Error1("xioopen_ipdgram_listen(): unknown address family %d", pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
|
@ -152,24 +107,24 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
#if WITH_IP4 /*|| WITH_IP6*/
|
#if WITH_IP4 /*|| WITH_IP6*/
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, pf, &fd->stream.para.socket.range) < 0) {
|
if (xioparserange(rangename, pf, &sfd->para.socket.range) < 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
free(rangename);
|
free(rangename);
|
||||||
fd->stream.para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_LIBWRAP
|
#if WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(&fd->stream, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* WITH_LIBWRAP */
|
#endif /* WITH_LIBWRAP */
|
||||||
|
|
||||||
if (retropt_ushort(opts, OPT_SOURCEPORT, &fd->stream.para.socket.ip.sourceport)
|
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport)
|
||||||
>= 0) {
|
>= 0) {
|
||||||
fd->stream.para.socket.ip.dosourceport = true;
|
sfd->para.socket.ip.dosourceport = true;
|
||||||
}
|
}
|
||||||
retropt_bool(opts, OPT_LOWPORT, &fd->stream.para.socket.ip.lowport);
|
retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport);
|
||||||
|
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
xiosetchilddied(); /* set SIGCHLD handler */
|
xiosetchilddied(); /* set SIGCHLD handler */
|
||||||
|
@ -184,40 +139,46 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
union sockaddr_union _sockname;
|
union sockaddr_union _sockname;
|
||||||
union sockaddr_union *la = &_sockname; /* local address */
|
union sockaddr_union *la = &_sockname; /* local address */
|
||||||
|
|
||||||
if ((fd->stream.fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) {
|
if ((sfd->fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
doreuseaddr |= (retropt_int(opts, OPT_SO_REUSEADDR, &reuseaddr) >= 0);
|
doreuseaddr |= (retropt_int(opts, OPT_SO_REUSEADDR, &reuseaddr) >= 0);
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTSOCKET);
|
applyopts(sfd->fd, opts, PH_PASTSOCKET);
|
||||||
if (doreuseaddr) {
|
if (doreuseaddr) {
|
||||||
if (Setsockopt(fd->stream.fd, opt_so_reuseaddr.major,
|
if (Setsockopt(sfd->fd, opt_so_reuseaddr.major,
|
||||||
opt_so_reuseaddr.minor, &reuseaddr, sizeof(reuseaddr))
|
opt_so_reuseaddr.minor, &reuseaddr, sizeof(reuseaddr))
|
||||||
< 0) {
|
< 0) {
|
||||||
Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s",
|
Warn6("setsockopt(%d, %d, %d, {%d}, "F_Zd"): %s",
|
||||||
fd->stream.fd, opt_so_reuseaddr.major,
|
sfd->fd, opt_so_reuseaddr.major,
|
||||||
opt_so_reuseaddr.minor, reuseaddr, sizeof(reuseaddr),
|
opt_so_reuseaddr.minor, reuseaddr, sizeof(reuseaddr),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
applyopts(fd->stream.fd, opts, PH_PREBIND);
|
applyopts(sfd->fd, opts, PH_PREBIND);
|
||||||
applyopts(fd->stream.fd, opts, PH_BIND);
|
applyopts(sfd->fd, opts, PH_BIND);
|
||||||
if (Bind(fd->stream.fd, &us.soa, uslen) < 0) {
|
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
|
||||||
Error4("bind(%d, {%s}, "F_socklen"): %s", fd->stream.fd,
|
Error4("bind(%d, {%s}, "F_socklen"): %s", sfd->fd,
|
||||||
sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)),
|
sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
|
||||||
uslen, strerror(errno));
|
uslen, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
/* under some circumstances bind() fills sockaddr with interesting info. */
|
/* under some circumstances bind() fills sockaddr with interesting info. */
|
||||||
if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) {
|
if (Getsockname(sfd->fd, &us->soa, &uslen) < 0) {
|
||||||
Error4("getsockname(%d, %p, {%d}): %s",
|
Error4("getsockname(%d, %p, {%d}): %s",
|
||||||
fd->stream.fd, &us.soa, uslen, strerror(errno));
|
sfd->fd, &us->soa, uslen, strerror(errno));
|
||||||
}
|
}
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTBIND);
|
applyopts(sfd->fd, opts, PH_PASTBIND);
|
||||||
|
|
||||||
|
if (ipproto == IPPROTO_UDP) {
|
||||||
Notice1("listening on UDP %s",
|
Notice1("listening on UDP %s",
|
||||||
sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)));
|
||||||
readfd.fd = fd->stream.fd;
|
} else {
|
||||||
|
Notice2("listening on PROTO%d %s", ipproto,
|
||||||
|
sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)));
|
||||||
|
}
|
||||||
|
|
||||||
|
readfd.fd = sfd->fd;
|
||||||
readfd.events = POLLIN|POLLERR;
|
readfd.events = POLLIN|POLLERR;
|
||||||
while (xiopoll(&readfd, 1, NULL) < 0) {
|
while (xiopoll(&readfd, 1, NULL) < 0) {
|
||||||
if (errno != EINTR) break;
|
if (errno != EINTR) break;
|
||||||
|
@ -225,12 +186,12 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
themlen = socket_init(pf, them);
|
themlen = socket_init(pf, them);
|
||||||
do {
|
do {
|
||||||
result = Recvfrom(fd->stream.fd, buff1, 1, MSG_PEEK,
|
result = Recvfrom(sfd->fd, buff1, 1, MSG_PEEK,
|
||||||
&them->soa, &themlen);
|
&them->soa, &themlen);
|
||||||
} while (result < 0 && errno == EINTR);
|
} while (result < 0 && errno == EINTR);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Error5("recvfrom(%d, %p, 1, MSG_PEEK, {%s}, {"F_socklen"}): %s",
|
Error5("recvfrom(%d, %p, 1, MSG_PEEK, {%s}, {"F_socklen"}): %s",
|
||||||
fd->stream.fd, buff1,
|
sfd->fd, buff1,
|
||||||
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)),
|
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
@ -239,11 +200,14 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
Notice1("accepting UDP connection from %s",
|
Notice1("accepting UDP connection from %s",
|
||||||
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)));
|
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)));
|
||||||
|
|
||||||
if (xiocheckpeer(&fd->stream, them, la) < 0) {
|
if (xiocheckpeer(sfd, them, la) < 0) {
|
||||||
|
Notice1("forbidding UDP connection from %s",
|
||||||
|
sockaddr_info(&them->soa, themlen,
|
||||||
|
infobuff, sizeof(infobuff)));
|
||||||
/* drop packet */
|
/* drop packet */
|
||||||
char buff[512];
|
char buff[512];
|
||||||
Recv(fd->stream.fd, buff, sizeof(buff), 0); /* drop packet */
|
Recv(sfd->fd, buff, sizeof(buff), 0); /* drop packet */
|
||||||
Close(fd->stream.fd);
|
Close(sfd->fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Info1("permitting UDP connection from %s",
|
Info1("permitting UDP connection from %s",
|
||||||
|
@ -264,8 +228,8 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
/* server: continue loop with socket()+recvfrom() */
|
/* server: continue loop with socket()+recvfrom() */
|
||||||
/* when we dont close this we get awkward behaviour on Linux 2.4:
|
/* when we dont close this we get awkward behaviour on Linux 2.4:
|
||||||
recvfrom gives 0 bytes with invalid socket address */
|
recvfrom gives 0 bytes with invalid socket address */
|
||||||
if (Close(fd->stream.fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", fd->stream.fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (maxchildren) {
|
while (maxchildren) {
|
||||||
|
@ -279,35 +243,88 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} /* end of the big while loop */
|
||||||
|
|
||||||
applyopts(fd->stream.fd, opts, PH_CONNECT);
|
applyopts(sfd->fd, opts, PH_CONNECT);
|
||||||
if ((result = Connect(fd->stream.fd, &them->soa, themlen)) < 0) {
|
if ((result = Connect(sfd->fd, &them->soa, themlen)) < 0) {
|
||||||
Error4("connect(%d, {%s}, "F_socklen"): %s",
|
Error4("connect(%d, {%s}, "F_socklen"): %s",
|
||||||
fd->stream.fd,
|
sfd->fd,
|
||||||
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)),
|
sockaddr_info(&them->soa, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the env vars describing the local and remote sockets */
|
/* set the env vars describing the local and remote sockets */
|
||||||
if (Getsockname(fd->stream.fd, &us.soa, &uslen) < 0) {
|
if (Getsockname(sfd->fd, &us->soa, &uslen) < 0) {
|
||||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||||
fd->stream.fd, &us.soa, uslen, strerror(errno));
|
sfd->fd, &us->soa, uslen, strerror(errno));
|
||||||
}
|
}
|
||||||
xiosetsockaddrenv("SOCK", &us, uslen, IPPROTO_UDP);
|
xiosetsockaddrenv("SOCK", us, uslen, IPPROTO_UDP);
|
||||||
xiosetsockaddrenv("PEER", them, themlen, IPPROTO_UDP);
|
xiosetsockaddrenv("PEER", them, themlen, IPPROTO_UDP);
|
||||||
|
|
||||||
fd->stream.howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
applyopts_fchown(fd->stream.fd, opts);
|
applyopts_fchown(sfd->fd, opts);
|
||||||
applyopts(fd->stream.fd, opts, PH_LATE);
|
applyopts(sfd->fd, opts, PH_LATE);
|
||||||
|
|
||||||
if ((result = _xio_openlate(&fd->stream, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we expect the form: port */
|
||||||
|
int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
|
int xioflags, xiofile_t *fd,
|
||||||
|
unsigned groups, int pf, int ipproto,
|
||||||
|
int protname) {
|
||||||
|
const char *portname = argv[1];
|
||||||
|
union sockaddr_union us;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
socklen_t uslen;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pf == PF_UNSPEC) {
|
||||||
|
#if WITH_IP4 && WITH_IP6
|
||||||
|
pf = xioopts.default_ip=='6'?PF_INET6:PF_INET;
|
||||||
|
#elif WITH_IP6
|
||||||
|
pf = PF_INET6;
|
||||||
|
#else
|
||||||
|
pf = PF_INET;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
|
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||||
|
|
||||||
|
if (applyopts_single(&fd->stream, opts, PH_INIT) < 0) return -1;
|
||||||
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
|
||||||
|
uslen = socket_init(pf, &us);
|
||||||
|
retropt_bind(opts, pf, socktype, ipproto,
|
||||||
|
(struct sockaddr *)&us, &uslen, 1,
|
||||||
|
fd->stream.para.socket.ip.res_opts[1],
|
||||||
|
fd->stream.para.socket.ip.res_opts[0]);
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
;
|
||||||
|
#if WITH_IP4
|
||||||
|
} else if (pf == PF_INET) {
|
||||||
|
us.ip4.sin_port = parseport(portname, ipproto);
|
||||||
|
#endif
|
||||||
|
#if WITH_IP6
|
||||||
|
} else if (pf == PF_INET6) {
|
||||||
|
us.ip6.sin6_port = parseport(portname, ipproto);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
Error1("xioopen_ipdgram_listen(): unknown address family %d", pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _xioopen_ipdgram_listen(&fd->stream, xioflags, &us, uslen,
|
||||||
|
opts, pf, socktype, ipproto);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
|
@ -24,6 +24,10 @@ extern const struct addrdesc addr_udp6_datagram;
|
||||||
extern const struct addrdesc addr_udp6_recvfrom;
|
extern const struct addrdesc addr_udp6_recvfrom;
|
||||||
extern const struct addrdesc addr_udp6_recv;
|
extern const struct addrdesc addr_udp6_recv;
|
||||||
|
|
||||||
|
extern int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
|
int xioflags, union sockaddr_union *us, socklen_t uslen,
|
||||||
|
struct opt *opts, int pf, int socktype, int ipproto);
|
||||||
|
|
||||||
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int rw, xiofile_t *fd,
|
int rw, xiofile_t *fd,
|
||||||
unsigned groups, int af, int ipproto,
|
unsigned groups, int af, int ipproto,
|
||||||
|
|
25
xioopen.c
25
xioopen.c
|
@ -41,6 +41,17 @@ const struct addrname addressnames[] = {
|
||||||
{ "datagram", &xioaddr_socket_datagram },
|
{ "datagram", &xioaddr_socket_datagram },
|
||||||
{ "dgram", &xioaddr_socket_datagram },
|
{ "dgram", &xioaddr_socket_datagram },
|
||||||
#endif
|
#endif
|
||||||
|
#if WITH_OPENSSL
|
||||||
|
{ "dtls", &xioaddr_openssl_dtls_client },
|
||||||
|
{ "dtls-c", &xioaddr_openssl_dtls_client },
|
||||||
|
{ "dtls-client", &xioaddr_openssl_dtls_client },
|
||||||
|
{ "dtls-connect", &xioaddr_openssl_dtls_client },
|
||||||
|
#if WITH_LISTEN
|
||||||
|
{ "dtls-l", &xioaddr_openssl_dtls_server },
|
||||||
|
{ "dtls-listen", &xioaddr_openssl_dtls_server },
|
||||||
|
{ "dtls-server", &xioaddr_openssl_dtls_server },
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if WITH_PIPE
|
#if WITH_PIPE
|
||||||
{ "echo", &addr_pipe },
|
{ "echo", &addr_pipe },
|
||||||
#endif
|
#endif
|
||||||
|
@ -122,10 +133,14 @@ const struct addrname addressnames[] = {
|
||||||
{ "open", &addr_open },
|
{ "open", &addr_open },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_OPENSSL
|
#if WITH_OPENSSL
|
||||||
{ "openssl", &addr_openssl },
|
{ "openssl", &xioaddr_openssl },
|
||||||
{ "openssl-connect", &addr_openssl },
|
{ "openssl-connect", &xioaddr_openssl },
|
||||||
|
{ "openssl-dtls-client", &xioaddr_openssl_dtls_client },
|
||||||
|
{ "openssl-dtls-connect", &xioaddr_openssl_dtls_client },
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
{ "openssl-listen", &addr_openssl_listen },
|
{ "openssl-dtls-listen", &xioaddr_openssl_dtls_server },
|
||||||
|
{ "openssl-dtls-server", &xioaddr_openssl_dtls_server },
|
||||||
|
{ "openssl-listen", &xioaddr_openssl_listen },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if WITH_PIPE
|
#if WITH_PIPE
|
||||||
|
@ -186,9 +201,9 @@ const struct addrname addressnames[] = {
|
||||||
{ "socks4a", &addr_socks4a_connect },
|
{ "socks4a", &addr_socks4a_connect },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_OPENSSL
|
#if WITH_OPENSSL
|
||||||
{ "ssl", &addr_openssl },
|
{ "ssl", &xioaddr_openssl },
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
{ "ssl-l", &addr_openssl_listen },
|
{ "ssl-l", &xioaddr_openssl_listen },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if WITH_STDIO
|
#if WITH_STDIO
|
||||||
|
|
Loading…
Reference in a new issue