Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0260.py @ 1758:a66d34353f34
plugin XEP-0260, XEP-0065: fixed session hash handling:
with XEP-0260, we need to manage 2 hashes (one with SHA1(SID + Initiator JID + Responder JID) and the other with SHA1(SID + Responder JID + Initiator JID)). This was not handled correclty, resulting in transfer failure in several cases.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 17 Dec 2015 22:37:59 +0100 |
parents | abd6d6f89006 |
children | d17772b0fe22 |
comparison
equal
deleted
inserted
replaced
1757:abd6d6f89006 | 1758:a66d34353f34 |
---|---|
130 client = self.host.getClient(profile) | 130 client = self.host.getClient(profile) |
131 content_data = session['contents'][content_name] | 131 content_data = session['contents'][content_name] |
132 transport_data = content_data['transport_data'] | 132 transport_data = content_data['transport_data'] |
133 sid = transport_data['sid'] = unicode(uuid.uuid4()) | 133 sid = transport_data['sid'] = unicode(uuid.uuid4()) |
134 session_hash = transport_data['session_hash'] = self._s5b.getSessionHash(client.jid, session['peer_jid'], sid) | 134 session_hash = transport_data['session_hash'] = self._s5b.getSessionHash(client.jid, session['peer_jid'], sid) |
135 transport_data['peer_session_hash'] = self._s5b.getSessionHash(session['peer_jid'], client.jid, sid) # requester and target are inversed for peer candidates | |
135 transport_data['stream_d'] = self._s5b.registerHash(session_hash, None, profile) | 136 transport_data['stream_d'] = self._s5b.registerHash(session_hash, None, profile) |
136 candidates = transport_data['candidates'] = yield self._s5b.getCandidates(profile) | 137 candidates = transport_data['candidates'] = yield self._s5b.getCandidates(profile) |
137 mode = 'tcp' # XXX: we only manage tcp for now | 138 mode = 'tcp' # XXX: we only manage tcp for now |
138 transport_elt = self._buildCandidates(session, candidates, sid, session_hash, client, mode) | 139 transport_elt = self._buildCandidates(session, candidates, sid, session_hash, client, mode) |
139 | 140 |
219 if best_candidate is None or peer_best_candidate is None: | 220 if best_candidate is None or peer_best_candidate is None: |
220 choosed_candidate = best_candidate or peer_best_candidate | 221 choosed_candidate = best_candidate or peer_best_candidate |
221 else: | 222 else: |
222 if best_candidate.priority == peer_best_candidate.priority: | 223 if best_candidate.priority == peer_best_candidate.priority: |
223 # same priority, we choose initiator one according to XEP-0260 §2.4 #4 | 224 # same priority, we choose initiator one according to XEP-0260 §2.4 #4 |
224 log.debug(u"Candidates have same priority, we choose the initiator one") | 225 log.debug(u"Candidates have same priority, we select the one choosed by initiator") |
225 if session['initiator'] == client.jid: | 226 if session['initiator'] == client.jid: |
226 choosed_candidate = best_candidate | 227 choosed_candidate = best_candidate |
227 else: | 228 else: |
228 choosed_candidate = peer_best_candidate | 229 choosed_candidate = peer_best_candidate |
229 else: | 230 else: |
351 elif action == self._j.A_SESSION_ACCEPT: | 352 elif action == self._j.A_SESSION_ACCEPT: |
352 # initiator side, we select a candidate in the ones sent by responder | 353 # initiator side, we select a candidate in the ones sent by responder |
353 assert 'peer_candidates' not in transport_data | 354 assert 'peer_candidates' not in transport_data |
354 transport_data['peer_candidates'] = self._parseCandidates(transport_elt) | 355 transport_data['peer_candidates'] = self._parseCandidates(transport_elt) |
355 | 356 |
356 # elif action == self._j.A_START: | |
357 elif action == self._j.A_START: | 357 elif action == self._j.A_START: |
358 session_hash = transport_data['session_hash'] | 358 session_hash = transport_data['session_hash'] |
359 peer_candidates = transport_data['peer_candidates'] | 359 peer_candidates = transport_data['peer_candidates'] |
360 file_obj = content_data['file_obj'] | 360 file_obj = content_data['file_obj'] |
361 self._s5b.associateFileObj(session_hash, file_obj, profile) | 361 self._s5b.associateFileObj(session_hash, file_obj, profile) |
362 stream_d = transport_data.pop('stream_d') | 362 stream_d = transport_data.pop('stream_d') |
363 stream_d.chainDeferred(content_data['finished_d']) | 363 stream_d.chainDeferred(content_data['finished_d']) |
364 d = self._s5b.getBestCandidate(peer_candidates, session_hash, profile) | 364 peer_session_hash = transport_data['peer_session_hash'] |
365 d = self._s5b.getBestCandidate(peer_candidates, session_hash, peer_session_hash, profile) | |
365 d.addCallback(self._foundPeerCandidate, session, transport_data, content_name, client) | 366 d.addCallback(self._foundPeerCandidate, session, transport_data, content_name, client) |
366 | 367 |
367 elif action == self._j.A_SESSION_INITIATE: | 368 elif action == self._j.A_SESSION_INITIATE: |
368 # responder side, we select a candidate in the ones sent by initiator | 369 # responder side, we select a candidate in the ones sent by initiator |
369 # and we give our candidates | 370 # and we give our candidates |
370 assert 'peer_candidates' not in transport_data | 371 assert 'peer_candidates' not in transport_data |
371 sid = transport_data['sid'] = transport_elt['sid'] | 372 sid = transport_data['sid'] = transport_elt['sid'] |
372 session_hash = transport_data['session_hash'] = self._s5b.getSessionHash(session['peer_jid'], client.jid, sid) | 373 session_hash = transport_data['session_hash'] = self._s5b.getSessionHash(client.jid, session['peer_jid'], sid) |
374 peer_session_hash = transport_data['peer_session_hash'] = self._s5b.getSessionHash(session['peer_jid'], client.jid, sid) # requester and target are inversed for peer candidates | |
373 peer_candidates = transport_data['peer_candidates'] = self._parseCandidates(transport_elt) | 375 peer_candidates = transport_data['peer_candidates'] = self._parseCandidates(transport_elt) |
374 file_obj = content_data['file_obj'] | 376 file_obj = content_data['file_obj'] |
375 stream_d = self._s5b.registerHash(session_hash, file_obj, profile) | 377 stream_d = self._s5b.registerHash(session_hash, file_obj, profile) |
376 stream_d.chainDeferred(content_data['finished_d']) | 378 stream_d.chainDeferred(content_data['finished_d']) |
377 d = self._s5b.getBestCandidate(peer_candidates, session_hash, profile) | 379 d = self._s5b.getBestCandidate(peer_candidates, session_hash, peer_session_hash, profile) |
378 d.addCallback(self._foundPeerCandidate, session, transport_data, content_name, client) | 380 d.addCallback(self._foundPeerCandidate, session, transport_data, content_name, client) |
379 candidates = yield self._s5b.getCandidates(profile) | 381 candidates = yield self._s5b.getCandidates(profile) |
380 # we remove duplicate candidates | 382 # we remove duplicate candidates |
381 candidates = [candidate for candidate in candidates if candidate not in peer_candidates] | 383 candidates = [candidate for candidate in candidates if candidate not in peer_candidates] |
382 | 384 |
400 break | 402 break |
401 | 403 |
402 if candidate_elt is None: | 404 if candidate_elt is None: |
403 log.warning(u"Unexpected transport element: {}".format(transport_elt.toXml())) | 405 log.warning(u"Unexpected transport element: {}".format(transport_elt.toXml())) |
404 elif action == self._j.A_DESTROY: | 406 elif action == self._j.A_DESTROY: |
405 # the transport is remplaced (fallback ?). We need mainly to stop kill XEP-0065 session | 407 # the transport is replaced (fallback ?), We need mainly to kill XEP-0065 session. |
406 # note that sid argument is not necessary for sessions created by this plugin | 408 # note that sid argument is not necessary for sessions created by this plugin |
407 self._s5b.killSession(None, transport_data['session_hash'], None, client) | 409 self._s5b.killSession(None, transport_data['session_hash'], None, client) |
408 else: | 410 else: |
409 log.warning(u"FIXME: unmanaged action {}".format(action)) | 411 log.warning(u"FIXME: unmanaged action {}".format(action)) |
410 | 412 |