INTRODUCTION
============
This document is an attempt to describe the basics of the DTLS element.
It hasn't been written by the author(s) and so, besides being incomplete,
*IT MIGHT ALSO BE INCORRECT*. So take it with a pinch of salt.

As always, if in doubt ask the #gstreamer IRC channel.

THE INTERNALS
=============
This plugin provides two main elements (dtlssrtpdec and dtlssrtpenc) and a few
minor elements necessary to implement them. The two elements dtlssrtpdec and
dtlssrtpenc are the only ones you are supposed to include in, respectively, the
RX and TX pipelines of your DTLS-enabled application. This means you're not
supposed to directly include those minor elements in your pipelines.

dtlssrtpenc
-----------
This element is to be included in the TX pipeline and will initiate the DTLS
handshake if configured to be the client. Its main configuration parameters are:

  - connection-id: a string that must match the connection-id in dtlssrtpdec;
  - is-client: a boolean that indicates whether this is going to be the client
							 or the server during the DTLS handshake.

Internally this element comprises the standard srtpenc element, the dtlsenc
element and a funnel to connect both these elements to one single output.
The srtpenc can be used to encrypt SRTP/SRTCP packets while the dtlsenc can be
used to encrypt generic data, e.g. for non-SRTP applications.

NB With the current implementation the TX pipeline containing the dtlssrtpenc
	 must be created *AFTER* the RX pipeline.

dtlssrtpdec
-----------
It is to be included in the RX pipeline. Its main configuration parameters are:

  - connection-id: a string that must match the connection-id in dtlssrtpenc;
	- pem: a string that can be used to provide your own certificate *AND* private
				 key in PEM format. The private key is required to carry out the
				 handshake so do not forget it or the DTLS negotiation will fail;
  - peer_pem: a read only parameter that can be used to retrieve the
							certificate sent from the other party in PEM format once the
							handshake is completed.

Internally this element comprises a dtlssrtpdemux, a standard srtpdec element
and the dtlsdec element. The dtlssrtpdemux element switches SRT(C)P packets to
the srtpdec element and DTLS packets to the dtlsdec element and discards any
other unknown packet. So, similarly for the dtlssrtpenc case, DTLS-SRTP
applications would exercise the srtpdec element and any other non-SRTP
application would exercise the dtlsdec element.

NB With the current implementation the RX pipeline containing the dtlssrtpdec
	 must be created *BEFORE* the TX pipeline.

EXAMPLE PIPELINE
================
The following is an example usage of the DTLS plugin. It is a python script that
creates two endpoints that exchange encrypted audio using DTLS to exchange the
encryption keys.

NB In theory we would show an example gst-launch command. However that would not
	 be enough because you need two pairs of TX/RX pipelines for a proper
	 handshake and you can't use gst-launch two start 4 different pipelines.
	 This why there is a python script in here.

```
#!/usr/bin/env python3

# create two endpoints, each with tx and rx pipelines using the DTLS
# elements and let audio flowing for a while to give time for a packet capture

import time
from gi.repository import Gst, GObject, GLib
GObject.threads_init()
Gst.init(None)


def _start_pipeline(pipeline):
    pipeline.set_state(Gst.State.PLAYING)
    pipeline.get_state(Gst.CLOCK_TIME_NONE)


def _sleep_while_iterating_gloop(secs):
    """ block for secs seconds but iterate the gloop while you do """
    for _ in range(10 * secs):
        gloop = GLib.MainLoop()
        gloop_context = gloop.get_context()
        gloop_context.iteration(may_block=False)
        time.sleep(0.1)

def dtls_tx_pipeline_description(name, is_client, port):
    return ' ! '.join([
        'audiotestsrc is-live=true',
        'audio/x-raw, rate=8000, format=S16LE, channels=1',
        'opusenc frame-size=10',
        'rtpopuspay pt=103',
        '.rtp_sink_0 dtlssrtpenc connection-id={name} is-client={client} .src',
        'udpsink port={port}'
    ]).format(name=name, client=is_client, port=port)


def dtls_rx_pipeline_description(name, port):
    return ' ! '.join([
        'udpsrc port={port}',
        '.sink dtlssrtpdec connection-id={name} .rtp_src',
        'queue',
        'fakesink async=false'
    ]).format(name=name, port=port)


class Endpoint:
    def __init__(self, name, is_client, tx_port, rx_port):
        self.name = name
        tx_pipeline_description = dtls_tx_pipeline_description(
            name, is_client, tx_port
        )
        rx_pipeline_description = dtls_rx_pipeline_description(name, rx_port)
        print(rx_pipeline_description)
        print(tx_pipeline_description)

        self.rx_pipeline = Gst.parse_launch(rx_pipeline_description)
        self.tx_pipeline = Gst.parse_launch(tx_pipeline_description)

    def start(self):
				# Start RX first, otherwise it fails due to the current implementation
        self.start_rx_pipeline()
        self.start_tx_pipeline()

    def start_rx_pipeline(self):
        _start_pipeline(self.rx_pipeline)

    def start_tx_pipeline(self):
        _start_pipeline(self.tx_pipeline)

    def stop(self):
        def stop_pipeline(p):
            p.set_state(Gst.State.NULL)
            p.get_state(Gst.CLOCK_TIME_NONE)
        stop_pipeline(self.tx_pipeline)
        stop_pipeline(self.rx_pipeline)

blue = Endpoint("blue", is_client=True, tx_port=23000, rx_port=23002)
red = Endpoint("red", is_client=False, tx_port=23002, rx_port=23000)

red.start()
blue.start()

_sleep_while_iterating_gloop(3)

red.stop()
blue.stop()
```
