reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
KeepAliveManager.cxx
Go to the documentation of this file.
7#include "rutil/Logger.hxx"
10
11#define RESIPROCATE_SUBSYSTEM Subsystem::DUM
12
13using namespace resip;
14using namespace std;
15
16int KeepAliveManager::mKeepAlivePongTimeoutMs = 10000; // Defaults to 10000ms (10s) as specified in RFC5626 section 4.4.1
17
18void
19KeepAliveManager::add(const Tuple& target, int keepAliveInterval, bool targetSupportsOutbound)
20{
22 NetworkAssociationMap::iterator it = mNetworkAssociations.find(target);
23 if (it == mNetworkAssociations.end())
24 {
25 DebugLog(<< "First keep alive for id=" << mCurrentId << ": " << target << ", interval="
26 << keepAliveInterval << "s, supportsOutbound=" << (targetSupportsOutbound ? "true" : "false"));
27
29 info.refCount = 1;
30 info.keepAliveInterval = keepAliveInterval;
31 info.id = mCurrentId;
32 info.supportsOutbound = targetSupportsOutbound;
33 info.pongReceivedForLastPing = false;
34 mNetworkAssociations.insert(NetworkAssociationMap::value_type(target, info));
36 SipStack &stack = mDum->getSipStack();
37 if(targetSupportsOutbound)
38 {
39 // Used randomized timeout between 80% and 100% of keepalivetime
40 stack.post(t, Helper::jitterValue(keepAliveInterval, 80, 100), mDum);
41 }
42 else
43 {
44 stack.post(t, keepAliveInterval, mDum);
45 }
46 ++mCurrentId;
47 }
48 else
49 {
50 it->second.refCount++;
51 if(keepAliveInterval < it->second.keepAliveInterval)
52 {
53 // Only allow value to be shortened. This can happen if 2 different profiles
54 // with different keepAliveTime settings are sharing this network association.
55 it->second.keepAliveInterval = keepAliveInterval;
56 }
57 if(targetSupportsOutbound)
58 {
59 // allow this to be updated to true only. If any usage get's an indication of
60 // outbound support on this flow, then we accept it
61 it->second.supportsOutbound = targetSupportsOutbound;
62 }
63 DebugLog(<< "Association added for keep alive id=" << it->second.id << ": " << target
64 << ", interval=" << it->second.keepAliveInterval << "s, supportsOutbound="
65 << (it->second.supportsOutbound ? "true" : "false")
66 << ", refCount=" << it->second.refCount);
67 }
68}
69
70void
72{
73 NetworkAssociationMap::iterator it = mNetworkAssociations.find(target);
74 if (it != mNetworkAssociations.end())
75 {
76 if (0 == --it->second.refCount)
77 {
78 DebugLog(<< "Last association removed for keep alive id=" << it->second.id << ": " << target);
79 mNetworkAssociations.erase(it);
80 }
81 else
82 {
83 DebugLog(<< "Association removed for keep alive id=" << it->second.id << ": " << target << ", refCount=" << it->second.refCount);
84 }
85 }
86}
87
88void
90{
92 static KeepAliveMessage msg;
93 NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target());
94 if (it != mNetworkAssociations.end() && timeout.id() == it->second.id)
95 {
96 SipStack &stack = mDum->getSipStack();
97 DebugLog(<< "Refreshing keepalive for id=" << it->second.id << ": " << it->first
98 << ", interval=" << it->second.keepAliveInterval << "s, supportsOutbound="
99 << (it->second.supportsOutbound ? "true" : "false")
100 << ", refCount=" << it->second.refCount);
101
102 if(InteropHelper::getOutboundVersion()>=8 && it->second.supportsOutbound && mKeepAlivePongTimeoutMs > 0)
103 {
104 // Assert if keep alive interval is too short in order to properly detect
105 // missing pong responses - ie. interval must be greater than 10s
106 resip_assert((it->second.keepAliveInterval*1000) > mKeepAlivePongTimeoutMs);
107
108 // Start pong timeout if transport is TCP based (note: pong processing of Stun messaging is currently not implemented)
109 if(isReliable(it->first.getType()))
110 {
111 DebugLog( << "Starting pong timeout for keepalive id " << it->second.id);
112 KeepAlivePongTimeout t(it->first, it->second.id);
114 }
115 }
116 it->second.pongReceivedForLastPing = false; // reset flag
117
118 stack.sendTo(msg, timeout.target(), mDum);
119 KeepAliveTimeout t(it->first, it->second.id);
120 if(it->second.supportsOutbound)
121 {
122 // Used randomized timeout between 80% and 100% of keepalivetime
123 stack.post(t, Helper::jitterValue(it->second.keepAliveInterval, 80, 100), mDum);
124 }
125 else
126 {
127 stack.post(t, it->second.keepAliveInterval, mDum);
128 }
129 }
130}
131
132void
134{
136 NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target());
137 if (it != mNetworkAssociations.end() && timeout.id() == it->second.id)
138 {
139 if(!it->second.pongReceivedForLastPing)
140 {
141 // Timeout expecting pong response
142 InfoLog(<< "Timed out expecting pong response for keep alive id=" << it->second.id << ": " << it->first);
143 mDum->getSipStack().terminateFlow(it->first);
144 }
145 }
146}
147
148void
150{
151 NetworkAssociationMap::iterator it = mNetworkAssociations.find(flow);
152 if (it != mNetworkAssociations.end())
153 {
154 DebugLog(<< "Received pong response for keep alive id=" << it->second.id << ": " << it->first);
155 it->second.pongReceivedForLastPing = true;
156 }
157}
158
159
160/* ====================================================================
161 * The Vovida Software License, Version 1.0
162 *
163 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
164 *
165 * Redistribution and use in source and binary forms, with or without
166 * modification, are permitted provided that the following conditions
167 * are met:
168 *
169 * 1. Redistributions of source code must retain the above copyright
170 * notice, this list of conditions and the following disclaimer.
171 *
172 * 2. Redistributions in binary form must reproduce the above copyright
173 * notice, this list of conditions and the following disclaimer in
174 * the documentation and/or other materials provided with the
175 * distribution.
176 *
177 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
178 * and "Vovida Open Communication Application Library (VOCAL)" must
179 * not be used to endorse or promote products derived from this
180 * software without prior written permission. For written
181 * permission, please contact vocal@vovida.org.
182 *
183 * 4. Products derived from this software may not be called "VOCAL", nor
184 * may "VOCAL" appear in their name, without prior written
185 * permission of Vovida Networks, Inc.
186 *
187 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
188 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
189 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
190 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
191 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
192 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
193 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
194 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
195 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
196 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
197 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
198 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
199 * DAMAGE.
200 *
201 * ====================================================================
202 *
203 * This software consists of voluntary contributions made by Vovida
204 * Networks, Inc. and many individuals on behalf of Vovida Networks,
205 * Inc. For more information on Vovida Networks, Inc., please see
206 * <http://www.vovida.org/>.
207 *
208 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define resip_assert(x)
This file needs to work for both C and C++ code.
static int jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum=0)
Used to jitter the expires in a SUBSCRIBE or REGISTER expires header.
Definition Helper.cxx:123
static int getOutboundVersion()
virtual void process(KeepAliveTimeout &timeout)
virtual void remove(const Tuple &target)
NetworkAssociationMap mNetworkAssociations
DialogUsageManager * mDum
virtual void add(const Tuple &target, int keepAliveInterval, bool targetSupportsOutbound)
virtual void receivedPong(const Tuple &flow)
const Tuple & target() const
const Tuple & target() const
This is the primary point of interaction between the app-layer and the stack.
Definition SipStack.hxx:160
void terminateFlow(const resip::Tuple &flow)
void post(std::unique_ptr< ApplicationMessage > message, unsigned int secondsLater, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in seconds.
void sendTo(std::unique_ptr< SipMessage > msg, const Uri &uri, TransactionUser *tu=0)
this is only if you want to send to a destination not in the route.
Definition SipStack.cxx:898
void postMS(std::unique_ptr< ApplicationMessage > message, unsigned int ms, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in milli-seconds.
Represents a network address.
Definition Tuple.hxx:59
dcm! – add UnusedChecking(_enum) below;
bool isReliable(TransportType type)
Returns true if passed in transport type is a reliable transport protocol.