• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

Makefile.amH A D19-Apr-2019758 3529

Makefile.inH A D03-May-202248.2 KiB1,2161,113

READMEH A D19-Apr-20195.6 KiB154120

gstdtlsagent.cH A D03-Sep-20198.1 KiB291215

gstdtlsagent.hH A D19-Apr-20193 KiB8329

gstdtlscertificate.cH A D19-Apr-20199.1 KiB353259

gstdtlscertificate.hH A D19-Apr-20193.1 KiB7328

gstdtlsconnection.cH A D03-Sep-201926.9 KiB1,041798

gstdtlsconnection.hH A D19-Apr-20194.6 KiB12438

gstdtlsdec.cH A D03-Sep-201919.7 KiB727545

gstdtlsdec.hH A D19-Apr-20192.5 KiB8140

gstdtlsenc.cH A D19-Apr-201916.8 KiB574434

gstdtlsenc.hH A D19-Apr-20192.5 KiB7835

gstdtlssrtpbin.cH A D19-Apr-20197.6 KiB243191

gstdtlssrtpbin.hH A D19-Apr-20192.5 KiB6729

gstdtlssrtpdec.cH A D19-Apr-201914.7 KiB463347

gstdtlssrtpdec.hH A D19-Apr-20192.3 KiB6224

gstdtlssrtpdemux.cH A D19-Apr-20194.7 KiB13888

gstdtlssrtpdemux.hH A D19-Apr-20192.4 KiB6528

gstdtlssrtpenc.cH A D19-Apr-201914.9 KiB468342

gstdtlssrtpenc.hH A D19-Apr-20192.5 KiB6526

meson.buildH A D19-Apr-2019777 2825

plugin.cH A D19-Apr-20192.2 KiB5828

README

