ANN: PyDTLS
I would like to announce Datagram Transport Layer Security for Python. From
the top of the project README:
PyDTLS brings Datagram Transport Layer Security (DTLS - RFC 6347:
http://tools.ietf.org/html/rfc6347) to the Python environment. In a
nutshell, DTLS brings security (encryption, server authentication,
user authentication, and message authentication) to UDP datagram
payloads in a manner equivalent to what SSL/TLS does for TCP stream
content.
DTLS is now very easy to use in Python. If you're familiar with the
ssl module in Python's standard library, you already know how. All it
takes is passing a datagram/UDP socket to the *wrap_socket* function
instead of a stream/TCP socket. Here's how one sets up the client side
of a connection:
import ssl
from socket import socket, AF_INET, SOCK_DGRAM
from dtls import do_patch
do_patch()
sock = ssl.wrap_socket(socket(AF_INET, SOCK_DGRAM))
sock.connect(('foo.bar.com', 1234))
sock.send('Hi there')
The project is hosted at https://github.com/rbit/pydtls. PyPI has packages:
http://pypi.python.org/pypi/Dtls/0.1.0.
I hope it proves useful.
Ray
--
http://mail.python.org/mailman/listinfo/python-list
Re: ANN: PyDTLS
Thank you. I will gladly port to Python 3 if there is interest from
the community.
Regarding PEP 3156: asynchronous use of unreliable network protocols
makes for an interesting use case. In particular, it forces
applications to deal with packet loss under some circumstances. 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. 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.
The PEP also considers only stream transports when referring to
"transport." Datagram transports do not, for example, have the
property that calling t.write(b'abc'); t.write(b'def') is equivalent
to calling t.write(b'abcdef'). I'm not sure what sort of impact this
omission of datagram transports has for an implementation. Though I
would certainly like to see datagram transports be treated as
first-class citizens, despite not being nearly used as often as stream
transports. I would hope that an implementer of, say, RTP over UDP,
can tie into the same event loop as someone implementing a
single-process, single-threaded Web server.
Implementing DTLS as a tulip transport sounds interesting. Is the
tulip package available somewhere so that I can try it out?
Ray
On Tue, Jan 8, 2013 at 6:53 AM, Guido van Rossum wrote:
> This sounds exciting. Are you considering a Python 3 port? It might make a
> nice demo of PEP 3156.
>
>
> On Monday, January 7, 2013, rbit wrote:
>>
>> I would like to announce Datagram Transport Layer Security for
>> Python. From the top of the project README:
>>
>> PyDTLS brings Datagram Transport Layer Security (DTLS - RFC 6347:
>> http://tools.ietf.org/html/rfc6347) to the Python environment. In a
>> nutshell, DTLS brings security (encryption, server authentication,
>> user authentication, and message authentication) to UDP datagram
>> payloads in a manner equivalent to what SSL/TLS does for TCP stream
>> content.
>>
>> DTLS is now very easy to use in Python. If you're familiar with the
>> ssl module in Python's standard library, you already know how. All it
>> takes is passing a datagram/UDP socket to the *wrap_socket* function
>> instead of a stream/TCP socket. Here's how one sets up the client side
>> of a connection:
>>
>> import ssl
>> from socket import socket, AF_INET, SOCK_DGRAM
>> from dtls import do_patch
>> do_patch()
>> sock = ssl.wrap_socket(socket(AF_INET, SOCK_DGRAM))
>> sock.connect(('foo.bar.com', 1234))
>> sock.send('Hi there')
>>
>> The project is hosted at https://github.com/rbit/pydtls, and licensed
>> under
>> the Apache license 2.0. PyPI has packages. I can be reached
>> at code AT liquibits DOT com for questions, feedback, etc.
>>
>> http://pypi.python.org/pypi/Dtls/0.1.0";>Dtls 0.1.0 -
>> Datagram Transport Layer Security for Python. (07-Jan-13)
>> --
>> http://mail.python.org/mailman/listinfo/python-announce-list
>>
>> Support the Python Software Foundation:
>> http://www.python.org/psf/donations/
>
>
>
> --
> --Guido van Rossum (python.org/~guido)
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
--
http://mail.python.org/mailman/listinfo/python-list
Re: ANN: PyDTLS
On Tue, Jan 8, 2013 at 9:09 PM, Guido van Rossum 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: PyDTLS
Neal, A network protocol that is unreliable (i.e., lacks retransmission of dropped packets) and lacks congestion control will certainly never be a common, general purpose protocol, due to the amount of work it imposes on its user. Implementing an AIMD congestion control algorithm is burdensome to an application, and only some use cases (like DNS) won't need congestion control. Use of the Datagram Congestion Control Protocol is a potential way out for applications, but DCCP (RFC 4340) isn't available on some common platforms, like Windows. That being said, if you find yourself in the kind of unique situation that requires a network protocol with characteristics different from TCP (namely prioritizing availability of data over its reliability), and you need network security as well, then RFC 6347 is really the only reasonable game in town over rolling your own solution. The following are some of the main use cases that force applications into datagram protocols: * Minimizing protocol overhead. TCP has relatively high overhead, for example, its 3-way handshake for connection establishment. One can see why DNS uses UDP. * Real-time data streaming. With this use case, it makes no sense to hold arrived data from the application, because prior packets are being recovered through retransmission. Such packets should just be forgotten about, especially if they fall within the margin of the error concealment strategy of the application. Any sort of audio and/or video transmission falls in this category. RTP is usually done over UDP (and is an illustrative use case for RFC 6347). * Anything that operates below the transport layer (layer 4 of the OSI model). Say you're writing a VPN at a virtual Ethernet level, transmitting Ethernet frames among machines. In that case, protocols that either implement reliability (say, HTTP over TCP) or consciously try to avoid it (say, RTP over UDP) sit above you, and you would neither want to duplicate their reliability functions, nor introduce this unwanted behavior, respectively. But you may want security for your VPN. I hope this helps. Ray On Wed, Jan 9, 2013 at 7:08 AM, Neal Becker wrote: > A bit OT, but the widespread use of rfc 6347 could have a big impact on my > work. > I wonder if it's likely to see widespread use? What are likely/possible > use > cases? > > Thank. > > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
