Statistics
| Branch: | Revision:

janus-gateway / dtls.c @ c63ddb33

History | View | Annotate | Download (33.4 KB)

1
/*! \file    dtls.c
2
 * \author   Lorenzo Miniero <lorenzo@meetecho.com>
3
 * \copyright GNU General Public License v3
4
 * \brief    DTLS/SRTP processing
5
 * \details  Implementation (based on OpenSSL and libsrtp) of the DTLS/SRTP
6
 * transport. The code takes care of the DTLS handshake between peers and
7
 * the gateway, and sets the proper SRTP and SRTCP context up accordingly.
8
 * A DTLS alert from a peer is notified to the plugin handling him/her
9
 * by means of the hangup_media callback.
10
 *
11
 * \ingroup protocols
12
 * \ref protocols
13
 */
14

    
15
#include "janus.h"
16
#include "debug.h"
17
#include "dtls.h"
18
#include "rtp.h"
19
#include "rtcp.h"
20
#include "events.h"
21

    
22
#include <openssl/err.h>
23
#include <openssl/bn.h>
24
#include <openssl/evp.h>
25
#include <openssl/rsa.h>
26
#include <openssl/asn1.h>
27

    
28

    
29
const gchar *janus_get_dtls_srtp_state(janus_dtls_state state) {
30
        switch(state) {
31
                case JANUS_DTLS_STATE_CREATED:
32
                        return "created";
33
                case JANUS_DTLS_STATE_TRYING:
34
                        return "trying";
35
                case JANUS_DTLS_STATE_CONNECTED:
36
                        return "connected";
37
                case JANUS_DTLS_STATE_FAILED:
38
                        return "failed";
39
                default:
40
                        return NULL;
41
        }
42
        return NULL;
43
}
44

    
45
const gchar *janus_get_dtls_srtp_role(janus_dtls_role role) {
46
        switch(role) {
47
                case JANUS_DTLS_ROLE_ACTPASS:
48
                        return "actpass";
49
                case JANUS_DTLS_ROLE_SERVER:
50
                        return "passive";
51
                case JANUS_DTLS_ROLE_CLIENT:
52
                        return "active";
53
                default:
54
                        return NULL;
55
        }
56
        return NULL;
57
}
58

    
59

    
60
/* Helper to notify DTLS state changes to the event handlers */
61
static void janus_dtls_notify_state_change(janus_dtls_srtp *dtls) {
62
        if(!janus_events_is_enabled())
63
                return;
64
        if(dtls == NULL)
65
                return;
66
        janus_ice_component *component = (janus_ice_component *)dtls->component;
67
        if(component == NULL)
68
                return;
69
        janus_ice_stream *stream = component->stream;
70
        if(stream == NULL)
71
                return;
72
        janus_ice_handle *handle = stream->handle;
73
        if(handle == NULL)
74
                return;
75
        janus_session *session = (janus_session *)handle->session;
76
        if(session == NULL)
77
                return;
78
        json_t *info = json_object();
79
        json_object_set_new(info, "dtls", json_string(janus_get_dtls_srtp_state(dtls->dtls_state)));
80
        json_object_set_new(info, "stream_id", json_integer(stream->stream_id));
81
        json_object_set_new(info, "component_id", json_integer(component->component_id));
82
        json_object_set_new(info, "retransmissions", json_integer(dtls->retransmissions));
83
        janus_events_notify_handlers(JANUS_EVENT_TYPE_WEBRTC, session->session_id, handle->handle_id, info);
84
}
85

    
86

    
87
/* DTLS stuff */
88
#define DTLS_CIPHERS        "ALL:NULL:eNULL:aNULL"
89
/* Duration for the self-generated certs: 1 year */
90
#define DTLS_AUTOCERT_DURATION        60*60*24*365
91

    
92

    
93
static SSL_CTX *ssl_ctx = NULL;
94
static X509* ssl_cert = NULL;
95
static EVP_PKEY* ssl_key = NULL;
96

    
97
static gchar local_fingerprint[160];
98
gchar *janus_dtls_get_local_fingerprint(void) {
99
        return (gchar *)local_fingerprint;
100
}
101

    
102

    
103
#ifdef HAVE_SCTP
104
/* Helper thread to create a SCTP association that will use this DTLS stack */
105
void *janus_dtls_sctp_setup_thread(void *data);
106
#endif
107

    
108

    
109
#if OPENSSL_VERSION_NUMBER < 0x10100000L
110
/*
111
 * DTLS locking stuff to make OpenSSL thread safe (not needed for 1.1.0)
112
 *
113
 * Note: this is an attempt to fix the infamous issue #316:
114
 *                 https://github.com/meetecho/janus-gateway/issues/316
115
 * that is the "tlsv1 alert decrypt error" randomly happening when
116
 * doing handshakes that force Janus to be restarted (issue affecting
117
 * OpenSSL but NOT BoringSSL, apparently). The cause might be related
118
 * to race conditions, and in fact OpenSSL docs state that:
119
 *
120
 *                 "OpenSSL can safely be used in multi-threaded applications
121
 *                 provided that at least two callback functions are set,
122
 *                 locking_function and threadid_func."
123
 *
124
 * See here for the whole docs:
125
 *                 https://www.openssl.org/docs/manmaster/crypto/threads.html
126
 *
127
 * The fix proposed here is heavily derived from a discussion related to
128
 * RTPEngine:
129
 *                 http://lists.sip-router.org/pipermail/sr-dev/2015-January/026860.html
130
 * where it was mentioned the issue was fixed in this commit:
131
 *                 https://github.com/sipwise/rtpengine/commit/935487b66363c9932684d8085f47450d65a8c37e
132
 * which does indeed implement the callbacks the OpenSSL docs suggest.
133
 *
134
 */