1INTRODUCTION
2============
3This document is an attempt to describe the basics of the DTLS element.
4It hasn't been written by the author(s) and so, besides being incomplete,
5*IT MIGHT ALSO BE INCORRECT*. So take it with a pinch of salt.
6
7As always, if in doubt ask the #gstreamer IRC channel.
8
9THE INTERNALS
10=============
11This plugin provides two main elements (dtlssrtpdec and dtlssrtpenc) and a few
12minor elements necessary to implement them. The two elements dtlssrtpdec and
13dtlssrtpenc are the only ones you are supposed to include in, respectively, the
14RX and TX pipelines of your DTLS-enabled application. This means you're not
15supposed to directly include those minor elements in your pipelines.
16
17dtlssrtpenc
18-----------
19This element is to be included in the TX pipeline and will initiate the DTLS
20handshake if configured to be the client. Its main configuration parameters are:
21
22  - connection-id: a string that must match the connection-id in dtlssrtpdec;
23  - is-client: a boolean that indicates whether this is going to be the client
24							 or the server during the DTLS handshake.
25
26Internally this element comprises the standard srtpenc element, the dtlsenc
27element and a funnel to connect both these elements to one single output.
28The srtpenc can be used to encrypt SRTP/SRTCP packets while the dtlsenc can be
29used to encrypt generic data, e.g. for non-SRTP applications.
30
31NB With the current implementation the TX pipeline containing the dtlssrtpenc
32	 must be created *AFTER* the RX pipeline.
33
34dtlssrtpdec
35-----------
36It is to be included in the RX pipeline. Its main configuration parameters are:
37
38  - connection-id: a string that must match the connection-id in dtlssrtpenc;
39	- pem: a string that can be used to provide your own certificate *AND* private
40				 key in PEM format. The private key is required to carry out the
41				 handshake so do not forget it or the DTLS negotiation will fail;
42  - peer_pem: a read only parameter that can be used to retrieve the
43							certificate sent from the other party in PEM format once the
44							handshake is completed.
45
46Internally this element comprises a dtlssrtpdemux, a standard srtpdec element
47and the dtlsdec element. The dtlssrtpdemux element switches SRT(C)P packets to
48the srtpdec element and DTLS packets to the dtlsdec element and discards any
49other unknown packet. So, similarly for the dtlssrtpenc case, DTLS-SRTP
50applications would exercise the srtpdec element and any other non-SRTP
51application would exercise the dtlsdec element.
52
53NB With the current implementation the RX pipeline containing the dtlssrtpdec
54	 must be created *BEFORE* the TX pipeline.
55
56EXAMPLE PIPELINE
57================
58The following is an example usage of the DTLS plugin. It is a python script that
59creates two endpoints that exchange encrypted audio using DTLS to exchange the
60encryption keys.
61
62NB In theory we would show an example gst-launch command. However that would not
63	 be enough because you need two pairs of TX/RX pipelines for a proper
64	 handshake and you can't use gst-launch two start 4 different pipelines.
65	 This why there is a python script in here.
66
67```
68#!/usr/bin/env python3
69
70# create two endpoints, each with tx and rx pipelines using the DTLS
71# elements and let audio flowing for a while to give time for a packet capture
72
73import time
74from gi.repository import Gst, GObject, GLib
75GObject.threads_init()
76Gst.init(None)
77
78
79def _start_pipeline(pipeline):
80    pipeline.set_state(Gst.State.PLAYING)
81    pipeline.get_state(Gst.CLOCK_TIME_NONE)
82
83
84def _sleep_while_iterating_gloop(secs):
85    """ block for secs seconds but iterate the gloop while you do """
86    for _ in range(10 * secs):
87        gloop = GLib.MainLoop()
88        gloop_context = gloop.get_context()
89        gloop_context.iteration(may_block=False)
90        time.sleep(0.1)
91
92def dtls_tx_pipeline_description(name, is_client, port):
93    return ' ! '.join([
94        'audiotestsrc is-live=true',
95        'audio/x-raw, rate=8000, format=S16LE, channels=1',
96        'opusenc frame-size=10',
97        'rtpopuspay pt=103',
98        '.rtp_sink_0 dtlssrtpenc connection-id={name} is-client={client} .src',
99        'udpsink port={port}'
100    ]).format(name=name, client=is_client, port=port)
101
102
103def dtls_rx_pipeline_description(name, port):
104    return ' ! '.join([
105        'udpsrc port={port}',
106        '.sink dtlssrtpdec connection-id={name} .rtp_src',
107        'queue',
108        'fakesink async=false'
109    ]).format(name=name, port=port)
110
111
112class Endpoint:
113    def __init__(self, name, is_client, tx_port, rx_port):
114        self.name = name
115        tx_pipeline_description = dtls_tx_pipeline_description(
116            name, is_client, tx_port
117        )
118        rx_pipeline_description = dtls_rx_pipeline_description(name, rx_port)
119        print(rx_pipeline_description)
120        print(tx_pipeline_description)
121
122        self.rx_pipeline = Gst.parse_launch(rx_pipeline_description)
123        self.tx_pipeline = Gst.parse_launch(tx_pipeline_description)
124
125    def start(self):
126				# Start RX first, otherwise it fails due to the current implementation
127        self.start_rx_pipeline()
128        self.start_tx_pipeline()
129
130    def start_rx_pipeline(self):
131        _start_pipeline(self.rx_pipeline)
132
133    def start_tx_pipeline(self):
134        _start_pipeline(self.tx_pipeline)
135
136    def stop(self):
137        def stop_pipeline(p):
138            p.set_state(Gst.State.NULL)
139            p.get_state(Gst.CLOCK_TIME_NONE)
140        stop_pipeline(self.tx_pipeline)
141        stop_pipeline(self.rx_pipeline)
142
143blue = Endpoint("blue", is_client=True, tx_port=23000, rx_port=23002)
144red = Endpoint("red", is_client=False, tx_port=23002, rx_port=23000)
145
146red.start()
147blue.start()
148
149_sleep_while_iterating_gloop(3)
150
151red.stop()
152blue.stop()
153```
154