1 ;; jabber-keepalive.el - try to detect lost connection
3 ;; Copyright (C) 2004, 2008 - Magnus Henoch - mange@freemail.hu
4 ;; Copyright (C) 2007 - Detlev Zundel - dzu@gnu.org
6 ;; This file is a part of jabber.el.
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program; if not, write to the Free Software
20 ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 ;;;; Keepalive - send something to the server and see if it answers
25 ;;; These keepalive functions send a urn:xmpp:ping request to the
26 ;;; server every X minutes, and considers the connection broken if
27 ;;; they get no answer within Y seconds.
29 (require 'jabber-ping
)
32 (defgroup jabber-keepalive nil
33 "Keepalive functions try to detect lost connection"
37 (defcustom jabber-keepalive-interval
600
38 "Interval in seconds between connection checks."
40 :group
'jabber-keepalive
)
43 (defcustom jabber-keepalive-timeout
20
44 "Seconds to wait for response from server."
46 :group
'jabber-keepalive
)
48 (defvar jabber-keepalive-timer nil
49 "Timer object for keepalive function")
51 (defvar jabber-keepalive-timeout-timer nil
52 "Timer object for keepalive timeout function")
54 (defvar jabber-keepalive-pending nil
55 "List of outstanding keepalive connections")
57 (defvar jabber-keepalive-debug nil
58 "Log keepalive traffic when non-nil")
61 (defun jabber-keepalive-start (&optional jc
)
63 That is, regularly send a ping request to the server, and
64 disconnect if it doesn't answer. See `jabber-keepalive-interval'
65 and `jabber-keepalive-timeout'.
67 The JC argument makes it possible to add this function to
68 `jabber-post-connect-hooks'; it is ignored. Keepalive is activated
69 for all accounts regardless of the argument."
72 (when jabber-keepalive-timer
73 (jabber-keepalive-stop))
75 (setq jabber-keepalive-timer
77 jabber-keepalive-interval
78 'jabber-keepalive-do
))
79 (add-hook 'jabber-post-disconnect-hook
'jabber-keepalive-stop
))
81 (defun jabber-keepalive-stop ()
82 "Deactivate keepalive"
85 (when jabber-keepalive-timer
86 (jabber-cancel-timer jabber-keepalive-timer
)
87 (setq jabber-keepalive-timer nil
)))
89 (defun jabber-keepalive-do ()
90 (when jabber-keepalive-debug
91 (message "%s: sending keepalive packet(s)" (current-time-string)))
92 (setq jabber-keepalive-timeout-timer
93 (run-with-timer jabber-keepalive-timeout
95 'jabber-keepalive-timeout
))
96 (setq jabber-keepalive-pending jabber-connections
)
97 (dolist (c jabber-connections
)
98 ;; Whether we get an error or not is not interesting.
99 ;; Getting a response at all is.
100 (jabber-ping-send c nil
'jabber-keepalive-got-response nil nil
)))
102 (defun jabber-keepalive-got-response (jc &rest args
)
103 (when jabber-keepalive-debug
104 (message "%s: got keepalive response from %s"
105 (current-time-string)
106 (plist-get (fsm-get-state-data jc
) :server
)))
107 (setq jabber-keepalive-pending
(remq jc jabber-keepalive-pending
))
108 (when (and (null jabber-keepalive-pending
) (timerp jabber-keepalive-timeout-timer
))
109 (jabber-cancel-timer jabber-keepalive-timeout-timer
)
110 (setq jabber-keepalive-timeout-timer nil
)))
112 (defun jabber-keepalive-timeout ()
113 (jabber-cancel-timer jabber-keepalive-timer
)
114 (setq jabber-keepalive-timer nil
)
116 (dolist (c jabber-keepalive-pending
)
117 (message "%s: keepalive timeout, connection to %s considered lost"
118 (current-time-string)
119 (plist-get (fsm-get-state-data c
) :server
))
121 (run-hooks jabber-lost-connection-hooks c
)
122 (jabber-disconnect-one c nil
)))
124 ;;;; Whitespace pings - less traffic, no error checking on our side
126 ;;; Openfire needs something like this, but I couldn't bring myself to
127 ;;; enable keepalive by default... Whitespace pings are light and
131 (defcustom jabber-whitespace-ping-interval
30
132 "Send a space character to the server with this interval, in seconds.
134 This is a traditional remedy for a number of problems: to keep NAT
135 boxes from considering the connection dead, to have the OS discover
136 earlier that the connection is lost, and to placate servers which rely
137 on the client doing this, e.g. Openfire.
139 If you want to verify that the server is able to answer, see
140 `jabber-keepalive-start' for another mechanism."
141 :type
'(integer :tag
"Interval in seconds")
144 (defvar jabber-whitespace-ping-timer nil
145 "Timer object for whitespace pings")
148 (defun jabber-whitespace-ping-start (&optional jc
)
149 "Start sending whitespace pings at regular intervals.
150 See `jabber-whitespace-ping-interval'.
152 The JC argument is ignored; whitespace pings are enabled for all
156 (when jabber-whitespace-ping-timer
157 (jabber-whitespace-ping-stop))
159 (setq jabber-whitespace-ping-timer
161 jabber-whitespace-ping-interval
162 'jabber-whitespace-ping-do
))
163 (add-hook 'jabber-post-disconnect-hook
'jabber-whitespace-ping-stop
))
165 (defun jabber-whitespace-ping-stop ()
166 "Deactivate whitespace pings"
169 (when jabber-whitespace-ping-timer
170 (jabber-cancel-timer jabber-whitespace-ping-timer
)
171 (setq jabber-whitespace-ping-timer nil
)))
173 (defun jabber-whitespace-ping-do ()
174 (dolist (c jabber-connections
)
175 (jabber-send-string c
" ")))
177 (provide 'jabber-keepalive
)
179 ;;; arch-tag: d19ca743-75a1-475f-9217-83bd18012146