135
static janus_mutex *janus_dtls_locks;
136

    
137
static void janus_dtls_cb_openssl_threadid(CRYPTO_THREADID *tid) {
138
        /* FIXME Assuming pthread, which is fine as GLib wraps pthread and
139
         * so that's what we use anyway? */
140
        pthread_t me = pthread_self();
141

    
142
        if(sizeof(me) == sizeof(void *)) {
143
                CRYPTO_THREADID_set_pointer(tid, (void *) me);
144
        } else {
145
                CRYPTO_THREADID_set_numeric(tid, (unsigned long) me);
146
        }
147
}
148

    
149
static void janus_dtls_cb_openssl_lock(int mode, int type, const char *file, int line) {
150
        if((mode & CRYPTO_LOCK)) {
151
                janus_mutex_lock(&janus_dtls_locks[type]);
152
        } else {
153
                janus_mutex_unlock(&janus_dtls_locks[type]);
154
        }
155
}
156
#endif
157

    
158

    
159
static int janus_dtls_generate_keys(X509** certificate, EVP_PKEY** private_key) {
160
        static const int num_bits = 2048;
161
        BIGNUM *bne = NULL;
162
        RSA *rsa_key = NULL;
163
        X509_NAME *cert_name = NULL;
164

    
165
        JANUS_LOG(LOG_VERB, "Generating DTLS key / cert\n");
166

    
167
        /* Create a big number object. */
168
        bne = BN_new();
169
        if(!bne) {
170
                JANUS_LOG(LOG_FATAL, "BN_new() failed\n");
171
                goto error;
172
        }
173

    
174
        if(!BN_set_word(bne, RSA_F4)) {  /* RSA_F4 == 65537 */
175
                JANUS_LOG(LOG_FATAL, "BN_set_word() failed\n");
176
                goto error;
177
        }
178

    
179
        /* Generate a RSA key. */
180
        rsa_key = RSA_new();
181
        if(!rsa_key) {
182
                JANUS_LOG(LOG_FATAL, "RSA_new() failed\n");
183
                goto error;
184
        }
185

    
186
        /* This takes some time. */
187
        if(!RSA_generate_key_ex(rsa_key, num_bits, bne, NULL)) {
188
                JANUS_LOG(LOG_FATAL, "RSA_generate_key_ex() failed\n");
189
                goto error;
190
        }
191

    
192
        /* Create a private key object (needed to hold the RSA key). */
193
        *private_key = EVP_PKEY_new();
194
        if(!*private_key) {
195
                JANUS_LOG(LOG_FATAL, "EVP_PKEY_new() failed\n");
196
                goto error;
197
        }
198

    
199
        if(!EVP_PKEY_assign_RSA(*private_key, rsa_key)) {
200
                JANUS_LOG(LOG_FATAL, "EVP_PKEY_assign_RSA() failed\n");
201
                goto error;
202
        }
203
        /* The RSA key now belongs to the private key, so don't clean it up separately. */
204
        rsa_key = NULL;
205

    
206
        /* Create the X509 certificate. */
207
        *certificate = X509_new();
208
        if(!*certificate) {
209
                JANUS_LOG(LOG_FATAL, "X509_new() failed\n");
210
                goto error;
211
        }
212

    
213
        /* Set version 3 (note that 0 means version 1). */
214
        X509_set_version(*certificate, 2);
215

    
216
        /* Set serial number. */
217
        ASN1_INTEGER_set(X509_get_serialNumber(*certificate), (long)g_random_int());
218

    
219
        /* Set valid period. */
220
        X509_gmtime_adj(X509_get_notBefore(*certificate), -1 * DTLS_AUTOCERT_DURATION);  /* -1 year */
221
        X509_gmtime_adj(X509_get_notAfter(*certificate), DTLS_AUTOCERT_DURATION);  /* 1 year */
222

    
223
        /* Set the public key for the certificate using the key. */
224
        if(!X509_set_pubkey(*certificate, *private_key)) {
225
                JANUS_LOG(LOG_FATAL, "X509_set_pubkey() failed\n");
226
                goto error;
227
        }
228

    
229
        /* Set certificate fields. */
230
        cert_name = X509_get_subject_name(*certificate);
231
        if(!cert_name) {
232
                JANUS_LOG(LOG_FATAL, "X509_get_subject_name() failed\n");
233
                goto error;
234
        }
235
        X509_NAME_add_entry_by_txt(cert_name, "O", MBSTRING_ASC, (const unsigned char*)"Janus", -1, -1, 0);
236
        X509_NAME_add_entry_by_txt(cert_name, "CN", MBSTRING_ASC, (const unsigned char*)"Janus", -1, -1, 0);
237

    
238
        /* It is self-signed so set the issuer name to be the same as the subject. */
239
        if(!X509_set_issuer_name(*certificate, cert_name)) {
240
                JANUS_LOG(LOG_FATAL, "X509_set_issuer_name() failed\n");
241
                goto error;
242
        }
243

    
244
        /* Sign the certificate with the private key. */
245
        if(!X509_sign(*certificate, *private_key, EVP_sha1())) {
246
                JANUS_LOG(LOG_FATAL, "X509_sign() failed\n");
247
                goto error;
248
        }
249

    
250
        /* Free stuff and resurn. */
251
        BN_free(bne);
252
        return 0;
253

    
254
error:
255
        if(bne)
256
                BN_free(bne);
257
        if(rsa_key && !*private_key)
258
                RSA_free(rsa_key);
259
        if(*private_key)
260
                EVP_PKEY_free(*private_key);  /* This also frees the RSA key. */
261
        if(*certificate)
262
                X509_free(*certificate);
263
        return -1;
264
}
265

    
266

    
267
static int janus_dtls_load_keys(const char* server_pem, const char* server_key, X509** certificate, EVP_PKEY** private_key) {
268
        FILE* f = NULL;
269

    
270
        f = fopen(server_pem, "r");
271
        if(!f) {
272
                JANUS_LOG(LOG_FATAL, "Error opening certificate file\n");
273
                goto error;
274
        }
275
        *certificate = PEM_read_X509(f, NULL, NULL, NULL);
276
        if(!*certificate) {
277
                JANUS_LOG(LOG_FATAL, "PEM_read_X509 failed\n");
278
                goto error;
279
        }
280
        fclose(f);
281

    
282
        f = fopen(server_key, "r");
283
        if(!f) {
284
                JANUS_LOG(LOG_FATAL, "Error opening key file\n");
285
                goto error;
286
        }
287
        *private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
288
        if(!*private_key) {
289
                JANUS_LOG(LOG_FATAL, "PEM_read_PrivateKey failed\n");
290
                goto error;
291
        }
292
        fclose(f);
293

    
294
        return 0;
295

    
296
error:
297
        if(*certificate) {
298
                X509_free(*certificate);
299
                *certificate = NULL;
300
        }
301
        if(*private_key) {
302
                EVP_PKEY_free(*private_key);
303
                *private_key = NULL;
304
        }
305
        return -1;
306
}
307

    
308

    
309
/* DTLS-SRTP initialization */
310
gint janus_dtls_srtp_init(const char* server_pem, const char* server_key) {
311
        const char *crypto_lib = NULL;
312
#if OPENSSL_VERSION_NUMBER < 0x10100000L
313
        crypto_lib = "OpenSSL pre-1.1.0";
314
        /* First of all make OpenSSL thread safe (see note above on issue #316) */
315
        janus_dtls_locks = g_malloc0(sizeof(*janus_dtls_locks) * CRYPTO_num_locks());
316
        int l=0;
317
        for(l = 0; l < CRYPTO_num_locks(); l++) {
318
                janus_mutex_init(&janus_dtls_locks[l]);
319
        }
320
        CRYPTO_THREADID_set_callback(janus_dtls_cb_openssl_threadid);
321
        CRYPTO_set_locking_callback(janus_dtls_cb_openssl_lock);
322
#else
323
        crypto_lib = "OpenSSL >= 1.1.0";
324
#endif
325
#ifdef HAVE_BORINGSSL
326
        crypto_lib = "BoringSSL";
327
#endif
328
        JANUS_LOG(LOG_INFO, "Crypto: %s\n", crypto_lib);
329

    
330
        /* Go on and create the DTLS context */
331
#if OPENSSL_VERSION_NUMBER < 0x10100000L
332
        ssl_ctx = SSL_CTX_new(DTLSv1_method());
333
#else
334
        ssl_ctx = SSL_CTX_new(DTLS_method());
335
#endif
336
        if(!ssl_ctx) {
337
                JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n");
338
                return -1;
339
        }
340
        SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback);
