DTLS in gnutls

Jonathan Bastien-Filiatrault joe at x2a.org
Mon Mar 14 22:44:06 CET 2011


On 2011-03-11 14:59, Nikos Mavrogiannopoulos wrote:
> Hello,
>  It seems that gnutls in master repository includes a fully
> functional DTLS 1.0 (rfc4347) implementation. Kudos to Jonathan
> for creating the initial functional implementation the current
> implementation was built on.

Great ! Thanks for putting it together and getting that last 10-20% done !

> Due to DTLS' requirements for handshake, several parts of
> gnutls' handshake subsystem were rewritten to allow maximum
> re-use between the two protocols (TLS and DTLS). DTLS'
> handshake is asynchronous meaning that it might operate
> even after gnutls_handshake() is terminated (e.g. retransmit
> handshake packets lost by the peer) and this requires
> substantial changes to how gnutls' functions can be
> called in DTLS. Now I emulate the synchronous behavior
> of gnutls_handshake() by waiting for few seconds for
> possible retransmissions by peer, and this has the
> disadvantage of gnutls_handshake() taking a fixed amount
> of seconds irrespective of calculations, but requires
> no semantic changes in the rest of the functions
> (such as gnutls_record_recv()).

This is a good starting point. However, as you must be aware, this adds
latency for the blocking case and is a Really Bad Idea in the async case.

The absolute worst case is a blocking, send-only application (think
CHARGEN).

The asynchronous case can be solved simply: require applications to
monitor the receive side even if they don't read after
gnutls_handshake() and call gnutls_record_recv() when this happens. This
assumes that you keep the last flight buffered neatly somewhere, ready
to send, for a while after gnutls_handshake().

Example sequence of events:

- Bunch of writes
- Event dispatch
- Bunch of writes
- Event dispatch
- Retransmit receive
- Socket readable event
- Event dispatch
- gnutls_record_read(). Here we read the socket, process and retransmit
if required. If we have no application data, we can (ab)use GNUTLS_E_AGAIN.
- Bunch of writes
- Event dispatch
- ...

Since this only adds a requirement and does not change existing ones
much, I think this is desirable.

For the blocking case, someone needs to monitor the receive side of the
socket. gnutls_record_send could set the socket to non-blocking mode,
call gnutls_record_recv, set it back to blocking mode and do the write.
This induces dependencies on some syscalls/application function pointers.

Giving a look at YaSSL and OpenSSL might give us a clue. The
responsibilities between application and library are still fuzzy for me
in that case. Handling os-specific timers and timeouts was also a big
part of my indecision in the handshake layer.

> Another solution is to require a DTLS server/client to
> call gnutls_record_recv() on every received record, even
> if he wasn't expecting one for his application protocol
> and reserve a special error code to indicate no data for
> application...

Is this the case I elaborated above ?
> 
> 
> I don't like the latter change of semantics, but I cannot
> see any obvious way of avoiding it... If you have suggestions
> or ideas please let me know.
> 
> best regards,
> Nikos
> 

All the best,
Jonathan

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 665 bytes
Desc: OpenPGP digital signature
URL: </pipermail/attachments/20110314/ccb34152/attachment.pgp>


More information about the Gnutls-devel mailing list