Skip to content
This repository was archived by the owner on Oct 11, 2023. It is now read-only.

Conversation

@nmeum
Copy link
Contributor

@nmeum nmeum commented Jul 14, 2018

These commits add support for DTLS to david. Meaning we can now use CoAP over DTLS.

DTLS itself was implemented using the tinydtls rubygem which was also written by myself. The gem is currently far from finished but works good enough to integrate it into david. The gem itself is simply a wrapper for the tinydtls C library but currently requires a few patches to that library. I am working with the tinydtls maintainer to change that.

Regarding the integration into david, I followed the multi protocol server structure used by the celluloid HTTP server (reel).

Design decisions are further documented in the commit messages but basically this introduces two new David::Server classes: One for CoAP and one for CoAPs. Other celluloid actors (e.g. the garbage collector) had to be adjusted to perform their operations on both of these new server objects.

Currently dual stack is supported meaning CoAP and CoAPs can be used at the same time. The CoAPs server is entirely optional though and disabled by default.

A few thing still need be done regarding the integration into david. I will point those out using inline comments. Besides I need to test this further, so for I have only done tests using the provided config.ru file.

CC: @obgm

:Observe => true,
:Port => ::CoAP::PORT
:Port => ::CoAP::PORT,
:PortDTLS => 5684 # TODO
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CoAP gem should support a ::CoAP::PORT_SECURE (or something like that) constant, which it doesn't currently, and that constant should be used instead here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


def server
Celluloid::Actor[:server]
def server_udp
Copy link
Contributor Author

@nmeum nmeum Jul 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server_udp and server_dtls functions are only used by the Registry#servers function. They could marked as private or directly integrated into the #servers function. Any preferences on this?

class CoAPs < Server
def create_socket(af)
socket = TinyDTLS::UDPSocket.new(af)
socket.add_client("foobar", "foobar")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somekind of API is needed to add identity, key pairs for DTLS to david.

def initialize(socket)
@log = Celluloid.logger
@socket = socket || server.socket
@socket = socket
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far I didn't manage to find a function which calls this constructor with nil as an argument. @nning are you aware of any functions which does this?

begin
Celluloid::Actor[:server].run
if options[:DTLS] == 'true'
Celluloid::Actor[:server_dtls].async.run
Copy link
Contributor Author

@nmeum nmeum Jul 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The David::Server#run runs an infinite loop and since we want to start two servers here the dtls server is started as async.run in the background not sure if that's really a good idea though.


def log
@log ||= server.log
@log ||= Celluloid.logger
Copy link
Contributor Author

@nmeum nmeum Jul 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have two servers now I simply used the Celluoid logger here. Not sure if thats's a good idea though.

@coveralls
Copy link

coveralls commented Jul 14, 2018

Coverage Status

Coverage decreased (-0.5%) to 92.446% when pulling 62dfe6d on ruby-dtls:dtls-support into b596345 on nning:master.

@nmeum
Copy link
Contributor Author

nmeum commented Jul 14, 2018

I didn't touch the test suite yet thus it obviously fails because it tries to initialize a David::Server instead of a David::Server::CoAP. So this needs to be fixed as well.

@nmeum
Copy link
Contributor Author

nmeum commented Jul 16, 2018

The commits I pushed a few minutes ago made the necessary changes to the test suite and also include a commit which ensures that the entire gem still works without tinydtls.


gemspec

group :dtls do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file lib/david.rb contains the following lines:

require 'bundler/setup'
Bundler.require(:default, :cbor)

Should I add Bundler.require(:default, :dtls) to that file as well?

nmeum added 4 commits July 23, 2018 17:16
Currently it is not possible to enable both CoAP und CoAPs at the same
time. Doing so would require starting multiple instance of all other
celluloid actors (observe, garbage collector, …). Alternatively we could
extend this actors in a way that they perform all operations on both
servers.

The support is implemented by implementing two different server classes
which extend the David::Server class:

1. David::Server::CoAP for doing CoAP over UDP
2. David::Server::CoAPs for doing CoAP over DTLS

This required some namespacing changes since the CoAP gem can now no
longer be addressed as CoAP::<...>.

This seems to be the preferred way of implementing multi protocol
servers with celluloid. Since this approach was also used for the reel
web server: https://github.com/celluloid/reel/wiki/Multi-Protocol-Server
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants