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.
This commit is contained in:
parent
bea35db274
commit
3515defd64
1 changed files with 19 additions and 0 deletions
|
|
@ -59,6 +59,8 @@ MAX_STANZA_ACK_R = 5
|
|||
MAX_DELAY_ACK_R = 30
|
||||
MAX_COUNTER = 2**32
|
||||
RESUME_MAX = 5*60
|
||||
# if we don't have an answer to ACK REQUEST after this delay, connection is aborted
|
||||
ACK_R_TIMEOUT = 25
|
||||
|
||||
|
||||
class ProfileSessionData(object):
|
||||
|
|
@ -77,6 +79,9 @@ class ProfileSessionData(object):
|
|||
self.buffer_idx = 0
|
||||
self._enabled = False
|
||||
self.timer = None
|
||||
# time used when doing a ack request
|
||||
# when it times out, connection is aborted
|
||||
self.req_timer = None
|
||||
self.callback_data = (callback, kw)
|
||||
|
||||
@property
|
||||
|
|
@ -230,8 +235,12 @@ class XEP_0198(object):
|
|||
|
||||
def requestAck(self, client):
|
||||
"""Send a request element"""
|
||||
session = client._xep_0198_session
|
||||
r_elt = domish.Element((NS_SM, 'r'))
|
||||
client.send(r_elt)
|
||||
if session.req_timer is not None:
|
||||
raise exceptions.InternalError("req_timer should not be set")
|
||||
session.req_timer = reactor.callLater(ACK_R_TIMEOUT, self.onAckTimeOut, client)
|
||||
|
||||
def _connectionFailed(self, failure_, connector):
|
||||
normal_host, normal_port = connector.normal_location
|
||||
|
|
@ -404,6 +413,11 @@ class XEP_0198(object):
|
|||
def onAckAnswer(self, a_elt, client):
|
||||
session = client._xep_0198_session
|
||||
session.ack_requested = False
|
||||
if session.req_timer is None:
|
||||
log.error("reg_timer should be set")
|
||||
else:
|
||||
session.req_timer.cancel()
|
||||
session.req_timer = None
|
||||
try:
|
||||
server_acked = int(a_elt['h'])
|
||||
except ValueError:
|
||||
|
|
@ -421,6 +435,11 @@ class XEP_0198(object):
|
|||
self.updateBuffer(session, server_acked)
|
||||
self.checkAcks(client)
|
||||
|
||||
def onAckTimeOut(self, client):
|
||||
"""Called when a requested ACK has not been received in time"""
|
||||
log.info(_(u"Ack was not received in time, aborting connection"))
|
||||
client.xmlstream.transport.abortConnection()
|
||||
|
||||
|
||||
class XEP_0198_handler(xmlstream.XMPPHandler):
|
||||
implements(iwokkel.IDisco)
|
||||
|
|
|
|||
Loading…
Reference in a new issue