comparison sat/plugins/plugin_xep_0198.py @ 2725:d0466af33483

plugin XEP-0198: abort connection if ack is not received after a timeout: If ack is not received after a given time (currently 25s), connection is aborted. This avoid waiting forever when TCP link is lost (i.e. switching from cable to wifi), and allows to use resuming mechanism.
author Goffi <goffi@goffi.org>
date Wed, 26 Dec 2018 14:37:13 +0100
parents 1ecceac3df96
children 59ac9284dee8
comparison
equal deleted inserted replaced
2724:35a0ab3032bb 2725:d0466af33483
57 MAX_STANZA_ACK_R = 5 57 MAX_STANZA_ACK_R = 5
58 # Max number of seconds before requesting ack 58 # Max number of seconds before requesting ack
59 MAX_DELAY_ACK_R = 30 59 MAX_DELAY_ACK_R = 30
60 MAX_COUNTER = 2**32 60 MAX_COUNTER = 2**32
61 RESUME_MAX = 5*60 61 RESUME_MAX = 5*60
62 # if we don't have an answer to ACK REQUEST after this delay, connection is aborted
63 ACK_R_TIMEOUT = 25
62 64
63 65
64 class ProfileSessionData(object): 66 class ProfileSessionData(object):
65 out_counter = 0 67 out_counter = 0
66 in_counter = 0 68 in_counter = 0
75 def __init__(self, callback, **kw): 77 def __init__(self, callback, **kw):
76 self.buffer = collections.deque() 78 self.buffer = collections.deque()
77 self.buffer_idx = 0 79 self.buffer_idx = 0
78 self._enabled = False 80 self._enabled = False
79 self.timer = None 81 self.timer = None
82 # time used when doing a ack request
83 # when it times out, connection is aborted
84 self.req_timer = None
80 self.callback_data = (callback, kw) 85 self.callback_data = (callback, kw)
81 86
82 @property 87 @property
83 def enabled(self): 88 def enabled(self):
84 return self._enabled 89 return self._enabled
228 a_elt['h'] = unicode(client._xep_0198_session.in_counter) 233 a_elt['h'] = unicode(client._xep_0198_session.in_counter)
229 client.send(a_elt) 234 client.send(a_elt)
230 235
231 def requestAck(self, client): 236 def requestAck(self, client):
232 """Send a request element""" 237 """Send a request element"""
238 session = client._xep_0198_session
233 r_elt = domish.Element((NS_SM, 'r')) 239 r_elt = domish.Element((NS_SM, 'r'))
234 client.send(r_elt) 240 client.send(r_elt)
241 if session.req_timer is not None:
242 raise exceptions.InternalError("req_timer should not be set")
243 session.req_timer = reactor.callLater(ACK_R_TIMEOUT, self.onAckTimeOut, client)
235 244
236 def _connectionFailed(self, failure_, connector): 245 def _connectionFailed(self, failure_, connector):
237 normal_host, normal_port = connector.normal_location 246 normal_host, normal_port = connector.normal_location
238 del connector.normal_location 247 del connector.normal_location
239 log.warning(_( 248 log.warning(_(
402 self.sendAck(client) 411 self.sendAck(client)
403 412
404 def onAckAnswer(self, a_elt, client): 413 def onAckAnswer(self, a_elt, client):
405 session = client._xep_0198_session 414 session = client._xep_0198_session
406 session.ack_requested = False 415 session.ack_requested = False
416 if session.req_timer is None:
417 log.error("reg_timer should be set")
418 else:
419 session.req_timer.cancel()
420 session.req_timer = None
407 try: 421 try:
408 server_acked = int(a_elt['h']) 422 server_acked = int(a_elt['h'])
409 except ValueError: 423 except ValueError:
410 log.warning(_(u"Server returned invalid ack element, disabling stream " 424 log.warning(_(u"Server returned invalid ack element, disabling stream "
411 u"management: {xml}").format(xml=a_elt)) 425 u"management: {xml}").format(xml=a_elt))
418 session.reset() 432 session.reset()
419 return 433 return
420 434
421 self.updateBuffer(session, server_acked) 435 self.updateBuffer(session, server_acked)
422 self.checkAcks(client) 436 self.checkAcks(client)
437
438 def onAckTimeOut(self, client):
439 """Called when a requested ACK has not been received in time"""
440 log.info(_(u"Ack was not received in time, aborting connection"))
441 client.xmlstream.transport.abortConnection()
423 442
424 443
425 class XEP_0198_handler(xmlstream.XMPPHandler): 444 class XEP_0198_handler(xmlstream.XMPPHandler):
426 implements(iwokkel.IDisco) 445 implements(iwokkel.IDisco)
427 446