341
        SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80");        /* FIXME Should we support something else as well? */
342

    
343
        if(!server_pem && !server_key) {
344
                JANUS_LOG(LOG_WARN, "No cert/key specified, autogenerating some...\n");
345
                if(janus_dtls_generate_keys(&ssl_cert, &ssl_key) != 0) {
346
                        JANUS_LOG(LOG_FATAL, "Error generating DTLS key/certificate\n");
347
                        return -2;
348
                }
349
        } else if(!server_pem || !server_key) {
350
                JANUS_LOG(LOG_FATAL, "DTLS certificate and key must be specified\n");
351
                return -2;
352
        } else if(janus_dtls_load_keys(server_pem, server_key, &ssl_cert, &ssl_key) != 0) {
353
                return -3;
354
        }
355

    
356
        if(!SSL_CTX_use_certificate(ssl_ctx, ssl_cert)) {
357
                JANUS_LOG(LOG_FATAL, "Certificate error (%s)\n", ERR_reason_error_string(ERR_get_error()));
358
                return -4;
359
        }
360
        if(!SSL_CTX_use_PrivateKey(ssl_ctx, ssl_key)) {
361
                JANUS_LOG(LOG_FATAL, "Certificate key error (%s)\n", ERR_reason_error_string(ERR_get_error()));
362
                return -5;
363
        }
364
        if(!SSL_CTX_check_private_key(ssl_ctx)) {
365
                JANUS_LOG(LOG_FATAL, "Certificate check error (%s)\n", ERR_reason_error_string(ERR_get_error()));
366
                return -6;
367
        }
368
        SSL_CTX_set_read_ahead(ssl_ctx,1);
369

    
370
        unsigned int size;
371
        unsigned char fingerprint[EVP_MAX_MD_SIZE];
372
        if(X509_digest(ssl_cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) {
373
                JANUS_LOG(LOG_FATAL, "Error converting X509 structure (%s)\n", ERR_reason_error_string(ERR_get_error()));
374
                return -7;
375
        }
376
        char *lfp = (char *)&local_fingerprint;
377
        unsigned int i = 0;
378
        for(i = 0; i < size; i++) {
379
                g_snprintf(lfp, 4, "%.2X:", fingerprint[i]);
380
                lfp += 3;
381
        }
382
        *(lfp-1) = 0;
383
        JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint);
384
        SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS);
385

    
386
        if(janus_dtls_bio_filter_init() < 0) {
387
                JANUS_LOG(LOG_FATAL, "Error initializing BIO filter\n");
388
                return -8;
389
        }
390

    
391
        /* Initialize libsrtp */
392
        if(srtp_init() != srtp_err_status_ok) {
393
                JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n");
394
                return 5;
395
        }
396
        return 0;
