瀏覽代碼

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

of forcing one or the other in automated tests).
dev1
Boris Grozev 10 年之前
父節點
當前提交
09640e23ba
共有 2 個檔案被更改,包括 114 行新增41 行删除
  1. 51
    1
      modules/xmpp/JingleSessionPC.js
  2. 63
    40
      modules/xmpp/SDP.js

+ 51
- 1
modules/xmpp/JingleSessionPC.js 查看文件

@@ -46,6 +46,9 @@ function JingleSessionPC(me, sid, connection, service) {
46 46
     this.ssrcOwners = {};
47 47
     this.ssrcVideoTypes = {};
48 48
 
49
+    this.webrtcIceUdpDisable = !!this.service.options.webrtcIceUdpDisable;
50
+    this.webrtcIceTcpDisable = !!this.service.options.webrtcIceTcpDisable;
51
+
49 52
     /**
50 53
      * The indicator which determines whether the (local) video has been muted
51 54
      * in response to a user command in contrast to an automatic decision made
@@ -58,6 +61,7 @@ function JingleSessionPC(me, sid, connection, service) {
58 61
     // stable and the ice connection state is connected.
59 62
     this.modifySourcesQueue.pause();
60 63
 }
64
+//XXX this is badly broken...
61 65
 JingleSessionPC.prototype = JingleSession.prototype;
62 66
 JingleSessionPC.prototype.constructor = JingleSessionPC;
63 67
 
@@ -97,6 +101,15 @@ JingleSessionPC.prototype.doInitialize = function () {
97 101
             this);
98 102
 
99 103
     this.peerconnection.onicecandidate = function (event) {
104
+        var protocol;
105
+        if (event && event.candidate) {
106
+            protocol = (typeof event.candidate.protocol === 'string')
107
+                ? event.candidate.protocol.toLowerCase() : '';
108
+            if ((self.webrtcIceTcpDisable && protocol == 'tcp') ||
109
+                (self.webrtcIceUdpDisable && protocol == 'udp')) {
110
+                return;
111
+            }
112
+        }
100 113
         self.sendIceCandidate(event.candidate);
101 114
     };
102 115
     this.peerconnection.onaddstream = function (event) {
@@ -227,6 +240,12 @@ JingleSessionPC.prototype.accept = function () {
227 240
         pranswer.sdp = pranswer.sdp.replace('a=inactive', 'a=sendrecv');
228 241
     }
229 242
     var prsdp = new SDP(pranswer.sdp);
243
+    if (self.webrtcIceTcpDisable) {
244
+        prsdp.removeTcpCandidates = true;
245
+    }
246
+    if (self.webrtcIceUdpDisable) {
247
+        prsdp.removeUdpCandidates = true;
248
+    }
230 249
     var accept = $iq({to: this.peerjid,
231 250
         type: 'set'})
232 251
         .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@@ -335,6 +354,12 @@ JingleSessionPC.prototype.sendIceCandidate = function (candidate) {
335 354
                     initiator: this.initiator,
336 355
                     sid: this.sid});
337 356
             this.localSDP = new SDP(this.peerconnection.localDescription.sdp);
357
+            if (self.webrtcIceTcpDisable) {
358
+                this.localSDP.removeTcpCandidates = true;
359
+            }
360
+            if (self.webrtcIceUdpDisable) {
361
+                this.localSDP.removeUdpCandidates = true;
362
+            }
338 363
             var sendJingle = function (ssrc) {
339 364
                 if(!ssrc)
340 365
                     ssrc = {};
@@ -533,6 +558,13 @@ JingleSessionPC.prototype.getSsrcOwner = function (ssrc) {
533 558
 JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
534 559
     //logger.log('setting remote description... ', desctype);
535 560
     this.remoteSDP = new SDP('');
561
+    if (self.webrtcIceTcpDisable) {
562
+        this.remoteSDP.removeTcpCandidates = true;
563
+    }
564
+    if (self.webrtcIceUdpDisable) {
565
+        this.remoteSDP.removeUdpCandidates = true;
566
+    }
567
+
536 568
     this.remoteSDP.fromJingle(elem);
537 569
     this.readSsrcInfo($(elem).find(">content"));
538 570
     if (this.peerconnection.remoteDescription) {
@@ -575,6 +607,10 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
575 607
     );
576 608
 };
577 609
 
610
+/**
611
+ * Adds remote ICE candidates to this Jingle session.
612
+ * @param elem An array of Jingle "content" elements?
613
+ */
578 614
 JingleSessionPC.prototype.addIceCandidate = function (elem) {
579 615
     var self = this;
580 616
     if (this.peerconnection.signalingState == 'closed') {
@@ -585,7 +621,7 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) {
585 621
         // create a PRANSWER for setRemoteDescription
586 622
         if (!this.remoteSDP) {
587 623
             var cobbled = 'v=0\r\n' +
588
-                'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
624
+                'o=- 1923518516 2 IN IP4 0.0.0.0\r\n' +// FIXME
589 625
                 's=-\r\n' +
590 626
                 't=0 0\r\n';
591 627
             // first, take some things from the local description
@@ -670,6 +706,14 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) {
670 706
         // TODO: check ice-pwd and ice-ufrag?
671 707
         $(this).find('transport>candidate').each(function () {
672 708
             var line, candidate;
709
+            var protocol = this.getAttribute('protocol');
710
+            protocol =
711
+                (typeof protocol === 'string') ? protocol.toLowerCase() : '';
712
+            if ((self.webrtcIceTcpDisable && protocol == 'tcp') ||
713
+                (self.webrtcIceUdpDisable && protocol == 'udp')) {
714
+                return;
715
+            }
716
+
673 717
             line = SDPUtil.candidateFromJingle(this);
674 718
             candidate = new RTCIceCandidate({sdpMLineIndex: idx,
675 719
                 sdpMid: name,
@@ -723,6 +767,12 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, provisional) {
723 767
                         initiator: self.initiator,
724 768
                         responder: self.responder,
725 769
                         sid: self.sid });
770
+                if (self.webrtcIceTcpDisable) {
771
+                    self.localSDP.removeTcpCandidates = true;
772
+                }
773
+                if (self.webrtcIceUdpDisable) {
774
+                    self.localSDP.removeUdpCandidates = true;
775
+                }
726 776
                 self.localSDP.toJingle(
727 777
                     accept,
728 778
                     self.initiator == self.me ? 'initiator' : 'responder',

+ 63
- 40
modules/xmpp/SDP.js 查看文件

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

Loading…
取消
儲存