annotate sat/plugins/plugin_xep_0198.py @ 2862:b2e898384c25

quick_frontend (app): progress callbacks handling: in addition to listeners, a frontend can now register progression callback and errback which are called when the given progressing action is finished. Those callbacks can be registered using registerProgressCbs or specified in actionManager.
author Goffi <goffi@goffi.org>
date Wed, 20 Mar 2019 09:08:47 +0100
parents fdc53c8a5439
children 9213c6dff48d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SàT plugin for managing raw XML log
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from sat.core.i18n import _
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.constants import Const as C
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core import exceptions
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core.log import getLogger
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from twisted.words.protocols.jabber import client as jabber_client
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import xmlstream
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.words.xish import domish
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from twisted.internet import defer
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from twisted.internet import task, reactor
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from functools import partial
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from wokkel import disco, iwokkel
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from zope.interface import implements
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 import collections
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 import time
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 log = getLogger(__name__)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 PLUGIN_INFO = {
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 C.PI_NAME: "Stream Management",
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 C.PI_IMPORT_NAME: "XEP-0198",
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 C.PI_TYPE: "XEP",
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 C.PI_MODES: C.PLUG_MODE_BOTH,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 C.PI_PROTOCOLS: ["XEP-0198"],
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 C.PI_DEPENDENCIES: [],
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 C.PI_MAIN: "XEP_0198",
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 C.PI_HANDLER: "yes",
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_DESCRIPTION: _(u"""Implementation of Stream Management"""),
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 }
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 NS_SM = u"urn:xmpp:sm:3"
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 SM_ENABLED = '/enabled[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 SM_RESUMED = '/resumed[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 SM_FAILED = '/failed[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 SM_R_REQUEST = '/r[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 SM_A_REQUEST = '/a[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 SM_H_REQUEST = '/h[@xmlns="' + NS_SM + '"]'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 # Max number of stanza to send before requesting ack
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 MAX_STANZA_ACK_R = 5
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 # Max number of seconds before requesting ack
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 MAX_DELAY_ACK_R = 30
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 MAX_COUNTER = 2**32
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 RESUME_MAX = 5*60
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
62 # if we don't have an answer to ACK REQUEST after this delay, connection is aborted
2729
edd230651138 plugin XEP-0198: rised ACK_TIMEOUT + set req_time to None when timing out to be ready after resuming
Goffi <goffi@goffi.org>
parents: 2727
diff changeset
63 ACK_TIMEOUT = 35
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
65
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 class ProfileSessionData(object):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 out_counter = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 in_counter = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 session_id = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 location = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 session_max = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 # True when an ack answer is expected
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 ack_requested = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 last_ack_r = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 disconnected_time = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
76
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 def __init__(self, callback, **kw):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 self.buffer = collections.deque()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 self.buffer_idx = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 self._enabled = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 self.timer = None
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
82 # time used when doing a ack request
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
83 # when it times out, connection is aborted
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
84 self.req_timer = None
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self.callback_data = (callback, kw)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
86
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 @property
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 def enabled(self):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 return self._enabled
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
90
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 @enabled.setter
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 def enabled(self, enabled):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 if enabled:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 if self._enabled:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 raise exceptions.InternalError(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 u"Stream Management can't be enabled twice")
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 self._enabled = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 callback, kw = self.callback_data
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 self.timer = task.LoopingCall(callback, **kw)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 self.timer.start(MAX_DELAY_ACK_R, now=False)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 self._enabled = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 if self.timer is not None:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 self.timer.stop()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 self.timer = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 @property
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 def resume_enabled(self):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 return self.session_id is not None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 def reset(self):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 self.enabled = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 self.buffer.clear()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 self.buffer_idx = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 self.in_counter = self.out_counter = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 self.session_id = self.location = None
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 self.ack_requested = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 self.last_ack_r = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 class XEP_0198(object):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 # FIXME: location is not handled yet
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 def __init__(self, host):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 log.info(_("Plugin Stream Management initialization"))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 self.host = host
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 host.registerNamespace(u'sm', NS_SM)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 host.trigger.add("stream_hooks", self.addHooks)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 host.trigger.add("xml_init", self._XMLInitTrigger)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 host.trigger.add("disconnecting", self._disconnectingTrigger)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 host.trigger.add("disconnected", self._disconnectedTrigger)
2727
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
132 try:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
133 self._ack_timeout = int(host.memory.getConfig("", "ack_timeout", ACK_TIMEOUT))
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
134 except ValueError:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
135 log.error(_(u"Invalid ack_timeout value, please check your configuration"))
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
136 self._ack_timeout = ACK_TIMEOUT
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
137 if not self._ack_timeout:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
138 log.info(_(u"Ack timeout disabled"))
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
139 else:
2729
edd230651138 plugin XEP-0198: rised ACK_TIMEOUT + set req_time to None when timing out to be ready after resuming
Goffi <goffi@goffi.org>
parents: 2727
diff changeset
140 log.info(_(u"Ack timeout set to {timeout}s").format(
2727
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
141 timeout=self._ack_timeout))
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 def profileConnecting(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 client._xep_0198_session = ProfileSessionData(callback=self.checkAcks,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 client=client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 def getHandler(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 return XEP_0198_handler(self)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
149
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 def addHooks(self, client, receive_hooks, send_hooks):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 """Add hooks to handle in/out stanzas counters"""
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 receive_hooks.append(partial(self.onReceive, client=client))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 send_hooks.append(partial(self.onSend, client=client))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 return True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 def _XMLInitTrigger(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 """Enable or resume a stream mangement"""
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 if not (NS_SM, u'sm') in client.xmlstream.features:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 log.warning(_(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 u"Your server doesn't support stream management ({namespace}), this is "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 u"used to improve connection problems detection (like network outages). "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 u"Please ask your server administrator to enable this feature.".format(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 namespace=NS_SM)))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 return True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 # a disconnect timer from a previous disconnection may still be active
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 disconnect_timer = session.disconnect_timer
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 except AttributeError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 pass
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 if disconnect_timer.active():
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 disconnect_timer.cancel()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 del session.disconnect_timer
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 if session.resume_enabled:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 # we are resuming a session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 resume_elt = domish.Element((NS_SM, 'resume'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 resume_elt['h'] = unicode(session.in_counter)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 resume_elt['previd'] = session.session_id
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 client.send(resume_elt)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 session.resuming = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 # session.enabled will be set on <resumed/> reception
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 return False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 # we start a new session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 assert session.out_counter == 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 enable_elt = domish.Element((NS_SM, 'enable'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 enable_elt[u'resume'] = u'true'
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 client.send(enable_elt)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 session.enabled = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 return True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 def _disconnectingTrigger(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 if session.enabled:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 self.sendAck(client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 # This is a requested disconnection, so we can reset the session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 # to disable resuming and close normally the stream
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 session.reset()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 return True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 def _disconnectedTrigger(self, client, reason):
2796
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
205 if client.is_component:
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
206 return True
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 session.enabled = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 if session.resume_enabled:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 session.disconnected_time = time.time()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 session.disconnect_timer = reactor.callLater(session.session_max,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 client.disconnectProfile,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 reason)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 # disconnectProfile must not be called at this point
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 # because session can be resumed
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 return False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 return True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
219
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 def checkAcks(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 """Request ack if needed"""
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 # log.debug("checkAcks (in_counter={}, out_counter={}, buf len={}, buf idx={})"
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 # .format(session.in_counter, session.out_counter, len(session.buffer),
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 # session.buffer_idx))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 if session.ack_requested or not session.buffer:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 return
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 if (session.out_counter - session.buffer_idx >= MAX_STANZA_ACK_R
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 or time.time() - session.last_ack_r >= MAX_DELAY_ACK_R):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 self.requestAck(client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 session.ack_requested = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 session.last_ack_r = time.time()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
233
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 def updateBuffer(self, session, server_acked):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 """Update buffer and buffer_index"""
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 if server_acked > session.buffer_idx:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 diff = server_acked - session.buffer_idx
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 for i in xrange(diff):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 session.buffer.pop()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 session.buffer_idx += diff
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
241
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 def sendAck(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 """Send an answer element with current IN counter"""
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 a_elt = domish.Element((NS_SM, 'a'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 a_elt['h'] = unicode(client._xep_0198_session.in_counter)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 client.send(a_elt)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
247
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 def requestAck(self, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 """Send a request element"""
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
250 session = client._xep_0198_session
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 r_elt = domish.Element((NS_SM, 'r'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 client.send(r_elt)
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
253 if session.req_timer is not None:
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
254 raise exceptions.InternalError("req_timer should not be set")
2727
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
255 if self._ack_timeout:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
256 session.req_timer = reactor.callLater(self._ack_timeout, self.onAckTimeOut,
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
257 client)
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
258
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 def _connectionFailed(self, failure_, connector):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 normal_host, normal_port = connector.normal_location
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 del connector.normal_location
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 log.warning(_(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 u"Connection failed using location given by server (host: {host}, port: "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 u"{port}), switching to normal host and port (host: {normal_host}, port: "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 u"{normal_port})".format(host=connector.host, port=connector.port,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 normal_host=normal_host, normal_port=normal_port)))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
267 connector.host, connector.port = normal_host, normal_port
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 connector.connectionFailed = connector.connectionFailed_ori
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 del connector.connectionFailed_ori
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 return connector.connectionFailed(failure_)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
271
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 def onEnabled(self, enabled_elt, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 session.in_counter = 0
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
275
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 # we check that resuming is possible and that we have a session id
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 resume = C.bool(enabled_elt.getAttribute(u'resume'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
278 session_id = enabled_elt.getAttribute(u'id')
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
279 if not session_id:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 log.warning(_(u'Incorrect <enabled/> element received, no "id" attribute'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
281 if not resume or not session_id:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
282 log.warning(_(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
283 u"You're server doesn't support session resuming with stream management, "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
284 u"please contact your server administrator to enable it"))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
285 return
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
286
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
287 session.session_id = session_id
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
288
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 # XXX: we disable resource binding, which must not be done
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 # when we resume the session.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
291 client.factory.authenticator.res_binding = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
292
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 # location, in case server want resuming session to be elsewhere
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 location = enabled_elt[u'location']
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 except KeyError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 pass
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 # TODO: handle IPv6 here (in brackets, cf. XEP)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 domain, port = location.split(':', 1)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 port = int(port)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
303 except ValueError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 log.warning(_(u"Invalid location received: {location}")
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 .format(location=location))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 session.location = (domain, port)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
308 # we monkey patch connector to use the new location
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
309 connector = client.xmlstream.transport.connector
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
310 connector.normal_location = connector.host, connector.port
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 connector.host = domain
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
312 connector.port = port
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
313 connector.connectionFailed_ori = connector.connectionFailed
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 connector.connectionFailed = partial(self._connectionFailed,
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
315 connector=connector)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
316
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
317 # resuming time
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
318 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
319 max_s = int(enabled_elt[u'max'])
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 except (ValueError, KeyError) as e:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
321 if isinstance(e, ValueError):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
322 log.warning(_(u'Invalid "max" attribute'))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
323 max_s = RESUME_MAX
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
324 log.info(_(u"Using default session max value ({max_s} s).".format(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
325 max_s=max_s)))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
326 log.info(_(u"Stream Management enabled"))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
327 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
328 log.info(_(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
329 u"Stream Management enabled, with a resumption time of {res_m} min"
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
330 .format(res_m = max_s/60)))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 session.session_max = max_s
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
332
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 def onResumed(self, enabled_elt, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
334 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
335 assert not session.enabled
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
336 del session.resuming
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
337 server_acked = int(enabled_elt['h'])
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 self.updateBuffer(session, server_acked)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
339 resend_count = len(session.buffer)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
340 # we resend all stanza which have not been received properly
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
341 while True:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
342 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
343 stanza = session.buffer.pop()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
344 except IndexError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 break
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 client.send(stanza)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
348 # now we can continue the session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
349 session.enabled = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
350 d_time = time.time() - session.disconnected_time
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
351 log.info(_(u"Stream session resumed (disconnected for {d_time} s, {count} "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
352 u"stanza(s) resent)").format(d_time=int(d_time), count=resend_count))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
353
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
354 def onFailed(self, failed_elt, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
355 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
356 condition_elt = failed_elt.firstChildElement()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
357 session.reset()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
358
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
359 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
360 del session.resuming
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
361 except AttributeError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
362 # stream management can't be started at all
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
363 msg = _(u"Can't use stream management")
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
364 if condition_elt is None:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
365 log.error(msg + u'.')
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
366 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
367 log.error(_(u"{msg}: {reason}").format(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
368 msg=msg, reason=condition_elt.name))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
369 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
370 # only stream resumption failed, we can try full session init
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
371 # XXX: we try to start full session init from this point, with many
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
372 # variables/attributes already initialised with a potentially different
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
373 # jid. This is experimental and may not be safe. It may be more
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
374 # secured to abord the connection and restart everything with a fresh
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
375 # client.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
376 msg = _(u"stream resumption not possible, restarting full session")
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
377
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
378 if condition_elt is None:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
379 log.warning(u'{msg}.'.format(msg=msg))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
380 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
381 log.warning(u"{msg}: {reason}".format(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
382 msg=msg, reason=condition_elt.name))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
383 # stream resumption failed, but we still can do normal stream management
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
384 # we restore attributes as if the session was new, and init stream
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
385 # we keep everything initialized, and only do binding, roster request
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
386 # and initial presence sending.
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
387 if client.conn_deferred.called:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
388 client.conn_deferred = defer.Deferred()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
389 else:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
390 log.error(u"conn_deferred should be called at this point")
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
391 # we need to recreate roster
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
392 client.handlers.remove(client.roster)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
393 client.roster = client.roster.__class__(self.host)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
394 client.roster.setHandlerParent(client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 # bind init is not done when resuming is possible, so we have to do it now
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
396 bind_init = jabber_client.BindInitializer(client.xmlstream)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 bind_init.required = True
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
398 d = bind_init.start()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
399 # we set the jid, which may have changed
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
400 d.addCallback(lambda __: setattr(client.factory.authenticator, "jid", client.jid))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 # we call the trigger who will send the <enable/> element
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
402 d.addCallback(lambda __: self._XMLInitTrigger(client))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
403 # then we have to re-request the roster, as changes may have occured
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
404 d.addCallback(lambda __: client.roster.requestRoster())
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
405 # we add got_roster to be sure to have roster before sending initial presence
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
406 d.addCallback(lambda __: client.roster.got_roster)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
407 # initial presence must be sent manually
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
408 d.addCallback(lambda __: client.presence.available())
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
409
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
410 def onReceive(self, element, client):
2796
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
411 if not client.is_component:
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
412 session = client._xep_0198_session
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
413 if session.enabled and element.name.lower() in C.STANZA_NAMES:
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
414 session.in_counter += 1 % MAX_COUNTER
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
415
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
416 def onSend(self, obj, client):
2796
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
417 if not client.is_component:
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
418 session = client._xep_0198_session
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
419 if (session.enabled
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
420 and domish.IElement.providedBy(obj)
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
421 and obj.name.lower() in C.STANZA_NAMES):
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
422 session.out_counter += 1 % MAX_COUNTER
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
423 session.buffer.appendleft(obj)
fdc53c8a5439 plugin XEP-0198: don't use hooks on components
Goffi <goffi@goffi.org>
parents: 2795
diff changeset
424 self.checkAcks(client)
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
425
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
426 def onAckRequest(self, r_elt, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
427 self.sendAck(client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
428
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
429 def onAckAnswer(self, a_elt, client):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
430 session = client._xep_0198_session
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
431 session.ack_requested = False
2727
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
432 if self._ack_timeout:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
433 if session.req_timer is None:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
434 log.error("reg_timer should be set")
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
435 else:
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
436 session.req_timer.cancel()
59ac9284dee8 plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents: 2725
diff changeset
437 session.req_timer = None
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
438 try:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
439 server_acked = int(a_elt['h'])
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
440 except ValueError:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
441 log.warning(_(u"Server returned invalid ack element, disabling stream "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
442 u"management: {xml}").format(xml=a_elt))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
443 session.enabled = False
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
444 return
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
445
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
446 if server_acked > session.out_counter:
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
447 log.error(_(u"Server acked more stanzas than we have sent, disabling stream "
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
448 u"management."))
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
449 session.reset()
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
450 return
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
451
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
452 self.updateBuffer(session, server_acked)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
453 self.checkAcks(client)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
454
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
455 def onAckTimeOut(self, client):
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
456 """Called when a requested ACK has not been received in time"""
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
457 log.info(_(u"Ack was not received in time, aborting connection"))
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
458 client.xmlstream.transport.abortConnection()
2795
25639611c303 plugin XEP-0198: fixed typo resulting in a crash on resume
Goffi <goffi@goffi.org>
parents: 2729
diff changeset
459 client._xep_0198_session.req_timer = None
2725
d0466af33483 plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents: 2691
diff changeset
460
2691
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
461
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
462 class XEP_0198_handler(xmlstream.XMPPHandler):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
463 implements(iwokkel.IDisco)
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
464
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
465 def __init__(self, plugin_parent):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
466 self.plugin_parent = plugin_parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
467 self.host = plugin_parent.host
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
468
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
469 def connectionInitialized(self):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
470 self.xmlstream.addObserver(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
471 SM_ENABLED, self.plugin_parent.onEnabled, client=self.parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
472 )
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
473 self.xmlstream.addObserver(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
474 SM_RESUMED, self.plugin_parent.onResumed, client=self.parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
475 )
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
476 self.xmlstream.addObserver(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
477 SM_FAILED, self.plugin_parent.onFailed, client=self.parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
478 )
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
479 self.xmlstream.addObserver(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
480 SM_R_REQUEST, self.plugin_parent.onAckRequest, client=self.parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
481 )
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
482 self.xmlstream.addObserver(
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
483 SM_A_REQUEST, self.plugin_parent.onAckAnswer, client=self.parent
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
484 )
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
485
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
486 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
487 return [disco.DiscoFeature(NS_SM)]
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
488
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
489 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
1ecceac3df96 plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
490 return []