dispatch iq-result for a jingle iq stanza, start listener after iq-result on session-initiate.
This commit is contained in:
parent
2203755734
commit
d0adcb1a05
|
@ -84,16 +84,26 @@ class ConnectionJingle(object):
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
jingle = stanza.getTag('jingle')
|
jingle = stanza.getTag('jingle')
|
||||||
if not jingle: return
|
# a jingle element is not necessary in iq-result stanza
|
||||||
|
# don't check for that
|
||||||
|
if jingle:
|
||||||
sid = jingle.getAttr('sid')
|
sid = jingle.getAttr('sid')
|
||||||
|
else:
|
||||||
|
sid = None
|
||||||
|
for sesn in self.__sessions.values():
|
||||||
|
if id in sesn.iq_ids:
|
||||||
|
sesn.on_stanza(stanza)
|
||||||
|
return
|
||||||
|
|
||||||
# do we need to create a new jingle object
|
# do we need to create a new jingle object
|
||||||
if sid not in self.__sessions:
|
if sid not in self.__sessions:
|
||||||
#TODO: tie-breaking and other things...
|
#TODO: tie-breaking and other things...
|
||||||
newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid)
|
newjingle = JingleSession(con=self, weinitiate=False, jid=jid,
|
||||||
|
iq_id = id, sid=sid)
|
||||||
self.__sessions[sid] = newjingle
|
self.__sessions[sid] = newjingle
|
||||||
|
|
||||||
# we already have such session in dispatcher...
|
# we already have such session in dispatcher...
|
||||||
|
self.__sessions[sid].collect_iq_id(id)
|
||||||
self.__sessions[sid].on_stanza(stanza)
|
self.__sessions[sid].on_stanza(stanza)
|
||||||
# Delete invalid/unneeded sessions
|
# Delete invalid/unneeded sessions
|
||||||
if sid in self.__sessions and self.__sessions[sid].state == JingleStates.ended:
|
if sid in self.__sessions and self.__sessions[sid].state == JingleStates.ended:
|
||||||
|
|
|
@ -23,6 +23,8 @@ import gajim
|
||||||
import xmpp
|
import xmpp
|
||||||
from jingle_content import contents, JingleContent
|
from jingle_content import contents, JingleContent
|
||||||
from jingle_transport import JingleTransportICEUDP, JingleTransportSocks5
|
from jingle_transport import JingleTransportICEUDP, JingleTransportSocks5
|
||||||
|
from common import helpers
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
log = logging.getLogger('gajim.c.jingle_ft')
|
log = logging.getLogger('gajim.c.jingle_ft')
|
||||||
|
@ -42,6 +44,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
self.callbacks['transport-replace'] += [self.__on_transport_replace] #fallback transport method
|
self.callbacks['transport-replace'] += [self.__on_transport_replace] #fallback transport method
|
||||||
self.callbacks['transport-reject'] += [self.__on_transport_reject]
|
self.callbacks['transport-reject'] += [self.__on_transport_reject]
|
||||||
self.callbacks['transport-info'] += [self.__on_transport_info]
|
self.callbacks['transport-info'] += [self.__on_transport_info]
|
||||||
|
self.callbacks['iq-result'] += [self.__on_iq_result]
|
||||||
|
|
||||||
self.file_props = file_props
|
self.file_props = file_props
|
||||||
if file_props is None:
|
if file_props is None:
|
||||||
|
@ -51,6 +54,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
|
|
||||||
if self.file_props is not None:
|
if self.file_props is not None:
|
||||||
self.file_props['sender'] = session.ourjid
|
self.file_props['sender'] = session.ourjid
|
||||||
|
self.file_props['receiver'] = session.peerjid
|
||||||
self.file_props['session-type'] = 'jingle'
|
self.file_props['session-type'] = 'jingle'
|
||||||
self.file_props['sid'] = session.sid
|
self.file_props['sid'] = session.sid
|
||||||
self.file_props['transfered_size'] = []
|
self.file_props['transfered_size'] = []
|
||||||
|
@ -130,6 +134,25 @@ class JingleFileTransfer(JingleContent):
|
||||||
def __on_transport_info(self, stanza, content, error, action):
|
def __on_transport_info(self, stanza, content, error, action):
|
||||||
log.info("__on_transport_info")
|
log.info("__on_transport_info")
|
||||||
|
|
||||||
|
def __on_iq_result(self, stanza, content, error, action):
|
||||||
|
log.info("__on_iq_result")
|
||||||
|
|
||||||
|
if self.weinitiate:
|
||||||
|
receiver = self.file_props['receiver']
|
||||||
|
sender = self.file_props['sender']
|
||||||
|
|
||||||
|
sha_str = helpers.get_auth_sha(self.file_props['sid'], sender, receiver)
|
||||||
|
self.file_props['sha_str'] = sha_str
|
||||||
|
|
||||||
|
port = gajim.config.get('file_transfers_port')
|
||||||
|
|
||||||
|
listener = gajim.socks5queue.start_listener(port, sha_str,
|
||||||
|
self._store_socks5_sid, self.file_props['sid'])
|
||||||
|
|
||||||
|
if not listener:
|
||||||
|
return
|
||||||
|
# send error message, notify the user
|
||||||
|
|
||||||
def _fill_content(self, content):
|
def _fill_content(self, content):
|
||||||
description_node = xmpp.simplexml.Node(tag=xmpp.NS_JINGLE_FILE_TRANSFER + ' description')
|
description_node = xmpp.simplexml.Node(tag=xmpp.NS_JINGLE_FILE_TRANSFER + ' description')
|
||||||
|
|
||||||
|
@ -145,6 +168,11 @@ class JingleFileTransfer(JingleContent):
|
||||||
|
|
||||||
content.addChild(node=description_node)
|
content.addChild(node=description_node)
|
||||||
|
|
||||||
|
def _store_socks5_sid(self, sid, hash_id):
|
||||||
|
# callback from socsk5queue.start_listener
|
||||||
|
self.file_props['hash'] = hash_id
|
||||||
|
return
|
||||||
|
|
||||||
def get_content(desc):
|
def get_content(desc):
|
||||||
return JingleFileTransfer
|
return JingleFileTransfer
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ import gajim #Get rid of that?
|
||||||
import xmpp
|
import xmpp
|
||||||
from jingle_transport import get_jingle_transport
|
from jingle_transport import get_jingle_transport
|
||||||
from jingle_content import get_jingle_content, JingleContentSetupException
|
from jingle_content import get_jingle_content, JingleContentSetupException
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger("gajim.c.jingle_session")
|
||||||
|
|
||||||
# FIXME: Move it to JingleSession.States?
|
# FIXME: Move it to JingleSession.States?
|
||||||
class JingleStates(object):
|
class JingleStates(object):
|
||||||
|
@ -58,7 +60,7 @@ class JingleSession(object):
|
||||||
negotiated between an initiator and a responder.
|
negotiated between an initiator and a responder.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, con, weinitiate, jid, sid=None):
|
def __init__(self, con, weinitiate, jid, iq_id = None, sid=None):
|
||||||
"""
|
"""
|
||||||
con -- connection object,
|
con -- connection object,
|
||||||
weinitiate -- boolean, are we the initiator?
|
weinitiate -- boolean, are we the initiator?
|
||||||
|
@ -84,6 +86,14 @@ class JingleSession(object):
|
||||||
sid = con.connection.getAnID()
|
sid = con.connection.getAnID()
|
||||||
self.sid = sid # sessionid
|
self.sid = sid # sessionid
|
||||||
|
|
||||||
|
# iq stanza id, used to determine which sessions to summon callback
|
||||||
|
# later on when iq-result stanza arrives
|
||||||
|
if iq_id is not None:
|
||||||
|
self.iq_ids = [iq_id]
|
||||||
|
else:
|
||||||
|
self.iq_ids = []
|
||||||
|
|
||||||
|
|
||||||
self.accepted = True # is this session accepted by user
|
self.accepted = True # is this session accepted by user
|
||||||
|
|
||||||
# callbacks to call on proper contents
|
# callbacks to call on proper contents
|
||||||
|
@ -110,10 +120,14 @@ class JingleSession(object):
|
||||||
'transport-replace': [self.__broadcast, self.__on_transport_replace], #TODO
|
'transport-replace': [self.__broadcast, self.__on_transport_replace], #TODO
|
||||||
'transport-accept': [self.__ack], #TODO
|
'transport-accept': [self.__ack], #TODO
|
||||||
'transport-reject': [self.__ack], #TODO
|
'transport-reject': [self.__ack], #TODO
|
||||||
'iq-result': [],
|
'iq-result': [self.__broadcast],
|
||||||
'iq-error': [self.__on_error],
|
'iq-error': [self.__on_error],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def collect_iq_id(self, iq_id):
|
||||||
|
if iq_id is not None:
|
||||||
|
self.iq_ids.append(iq_id)
|
||||||
|
|
||||||
def approve_session(self):
|
def approve_session(self):
|
||||||
"""
|
"""
|
||||||
Called when user accepts session in UI (when we aren't the initiator)
|
Called when user accepts session in UI (when we aren't the initiator)
|
||||||
|
@ -463,6 +477,17 @@ class JingleSession(object):
|
||||||
"""
|
"""
|
||||||
Broadcast the stanza contents to proper content handlers
|
Broadcast the stanza contents to proper content handlers
|
||||||
"""
|
"""
|
||||||
|
#if jingle is None: # it is a iq-result stanza
|
||||||
|
# for cn in self.contents.values():
|
||||||
|
# cn.on_stanza(stanza, None, error, action)
|
||||||
|
# return
|
||||||
|
|
||||||
|
# special case: iq-result stanza does not come with a jingle element
|
||||||
|
if action == 'iq-result':
|
||||||
|
for cn in self.contents.values():
|
||||||
|
cn.on_stanza(stanza, None, error, action)
|
||||||
|
return
|
||||||
|
|
||||||
for content in jingle.iterTags('content'):
|
for content in jingle.iterTags('content'):
|
||||||
name = content['name']
|
name = content['name']
|
||||||
creator = content['creator']
|
creator = content['creator']
|
||||||
|
@ -606,6 +631,7 @@ class JingleSession(object):
|
||||||
self.__append_contents(jingle)
|
self.__append_contents(jingle)
|
||||||
self.__broadcast(stanza, jingle, None, 'session-initiate-sent')
|
self.__broadcast(stanza, jingle, None, 'session-initiate-sent')
|
||||||
self.connection.connection.send(stanza)
|
self.connection.connection.send(stanza)
|
||||||
|
self.collect_iq_id(stanza.getID())
|
||||||
self.state = JingleStates.pending
|
self.state = JingleStates.pending
|
||||||
|
|
||||||
def __session_accept(self):
|
def __session_accept(self):
|
||||||
|
@ -614,6 +640,7 @@ class JingleSession(object):
|
||||||
self.__append_contents(jingle)
|
self.__append_contents(jingle)
|
||||||
self.__broadcast(stanza, jingle, None, 'session-accept-sent')
|
self.__broadcast(stanza, jingle, None, 'session-accept-sent')
|
||||||
self.connection.connection.send(stanza)
|
self.connection.connection.send(stanza)
|
||||||
|
self.collect_iq_id(stanza.getID())
|
||||||
self.state = JingleStates.active
|
self.state = JingleStates.active
|
||||||
|
|
||||||
def __session_info(self, payload=None):
|
def __session_info(self, payload=None):
|
||||||
|
|
|
@ -147,7 +147,8 @@ class ConnectionBytestream:
|
||||||
if not gajim.socks5queue.get_file_props(session.ourjid, sid):
|
if not gajim.socks5queue.get_file_props(session.ourjid, sid):
|
||||||
gajim.socks5queue.add_file_props(session.ourjid, file_props)
|
gajim.socks5queue.add_file_props(session.ourjid, file_props)
|
||||||
gajim.socks5queue.connect_to_hosts(session.ourjid, sid,
|
gajim.socks5queue.connect_to_hosts(session.ourjid, sid,
|
||||||
None, None)
|
lambda streamhost: log.info("connected to" + str(streamhost)),
|
||||||
|
lambda a, b, c, d: log.info("connect error!" + a + b + c + d))
|
||||||
return
|
return
|
||||||
|
|
||||||
iq = xmpp.Iq(to=unicode(file_props['sender']), typ='result')
|
iq = xmpp.Iq(to=unicode(file_props['sender']), typ='result')
|
||||||
|
|
|
@ -35,6 +35,10 @@ from errno import EISCONN
|
||||||
from errno import EINPROGRESS
|
from errno import EINPROGRESS
|
||||||
from errno import EAFNOSUPPORT
|
from errno import EAFNOSUPPORT
|
||||||
from xmpp.idlequeue import IdleObject
|
from xmpp.idlequeue import IdleObject
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger('gajim.c.socks5')
|
||||||
|
|
||||||
MAX_BUFF_LEN = 65536
|
MAX_BUFF_LEN = 65536
|
||||||
|
|
||||||
# after foo seconds without activity label transfer as 'stalled'
|
# after foo seconds without activity label transfer as 'stalled'
|
||||||
|
@ -257,6 +261,7 @@ class SocksQueue:
|
||||||
|
|
||||||
def send_file(self, file_props, account):
|
def send_file(self, file_props, account):
|
||||||
if 'hash' in file_props and file_props['hash'] in self.senders:
|
if 'hash' in file_props and file_props['hash'] in self.senders:
|
||||||
|
log.info("socks5: sending file")
|
||||||
sender = self.senders[file_props['hash']]
|
sender = self.senders[file_props['hash']]
|
||||||
file_props['streamhost-used'] = True
|
file_props['streamhost-used'] = True
|
||||||
sender.account = account
|
sender.account = account
|
||||||
|
@ -269,6 +274,8 @@ class SocksQueue:
|
||||||
file_props['last-time'] = self.idlequeue.current_time()
|
file_props['last-time'] = self.idlequeue.current_time()
|
||||||
file_props['received-len'] = 0
|
file_props['received-len'] = 0
|
||||||
sender.file_props = file_props
|
sender.file_props = file_props
|
||||||
|
else:
|
||||||
|
log.info("socks5: NOT sending file")
|
||||||
|
|
||||||
def add_file_props(self, account, file_props):
|
def add_file_props(self, account, file_props):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -37,7 +37,7 @@ from hashlib import sha256
|
||||||
from hmac import HMAC
|
from hmac import HMAC
|
||||||
from common import crypto
|
from common import crypto
|
||||||
|
|
||||||
if gajim.HAVE_PYCRYPTO:
|
if gajim.HAVE_PYCRYPTO and False:
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue