ANN: PyDTLS

rbit py at liquibits.com
Wed Jan 9 02:38:01 EST 2013


On Tue, Jan 8, 2013 at 9:09 PM, Guido van Rossum <guido at python.org> wrote:
> But don't you have to deal with that when doing synchronous I/O as
> well? It's a datagram protocol after all.

No: when dealing with blocking sockets, the OpenSSL library activates its
own retransmission timers, and the application never becomes aware of
whether timeouts occurred. Since OpenSSL can't do this in the the case of
non-blocking sockets, it becomes the application's problem to call back
into OpenSSL at some point in the future (the very same time for which
OpenSSL would have set its own timeout had the socket been blocking).
OpenSSL exports functions DTLSv1_get_timeout and DTLSv1_handle_timeout to
applications to address this case. The timeouts start at one second, and
double for each encountered timeout, until the timeout ceiling of one
minutes is reached. I'm using the term "application" here for any code that
uses the OpenSSL library, but is not part of it.

>> One
>> such situation occurs during DTLS's handshaking phase: if no response
>> is received from the peer after some period of time, we must assume
>> that our most recent datagram has been lost, and so we need to
>> retransmit.
>
> Is this something the transport can handle, or does the protocol (and
> hence the application) need to be involved here?

Given my current understanding of the PEP, I think this can be handled in
the transport. Maybe there's some pitfall here that I can't quite see yet -
even more reason for me to try to implement it.

>> The event loop interface as outlined in the PEP makes this
>> a bit difficult (as did the asyncore module). One possible way to make
>> things easier would be by adding two parameters to add_reader: a
>> callable to retrieve the current timeout, and a callable that is
>> invoked if that timeout expires before the descriptor becomes
>> readable. Each loop iteration would then collect all given timeouts,
>> and pass the minimum of that set to whatever polling facility it
>> invokes. If that timeout expires, the corresponding timeout handler
>> would be invoked prior to the next loop iteration.
>
> Hm, this would add a fair amount of complexity to the event loop. It's
> true that I don't have the complete story for timeouts yet, but I am
> hopeful that things like this can be implemented by using call_later()
> with some callback that does the retransmit (and resets some internal
> state), and cancelling that callback whenever a packet is received
> (i.e. in the protocol's datagram_received() method).

Yes, ok, I can see how that could work, too. I thought that it might make
sense to centralize handling timeouts in the event loop in order to prevent
proliferation in the transports (since there are multiple event loop
implementations, perhaps a mix-in would be good?). I think one will want to
contain handshake (vs. application data) timeout handling at least to the
transport, though, and not let it spill over into various protocols. I'm
not sure yet where the right place is for cancelling a timeout callback.

>> Implementing DTLS as a tulip transport sounds interesting. Is the
>> tulip package available somewhere so that I can try it out?
>
> Absolutely -- it is very much in flux, but you can check out the
> latest source from http://code.google.com/p/tulip/source/checkout
> using Mercurial.

All right, thanks, I'll check it out.

Ray
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20130108/afcad699/attachment.html>


More information about the Python-list mailing list