nplab / dtls-examples Goto Github PK
View Code? Open in Web Editor NEWExamples for DTLS via SCTP and UDP using OpenSSL
License: BSD 3-Clause "New" or "Revised" License
Examples for DTLS via SCTP and UDP using OpenSSL
License: BSD 3-Clause "New" or "Revised" License
I was testing under Ubuntu 19.04, and got such gcc errors:
DTLS-Examples/src$ make
cc -std=c99 -pedantic -Wall -g -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-overlength-strings -I/usr/local/include -o dtls_sctp_chargen dtls_sctp_chargen.c -L/usr/local/lib -lssl -lcrypto -pthread -lm -ldl
dtls_sctp_chargen.c:48:10: fatal error: netinet/sctp.h: No such file or directory
#include <netinet/sctp.h>
^~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:21: dtls_sctp_chargen] Error 1
suggestion:
sudo apt-get install libsctp-dev
$ dpkg-query --listfiles libsctp-dev
/usr/include/netinet
/usr/include/netinet/sctp.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libsctp.a
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/libsctp.pc
...
➜ ~ uname -a
Linux wks1 4.18.0-13-generic #14-Ubuntu SMP Wed Dec 5 09:04:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
➜ ~ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.10
Release: 18.10
Codename: cosmic
➜ src git:(refurbish) ✗ LD_LIBRARY_PATH=~/openssl/lib /home/weinrank/openssl/bin/openssl version
OpenSSL 1.1.1b-dev xx XXX xxxx
➜ src git:(refurbish) ✗ LD_LIBRARY_PATH=~/openssl/lib valgrind ./dtls_sctp_chargen 212.201.121.83
==31897== Memcheck, a memory error detector
==31897== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==31897== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==31897== Command: ./dtls_sctp_chargen 212.201.121.83
==31897==
==31897== Invalid read of size 8
==31897== at 0x498C450: BIO_method_type (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4991528: BIO_dgram_is_sctp (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x48962DF: state_machine.part.5 (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x4880EC3: SSL_do_handshake (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x10C347: start_client (dtls_sctp_chargen.c:778)
==31897== by 0x10D04F: main (dtls_sctp_chargen.c:1021)
==31897== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==31897==
==31897==
==31897== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==31897== Access not within mapped region at address 0x0
==31897== at 0x498C450: BIO_method_type (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4991528: BIO_dgram_is_sctp (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x48962DF: state_machine.part.5 (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x4880EC3: SSL_do_handshake (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x10C347: start_client (dtls_sctp_chargen.c:778)
==31897== by 0x10D04F: main (dtls_sctp_chargen.c:1021)
==31897== If you believe this happened as a result of a stack
==31897== overflow in your program's main thread (unlikely but
==31897== possible), you can try to increase the size of the
==31897== main thread stack using the --main-stacksize= flag.
==31897== The main thread stack size used in this run was 8388608.
==31897== Invalid read of size 8
==31897== at 0x4DF3B89: check_free (dlerror.c:188)
==31897== by 0x4DF3B89: free_key_mem (dlerror.c:218)
==31897== by 0x4DF3B89: __dlerror_main_freeres (dlerror.c:236)
==31897== by 0x4D99A41: __libc_freeres (in /lib/x86_64-linux-gnu/libc-2.28.so)
==31897== by 0x482D19E: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==31897== by 0x4991528: BIO_dgram_is_sctp (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x48962DF: state_machine.part.5 (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x4880EC3: SSL_do_handshake (in /home/weinrank/openssl/lib/libssl.so.1.1)
==31897== by 0x10C347: start_client (dtls_sctp_chargen.c:778)
==31897== by 0x10D04F: main (dtls_sctp_chargen.c:1021)
==31897== Address 0x4e0d738 is 12 bytes after a block of size 12 alloc'd
==31897== at 0x483774F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==31897== by 0x4A63768: CRYPTO_zalloc (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A5F33D: ossl_init_thread_start (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A3910B: ERR_get_state (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A39675: ERR_clear_error (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A5E9A8: ossl_init_engine_dynamic_ossl_ (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4BF70C6: __pthread_once_slow (pthread_once.c:116)
==31897== by 0x4AD1078: CRYPTO_THREAD_run_once (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A5F26B: OPENSSL_init_crypto (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x49C983D: openssl_config_int (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4A5EA3F: ossl_init_config_ossl_ (in /home/weinrank/openssl/lib/libcrypto.so.1.1)
==31897== by 0x4BF70C6: __pthread_once_slow (pthread_once.c:116)
==31897==
==31897==
==31897== HEAP SUMMARY:
==31897== in use at exit: 152,952 bytes in 3,797 blocks
==31897== total heap usage: 4,882 allocs, 1,085 frees, 295,219 bytes allocated
==31897==
==31897== LEAK SUMMARY:
==31897== definitely lost: 0 bytes in 0 blocks
==31897== indirectly lost: 0 bytes in 0 blocks
==31897== possibly lost: 0 bytes in 0 blocks
==31897== still reachable: 152,952 bytes in 3,797 blocks
==31897== suppressed: 0 bytes in 0 blocks
==31897== Rerun with --leak-check=full to see details of leaked memory
==31897==
==31897== For counts of detected and suppressed errors, rerun with: -v
==31897== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
do anybody try the daemon?
I built and run dtls_udp_echo , on client side, socket can be set up and recv echo response successfully.
but on server side, DTLSv1_listen() still return 1 then new alloc thread to handle it.
my openssl version:
openssl-1.1.0j
I've followed all the README steps, but got the next error:
$ LD_LIBRARY_PATH=/opt/openssl/lib ./dtls_sctp_echo
139858668435264:error:20091002:BIO routines:BIO_new_dgram_sctp:system lib:crypto/bio/bss_dgram.c:844:Ensure SCTP AUTH chunks are enabled in kernel
As pointed here: openssl/openssl#8582 (comment), this message shows that SCTP AUTH chuncks are disabled in the kernel.
I suggest to add to README recommendation to check that /proc/sys/net/sctp/auth_enable
contains 1
. Otherwise, to run
sysctl -w net.sctp.auth_enable=1
as root.
The dtls_udp_echo
server is a multi-threaded application, but things get weird when 2 server threads
are running together.
For example, I start 1 echo server, then start 2 client process:
# Echo server
/dtls_udp_echo -L 127.0.0.1 -p 23232 -v
# Then in another terminal, start 2 clients concurrently
./dtls_udp_echo -p 23232 127.0.0.1 & ./dtls_udp_echo -p 23232 127.0.0.1
I have been testing whether it could serve 2 or more clients concurrently. The tcpdump/wireshark packet sniffer shows that the DTLS handshake would be disturbed when 2 threads are running together, and only the first client can complete the DTLS handshake with the echo server.
There is a question in openssl's offical FAQ page:
- Is OpenSSL thread-safe?
Yes but with some limitations; for example, an SSL connection cannot be used concurrently by multiple threads. This is true for most OpenSSL objects.
For version 1.1.0 and later, there is nothing further you need do.
For earlier versions than 1.1.0, it is necessary for your application to set up the thread callback functions. To do this, your application must call CRYPTO_set_locking_callback(3) and one of the CRYPTO_THREADID_set... API's. See the OpenSSL threads manpage for details and "note on multi-threading" in the INSTALL file in the source distribution.
The following code does create different SSL connection for each thread, and each SSL connection has its own BIO buffer. But it doesn't work as expected when 2 clients connect to the same echo server concurrently.
int start_server()
{
fd = socket(server_addr.ss.ss_family, SOCK_DGRAM, 0);
//...
if (server_addr.ss.ss_family == AF_INET) {
bind(fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
} else {
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off));
bind(fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in6));
}
//...
while (1) {
memset(&client_addr, 0, sizeof(struct sockaddr_storage));
/* Create BIO */
bio = BIO_new_dgram(fd, BIO_NOCLOSE);
/* Set and activate timeouts */
timeout.tv_sec = 5;
timeout.tv_usec = 0;
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
ssl = SSL_new(ctx);
SSL_set_bio(ssl, bio, bio);
SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
while (DTLSv1_listen(ssl, (BIO_ADDR *) &client_addr) <= 0){
;
}
info = (struct pass_info*) malloc (sizeof(struct pass_info));
memcpy(&info->server_addr, &server_addr, sizeof(struct sockaddr_storage));
memcpy(&info->client_addr, &client_addr, sizeof(struct sockaddr_storage));
info->ssl = ssl;
if (pthread_create( &tid, NULL, connection_handle, info) != 0) {
perror("pthread_create");
exit(-1);
}
}
}
Here in the main loop of start_server()
, all the bio
s share the same UDP socket fd
to listen, even if each server thread has its own bio
and ssl
object.
In each service thread, connection_handle()
builds a different socket fd and and update the bio to use the new fd.
On Ubuntu 19.04 with Linux 5.0 kernel,
the kernel header file /usr/include/linux/sctp.h
added the following line:
#define SCTP_EVENT 127
This breaks the following code that rely on the SCTP_EVENT
micro which were disabled in the past (Linux 4.18 kernel).
DTLS-Examples/src/dtls_sctp_chargen.c
Lines 584 to 599 in 114cb15
On Ubuntu 19.04 I got such gcc error:
$ make
cc -std=c99 -pedantic -Wall -g -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-overlength-strings -I/usr/local/include -o dtls_sctp_chargen dtls_sctp_chargen.c -L/usr/local/lib -lssl -lcrypto -pthread -lm -ldl
dtls_sctp_chargen.c: In function ‘start_server’:
dtls_sctp_chargen.c:586:23: error: ‘SCTP_FUTURE_ASSOC’ undeclared (first use in this function); did you mean ‘SCTP_RESET_ASSOC’?
event.se_assoc_id = SCTP_FUTURE_ASSOC;
^~~~~~~~~~~~~~~~~
SCTP_RESET_ASSOC
dtls_sctp_chargen.c:586:23: note: each undeclared identifier is reported only once for each function it appears in
...
$ uname -a
Linux vmware 5.0.0-15-generic #16-Ubuntu SMP Mon May 6 17:41:33 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
header file /usr/include/netinet/sctp.h
provided by libsctp-dev relies on /usr/include/linux/sctp.h
.
And there is NO definition of SCTP_FUTURE_ASSOC
in any version of Linux kernel headers (4.18.x-5.0.x).
I guess the SCTP_FUTURE_ASSOC
only came with freebsd kernel...
windows不支持UDP的端口复用,所以在Linux中server支持多client同时连接,握手和通信,但是winodws中server只能支持一个client的访问。我尝试用了一个很复杂的办法解决这个问题,最终成功了。
我是在localhost上开启了多个server,每个server只为一个client提供服务。又做了一个udp的转发模块,监听一个外部端口,将所有的通信按照ip+port进行向内转发,同时内部server回复的所有消息也按照同样的规则向外转发。这样对外模拟出一个支持多client同时接入的server
I suggest using getaddrinfo
instead of manually packing the structs. https://beej.us/guide/bgnet/html/#getaddrinfoman
Also, is there a reason why SSL_CTX_set_verify_depth
is 2?
communication is not possible after running the code. The client is stuck in ssl_connect and the server is stuck in ssl-accept.my environment is windows 7 64bits and vs2015 and openssl-1.1.1w.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.