[asterisk-commits] russell: branch russell/dtls r206085 - /team/russell/dtls/main/dtls.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Jul 12 16:28:36 CDT 2009
Author: russell
Date: Sun Jul 12 16:28:33 2009
New Revision: 206085
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=206085
Log:
Put down some notes while this is still fresh in my mind.
Modified:
team/russell/dtls/main/dtls.c
Modified: team/russell/dtls/main/dtls.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/russell/dtls/main/dtls.c?view=diff&rev=206085&r1=206084&r2=206085
==============================================================================
--- team/russell/dtls/main/dtls.c (original)
+++ team/russell/dtls/main/dtls.c Sun Jul 12 16:28:33 2009
@@ -30,9 +30,86 @@
/*!
* \page DTLSsupport DTLS Support
*
+ * \section DTLSoverview Overview
+ *
+ * This section describes how DTLS support works in Asterisk. It is different
+ * and in ways more complex than TCP/TLS support because of the nature of UDP,
+ * as well as some shortcomings in the API provided by OpenSSL for DTLS.
+ *
+ * \subsection DTLSsockethandling Socket Handling
+ *
+ * One of the biggest differences between TCP/TLS support and DTLS support is that
+ * with DTLS, our code maintains complete control over the UDP sockets. With TCP,
+ * there is a socket per connection. So, there is a 1 to 1 mapping between
+ * \code SSL * \endcode connections and sockets. With UDP, this is often not the
+ * case. We must be able to handle multiple connections on the same socket.
+ *
+ * The APIs provided by OpenSSL for DTLS are extremely similar to those provided
+ * for TCP/TLS. So, as a result, it falls short at being able to handle DTLS with
+ * multiple connections on the same socket. It seems very likely that this will
+ * be improved in OpenSSL at some point, but for now, we work around it.
+ *
+ * After searching around, I came across an excellent idea for how to work around
+ * this problem. It involves taking control of the socket away from OpenSSL and
+ * doing connection mapping ourselves. This code uses OpenSSL for encryption and
+ * decryption, but instead of allowing OpenSSL to do I/O with a socket, it does it
+ * in buffers in memory (a mem BIO in OpenSSL terminology).
+ *
+ * For a given socket, we maintain a container of active DTLS connections. A
+ * connection is associated with a remote IP and port number. This code sits
+ * between the application and the socket, and feeds the data through the
+ * appropriate \code SSL * \endcode instance depending on where the packet is
+ * going, or where it came from.
+ *
+ * See the link to the net-snmp wiki for the original source of the memory BIO
+ * usage idea.
+ *
+ * \subsection DTLSoverheadhandling Overhead Handling
+ *
+ * After solving the first problem of how to handle multiple connections on the same
+ * socket, the next problem is designing the interface provided to the application
+ * code, and the I/O strategy to handle DTLS overhead.
+ *
+ * Since OpenSSL is not given access to the socket, this code must be aware of the
+ * overhead associated with DTLS connections. There is not a 1 to 1 mapping between
+ * application layer messages and messages being sent and received on the network.
+ * Because of this, the I/O strategy for supporting DTLS can not be as simple as
+ * wrapping sendto() and recvfrom().
+ *
+ * Even though this overhead is present, a design goal for this code was to not make
+ * the implementation any more difficult at the application level than what is needed
+ * for normal UDP support. The interface exposed to the application has two parts.
+ * \code ast_dtls_send() \endcode is called to send a packet and uses similar arguments
+ * as \code sendto() \endcode . When an application layer message arrives from the
+ * network, it is passed in decrypted form via a callback.
+ *
+ * The magic required to handle DTLS overhead is done by a background thread that is
+ * created when a DTLS service is started. It maintains state for each connection to
+ * know when it is possible to send application messages, or when it must wait for
+ * a DTLS layer operation to complete before proceeding with application messages.
+ *
+ *
+ * \section DTLScaveats Caveats
+ *
+ * There are some details about how DTLS works that introduce some minor caveats to
+ * its usage as compared to a UDP service without DTLS. As mentioned before,
+ * multiple DTLS connections on the same UDP socket are possible. However, the only
+ * way to map packets to DTLS connections is using the IP address and port number.
+ * Because of this, it is not possible to make a connection from a socket to the same
+ * socket. For example, even though you can do Dial(IAX2/1234 at localhost) with normal
+ * UDP, you would not be able to complete a call in this manner using DTLS. To make
+ * this work, a client side and server side \code SSL * \endcode instance are needed.
+ * However, there would be no way to tell which side of the connection a packet belonged
+ * to since they would all carry the same source and destination IP address and port.
+ *
+ * In practice, this is not likely to matter. However, it is useful to understand and
+ * be aware of.
+ *
+ *
* \section DTLStodo TODO
*
* \todo Figure out how to handle timing out connections.
+ *
*
* \section DTLSlinks Useful Links
*
More information about the asterisk-commits
mailing list