397
}
398

    
399

    
400
void janus_dtls_srtp_cleanup(void) {
401
        if(ssl_cert != NULL) {
402
                X509_free(ssl_cert);
403
                ssl_cert = NULL;
404
        }
405
        if(ssl_key != NULL) {
406
                EVP_PKEY_free(ssl_key);
407
                ssl_key = NULL;
408
        }
409
        if(ssl_ctx != NULL) {
410
                SSL_CTX_free(ssl_ctx);
411
                ssl_ctx = NULL;
412
        }
413
}
414

    
415

    
416
janus_dtls_srtp *janus_dtls_srtp_create(void *ice_component, janus_dtls_role role) {
417
        janus_ice_component *component = (janus_ice_component *)ice_component;
418
        if(component == NULL) {
419
                JANUS_LOG(LOG_ERR, "No component, no DTLS...\n");
420
                return NULL;
421
        }
422
        janus_ice_stream *stream = component->stream;
423
        if(!stream) {
424
                JANUS_LOG(LOG_ERR, "No stream, no DTLS...\n");
425
                return NULL;
426
        }
427
        janus_ice_handle *handle = stream->handle;
428
        if(!handle || !handle->agent) {
429
                JANUS_LOG(LOG_ERR, "No handle/agent, no DTLS...\n");
430
                return NULL;
431
        }
432
        janus_dtls_srtp *dtls = g_malloc0(sizeof(janus_dtls_srtp));
433
        if(dtls == NULL) {
434
                JANUS_LOG(LOG_FATAL, "Memory error!\n");
435
                return NULL;
436
        }
437
        /* Create SSL context, at last */
438
        dtls->srtp_valid = 0;
439
        dtls->ssl = SSL_new(ssl_ctx);
440
        if(!dtls->ssl) {
441
                JANUS_LOG(LOG_ERR, "[%"SCNu64"]     Error creating DTLS session! (%s)\n",
442
                        handle->handle_id, ERR_reason_error_string(ERR_get_error()));
443
                janus_dtls_srtp_destroy(dtls);
444
                return NULL;
445
        }
446
        SSL_set_ex_data(dtls->ssl, 0, dtls);
447
        SSL_set_info_callback(dtls->ssl, janus_dtls_callback);
448
        dtls->read_bio = BIO_new(BIO_s_mem());
449
        if(!dtls->read_bio) {
450
                JANUS_LOG(LOG_ERR, "[%"SCNu64"]   Error creating read BIO! (%s)\n",
451
                        handle->handle_id, ERR_reason_error_string(ERR_get_error()));
452
                janus_dtls_srtp_destroy(dtls);
453
                return NULL;
454
        }
455
        BIO_set_mem_eof_return(dtls->read_bio, -1);
456
        dtls->write_bio = BIO_new(BIO_s_mem());
457
        if(!dtls->write_bio) {
458
                JANUS_LOG(LOG_ERR, "[%"SCNu64"]   Error creating write BIO! (%s)\n",
459
                        handle->handle_id, ERR_reason_error_string(ERR_get_error()));
460
                janus_dtls_srtp_destroy(dtls);
461
                return NULL;
462
        }
463
        BIO_set_mem_eof_return(dtls->write_bio, -1);
464
        /* The write BIO needs our custom filter, or fragmentation won't work */
465
        dtls->filter_bio = BIO_new(BIO_janus_dtls_filter());
466
        if(!dtls->filter_bio) {
467
                JANUS_LOG(LOG_ERR, "[%"SCNu64"]   Error creating filter BIO! (%s)\n",
468
                        handle->handle_id, ERR_reason_error_string(ERR_get_error()));
469
                janus_dtls_srtp_destroy(dtls);
470
                return NULL;
471
        }
472
        /* Chain filter and write BIOs */
473
        BIO_push(dtls->filter_bio, dtls->write_bio);
474
        /* Set the filter as the BIO to use for outgoing data */
475
        SSL_set_bio(dtls->ssl, dtls->read_bio, dtls->filter_bio);
476
        dtls->dtls_role = role;
477
        if(dtls->dtls_role == JANUS_DTLS_ROLE_CLIENT) {
478
                JANUS_LOG(LOG_VERB, "[%"SCNu64"]   Setting connect state (DTLS client)\n", handle->handle_id);
479
                SSL_set_connect_state(dtls->ssl);
480
        } else {
481
                JANUS_LOG(LOG_VERB, "[%"SCNu64"]   Setting accept state (DTLS server)\n", handle->handle_id);
482
                SSL_set_accept_state(dtls->ssl);
483
        }
484
        /* https://code.google.com/p/chromium/issues/detail?id=406458
485
         * Specify an ECDH group for ECDHE ciphers, otherwise they cannot be
486
         * negotiated when acting as the server. Use NIST's P-256 which is
487
         * commonly supported.
488
         */
489
        EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
490
        if(ecdh == NULL) {
491
                JANUS_LOG(LOG_ERR, "[%"SCNu64"]   Error creating ECDH group! (%s)\n",
492
                        handle->handle_id, ERR_reason_error_string(ERR_get_error()));
493
                janus_dtls_srtp_destroy(dtls);
494
                return NULL;
495
        }
496
        SSL_set_options(dtls->ssl, SSL_OP_SINGLE_ECDH_USE);
497
        SSL_set_tmp_ecdh(dtls->ssl, ecdh);
498
        EC_KEY_free(ecdh);
499
#ifdef HAVE_DTLS_SETTIMEOUT
500
        guint ms = 100;
501
        JANUS_LOG(LOG_VERB, "[%"SCNu64"]   Setting DTLS initial timeout: %u\n", handle->handle_id, ms);
502
        DTLSv1_set_initial_timeout_duration(dtls->ssl, ms);
503
#endif
504
        dtls->ready = 0;
505
        dtls->retransmissions = 0;
506
#ifdef HAVE_SCTP
507
        dtls->sctp = NULL;
508
#endif
509
        janus_mutex_init(&dtls->srtp_mutex);
510
        /* Done */
511
        dtls->dtls_connected = 0;
512
        dtls->component = component;
513
        return dtls;
514
}
515

    
516
void janus_dtls_srtp_handshake(janus_dtls_srtp *dtls) {
517
        if(dtls == NULL || dtls->ssl == NULL)
518
                return;
519
        if(dtls->dtls_state == JANUS_DTLS_STATE_CREATED)
520
                dtls->dtls_state = JANUS_DTLS_STATE_TRYING;
521
        SSL_do_handshake(dtls->ssl);
522
        janus_dtls_fd_bridge(dtls);
523

    
524
        /* Notify event handlers */
525
        janus_dtls_notify_state_change(dtls);
526
}
527

    
528
void janus_dtls_srtp_incoming_msg(janus_dtls_srtp *dtls, char *buf, uint16_t len) {
529
        if(dtls == NULL) {
530
                JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no incoming message...\n");
531
                return;
532
        }
533
        janus_ice_component *component = (janus_ice_component *)dtls->component;
534
        if(component == NULL) {
535
                JANUS_LOG(LOG_ERR, "No component, no DTLS...\n");
536
                return;
537
        }
538
        janus_ice_stream *stream = component->stream;
539
        if(!stream) {
540
                JANUS_LOG(LOG_ERR, "No stream, no DTLS...\n");
541
                return;
542
        }
543
        janus_ice_handle *handle = stream->handle;
544
        if(!handle || !handle->agent) {
545
                JANUS_LOG(LOG_ERR, "No handle/agent, no DTLS...\n");
546
                return;
547
        }
548
        if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT)) {
549
                JANUS_LOG(LOG_WARN, "[%"SCNu64"] Alert already triggered, clearing up...\n", handle->handle_id);
550
                return;
551
        }
