Quellcode durchsuchen

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

of forcing one or the other in automated tests).
tags/v0.0.2
Boris Grozev vor 10 Jahren
Ursprung
Commit
09640e23ba
2 geänderte Dateien mit 114 neuen und 41 gelöschten Zeilen
  1. 51
    1
      modules/xmpp/JingleSessionPC.js
  2. 63
    40
      modules/xmpp/SDP.js

+ 51
- 1
modules/xmpp/JingleSessionPC.js Datei anzeigen

@@ -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 Datei anzeigen

@@ -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');

Laden…
Abbrechen
Speichern