Smacks class added, responds to ack requests

This commit is contained in:
Jefry Lagrange 2011-05-30 20:14:26 -04:00
parent 9cf9de2a14
commit 5b1edd03b8
4 changed files with 76 additions and 8 deletions

View File

@ -21,7 +21,7 @@ Can be used both for client and transport authentication
See client_nb.py
"""
from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH
from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH, NS_STREAM_MGMT
from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID
from plugin import PlugIn
import base64
@ -31,7 +31,7 @@ import dispatcher_nb
import hashlib
import hmac
import hashlib
from smacks import Smacks
import logging
log = logging.getLogger('gajim.c.x.auth_nb')
@ -491,7 +491,8 @@ class NonBlockingNonSASL(PlugIn):
self.password = password
self.resource = resource
self.on_auth = on_auth
def plugin(self, owner):
"""
Determine the best auth method (digest/0k/plain) and use it for auth.
@ -564,6 +565,7 @@ class NonBlockingBind(PlugIn):
def __init__(self):
PlugIn.__init__(self)
self.bound = None
self.supports_sm = False
def plugin(self, owner):
''' Start resource binding, if allowed at this time. Used internally. '''
@ -580,8 +582,14 @@ class NonBlockingBind(PlugIn):
def FeaturesHandler(self, conn, feats):
"""
Determine if server supports resource binding and set some internal
attributes accordingly
attributes accordingly.
It also checks if server supports stream management
"""
if feats.getTag('sm', namespace=NS_STREAM_MGMT):
self.supports_sm = True # server supports stream management
if not feats.getTag('bind', namespace=NS_BIND):
log.info('Server does not requested binding.')
# we try to bind resource anyway
@ -625,6 +633,14 @@ class NonBlockingBind(PlugIn):
jid = JID(resp.getTag('bind').getTagData('jid'))
self._owner.User = jid.getNode()
self._owner.Resource = jid.getResource()
# Only negociate stream management after bounded
if self.supports_sm:
# starts negociation
sm = Smacks(self._owner)
self._owner.Dispatcher.supports_sm = True
self._owner.Dispatcher.sm = sm
sm.negociate()
if hasattr(self, 'session') and self.session == -1:
# Server don't want us to initialize a session
log.info('No session required.')

View File

@ -75,7 +75,7 @@ class XMPPDispatcher(PlugIn):
stream headers (used by SASL f.e.).
"""
def __init__(self):
def __init__(self):
PlugIn.__init__(self)
self.handlers = {}
self._expected = {}
@ -89,6 +89,9 @@ class XMPPDispatcher(PlugIn):
self.UnregisterHandler, self.RegisterProtocol,
self.SendAndWaitForResponse, self.SendAndCallForResponse,
self.getAnID, self.Event, self.send]
# Let the dispatcher know if there is support for stream management
self.supports_sm = False
def getAnID(self):
global outgoingID
@ -110,6 +113,7 @@ class XMPPDispatcher(PlugIn):
"""
self.handlers = handlers
def _init(self):
"""
Register default namespaces/protocols/handlers. Used internally
@ -125,7 +129,7 @@ class XMPPDispatcher(PlugIn):
self.RegisterDefaultHandler(self.returnStanzaHandler)
self.RegisterEventHandler(self._owner._caller._event_dispatcher)
self.on_responses = {}
def plugin(self, owner):
"""
Plug the Dispatcher instance into Client class instance and send initial
@ -416,7 +420,11 @@ class XMPPDispatcher(PlugIn):
typ = ''
stanza.props = stanza.getProperties()
ID = stanza.getID()
if self.supports_sm and (stanza.getName() != 'r' and
stanza.getName() != 'a' and
stanza.getName() != 'enabled') :
# increments the number of stanzas that has been handled
self.sm.in_h = self.sm.in_h + 1
list_ = ['default'] # we will use all handlers:
if typ in self.handlers[xmlns][name]:
list_.append(typ) # from very common...

View File

@ -143,7 +143,7 @@ NS_DATA_LAYOUT = 'http://jabber.org/protocol/xdata-layout' # XEP-0141
NS_DATA_VALIDATE = 'http://jabber.org/protocol/xdata-validate' # XEP-0122
NS_XMPP_STREAMS = 'urn:ietf:params:xml:ns:xmpp-streams'
NS_RECEIPTS = 'urn:xmpp:receipts'
NS_STREAM_MGMT = 'urn:xmpp:sm:3' # XEP-198
NS_STREAM_MGMT = 'urn:xmpp:sm:2' # XEP-198
xmpp_stream_error_conditions = '''
bad-format -- -- -- The entity has sent XML that cannot be processed.

44
src/common/xmpp/smacks.py Normal file
View File

@ -0,0 +1,44 @@
from protocol import Acks
from protocol import NS_STREAM_MGMT
class Smacks():
'''
This is Smacks is the Stream Management class. It takes care of requesting
and sending acks. Also, it keeps track of the unhandled outgoing stanzas.
The dispatcher has to be able to access this class to increment the
number of handled stanzas
'''
def __init__(self, owner):
self._owner = owner
self.out_h = 0 # Outgoing stanzas handled
self.in_h = 0 # Incoming stanzas handled
self.uqueue = [] # Unhandled stanzas queue
#Register handlers
owner.Dispatcher.RegisterNamespace(NS_STREAM_MGMT)
owner.Dispatcher.RegisterHandler('enabled', self._neg_response
,xmlns=NS_STREAM_MGMT)
owner.Dispatcher.RegisterHandler('r', self.send_ack
,xmlns=NS_STREAM_MGMT)
def negociate(self):
stanza = Acks()
stanza.buildEnable()
self._owner.Connection.send(stanza, True)
def _neg_response(self, disp, stanza):
pass
def send_ack(self, disp, stanza):
ack = Acks()
ack.buildAnswer(self.in_h)
self._owner.Connection.send(ack, False)
def request_ack(self):
r = Acks()
r.buildRequest()
self._owner.Connection.send(r, False)