JingleFT IBB fallback
This commit is contained in:
parent
dc3b203168
commit
a8fe25aaa4
|
@ -16,6 +16,7 @@ Handles Jingle contents (XEP 0166)
|
|||
"""
|
||||
|
||||
import xmpp
|
||||
from jingle_transport import JingleTransportIBB
|
||||
|
||||
contents = {}
|
||||
|
||||
|
@ -69,7 +70,7 @@ class JingleContent(object):
|
|||
'session-initiate': [self.__on_transport_info],
|
||||
'session-terminate': [],
|
||||
'transport-info': [self.__on_transport_info],
|
||||
'transport-replace': [],
|
||||
'transport-replace': [self.__on_transport_replace],
|
||||
'transport-accept': [],
|
||||
'transport-reject': [],
|
||||
'iq-result': [],
|
||||
|
@ -109,6 +110,10 @@ class JingleContent(object):
|
|||
for callback in self.callbacks[action]:
|
||||
callback(stanza, content, error, action)
|
||||
|
||||
def __on_transport_replace(self, stanza, content, error, action):
|
||||
|
||||
content.addChild(node=self.transport.make_transport())
|
||||
|
||||
def __on_transport_info(self, stanza, content, error, action):
|
||||
"""
|
||||
Got a new transport candidate
|
||||
|
|
|
@ -23,6 +23,8 @@ import gajim
|
|||
import xmpp
|
||||
from jingle_content import contents, JingleContent
|
||||
from jingle_transport import JingleTransportICEUDP, JingleTransportSocks5
|
||||
from jingle_transport import JingleTransportIBB
|
||||
from jingle_session import JingleStates
|
||||
from common import helpers
|
||||
from common.socks5 import Socks5Receiver
|
||||
from common.connection_handlers_events import FileRequestReceivedEvent
|
||||
|
@ -35,6 +37,7 @@ STATE_INITIALIZED = 1
|
|||
STATE_ACCEPTED = 2
|
||||
STATE_TRANSPORT_INFO = 3
|
||||
STATE_PROXY_ACTIVATED = 4
|
||||
STATE_TRANSPORT_REPLACE = 5
|
||||
|
||||
class JingleFileTransfer(JingleContent):
|
||||
def __init__(self, session, transport=None, file_props=None,
|
||||
|
@ -98,6 +101,19 @@ class JingleFileTransfer(JingleContent):
|
|||
security = content.getTag('security')
|
||||
if not security: # responder can not verify our fingerprint
|
||||
self.use_security = False
|
||||
|
||||
if self.state == STATE_TRANSPORT_REPLACE:
|
||||
# We ack the session accept
|
||||
response = stanza.buildReply('result')
|
||||
con = self.session.connection
|
||||
con.connection.send(response)
|
||||
# We send the file
|
||||
con.files_props[self.file_props['sid']] = self.file_props
|
||||
fp = open(self.file_props['file-name'], 'r')
|
||||
con.OpenStream( self.transport.sid, self.session.peerjid,
|
||||
fp, blocksize=4096)
|
||||
raise xmpp.NodeProcessed
|
||||
|
||||
|
||||
def __on_session_terminate(self, stanza, content, error, action):
|
||||
log.info("__on_session_terminate")
|
||||
|
@ -197,7 +213,7 @@ class JingleFileTransfer(JingleContent):
|
|||
elif self.weinitiate and self.state == STATE_INITIALIZED:
|
||||
# proxy activated
|
||||
self.state = STATE_PROXY_ACTIVATED
|
||||
|
||||
|
||||
def send_candidate_used(self, streamhost):
|
||||
"""
|
||||
send candidate-used stanza
|
||||
|
|
|
@ -28,8 +28,10 @@ Handles Jingle sessions (XEP 0166)
|
|||
|
||||
import gajim #Get rid of that?
|
||||
import xmpp
|
||||
from jingle_transport import get_jingle_transport
|
||||
from jingle_transport import get_jingle_transport, JingleTransportIBB
|
||||
from jingle_content import get_jingle_content, JingleContentSetupException
|
||||
from jingle_content import JingleContent
|
||||
from jingle_ft import STATE_TRANSPORT_REPLACE
|
||||
from common.connection_handlers_events import *
|
||||
import logging
|
||||
log = logging.getLogger("gajim.c.jingle_session")
|
||||
|
@ -213,11 +215,19 @@ class JingleSession(object):
|
|||
if not self.contents:
|
||||
self.end_session()
|
||||
|
||||
def modify_content(self, creator, name, *someother):
|
||||
"""
|
||||
We do not need this now
|
||||
"""
|
||||
pass
|
||||
def modify_content(self, creator, name, transport = None):
|
||||
'''
|
||||
Currently used for transport replacement
|
||||
'''
|
||||
|
||||
content = self.contents[(creator,name)]
|
||||
transport.set_sid(content.transport.sid)
|
||||
transport.set_file_props(content.transport.file_props)
|
||||
content.transport = transport
|
||||
# The content will have to be resend now that it is modified
|
||||
content.sent = False
|
||||
content.accepted = True
|
||||
|
||||
|
||||
def on_session_state_changed(self, content=None):
|
||||
if self.state == JingleStates.ended:
|
||||
|
@ -343,18 +353,43 @@ class JingleSession(object):
|
|||
error_name = child.getName()
|
||||
self.__dispatch_error(error_name, text, error.getAttr('type'))
|
||||
# FIXME: Not sure when we would want to do that...
|
||||
def transport_replace(self):
|
||||
transport = JingleTransportIBB()
|
||||
# For debug only, delete this and replace for a function
|
||||
# that will identify contents by its sid
|
||||
for creator, name in self.contents.keys():
|
||||
self.modify_content(creator, name, transport)
|
||||
cont = self.contents[(creator, name)]
|
||||
cont.transport = transport
|
||||
cont.state = STATE_TRANSPORT_REPLACE
|
||||
|
||||
stanza, jingle = self.__make_jingle('transport-replace')
|
||||
self.__append_contents(jingle)
|
||||
self.__broadcast(stanza, jingle, None, 'transport-replace')
|
||||
self.connection.connection.send(stanza)
|
||||
#self.collect_iq_id(stanza.getID())
|
||||
|
||||
|
||||
def __on_transport_replace(self, stanza, jingle, error, action):
|
||||
for content in jingle.iterTags('content'):
|
||||
creator = content['creator']
|
||||
name = content['name']
|
||||
if (creator, name) in self.contents:
|
||||
transport_ns = content.getTag('transport').getNamespace()
|
||||
if transport_ns == xmpp.JINGLE_ICE_UDP:
|
||||
if transport_ns == xmpp.NS_JINGLE_ICE_UDP:
|
||||
# FIXME: We don't manage anything else than ICE-UDP now...
|
||||
# What was the previous transport?!?
|
||||
# Anyway, content's transport is not modifiable yet
|
||||
pass
|
||||
elif transport_ns == xmpp.NS_JINGLE_IBB:
|
||||
|
||||
transport = JingleTransportIBB()
|
||||
self.modify_content(creator, name, transport)
|
||||
#self.state = JingleStates.pending
|
||||
self.contents[(creator,name)].state = STATE_TRANSPORT_REPLACE
|
||||
self.__ack(stanza, jingle, error, action)
|
||||
self.__session_accept()
|
||||
|
||||
else:
|
||||
stanza, jingle = self.__make_jingle('transport-reject')
|
||||
content = jingle.setTag('content', attrs={'creator': creator,
|
||||
|
@ -400,6 +435,7 @@ class JingleSession(object):
|
|||
if self.state != JingleStates.pending:
|
||||
raise OutOfOrder
|
||||
self.state = JingleStates.active
|
||||
|
||||
|
||||
def __on_content_accept(self, stanza, jingle, error, action):
|
||||
"""
|
||||
|
@ -562,12 +598,19 @@ class JingleSession(object):
|
|||
return (contents, contents_rejected, failure_reason)
|
||||
|
||||
def __dispatch_error(self, error=None, text=None, type_=None):
|
||||
|
||||
if type_ == 'cancel' and error == 'item-not-found':
|
||||
# We coudln't connect with sock5stream, we fallback to IBB
|
||||
self.transport_replace()
|
||||
return
|
||||
if text:
|
||||
text = '%s (%s)' % (error, text)
|
||||
if type_ != 'modify':
|
||||
gajim.nec.push_incoming_event(JingleErrorReceivedEvent(None,
|
||||
conn=self.connection, jingle_session=self,
|
||||
reason=text or error))
|
||||
|
||||
|
||||
|
||||
def __reason_from_stanza(self, stanza):
|
||||
# TODO: Move to GUI?
|
||||
|
@ -595,6 +638,8 @@ class JingleSession(object):
|
|||
attrs['initiator'] = self.initiator
|
||||
elif action == 'session-accept':
|
||||
attrs['responder'] = self.responder
|
||||
elif action == 'transport-replace':
|
||||
attrs['initiator'] = self.initiator
|
||||
jingle = stanza.addChild('jingle', attrs=attrs, namespace=xmpp.NS_JINGLE)
|
||||
if reason is not None:
|
||||
jingle.addChild(node=reason)
|
||||
|
|
|
@ -165,7 +165,7 @@ class JingleTransportSocks5(JingleTransport):
|
|||
for addr in socket.getaddrinfo(socket.gethostname(), None):
|
||||
if not addr[4][0] in local_ip_cand and not addr[4][0].startswith('127'):
|
||||
c = {'host': addr[4][0]}
|
||||
c['candidate_id'] = conn.connection.getAnID()
|
||||
c['candidate_id'] = self.connection.connection.getAnID()
|
||||
c['port'] = port
|
||||
c['type'] = 'direct'
|
||||
c['jid'] = self.ourjid
|
||||
|
@ -272,6 +272,39 @@ class JingleTransportSocks5(JingleTransport):
|
|||
return
|
||||
sesn.send_transport_info(content)
|
||||
|
||||
|
||||
class JingleTransportIBB(JingleTransport):
|
||||
|
||||
def __init__(self, node=None, block_sz=None):
|
||||
|
||||
JingleTransport.__init__(self, TransportType.streaming)
|
||||
|
||||
if block_sz:
|
||||
self.block_sz = block_sz
|
||||
else:
|
||||
self.block_sz = '4096'
|
||||
|
||||
self.connection = None
|
||||
self.sid = None
|
||||
if node and node.getAttr('sid'):
|
||||
self.sid = node.getAttr('sid')
|
||||
|
||||
|
||||
def set_sid(self, sid):
|
||||
self.sid = sid
|
||||
|
||||
def make_transport(self):
|
||||
|
||||
transport = JingleTransport.make_transport(self)
|
||||
transport.setNamespace(xmpp.NS_JINGLE_IBB)
|
||||
transport.setAttr('block-size', self.block_sz)
|
||||
transport.setAttr('sid', self.sid)
|
||||
return transport
|
||||
|
||||
def set_file_props(self, file_props):
|
||||
self.file_props = file_props
|
||||
|
||||
|
||||
import farsight
|
||||
|
||||
class JingleTransportICEUDP(JingleTransport):
|
||||
|
@ -347,3 +380,4 @@ class JingleTransportICEUDP(JingleTransport):
|
|||
|
||||
transports[xmpp.NS_JINGLE_ICE_UDP] = JingleTransportICEUDP
|
||||
transports[xmpp.NS_JINGLE_BYTESTREAM] = JingleTransportSocks5
|
||||
transports[xmpp.NS_JINGLE_IBB] = JingleTransportIBB
|
||||
|
|
|
@ -91,6 +91,7 @@ NS_JINGLE_XTLS='urn:xmpp:jingle:security:xtls:0' # XTLS: EX
|
|||
NS_JINGLE_RAW_UDP = 'urn:xmpp:jingle:transports:raw-udp:1' # XEP-0177
|
||||
NS_JINGLE_ICE_UDP = 'urn:xmpp:jingle:transports:ice-udp:1' # XEP-0176
|
||||
NS_JINGLE_BYTESTREAM ='urn:xmpp:jingle:transports:s5b:1' # XEP-0260
|
||||
NS_JINGLE_IBB = 'urn:xmpp:jingle:transports:ibb:1' # XEP-0261
|
||||
NS_LAST = 'jabber:iq:last'
|
||||
NS_LOCATION = 'http://jabber.org/protocol/geoloc' # XEP-0080
|
||||
NS_MESSAGE = 'message' # Jabberd2
|
||||
|
|
Loading…
Reference in New Issue