Mercurial > libervia-backend
annotate sat/plugins/plugin_xep_0198.py @ 2787:298408833ec2
memory (sqlite): optimizations
indexes were missing on foreign keys for "message", "subject" and "thread" tables, seriously impacting performances.
In addition to those indexes, two indexes have been added to speed ordering by timestamp on "history", and one on "files" table.
history.rowid is not used anymore as there is an index on (profile_id, received_timestamp) which will speed up the query.
Primary keys order has been changed to use automatic index in most common cases (filtering by profile_id then namespace).
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 19 Jan 2019 22:49:32 +0100 |
parents | edd230651138 |
children | 25639611c303 |
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): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
205 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
206 session.enabled = False |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
207 if session.resume_enabled: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
208 session.disconnected_time = time.time() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
209 session.disconnect_timer = reactor.callLater(session.session_max, |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
210 client.disconnectProfile, |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
211 reason) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
212 # disconnectProfile must not be called at this point |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
213 # because session can be resumed |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
214 return False |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
215 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
216 return True |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
217 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
218 def checkAcks(self, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
219 """Request ack if needed""" |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
221 # 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
|
222 # .format(session.in_counter, session.out_counter, len(session.buffer), |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
223 # session.buffer_idx)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
224 if session.ack_requested or not session.buffer: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
225 return |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
226 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
|
227 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
|
228 self.requestAck(client) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
229 session.ack_requested = True |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
230 session.last_ack_r = time.time() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
231 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
232 def updateBuffer(self, session, server_acked): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
233 """Update buffer and buffer_index""" |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
234 if server_acked > session.buffer_idx: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
235 diff = server_acked - session.buffer_idx |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
236 for i in xrange(diff): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
237 session.buffer.pop() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
238 session.buffer_idx += diff |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
239 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
240 def sendAck(self, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
241 """Send an answer element with current IN counter""" |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
242 a_elt = domish.Element((NS_SM, 'a')) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
243 a_elt['h'] = unicode(client._xep_0198_session.in_counter) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
244 client.send(a_elt) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
245 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
246 def requestAck(self, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
247 """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
|
248 session = client._xep_0198_session |
2691
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
249 r_elt = domish.Element((NS_SM, 'r')) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
250 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
|
251 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
|
252 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
|
253 if self._ack_timeout: |
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
254 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
|
255 client) |
2691
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
256 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
257 def _connectionFailed(self, failure_, connector): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
258 normal_host, normal_port = connector.normal_location |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
259 del connector.normal_location |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
260 log.warning(_( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
261 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
|
262 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
|
263 u"{normal_port})".format(host=connector.host, port=connector.port, |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
264 normal_host=normal_host, normal_port=normal_port))) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
265 connector.host, connector.port = normal_host, normal_port |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
266 connector.connectionFailed = connector.connectionFailed_ori |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
267 del connector.connectionFailed_ori |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
268 return connector.connectionFailed(failure_) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
269 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
270 def onEnabled(self, enabled_elt, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
271 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
272 session.in_counter = 0 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
273 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
274 # 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
|
275 resume = C.bool(enabled_elt.getAttribute(u'resume')) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
276 session_id = enabled_elt.getAttribute(u'id') |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
277 if not session_id: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
278 log.warning(_(u'Incorrect <enabled/> element received, no "id" attribute')) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
279 if not resume or not session_id: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
280 log.warning(_( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
281 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
|
282 u"please contact your server administrator to enable it")) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
283 return |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
284 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
285 session.session_id = session_id |
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 # XXX: we disable resource binding, which must not be done |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
288 # when we resume the session. |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
289 client.factory.authenticator.res_binding = False |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
290 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
291 # location, in case server want resuming session to be elsewhere |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
292 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
293 location = enabled_elt[u'location'] |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
294 except KeyError: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
295 pass |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
296 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
297 # TODO: handle IPv6 here (in brackets, cf. XEP) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
298 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
299 domain, port = location.split(':', 1) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
300 port = int(port) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
301 except ValueError: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
302 log.warning(_(u"Invalid location received: {location}") |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
303 .format(location=location)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
304 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
305 session.location = (domain, port) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
306 # we monkey patch connector to use the new location |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
307 connector = client.xmlstream.transport.connector |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
308 connector.normal_location = connector.host, connector.port |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
309 connector.host = domain |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
310 connector.port = port |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
311 connector.connectionFailed_ori = connector.connectionFailed |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
312 connector.connectionFailed = partial(self._connectionFailed, |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
313 connector=connector) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
314 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
315 # resuming time |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
316 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
317 max_s = int(enabled_elt[u'max']) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
318 except (ValueError, KeyError) as e: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
319 if isinstance(e, ValueError): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
320 log.warning(_(u'Invalid "max" attribute')) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
321 max_s = RESUME_MAX |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
322 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
|
323 max_s=max_s))) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
324 log.info(_(u"Stream Management enabled")) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
325 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
326 log.info(_( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
327 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
|
328 .format(res_m = max_s/60))) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
329 session.session_max = max_s |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
330 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
331 def onResumed(self, enabled_elt, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
332 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
333 assert not session.enabled |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
334 del session.resuming |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
335 server_acked = int(enabled_elt['h']) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
336 self.updateBuffer(session, server_acked) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
337 resend_count = len(session.buffer) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
338 # we resend all stanza which have not been received properly |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
339 while True: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
340 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
341 stanza = session.buffer.pop() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
342 except IndexError: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
343 break |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
344 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
345 client.send(stanza) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
346 # now we can continue the session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
347 session.enabled = True |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
348 d_time = time.time() - session.disconnected_time |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
349 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
|
350 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
|
351 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
352 def onFailed(self, failed_elt, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
353 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
354 condition_elt = failed_elt.firstChildElement() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
355 session.reset() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
356 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
357 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
358 del session.resuming |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
359 except AttributeError: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
360 # stream management can't be started at all |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
361 msg = _(u"Can't use stream management") |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
362 if condition_elt is None: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
363 log.error(msg + u'.') |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
364 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
365 log.error(_(u"{msg}: {reason}").format( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
366 msg=msg, reason=condition_elt.name)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
367 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
368 # only stream resumption failed, we can try full session init |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
369 # 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
|
370 # variables/attributes already initialised with a potentially different |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
371 # 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
|
372 # 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
|
373 # client. |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
374 msg = _(u"stream resumption not possible, restarting full session") |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
375 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
376 if condition_elt is None: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
377 log.warning(u'{msg}.'.format(msg=msg)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
378 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
379 log.warning(u"{msg}: {reason}".format( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
380 msg=msg, reason=condition_elt.name)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
381 # 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
|
382 # 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
|
383 # we keep everything initialized, and only do binding, roster request |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
384 # and initial presence sending. |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
385 if client.conn_deferred.called: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
386 client.conn_deferred = defer.Deferred() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
387 else: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
388 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
|
389 # we need to recreate roster |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
390 client.handlers.remove(client.roster) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
391 client.roster = client.roster.__class__(self.host) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
392 client.roster.setHandlerParent(client) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
393 # 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
|
394 bind_init = jabber_client.BindInitializer(client.xmlstream) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
395 bind_init.required = True |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
396 d = bind_init.start() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
397 # we set the jid, which may have changed |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
398 d.addCallback(lambda __: setattr(client.factory.authenticator, "jid", client.jid)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
399 # we call the trigger who will send the <enable/> element |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
400 d.addCallback(lambda __: self._XMLInitTrigger(client)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
401 # 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
|
402 d.addCallback(lambda __: client.roster.requestRoster()) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
403 # 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
|
404 d.addCallback(lambda __: client.roster.got_roster) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
405 # initial presence must be sent manually |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
406 d.addCallback(lambda __: client.presence.available()) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
407 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
408 def onReceive(self, element, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
409 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
410 if session.enabled and element.name.lower() in C.STANZA_NAMES: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
411 session.in_counter += 1 % MAX_COUNTER |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
412 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
413 def onSend(self, obj, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
414 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
415 if (session.enabled |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
416 and domish.IElement.providedBy(obj) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
417 and obj.name.lower() in C.STANZA_NAMES): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
418 session.out_counter += 1 % MAX_COUNTER |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
419 session.buffer.appendleft(obj) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
420 self.checkAcks(client) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
421 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
422 def onAckRequest(self, r_elt, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
423 self.sendAck(client) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
424 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
425 def onAckAnswer(self, a_elt, client): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
426 session = client._xep_0198_session |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
427 session.ack_requested = False |
2727
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
428 if self._ack_timeout: |
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
429 if session.req_timer is None: |
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
430 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
|
431 else: |
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
432 session.req_timer.cancel() |
59ac9284dee8
plugin XEP-0198: allow to customise/disable ack_timeout:
Goffi <goffi@goffi.org>
parents:
2725
diff
changeset
|
433 session.req_timer = None |
2691
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
434 try: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
435 server_acked = int(a_elt['h']) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
436 except ValueError: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
437 log.warning(_(u"Server returned invalid ack element, disabling stream " |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
438 u"management: {xml}").format(xml=a_elt)) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
439 session.enabled = False |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
440 return |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
441 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
442 if server_acked > session.out_counter: |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
443 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
|
444 u"management.")) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
445 session.reset() |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
446 return |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
447 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
448 self.updateBuffer(session, server_acked) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
449 self.checkAcks(client) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
450 |
2725
d0466af33483
plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents:
2691
diff
changeset
|
451 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
|
452 """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
|
453 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
|
454 client.xmlstream.transport.abortConnection() |
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
|
455 client._xep_0198_session.req_time = None |
2725
d0466af33483
plugin XEP-0198: abort connection if ack is not received after a timeout:
Goffi <goffi@goffi.org>
parents:
2691
diff
changeset
|
456 |
2691
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
457 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
458 class XEP_0198_handler(xmlstream.XMPPHandler): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
459 implements(iwokkel.IDisco) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
460 |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
461 def __init__(self, plugin_parent): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
462 self.plugin_parent = plugin_parent |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
463 self.host = plugin_parent.host |
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 connectionInitialized(self): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
466 self.xmlstream.addObserver( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
467 SM_ENABLED, self.plugin_parent.onEnabled, client=self.parent |
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 self.xmlstream.addObserver( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
470 SM_RESUMED, self.plugin_parent.onResumed, client=self.parent |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
471 ) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
472 self.xmlstream.addObserver( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
473 SM_FAILED, self.plugin_parent.onFailed, client=self.parent |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
474 ) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
475 self.xmlstream.addObserver( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
476 SM_R_REQUEST, self.plugin_parent.onAckRequest, client=self.parent |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
477 ) |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
478 self.xmlstream.addObserver( |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
479 SM_A_REQUEST, self.plugin_parent.onAckAnswer, client=self.parent |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
480 ) |
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 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
483 return [disco.DiscoFeature(NS_SM)] |
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 def getDiscoItems(self, requestor, target, nodeIdentifier=""): |
1ecceac3df96
plugin XEP-0198: Stream Management implementation:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
486 return [] |