552
        if(!dtls->ssl || !dtls->read_bio) {
553
                JANUS_LOG(LOG_ERR, "[%"SCNu64"] No DTLS stuff for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
554
                return;
555
        }
556
        janus_dtls_fd_bridge(dtls);
557
        int written = BIO_write(dtls->read_bio, buf, len);
558
        if(written != len) {
559
                JANUS_LOG(LOG_WARN, "[%"SCNu64"]     Only written %d/%d of those bytes on the read BIO...\n", handle->handle_id, written, len);
560
        } else {
561
                JANUS_LOG(LOG_HUGE, "[%"SCNu64"]     Written %d bytes on the read BIO...\n", handle->handle_id, written);
562
        }
563
        janus_dtls_fd_bridge(dtls);
564
        /* Try to read data */
565
        char data[1500];        /* FIXME */
566
        memset(&data, 0, 1500);
567
        int read = SSL_read(dtls->ssl, &data, 1500);
568
        JANUS_LOG(LOG_HUGE, "[%"SCNu64"]     ... and read %d of them from SSL...\n", handle->handle_id, read);
569
        if(read < 0) {
570
                unsigned long err = SSL_get_error(dtls->ssl, read);
571
                if(err == SSL_ERROR_SSL) {
572
                        /* Ops, something went wrong with the DTLS handshake */
573
                        char error[200];
574
                        ERR_error_string_n(ERR_get_error(), error, 200);
575
                        JANUS_LOG(LOG_ERR, "[%"SCNu64"] Handshake error: %s\n", handle->handle_id, error);
576
                        return;
577
                }
578
        }
579
        janus_dtls_fd_bridge(dtls);
580
        if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP) || janus_is_stopping()) {
581
                /* DTLS alert triggered, we should end it here */
582
                JANUS_LOG(LOG_VERB, "[%"SCNu64"] Forced to stop it here...\n", handle->handle_id);
583
                return;
584
        }
585
        if(!SSL_is_init_finished(dtls->ssl)) {
586
                /* Nothing else to do for now */
587
                JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Initialization not finished yet...\n", handle->handle_id);
588
                return;
589
        }
