Просмотр исходного кода

Adds config options to filter out TCP or UDP candidates (for the purpose

of forcing one or the other in automated tests).
master
Boris Grozev 9 лет назад
Родитель
Сommit
62d3b749bb
4 измененных файлов: 117 добавлений и 44 удалений
  1. 5
    0
      config.js
  2. 1
    1
      index.html
  3. 48
    2
      modules/xmpp/JingleSessionPC.js
  4. 63
    41
      modules/xmpp/SDP.js

+ 5
- 0
config.js Просмотреть файл

@@ -43,6 +43,11 @@ var config = {
43 43
     // The URL to the Firefox extension for desktop sharing.
44 44
     desktopSharingFirefoxExtensionURL: null,
45 45
 
46
+    // Disables ICE/UDP by filtering out local and remote UDP candidates in signalling.
47
+    webrtcIceUdpDisable: false,
48
+    // Disables ICE/TCP by filtering out local and remote TCP candidates in signalling.
49
+    webrtcIceTcpDisable: false,
50
+
46 51
     openSctp: true, // Toggle to enable/disable SCTP channels
47 52
     disableStats: false,
48 53
     disableAudioLevels: false,

+ 1
- 1
index.html Просмотреть файл

@@ -11,7 +11,7 @@
11 11
     <meta itemprop="image" content="/images/jitsilogo.png"/>
12 12
     <script src="https://api.callstats.io/static/callstats.min.js"></script>
13 13
     <script src="libs/jquery-2.1.1.min.js"></script>
14
-    <script src="config.js?v=13"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
14
+    <script src="config.js?v=14"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
15 15
     <script src="libs/strophe/strophe.min.js?v=2"></script>
16 16
     <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
17 17
     <script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>

+ 48
- 2
modules/xmpp/JingleSessionPC.js Просмотреть файл

@@ -56,6 +56,7 @@ function JingleSessionPC(me, sid, connection, service, eventEmitter) {
56 56
     // stable and the ice connection state is connected.
57 57
     this.modifySourcesQueue.pause();
58 58
 }
59
+//XXX this is badly broken...
59 60
 JingleSessionPC.prototype = JingleSession.prototype;
60 61
 JingleSessionPC.prototype.constructor = JingleSessionPC;
61 62
 
@@ -95,6 +96,15 @@ JingleSessionPC.prototype.doInitialize = function () {
95 96
             this);
96 97
 
97 98
     this.peerconnection.onicecandidate = function (event) {
99
+        var protocol;
100
+        if (event && event.candidate) {
101
+            protocol = (typeof event.candidate.protocol === 'string')
102
+                ? event.candidate.protocol.toLowerCase() : '';
103
+            if ((config.webrtcIceTcpDisable && protocol == 'tcp') ||
104
+                (config.webrtcIceUdpDisable && protocol == 'udp')) {
105
+                return;
106
+            }
107
+        }
98 108
         self.sendIceCandidate(event.candidate);
99 109
     };
100 110
     this.peerconnection.onaddstream = function (event) {
@@ -229,6 +239,12 @@ JingleSessionPC.prototype.accept = function () {
229 239
         pranswer.sdp = pranswer.sdp.replace('a=inactive', 'a=sendrecv');
230 240
     }
231 241
     var prsdp = new SDP(pranswer.sdp);
242
+    if (config.webrtcIceTcpDisable) {
243
+        prsdp.removeTcpCandidates = true;
244
+    }
245
+    if (config.webrtcIceUdpDisable) {
246
+        prsdp.removeUdpCandidates = true;
247
+    }
232 248
     var accept = $iq({to: this.peerjid,
233 249
         type: 'set'})
234 250
         .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@@ -337,6 +353,12 @@ JingleSessionPC.prototype.sendIceCandidate = function (candidate) {
337 353
                     initiator: this.initiator,
338 354
                     sid: this.sid});
339 355
             this.localSDP = new SDP(this.peerconnection.localDescription.sdp);
356
+            if (config.webrtcIceTcpDisable) {
357
+                this.localSDP.removeTcpCandidates = true;
358
+            }
359
+            if (config.webrtcIceUdpDisable) {
360
+                this.localSDP.removeUdpCandidates = true;
361
+            }
340 362
             var sendJingle = function (ssrc) {
341 363
                 if(!ssrc)
342 364
                     ssrc = {};
@@ -533,8 +555,14 @@ JingleSessionPC.prototype.getSsrcOwner = function (ssrc) {
533 555
 };
534 556
 
535 557
 JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
536
-    //console.log('setting remote description... ', desctype);
537 558
     this.remoteSDP = new SDP('');
559
+    if (config.webrtcIceTcpDisable) {
560
+        this.remoteSDP.removeTcpCandidates = true;
561
+    }
562
+    if (config.webrtcIceUdpDisable) {
563
+        this.remoteSDP.removeUdpCandidates = true;
564
+    }
565
+
538 566
     this.remoteSDP.fromJingle(elem);
539 567
     this.readSsrcInfo($(elem).find(">content"));
540 568
     if (this.peerconnection.remoteDescription !== null) {
@@ -577,6 +605,10 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
577 605
     );
578 606
 };
579 607
 
608
+/**
609
+ * Adds remote ICE candidates to this Jingle session.
610
+ * @param elem An array of Jingle "content" elements?
611
+ */
580 612
 JingleSessionPC.prototype.addIceCandidate = function (elem) {
581 613
     var self = this;
582 614
     if (this.peerconnection.signalingState == 'closed') {
@@ -587,7 +619,7 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) {
587 619
         // create a PRANSWER for setRemoteDescription
588 620
         if (!this.remoteSDP) {
589 621
             var cobbled = 'v=0\r\n' +
590
-                'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
622
+                'o=- 1923518516 2 IN IP4 0.0.0.0\r\n' +// FIXME
591 623
                 's=-\r\n' +
592 624
                 't=0 0\r\n';
593 625
             // first, take some things from the local description
@@ -672,6 +704,14 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) {
672 704
         // TODO: check ice-pwd and ice-ufrag?
673 705
         $(this).find('transport>candidate').each(function () {
674 706
             var line, candidate;
707
+            var protocol = this.getAttribute('protocol');
708
+            protocol =
709
+                (typeof protocol === 'string') ? protocol.toLowerCase() : '';
710
+            if ((config.webrtcIceTcpDisable && protocol == 'tcp') ||
711
+                (config.webrtcIceUdpDisable && protocol == 'udp')) {
712
+                return;
713
+            }
714
+
675 715
             line = SDPUtil.candidateFromJingle(this);
676 716
             candidate = new RTCIceCandidate({sdpMLineIndex: idx,
677 717
                 sdpMid: name,
@@ -724,6 +764,12 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, provisional) {
724 764
                         initiator: self.initiator,
725 765
                         responder: self.responder,
726 766
                         sid: self.sid });
767
+                if (config.webrtcIceTcpDisable) {
768
+                    self.localSDP.removeTcpCandidates = true;
769
+                }
770
+                if (config.webrtcIceUdpDisable) {
771
+                    self.localSDP.removeUdpCandidates = true;
772
+                }
727 773
                 self.localSDP.toJingle(
728 774
                     accept,
729 775
                     self.initiator == self.me ? 'initiator' : 'responder',

+ 63
- 41
modules/xmpp/SDP.js Просмотреть файл

@@ -4,6 +4,18 @@ var SDPUtil = require("./SDPUtil");
4 4
 
5 5
 // SDP STUFF
6 6
 function SDP(sdp) {
7
+    /**
8
+     * Whether or not to remove TCP ice candidates when translating from/to jingle.
9
+     * @type {boolean}
10
+     */
11
+    this.removeTcpCandidates = false;
12
+
13
+    /**
14
+     * Whether or not to remove UDP ice candidates when translating from/to jingle.
15
+     * @type {boolean}
16
+     */
17
+    this.removeUdpCandidates = false;
18
+
7 19
     this.media = sdp.split('\r\nm=');
8 20
     for (var i = 1; i < this.media.length; i++) {
9 21
         this.media[i] = 'm=' + this.media[i];
@@ -14,6 +26,7 @@ function SDP(sdp) {
14 26
     this.session = this.media.shift() + '\r\n';
15 27
     this.raw = this.session + this.media.join('');
16 28
 }
29
+
17 30
 /**
18 31
  * Returns map of MediaChannel mapped per channel idx.
19 32
  */
@@ -63,18 +76,16 @@ SDP.prototype.getMediaSsrcMap = function() {
63 76
  */
64 77
 SDP.prototype.containsSSRC = function(ssrc) {
65 78
     var medias = this.getMediaSsrcMap();
66
-    var contains = false;
67 79
     Object.keys(medias).forEach(function(mediaindex){
68 80
         var media = medias[mediaindex];
69 81
         //console.log("Check", channel, ssrc);
70 82
         if(Object.keys(media.ssrcs).indexOf(ssrc) != -1){
71
-            contains = true;
83
+            return true;
72 84
         }
73 85
     });
74
-    return contains;
86
+    return false;
75 87
 };
76 88
 
77
-
78 89
 // remove iSAC and CN from SDP
79 90
 SDP.prototype.mangle = function () {
80 91
     var i, j, mline, lines, rtpmap, newdesc;
@@ -129,8 +140,7 @@ SDP.prototype.removeMediaLines = function(mediaindex, prefix) {
129 140
 // add content's to a jingle element
130 141
 SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
131 142
 //    console.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
132
-    var i, j, k, mline, ssrc, rtpmap, tmp, line, lines;
133
-    var self = this;
143
+    var i, j, k, mline, ssrc, rtpmap, tmp, lines;
134 144
     // new bundle plan
135 145
     if (SDPUtil.find_line(this.session, 'a=group:')) {
136 146
         lines = SDPUtil.find_lines(this.session, 'a=group:');
@@ -155,12 +165,11 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
155 165
         if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
156 166
             ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
157 167
         } else {
158
-            if(ssrcs && ssrcs[mline.media])
159
-            {
168
+            if(ssrcs && ssrcs[mline.media]) {
160 169
                 ssrc = ssrcs[mline.media];
161
-            }
162
-            else
170
+            } else {
163 171
                 ssrc = false;
172
+            }
164 173
         }
165 174
 
166 175
         elem.c('content', {creator: thecreator, name: mline.media});
@@ -170,8 +179,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
170 179
             elem.attrs({ name: mid });
171 180
         }
172 181
 
173
-        if (SDPUtil.find_line(this.media[i], 'a=rtpmap:').length)
174
-        {
182
+        if (SDPUtil.find_line(this.media[i], 'a=rtpmap:').length) {
175 183
             elem.c('description',
176 184
                 {xmlns: 'urn:xmpp:jingle:apps:rtp:1',
177 185
                     media: mline.media });
@@ -188,7 +196,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
188 196
                         elem.c('parameter', tmp[k]).up();
189 197
                     }
190 198
                 }
191
-                this.RtcpFbToJingle(i, elem, mline.fmt[j]); // XEP-0293 -- map a=rtcp-fb
199
+                this.rtcpFbToJingle(i, elem, mline.fmt[j]); // XEP-0293 -- map a=rtcp-fb
192 200
 
193 201
                 elem.up();
194 202
             }
@@ -208,7 +216,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
208 216
                 var ssrclines = SDPUtil.find_lines(this.media[i], 'a=ssrc:');
209 217
                 if(ssrclines.length > 0) {
210 218
                     ssrclines.forEach(function (line) {
211
-                        idx = line.indexOf(' ');
219
+                        var idx = line.indexOf(' ');
212 220
                         var linessrc = line.substr(0, idx).substr(7);
213 221
                         if (linessrc != ssrc) {
214 222
                             elem.up();
@@ -229,9 +237,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
229 237
                         }
230 238
                         elem.up();
231 239
                     });
232
-                }
233
-                else
234
-                {
240
+                } else {
235 241
                     elem.up();
236 242
                     elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
237 243
                     elem.c('parameter');
@@ -261,7 +267,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
261 267
                 // XEP-0339 handle ssrc-group attributes
262 268
                 var ssrc_group_lines = SDPUtil.find_lines(this.media[i], 'a=ssrc-group:');
263 269
                 ssrc_group_lines.forEach(function(line) {
264
-                    idx = line.indexOf(' ');
270
+                    var idx = line.indexOf(' ');
265 271
                     var semantics = line.substr(0, idx).substr(13);
266 272
                     var ssrcs = line.substr(14 + semantics.length).split(' ');
267 273
                     if (ssrcs.length) {
@@ -280,7 +286,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
280 286
             }
281 287
 
282 288
             // XEP-0293 -- map a=rtcp-fb:*
283
-            this.RtcpFbToJingle(i, elem, '*');
289
+            this.rtcpFbToJingle(i, elem, '*');
284 290
 
285 291
             // XEP-0294
286 292
             if (SDPUtil.find_line(this.media[i], 'a=extmap:')) {
@@ -314,7 +320,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
314 320
         }
315 321
 
316 322
         // map ice-ufrag/pwd, dtls fingerprint, candidates
317
-        this.TransportToJingle(i, elem);
323
+        this.transportToJingle(i, elem);
318 324
 
319 325
         if (SDPUtil.find_line(this.media[i], 'a=sendrecv', this.session)) {
320 326
             elem.attrs({senders: 'both'});
@@ -335,25 +341,24 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
335 341
     return elem;
336 342
 };
337 343
 
338
-SDP.prototype.TransportToJingle = function (mediaindex, elem) {
339
-    var i = mediaindex;
340
-    var tmp;
344
+SDP.prototype.transportToJingle = function (mediaindex, elem) {
345
+    var tmp, sctpmap, sctpAttrs, fingerprints;
341 346
     var self = this;
342 347
     elem.c('transport');
343 348
 
344 349
     // XEP-0343 DTLS/SCTP
345 350
     if (SDPUtil.find_line(this.media[mediaindex], 'a=sctpmap:').length)
346 351
     {
347
-        var sctpmap = SDPUtil.find_line(
348
-            this.media[i], 'a=sctpmap:', self.session);
352
+        sctpmap = SDPUtil.find_line(
353
+            this.media[mediaindex], 'a=sctpmap:', self.session);
349 354
         if (sctpmap)
350 355
         {
351
-            var sctpAttrs = SDPUtil.parse_sctpmap(sctpmap);
356
+            sctpAttrs = SDPUtil.parse_sctpmap(sctpmap);
352 357
             elem.c('sctpmap',
353 358
                 {
354 359
                     xmlns: 'urn:xmpp:jingle:transports:dtls-sctp:1',
355 360
                     number: sctpAttrs[0], /* SCTP port */
356
-                    protocol: sctpAttrs[1], /* protocol */
361
+                    protocol: sctpAttrs[1] /* protocol */
357 362
                 });
358 363
             // Optional stream count attribute
359 364
             if (sctpAttrs.length > 2)
@@ -362,7 +367,7 @@ SDP.prototype.TransportToJingle = function (mediaindex, elem) {
362 367
         }
363 368
     }
364 369
     // XEP-0320
365
-    var fingerprints = SDPUtil.find_lines(this.media[mediaindex], 'a=fingerprint:', this.session);
370
+    fingerprints = SDPUtil.find_lines(this.media[mediaindex], 'a=fingerprint:', this.session);
366 371
     fingerprints.forEach(function(line) {
367 372
         tmp = SDPUtil.parse_fingerprint(line);
368 373
         tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0';
@@ -383,14 +388,22 @@ SDP.prototype.TransportToJingle = function (mediaindex, elem) {
383 388
         if (SDPUtil.find_line(this.media[mediaindex], 'a=candidate:', this.session)) { // add any a=candidate lines
384 389
             var lines = SDPUtil.find_lines(this.media[mediaindex], 'a=candidate:', this.session);
385 390
             lines.forEach(function (line) {
386
-                elem.c('candidate', SDPUtil.candidateToJingle(line)).up();
391
+                var candidate = SDPUtil.candidateToJingle(line);
392
+                var protocol = (candidate &&
393
+                        typeof candidate.protocol === 'string')
394
+                    ? candidate.protocol.toLowerCase() : '';
395
+                if ((self.removeTcpCandidates && protocol === 'tcp') ||
396
+                    (self.removeUdpCandidates && protocol === 'udp')) {
397
+                    return;
398
+                }
399
+                elem.c('candidate', candidate).up();
387 400
             });
388 401
         }
389 402
     }
390 403
     elem.up(); // end of transport
391 404
 };
392 405
 
393
-SDP.prototype.RtcpFbToJingle = function (mediaindex, elem, payloadtype) { // XEP-0293
406
+SDP.prototype.rtcpFbToJingle = function (mediaindex, elem, payloadtype) { // XEP-0293
394 407
     var lines = SDPUtil.find_lines(this.media[mediaindex], 'a=rtcp-fb:' + payloadtype);
395 408
     lines.forEach(function (line) {
396 409
         var tmp = SDPUtil.parse_rtcpfb(line);
@@ -407,7 +420,7 @@ SDP.prototype.RtcpFbToJingle = function (mediaindex, elem, payloadtype) { // XEP
407 420
     });
408 421
 };
409 422
 
410
-SDP.prototype.RtcpFbFromJingle = function (elem, payloadtype) { // XEP-0293
423
+SDP.prototype.rtcpFbFromJingle = function (elem, payloadtype) { // XEP-0293
411 424
     var media = '';
412 425
     var tmp = elem.find('>rtcp-fb-trr-int[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
413 426
     if (tmp.length) {
@@ -434,7 +447,7 @@ SDP.prototype.RtcpFbFromJingle = function (elem, payloadtype) { // XEP-0293
434 447
 SDP.prototype.fromJingle = function (jingle) {
435 448
     var self = this;
436 449
     this.raw = 'v=0\r\n' +
437
-        'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
450
+        'o=- 1923518516 2 IN IP4 0.0.0.0\r\n' +// FIXME
438 451
         's=-\r\n' +
439 452
         't=0 0\r\n';
440 453
     // http://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-04#section-8
@@ -490,14 +503,11 @@ SDP.prototype.jingle2media = function (content) {
490 503
     } else {
491 504
         tmp.proto = 'RTP/AVPF';
492 505
     }
493
-    if (!sctp.length)
494
-    {
506
+    if (!sctp.length) {
495 507
         tmp.fmt = desc.find('payload-type').map(
496 508
             function () { return this.getAttribute('id'); }).get();
497 509
         media += SDPUtil.build_mline(tmp) + '\r\n';
498
-    }
499
-    else
500
-    {
510
+    } else {
501 511
         media += 'm=application 1 DTLS/SCTP ' + sctp.attr('number') + '\r\n';
502 512
         media += 'a=sctpmap:' + sctp.attr('number') +
503 513
             ' ' + sctp.attr('protocol');
@@ -568,15 +578,19 @@ SDP.prototype.jingle2media = function (content) {
568 578
         media += SDPUtil.build_rtpmap(this) + '\r\n';
569 579
         if ($(this).find('>parameter').length) {
570 580
             media += 'a=fmtp:' + this.getAttribute('id') + ' ';
571
-            media += $(this).find('parameter').map(function () { return (this.getAttribute('name') ? (this.getAttribute('name') + '=') : '') + this.getAttribute('value'); }).get().join('; ');
581
+            media += $(this).find('parameter').map(function () {
582
+                return (this.getAttribute('name')
583
+                        ? (this.getAttribute('name') + '=') : '') +
584
+                    this.getAttribute('value');
585
+            }).get().join('; ');
572 586
             media += '\r\n';
573 587
         }
574 588
         // xep-0293
575
-        media += self.RtcpFbFromJingle($(this), this.getAttribute('id'));
589
+        media += self.rtcpFbFromJingle($(this), this.getAttribute('id'));
576 590
     });
577 591
 
578 592
     // xep-0293
579
-    media += self.RtcpFbFromJingle(desc, '*');
593
+    media += self.rtcpFbFromJingle(desc, '*');
580 594
 
581 595
     // xep-0294
582 596
     tmp = desc.find('>rtp-hdrext[xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"]');
@@ -585,11 +599,19 @@ SDP.prototype.jingle2media = function (content) {
585 599
     });
586 600
 
587 601
     content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]>candidate').each(function () {
602
+        var protocol = this.getAttribute('protocol');
603
+        protocol = (typeof protocol === 'string') ? protocol.toLowerCase(): '';
604
+
605
+        if ((self.removeTcpCandidates && protocol === 'tcp') ||
606
+            (self.removeUdpCandidates && protocol === 'udp')) {
607
+            return;
608
+        }
609
+
588 610
         media += SDPUtil.candidateFromJingle(this);
589 611
     });
590 612
 
591 613
     // XEP-0339 handle ssrc-group attributes
592
-    tmp = content.find('description>ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
614
+    content.find('description>ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
593 615
         var semantics = this.getAttribute('semantics');
594 616
         var ssrcs = $(this).find('>source').map(function() {
595 617
             return this.getAttribute('ssrc');

Загрузка…
Отмена
Сохранить