Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 58 additions & 29 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var util = require('util');
var intersect = require('intersect');
var WildEmitter = require('wildemitter');
var webrtc = require('webrtcsupport');

Expand All @@ -8,6 +7,12 @@ var MediaSession = require('jingle-media-session');
var FileSession = require('jingle-filetransfer-session');


var defaultDeny = function () {
console.log(arguments);
return false;
};


function SessionManager(conf) {
WildEmitter.call(this);

Expand All @@ -28,6 +33,12 @@ function SessionManager(conf) {
}
};

this.trustInitiator = conf.trustInitiator || defaultDeny;
this.trustResponder = conf.trustResponder || defaultDeny;
this.checkSessionTie = conf.checkSessionTie || defaultDeny;

console.log(conf);

this.screenSharingSupport = webrtc.screenSharing;

this.capabilities = [
Expand Down Expand Up @@ -93,25 +104,33 @@ SessionManager.prototype.addICEServer = function (server) {
this.iceServers.push(server);
};

SessionManager.prototype._addSessionForPeer = function (peerID, session) {
if (!this.peers[peerID]) {
this.peers[peerID] = [];
}

this.peers[peerID].push(session);
};

SessionManager.prototype._removeSessionForPeer = function (peerID, session) {
var peers = this.peers[peerID] || [];
if (peers.length) {
peers.splice(peers.indexOf(session), 1);
}
};

SessionManager.prototype.addSession = function (session) {
var self = this;

var sid = session.sid;
var peer = session.peerID;

this.sessions[sid] = session;
if (!this.peers[peer]) {
this.peers[peer] = [];
}

this.peers[peer].push(session);
this._addSessionForPeer(peer, session);

// Automatically clean up tracked sessions
session.on('terminated', function () {
var peers = self.peers[peer] || [];
if (peers.length) {
peers.splice(peers.indexOf(session), 1);
}
self._removeSessionForPeer(peer, session);
delete self.sessions[sid];
});

Expand Down Expand Up @@ -233,7 +252,11 @@ SessionManager.prototype.process = function (req) {
var sid = !!req.jingle ? req.jingle.sid : null;
var session = this.sessions[sid] || null;
var rid = req.id;
var sender = req.from.full || req.from;
var sender = req.from;
var senderID = sender.full || sender;

var responder = !!req.jingle ? req.jingle.responder : null;
var initiator = !!req.jingle ? req.jingle.initiator : null;


if (req.type === 'error') {
Expand Down Expand Up @@ -313,7 +336,7 @@ SessionManager.prototype.process = function (req) {
}
} else if (session) {
// Don't accept a new session if we already have one.
if (session.peerID !== sender) {
if (session.peerID !== senderID) {
this._log('error', 'Duplicate sid from new sender');
return this._sendError(sender, rid, {
condition: 'service-unavailable'
Expand All @@ -338,24 +361,19 @@ SessionManager.prototype.process = function (req) {
jingleCondition: 'out-of-order'
});
}
} else if (this.peers[sender] && this.peers[sender].length) {
} else if (this.peers[senderID] && this.peers[senderID].length) {
// Check if we need to have a tie breaker because we already have
// a different session with this peer that is using the requested
// content description types.
for (var i = 0, len = this.peers[sender].length; i < len; i++) {
var sess = this.peers[sender][i];
if (sess && sess.pending) {
if (intersect(descriptionTypes, sess.pendingDescriptionTypes).length) {
// We already have a pending session request for this content type.
if (sess.sid > sid) {
// We won the tie breaker
this._log('info', 'Tie break');
return this._sendError(sender, rid, {
condition: 'conflict',
jingleCondition: 'tie-break'
});
}
}
for (var i = 0, len = this.peers[senderID].length; i < len; i++) {
var sess = this.peers[senderID][i];
if (sess && sess.pending && sess.sid > sid && this.checkSessionTie(sess, descriptionTypes, sender)) {
// We won the tie breaker
this._log('info', 'Tie break');
return this._sendError(sender, rid, {
condition: 'conflict',
jingleCondition: 'tie-break'
});
}
}
}
Expand All @@ -369,10 +387,13 @@ SessionManager.prototype.process = function (req) {
});
}

if (!initiator || !this.trustInitiator(sender, initiator)) {
initiator = req.from;
}

session = this._createIncomingSession({
sid: sid,
peer: req.from,
peerID: sender,
peer: initiator,
initiator: false,
parent: this,
descriptionTypes: descriptionTypes,
Expand All @@ -382,6 +403,14 @@ SessionManager.prototype.process = function (req) {
}, req);
}

if (action === 'session-accept' && this.trustResponder(sender, responder)) {
this._removeSessionForPeer(session.peerID, session);

session.changePeer(responder);

this._addSessionForPeer(session.peerID, session);
}

session.process(action, req.jingle, function (err) {
if (err) {
self._log('error', 'Could not process request', req, err);
Expand Down
11 changes: 9 additions & 2 deletions test/tiebreaking.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var test = require('tape');
var intersect = require('intersect');
var SessionManager = require('../');
var GenericSession = require('jingle-session');

Expand All @@ -7,7 +8,10 @@ test('Test tie-break from duplicate sids', function (t) {
t.plan(1);

var jingle = new SessionManager({
jid: 'zuser@example.com'
jid: 'zuser@example.com',
checkSessionTie: function (oldSession, newDescriptionTypes) {
return intersect(oldSession.pendingDescriptionTypes, newDescriptionTypes).length > 0;
}
});

var sess = new GenericSession({
Expand Down Expand Up @@ -55,7 +59,10 @@ test('Test tie-break from existing session', function (t) {
t.plan(1);

var jingle = new SessionManager({
jid: 'zuser@example.com'
jid: 'zuser@example.com',
checkSessionTie: function (oldSession, newDescriptionTypes) {
return intersect(oldSession.pendingDescriptionTypes, newDescriptionTypes).length > 0;
}
});

var sess = new GenericSession({
Expand Down