590
        if(dtls->ready) {
591
                /* There's data to be read? */
592
                JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Any data available?\n", handle->handle_id);
593
#ifdef HAVE_SCTP
594
                if(dtls->sctp != NULL && read > 0) {
595
                        JANUS_LOG(LOG_HUGE, "[%"SCNu64"] Sending data (%d bytes) to the SCTP stack...\n", handle->handle_id, read);
596
                        janus_sctp_data_from_dtls(dtls->sctp, data, read);
597
                }
598
#else
599
                if(read > 0) {
600
                        JANUS_LOG(LOG_WARN, "[%"SCNu64"] Data available but Data Channels support disabled...\n", handle->handle_id);
601
                }
602
#endif
603
        } else {
604
                JANUS_LOG(LOG_VERB, "[%"SCNu64"] DTLS established, yay!\n", handle->handle_id);
605
                /* Check the remote fingerprint */
606
                X509 *rcert = SSL_get_peer_certificate(dtls->ssl);
607
                if(!rcert) {
608
                        JANUS_LOG(LOG_ERR, "[%"SCNu64"] No remote certificate?? (%s)\n",
609
                                handle->handle_id, ERR_reason_error_string(ERR_get_error()));
610
                } else {
611
                        unsigned int rsize;
612
                        unsigned char rfingerprint[EVP_MAX_MD_SIZE];
613
                        char remote_fingerprint[160];
614
                        char *rfp = (char *)&remote_fingerprint;
615
                        if(stream->remote_hashing && !strcasecmp(stream->remote_hashing, "sha-1")) {
616
                                JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-1 fingerprint of remote certificate...\n", handle->handle_id);
617
                                X509_digest(rcert, EVP_sha1(), (unsigned char *)rfingerprint, &rsize);
618
                        } else {
619
                                JANUS_LOG(LOG_VERB, "[%"SCNu64"] Computing sha-256 fingerprint of remote certificate...\n", handle->handle_id);
620
                                X509_digest(rcert, EVP_sha256(), (unsigned char *)rfingerprint, &rsize);
621
                        }
622
                        X509_free(rcert);
623
                        rcert = NULL;
624
                        unsigned int i = 0;
625
                        for(i = 0; i < rsize; i++) {
626
                                g_snprintf(rfp, 4, "%.2X:", rfingerprint[i]);
627
                                rfp += 3;
628
                        }
629
                        *(rfp-1) = 0;
630
                        JANUS_LOG(LOG_VERB, "[%"SCNu64"] Remote fingerprint (%s) of the client is %s\n",
631
                                handle->handle_id, stream->remote_hashing ? stream->remote_hashing : "sha-256", remote_fingerprint);
632
                        if(!strcasecmp(remote_fingerprint, stream->remote_fingerprint ? stream->remote_fingerprint : "(none)")) {
633
                                JANUS_LOG(LOG_VERB, "[%"SCNu64"]  Fingerprint is a match!\n", handle->handle_id);
634
                                dtls->dtls_state = JANUS_DTLS_STATE_CONNECTED;
635
                                dtls->dtls_connected = janus_get_monotonic_time();
636
                                /* Notify event handlers */
637
                                janus_dtls_notify_state_change(dtls);
638
                        } else {
639
                                /* FIXME NOT a match! MITM? */
640
                                JANUS_LOG(LOG_ERR, "[%"SCNu64"]  Fingerprint is NOT a match! got %s, expected %s\n", handle->handle_id, remote_fingerprint, stream->remote_fingerprint);
641
                                dtls->dtls_state = JANUS_DTLS_STATE_FAILED;
642
                                /* Notify event handlers */
643
                                janus_dtls_notify_state_change(dtls);
644
                                goto done;
645
                        }
646
                        if(dtls->dtls_state == JANUS_DTLS_STATE_CONNECTED) {
647
                                if(component->stream_id == handle->audio_id || component->stream_id == handle->video_id) {
648
                                        /* Complete with SRTP setup */
649
                                        unsigned char material[SRTP_MASTER_LENGTH*2];
650
                                        unsigned char *local_key, *local_salt, *remote_key, *remote_salt;
651
                                        /* Export keying material for SRTP */
652
                                        if(!SSL_export_keying_material(dtls->ssl, material, SRTP_MASTER_LENGTH*2, "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0)) {
653
                                                /* Oops... */
654
                                                JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, couldn't extract SRTP keying material for component %d in stream %d?? (%s)\n",
655
                                                        handle->handle_id, component->component_id, stream->stream_id, ERR_reason_error_string(ERR_get_error()));
656
                                                goto done;
657
                                        }
658
                                        /* Key derivation (http://tools.ietf.org/html/rfc5764#section-4.2) */
659
                                        if(dtls->dtls_role == JANUS_DTLS_ROLE_CLIENT) {
660
                                                local_key = material;
661
                                                remote_key = local_key + SRTP_MASTER_KEY_LENGTH;
662
                                                local_salt = remote_key + SRTP_MASTER_KEY_LENGTH;
663
                                                remote_salt = local_salt + SRTP_MASTER_SALT_LENGTH;
664
                                        } else {
665
                                                remote_key = material;
666
                                                local_key = remote_key + SRTP_MASTER_KEY_LENGTH;
667
                                                remote_salt = local_key + SRTP_MASTER_KEY_LENGTH;
668
                                                local_salt = remote_salt + SRTP_MASTER_SALT_LENGTH;
669
                                        }
670
                                        /* Build master keys and set SRTP policies */
671
                                                /* Remote (inbound) */
672
                                        srtp_crypto_policy_set_rtp_default(&(dtls->remote_policy.rtp));
673
                                        srtp_crypto_policy_set_rtcp_default(&(dtls->remote_policy.rtcp));
674
                                        dtls->remote_policy.ssrc.type = ssrc_any_inbound;
675
                                        unsigned char remote_policy_key[SRTP_MASTER_LENGTH];
676
                                        dtls->remote_policy.key = (unsigned char *)&remote_policy_key;
677
                                        memcpy(dtls->remote_policy.key, remote_key, SRTP_MASTER_KEY_LENGTH);
678
                                        memcpy(dtls->remote_policy.key + SRTP_MASTER_KEY_LENGTH, remote_salt, SRTP_MASTER_SALT_LENGTH);
679
#if HAS_DTLS_WINDOW_SIZE
680
                                        dtls->remote_policy.window_size = 128;
681
                                        dtls->remote_policy.allow_repeat_tx = 0;
682
#endif
683
                                        dtls->remote_policy.next = NULL;
684
                                                /* Local (outbound) */
685
                                        srtp_crypto_policy_set_rtp_default(&(dtls->local_policy.rtp));
686
                                        srtp_crypto_policy_set_rtcp_default(&(dtls->local_policy.rtcp));
687
                                        dtls->local_policy.ssrc.type = ssrc_any_outbound;
688
                                        unsigned char local_policy_key[SRTP_MASTER_LENGTH];
689
                                        dtls->local_policy.key = (unsigned char *)&local_policy_key;
690
                                        memcpy(dtls->local_policy.key, local_key, SRTP_MASTER_KEY_LENGTH);
691
                                        memcpy(dtls->local_policy.key + SRTP_MASTER_KEY_LENGTH, local_salt, SRTP_MASTER_SALT_LENGTH);
692
#if HAS_DTLS_WINDOW_SIZE
693
                                        dtls->local_policy.window_size = 128;
694
                                        dtls->local_policy.allow_repeat_tx = 0;
695
#endif
696
                                        dtls->local_policy.next = NULL;
697
                                        /* Create SRTP sessions */
698
                                        srtp_err_status_t res = srtp_create(&(dtls->srtp_in), &(dtls->remote_policy));
699
                                        if(res != srtp_err_status_ok) {
700
                                                /* Something went wrong... */
701
                                                JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating inbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
702
                                                JANUS_LOG(LOG_ERR, "[%"SCNu64"]  -- %d (%s)\n", handle->handle_id, res, janus_srtp_error_str(res));
703
                                                goto done;
704
                                        }
705
                                        JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created inbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id);
706
                                        res = srtp_create(&(dtls->srtp_out), &(dtls->local_policy));
707
                                        if(res != srtp_err_status_ok) {
708
                                                /* Something went wrong... */
709
                                                JANUS_LOG(LOG_ERR, "[%"SCNu64"] Oops, error creating outbound SRTP session for component %d in stream %d??\n", handle->handle_id, component->component_id, stream->stream_id);
710
                                                JANUS_LOG(LOG_ERR, "[%"SCNu64"]  -- %d (%s)\n", handle->handle_id, res, janus_srtp_error_str(res));
711
                                                goto done;
712
                                        }
713
                                        dtls->srtp_valid = 1;
714
                                        JANUS_LOG(LOG_VERB, "[%"SCNu64"] Created outbound SRTP session for component %d in stream %d\n", handle->handle_id, component->component_id, stream->stream_id);
715
                                }
716
#ifdef HAVE_SCTP
717
                                if(component->stream_id == handle->data_id ||
718
                                                (janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_BUNDLE) &&
719
                                                janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_DATA_CHANNELS))) {
720
                                        /* FIXME Create SCTP association as well (5000 should be dynamic, from the SDP...) */
721
                                        dtls->sctp = janus_sctp_association_create(dtls, handle->handle_id, 5000);
722
                                        if(dtls->sctp != NULL) {
723
                                                /* FIXME We need to start it in a thread, though, since it has blocking accept/connect stuff */
724
                                                GError *error = NULL;
725
                                                char tname[16];
726
                                                g_snprintf(tname, sizeof(tname), "sctpinit %"SCNu64, handle->handle_id);
727
                                                g_thread_try_new(tname, janus_dtls_sctp_setup_thread, dtls, &error);
728
                                                if(error != NULL) {
729
                                                        /* Something went wrong... */
730
                                                        JANUS_LOG(LOG_ERR, "[%"SCNu64"] Got error %d (%s) trying to launch the DTLS-SCTP thread...\n", handle->handle_id, error->code, error->message ? error->message : "??");
731
                                                }
732
                                                dtls->srtp_valid = 1;
733
                                        }
734
                                }
735
#endif
736
                                dtls->ready = 1;
737
                        }
738
done:
739
                        if(!janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT) && dtls->srtp_valid) {
740
                                /* Handshake successfully completed */
741
                                janus_ice_dtls_handshake_done(handle, component);
742
                        } else {
743
                                /* Something went wrong in either DTLS or SRTP... tell the plugin about it */
744
                                janus_dtls_callback(dtls->ssl, SSL_CB_ALERT, 0);
745
                                janus_flags_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_CLEANING);
746
                        }
747
                }
748
        }
749
}
750

    
751
void janus_dtls_srtp_send_alert(janus_dtls_srtp *dtls) {
752
        /* Send alert */
753
        if(dtls != NULL && dtls->ssl != NULL) {
754
                SSL_shutdown(dtls->ssl);
755
                janus_dtls_fd_bridge(dtls);
756
        }
757
}
758

    
759
void janus_dtls_srtp_destroy(janus_dtls_srtp *dtls) {
760
        if(dtls == NULL)
761
                return;
762
        dtls->ready = 0;
763
        dtls->retransmissions = 0;
764
#ifdef HAVE_SCTP
765
        /* Destroy the SCTP association if this is a DataChannel */
766
        if(dtls->sctp != NULL) {
767
                janus_sctp_association_destroy(dtls->sctp);
768
                dtls->sctp = NULL;
769
        }
770
#endif
771
        /* Destroy DTLS stack and free resources */
772
        dtls->component = NULL;
773
        if(dtls->ssl != NULL) {
774
                SSL_free(dtls->ssl);
775
                dtls->ssl = NULL;
776
        }
777
        /* BIOs are destroyed by SSL_free */
778
        dtls->read_bio = NULL;
779
        dtls->write_bio = NULL;
780
        dtls->filter_bio = NULL;
781
        if(dtls->srtp_valid) {
782
                if(dtls->srtp_in) {
783
                        srtp_dealloc(dtls->srtp_in);
784
                        dtls->srtp_in = NULL;
785
                }
786
                if(dtls->srtp_out) {
787
                        srtp_dealloc(dtls->srtp_out);
788
                        dtls->srtp_out = NULL;
789
                }
790
                /* FIXME What about dtls->remote_policy and dtls->local_policy? */
791
        }
792
        g_free(dtls);
793
        dtls = NULL;
794
}
795

    
796
/* DTLS alert callback */
797
void janus_dtls_callback(const SSL *ssl, int where, int ret) {
798
        /* We only care about alerts */
799
        if(!(where & SSL_CB_ALERT)) {
800
                return;
801
        }
802
        janus_dtls_srtp *dtls = SSL_get_ex_data(ssl, 0);
803
        if(!dtls) {
804
                JANUS_LOG(LOG_ERR, "No DTLS session related to this alert...\n");
805
                return;
806
        }
807
        janus_ice_component *component = dtls->component;
808
        if(component == NULL) {
809
                JANUS_LOG(LOG_ERR, "No ICE component related to this alert...\n");
810
                return;
811
        }
812
        janus_ice_stream *stream = component->stream;
813
        if(!stream) {
814
                JANUS_LOG(LOG_ERR, "No ICE stream related to this alert...\n");
815
                return;
816
        }
817
        janus_ice_handle *handle = stream->handle;
818
        if(!handle) {
819
                JANUS_LOG(LOG_ERR, "No ICE handle related to this alert...\n");
820
                return;
821
        }
822
        JANUS_LOG(LOG_VERB, "[%"SCNu64"] DTLS alert triggered on stream %"SCNu16" (component %"SCNu16"), closing...\n", handle->handle_id, stream->stream_id, component->component_id);
823
        janus_ice_webrtc_hangup(handle, "DTLS alert");
824
}
825

    
826
/* DTLS certificate verification callback */
827
int janus_dtls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
828
        /* We just use the verify_callback to request a certificate from the client */
829
        return 1;
