Mercurial > libervia-backend
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 |