dispatch iq-result for a jingle iq stanza, start listener after iq-result on session-initiate.

This commit is contained in:
Zhenchao Li 2010-07-03 16:22:47 +08:00
parent 2203755734
commit d0adcb1a05
6 changed files with 80 additions and 7 deletions

View File

@ -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:

View File

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

View File

@ -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):

View File

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

View File

@ -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):
""" """

View File

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