830
}
831

    
832
/* DTLS BIOs to/from socket bridge */
833
void janus_dtls_fd_bridge(janus_dtls_srtp *dtls) {
834
        if(dtls == NULL) {
835
                JANUS_LOG(LOG_ERR, "No DTLS-SRTP stack, no DTLS bridge...\n");
836
                return;
837
        }
838
        janus_ice_component *component = (janus_ice_component *)dtls->component;
839
        if(component == NULL) {
840
                JANUS_LOG(LOG_ERR, "No component, no DTLS bridge...\n");
841
                return;
842
        }
843
        janus_ice_stream *stream = component->stream;
844
        if(!stream) {
845
                JANUS_LOG(LOG_ERR, "No stream, no DTLS bridge...\n");
846
                return;
847
        }
848
        janus_ice_handle *handle = stream->handle;
849
        if(!handle || !handle->agent || !dtls->write_bio) {
850
                JANUS_LOG(LOG_ERR, "No handle/agent/bio, no DTLS bridge...\n");
851
                return;
852
        }
853
        int pending = BIO_ctrl_pending(dtls->filter_bio);
854
        while(pending > 0) {
855
                JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> Going to send DTLS data: %d bytes\n", handle->handle_id, pending);
856
                char outgoing[pending];
857
                int out = BIO_read(dtls->write_bio, outgoing, sizeof(outgoing));
858
                JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> Read %d bytes from the write_BIO...\n", handle->handle_id, out);
859
                if(out > 1500) {
860
                        /* FIXME Just a warning for now, this will need to be solved with proper fragmentation */
861
                        JANUS_LOG(LOG_WARN, "[%"SCNu64"] The DTLS stack is trying to send a packet of %d bytes, this may be larger than the MTU and get dropped!\n", handle->handle_id, out);
862
                }
863
                int bytes = nice_agent_send(handle->agent, component->stream_id, component->component_id, out, outgoing);
864
                if(bytes < out) {
865
                        JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error sending DTLS message on component %d of stream %d (%d)\n", handle->handle_id, component->component_id, stream->stream_id, bytes);
866
                } else {
867
                        JANUS_LOG(LOG_HUGE, "[%"SCNu64"] >> >> ... and sent %d of those bytes on the socket\n", handle->handle_id, bytes);
868
                }
869
                /* Update stats (TODO Do the same for the last second window as well)
870
                 * FIXME: the Data stats includes the bytes used for the handshake */
871
                if(bytes > 0) {
872
                        component->out_stats.data_packets++;
873
                        component->out_stats.data_bytes += bytes;
874
                }
875
                /* Check if there's anything left to send (e.g., fragmented packets) */
876
                pending = BIO_ctrl_pending(dtls->filter_bio);
877
        }
878
}
879

    
880
#ifdef HAVE_SCTP
881
void janus_dtls_wrap_sctp_data(janus_dtls_srtp *dtls, char *buf, int len) {
882
        if(dtls == NULL || !dtls->ready || dtls->sctp == NULL || buf == NULL || len < 1)
883
                return;
884
        janus_sctp_send_data(dtls->sctp, buf, len);
885
}
886

    
887
int janus_dtls_send_sctp_data(janus_dtls_srtp *dtls, char *buf, int len) {
888
        if(dtls == NULL || !dtls->ready || buf == NULL || len < 1)
889
                return -1;
890
        int res = SSL_write(dtls->ssl, buf, len);
891
        if(res <= 0) {
892
                unsigned long err = SSL_get_error(dtls->ssl, res);
893
                JANUS_LOG(LOG_ERR, "Error sending data: %s\n", ERR_reason_error_string(err));
894
        } else {
895
                janus_dtls_fd_bridge(dtls);
896
        }
897
        return res;
898
}
899

    
900
void janus_dtls_notify_data(janus_dtls_srtp *dtls, char *buf, int len) {
901
        if(dtls == NULL || buf == NULL || len < 1)
902
                return;
903
        janus_ice_component *component = (janus_ice_component *)dtls->component;
904
        if(component == NULL) {
905
                JANUS_LOG(LOG_ERR, "No component...\n");
906
                return;
907
        }
908
        janus_ice_stream *stream = component->stream;
909
        if(!stream) {
910
                JANUS_LOG(LOG_ERR, "No stream...\n");
911
                return;
912
        }
913
        janus_ice_handle *handle = stream->handle;
914
        if(!handle || !handle->agent || !dtls->write_bio) {
915
                JANUS_LOG(LOG_ERR, "No handle...\n");
916
                return;
917
        }
918
        janus_ice_incoming_data(handle, buf, len);
919
}
920
#endif
921

    
922
gboolean janus_dtls_retry(gpointer stack) {
923
        janus_dtls_srtp *dtls = (janus_dtls_srtp *)stack;
924
        if(dtls == NULL)
925
                return FALSE;
926
        janus_ice_component *component = (janus_ice_component *)dtls->component;
927
        if(component == NULL)
928
                return FALSE;
929
        janus_ice_stream *stream = component->stream;
930
        if(!stream)
931
                return FALSE;
932
        janus_ice_handle *handle = stream->handle;
933
        if(!handle)
934
                return FALSE;
935
        if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP))
936
                return FALSE;
937
        if(dtls->dtls_state == JANUS_DTLS_STATE_CONNECTED) {
938
                JANUS_LOG(LOG_VERB, "[%"SCNu64"]  DTLS already set up, disabling retransmission timer!\n", handle->handle_id);
939
                if(component->source != NULL) {
940
                        g_source_destroy(component->source);
941
                        g_source_unref(component->source);
942
                        component->source = NULL;
943
                }
944
                return FALSE;
945
        }
946
        struct timeval timeout = {0};
947
        DTLSv1_get_timeout(dtls->ssl, &timeout);
948
        guint64 timeout_value = timeout.tv_sec*1000 + timeout.tv_usec/1000;
949
        JANUS_LOG(LOG_HUGE, "[%"SCNu64"] DTLSv1_get_timeout: %"SCNu64"\n", handle->handle_id, timeout_value);
950
        if(timeout_value == 0) {
951
                dtls->retransmissions++;
952
                JANUS_LOG(LOG_VERB, "[%"SCNu64"] DTLS timeout on component %d of stream %d, retransmitting\n", handle->handle_id, component->component_id, stream->stream_id);
953
                /* Notify event handlers */
954
                janus_dtls_notify_state_change(dtls);
955
                /* Retransmit the packet */
956
                DTLSv1_handle_timeout(dtls->ssl);
957
                janus_dtls_fd_bridge(dtls);
958
        }
959
        return TRUE;
960
}
961

    
962

    
963
#ifdef HAVE_SCTP
964
/* Helper thread to create a SCTP association that will use this DTLS stack */
965
void *janus_dtls_sctp_setup_thread(void *data) {
966
        if(data == NULL) {
967
                JANUS_LOG(LOG_ERR, "No DTLS stack??\n");
968
                g_thread_unref(g_thread_self());
969
                return NULL;
970
        }
971
        janus_dtls_srtp *dtls = (janus_dtls_srtp *)data;
972
        if(dtls->sctp == NULL) {
973
                JANUS_LOG(LOG_ERR, "No SCTP stack??\n");
974
                g_thread_unref(g_thread_self());
975
                return NULL;
976
        }
977
        janus_sctp_association *sctp = (janus_sctp_association *)dtls->sctp;
978
        /* Do the accept/connect stuff now */
979
        JANUS_LOG(LOG_VERB, "[%"SCNu64"] Started thread: setup of the SCTP association\n", sctp->handle_id);
980
        janus_sctp_association_setup(sctp);
981
        g_thread_unref(g_thread_self());
982
        return NULL;
983
}
984
#endif