Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix negotiations by better protecting access to PeerConnection #1371

Merged
merged 5 commits into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion erizo_controller/erizoClient/src/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {
if (stream && stream.pc && !stream.failed) {
stream.pc.processSignalingMessage(arg.mess);
} else {
Logger.error(`Failed appyling a signaling message in ${stream.getID()}`);
Logger.error(`Failed applying a signaling message in ${stream.getID()}`, arg.mess);
}
};

Expand Down
3 changes: 2 additions & 1 deletion erizo_controller/erizoClient/src/webrtc-stacks/BaseStack.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ const BaseStack = (specInput) => {
});

// We need to protect it against calling multiple times to createOffer.
// Otherwise it could change the ICE credentials before calling setLocalDescription the first time in Chrome.
// Otherwise it could change the ICE credentials before calling setLocalDescription
// the first time in Chrome.
that.createOffer = firstOfferQueue.protectFunction((isSubscribe = false, forceOfferToReceive = false, streamId = '') => {
if (!firstOfferCreated) {
firstOfferQueue.startEnqueuing();
Expand Down
40 changes: 24 additions & 16 deletions erizo_controller/erizoJS/erizoJSController.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,23 @@ exports.ErizoJSController = (threadPool, ioThreadPool) => {
const connection = node.connection;
log.debug(`message: closeNode, clientId: ${node.clientId}, streamId: ${node.streamId}`);

node.close();

const client = clients.get(clientId);
if (client === undefined) {
log.debug('message: trying to close node with no associated client,' +
`clientId: ${clientId}, streamId: ${node.streamId}`);
return;
}
return new Promise((resolve) => {
const client = clients.get(clientId);
if (client === undefined) {
log.debug('message: trying to close node with no associated client,' +
`clientId: ${clientId}, streamId: ${node.streamId}`);
return;
lodoyun marked this conversation as resolved.
Show resolved Hide resolved
}

const remainingConnections = client.maybeCloseConnection(connection.id);
if (remainingConnections === 0) {
log.debug(`message: Removing empty client from list, clientId: ${client.id}`);
clients.delete(client.id);
}
const remainingConnections = client.maybeCloseConnection(connection.id);
if (remainingConnections === 0) {
log.debug(`message: Removing empty client from list, clientId: ${client.id}`);
clients.delete(client.id);
}
node.close().then(() => {
lodoyun marked this conversation as resolved.
Show resolved Hide resolved
resolve();
});
});
};

that.rovMessage = (args, callback) => {
Expand Down Expand Up @@ -307,10 +310,15 @@ exports.ErizoJSController = (threadPool, ioThreadPool) => {
const subscriber = publisher.getSubscriber(clientId);
log.info(`message: removing subscriber, streamId: ${subscriber.streamId}, ` +
`clientId: ${clientId}`);
closeNode(subscriber);
publisher.removeSubscriber(clientId);
closeNode(subscriber).then(() => {
log.info(`message: subscriber node Closed, streamId: ${subscriber.streamId}`);
publisher.removeSubscriber(clientId);
callback('callback', true);
});
} else {
log.warn(`message: removeSubscriber no publisher has this subscriber, clientId: ${clientId}, streamId: ${streamId}`);
callback('callback', true);
}
callback('callback', true);
};

/*
Expand Down
36 changes: 28 additions & 8 deletions erizo_controller/erizoJS/models/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const CONN_SDP_PROCESSED = 203;
const CONN_FAILED = 500;
const WARN_BAD_CONNECTION = 502;

const RESEND_LAST_ANSWER_RETRY_TIMEOUT = 50;

class Connection extends events.EventEmitter {
constructor(id, threadPool, ioThreadPool, options = {}) {
super();
Expand Down Expand Up @@ -120,19 +122,34 @@ class Connection extends events.EventEmitter {
this.emit('status_event', info, evt, streamId);
}

_retryWithPromise(fn, timeout) {
lodoyun marked this conversation as resolved.
Show resolved Hide resolved
lodoyun marked this conversation as resolved.
Show resolved Hide resolved
return new Promise((resolve, reject) => {
fn().then(resolve)
.catch((error) => {
if (error === 'retry') {
setTimeout(() => {
this._retryWithPromise(fn, timeout).then(resolve, reject);
}, timeout);
} else {
// For now we're resolving the promise instead of rejecting it since
// we don't handle this error at the moment
resolve();
}
});
});
}

_resendLastAnswer(evt, streamId, label, forceOffer = false, removeStream = false) {
if (!this.wrtc || !this.wrtc.localDescription) {
return;
log.error('message: _resendLastAnswer, this.wrtc or this.wrtc.localDescription are not present');
return Promise.reject('fail');
}
this.wrtc.localDescription = new SessionDescription(this.wrtc.getLocalDescription());
const sdp = this.wrtc.localDescription.getSdp(this.sessionVersion);
const stream = sdp.getStream(label);
if (stream && removeStream) {
log.info(`resendLastAnswer: StreamId ${streamId} is stream and removeStream, label ${label}, sessionVersion ${this.sessionVersion}`);
setTimeout(() => {
this._resendLastAnswer(evt, streamId, label, forceOffer, removeStream);
}, 50);
return;
return Promise.reject('retry');
}
this.sessionVersion += 1;
let message = sdp.toString();
Expand All @@ -141,6 +158,7 @@ class Connection extends events.EventEmitter {
const info = { type: this.options.createOffer || forceOffer ? 'offer' : 'answer', sdp: message };
log.debug(`message: _resendLastAnswer sending event, type: ${info.type}, streamId: ${streamId}`);
this.emit('status_event', info, evt, streamId);
return Promise.resolve();
}

init(newStreamId) {
Expand Down Expand Up @@ -223,10 +241,12 @@ class Connection extends events.EventEmitter {
this.wrtc.removeMediaStream(id);
this.mediaStreams.get(id).close();
this.mediaStreams.delete(id);
this._resendLastAnswer(CONN_SDP, id, label, true, true);
} else {
log.error(`message: Trying to remove mediaStream not found, id: ${id}`);
return this._retryWithPromise(
this._resendLastAnswer.bind(this, CONN_SDP, id, label, true, true),
RESEND_LAST_ANSWER_RETRY_TIMEOUT);
}
log.error(`message: Trying to remove mediaStream not found, id: ${id}`);
return Promise.resolve();
}

setRemoteDescription(sdp, streamId) {
Expand Down
4 changes: 3 additions & 1 deletion erizo_controller/erizoJS/models/Publisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ class Source extends NodeClass {

// eslint-disable-next-line class-methods-use-this
close() {
return Promise.resolve();
}
}

Expand Down Expand Up @@ -443,7 +444,6 @@ class Publisher extends Source {
}

close() {
this.connection.removeMediaStream(this.mediaStream.id);
this.connection.removeListener('status_event', this._connectionListener);
if (this.mediaStream.monitorInterval) {
clearInterval(this.mediaStream.monitorInterval);
Expand All @@ -453,6 +453,7 @@ class Publisher extends Source {
clearInterval(this.mediaStream.periodicPlis);
this.mediaStream.periodicPlis = undefined;
}
return this.connection.removeMediaStream(this.mediaStream.id);
lodoyun marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -483,6 +484,7 @@ class ExternalInput extends Source {
}
// eslint-disable-next-line class-methods-use-this
close() {
return Promise.resolve();
}
}

Expand Down
25 changes: 15 additions & 10 deletions erizo_controller/erizoJS/models/Subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,21 @@ class Subscriber extends NodeClass {
}

close() {
log.debug(`msg: Closing subscriber, streamId:${this.streamId}`);
this.publisher = undefined;
if (this.connection) {
this.connection.removeMediaStream(this.mediaStream.id);
this.connection.removeListener('status_event', this._connectionListener);
this.connection.removeListener('media_stream_event', this._mediaStreamListener);
}
if (this.mediaStream && this.mediaStream.monitorInterval) {
clearInterval(this.mediaStream.monitorInterval);
}
return new Promise((resolve) => {
log.debug(`msg: Closing subscriber, streamId:${this.streamId}`);
this.publisher = undefined;
if (this.mediaStream && this.mediaStream.monitorInterval) {
clearInterval(this.mediaStream.monitorInterval);
}
if (this.connection) {
this.connection.removeMediaStream(this.mediaStream.id).then(() => {
this.connection.removeListener('status_event', this._connectionListener);
this.connection.removeListener('media_stream_event', this._mediaStreamListener);
resolve();
});
}
resolve();
jcague marked this conversation as resolved.
Show resolved Hide resolved
});
}
}

Expand Down