|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/stack/AbandonServerTransaction.hxx" 00006 #include "resip/stack/ApplicationMessage.hxx" 00007 #include "resip/stack/CancelClientInviteTransaction.hxx" 00008 #include "resip/stack/Helper.hxx" 00009 #include "resip/stack/TerminateFlow.hxx" 00010 #include "resip/stack/EnableFlowTimer.hxx" 00011 #include "resip/stack/ZeroOutStatistics.hxx" 00012 #include "resip/stack/PollStatistics.hxx" 00013 #include "resip/stack/ShutdownMessage.hxx" 00014 #include "resip/stack/SipMessage.hxx" 00015 #include "resip/stack/TransactionController.hxx" 00016 #include "resip/stack/TransactionState.hxx" 00017 #ifdef USE_SSL 00018 #include "resip/stack/ssl/Security.hxx" 00019 #endif 00020 #include "rutil/CongestionManager.hxx" 00021 #include "rutil/DnsUtil.hxx" 00022 #include "rutil/Logger.hxx" 00023 #include "resip/stack/SipStack.hxx" 00024 #include "rutil/WinLeakCheck.hxx" 00025 00026 using namespace resip; 00027 00028 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION 00029 00030 #if defined(WIN32) && !defined (__GNUC__) 00031 #pragma warning( disable : 4355 ) // using this in base member initializer list 00032 #endif 00033 00034 unsigned int TransactionController::MaxTUFifoSize = 0; 00035 unsigned int TransactionController::MaxTUFifoTimeDepthSecs = 0; 00036 00037 TransactionController::TransactionController(SipStack& stack, 00038 AsyncProcessHandler* handler) : 00039 mStack(stack), 00040 mDiscardStrayResponses(true), 00041 mFixBadDialogIdentifiers(true), 00042 mFixBadCSeqNumbers(true), 00043 mStateMacFifo(handler), 00044 mStateMacFifoOutBuffer(mStateMacFifo), 00045 mCongestionManager(0), 00046 mTuSelector(stack.mTuSelector), 00047 mTransportSelector(mStateMacFifo, 00048 stack.getSecurity(), 00049 stack.getDnsStub(), 00050 stack.getCompression()), 00051 mTimers(mTimerFifo), 00052 mShuttingDown(false), 00053 mStatsManager(stack.mStatsManager), 00054 mHostname(DnsUtil::getLocalHostName()) 00055 { 00056 mStateMacFifo.setDescription("TransactionController::mStateMacFifo"); 00057 } 00058 00059 #if defined(WIN32) && !defined(__GNUC__) 00060 #pragma warning( default : 4355 ) 00061 #endif 00062 00063 TransactionController::~TransactionController() 00064 { 00065 if(mClientTransactionMap.size()) 00066 { 00067 WarningLog(<< "On shutdown, there are Client TransactionStates remaining!"); 00068 } 00069 00070 if(mServerTransactionMap.size()) 00071 { 00072 WarningLog(<< "On shutdown, there are Server TransactionStates remaining!"); 00073 } 00074 } 00075 00076 00077 bool 00078 TransactionController::isTUOverloaded() const 00079 { 00080 return !mTuSelector.wouldAccept(TimeLimitFifo<Message>::EnforceTimeDepth); 00081 } 00082 00083 void 00084 TransactionController::shutdown() 00085 { 00086 mShuttingDown = true; 00087 mTransportSelector.shutdown(); 00088 } 00089 00090 void 00091 TransactionController::process(int timeout) 00092 { 00093 if (mShuttingDown && 00094 //mTimers.empty() && 00095 !mStateMacFifoOutBuffer.messageAvailable() && // !dcm! -- see below 00096 !mStack.mTUFifo.messageAvailable() && 00097 mTransportSelector.isFinished()) 00098 // !dcm! -- why would one wait for the Tu's fifo to be empty before delivering a 00099 // shutdown message? 00100 { 00102 mTuSelector.add(new ShutdownMessage, TimeLimitFifo<Message>::InternalElement); 00103 } 00104 else 00105 { 00106 unsigned int nextTimer(mTimers.msTillNextTimer()); 00107 timeout=resipMin((int)nextTimer, timeout); 00108 if(timeout==0) 00109 { 00110 // *sigh* 00111 timeout=-1; 00112 } 00113 00114 // If non-zero is passed for timeout, we understand that the caller is ok 00115 // with us waiting up to that long on this call. A non-zero timeout is 00116 // passed by TransactionControllerThread, for example. This gets us 00117 // something approximating a blocking wait on both the state machine fifo 00118 // and the timer queue. 00119 TransactionMessage* message=mStateMacFifoOutBuffer.getNext(timeout); 00120 00121 // If we either had timers ready to go at the beginning of this call, or 00122 // the getNext() call above timed out, our timer queue is likely ready to 00123 // be serviced. 00124 if(!message || nextTimer==0) 00125 { 00126 mTimers.process(); 00127 TimerMessage* timer; 00128 while ((timer=mTimerFifo.getNext(-1))) 00129 { 00130 TransactionState::processTimer(*this,timer); 00131 } 00132 } 00133 00134 if(message) 00135 { 00136 // Only do 16 at a time; don't let the timer queue (or other 00137 // processing) starve. 00138 int runs=16; 00139 while(message) 00140 { 00141 TransactionState::process(*this, message); 00142 if(--runs==0) 00143 { 00144 break; 00145 } 00146 message = mStateMacFifoOutBuffer.getNext(-1); 00147 } 00148 00149 mTransportSelector.poke(); 00150 } 00151 } 00152 } 00153 00154 unsigned int 00155 TransactionController::getTimeTillNextProcessMS() 00156 { 00157 if ( mStateMacFifoOutBuffer.messageAvailable() ) 00158 { 00159 return 0; 00160 } 00161 return mTimers.msTillNextTimer(); 00162 } 00163 00164 void 00165 TransactionController::send(SipMessage* msg) 00166 { 00167 if(msg->isRequest() && 00168 msg->method() != ACK && 00169 getRejectionBehavior()!=CongestionManager::NORMAL) 00170 { 00171 // Need to 503 this. 00172 SipMessage* resp(Helper::makeResponse(*msg, 503)); 00173 resp->header(h_RetryAfter).value()=(UInt32)mStateMacFifo.expectedWaitTimeMilliSec()/1000; 00174 resp->setTransactionUser(msg->getTransactionUser()); 00175 mTuSelector.add(resp, TimeLimitFifo<Message>::InternalElement); 00176 delete msg; 00177 return; 00178 } 00179 mStateMacFifo.add(msg); 00180 } 00181 00182 00183 unsigned int 00184 TransactionController::getTuFifoSize() const 00185 { 00186 return mTuSelector.size(); 00187 } 00188 00189 unsigned int 00190 TransactionController::sumTransportFifoSizes() const 00191 { 00192 return mTransportSelector.sumTransportFifoSizes(); 00193 } 00194 00195 unsigned int 00196 TransactionController::getTransactionFifoSize() const 00197 { 00198 // Should we include the stuff in mStateMacFifoOutBuffer here too? This is 00199 // likely to be called from other threads... 00200 return mStateMacFifo.size(); 00201 } 00202 00203 unsigned int 00204 TransactionController::getNumClientTransactions() const 00205 { 00206 return mClientTransactionMap.size(); 00207 } 00208 00209 unsigned int 00210 TransactionController::getNumServerTransactions() const 00211 { 00212 return mServerTransactionMap.size(); 00213 } 00214 00215 unsigned int 00216 TransactionController::getTimerQueueSize() const 00217 { 00218 return mTimers.size(); 00219 } 00220 00221 void 00222 TransactionController::zeroOutStatistics() 00223 { 00224 mStateMacFifo.add(new ZeroOutStatistics()); 00225 } 00226 00227 void 00228 TransactionController::pollStatistics() 00229 { 00230 mStateMacFifo.add(new PollStatistics()); 00231 } 00232 00233 void 00234 TransactionController::registerMarkListener(MarkListener* listener) 00235 { 00236 mTransportSelector.registerMarkListener(listener); 00237 } 00238 00239 void TransactionController::unregisterMarkListener(MarkListener* listener) 00240 { 00241 mTransportSelector.unregisterMarkListener(listener); 00242 } 00243 00244 void 00245 TransactionController::abandonServerTransaction(const Data& tid) 00246 { 00247 mStateMacFifo.add(new AbandonServerTransaction(tid)); 00248 } 00249 00250 void 00251 TransactionController::cancelClientInviteTransaction(const Data& tid) 00252 { 00253 mStateMacFifo.add(new CancelClientInviteTransaction(tid)); 00254 } 00255 00256 void 00257 TransactionController::terminateFlow(const resip::Tuple& flow) 00258 { 00259 mStateMacFifo.add(new TerminateFlow(flow)); 00260 } 00261 00262 void 00263 TransactionController::enableFlowTimer(const resip::Tuple& flow) 00264 { 00265 mStateMacFifo.add(new EnableFlowTimer(flow)); 00266 } 00267 00268 void 00269 TransactionController::setInterruptor(AsyncProcessHandler* handler) 00270 { 00271 mStateMacFifo.setInterruptor(handler); 00272 } 00273 00274 /* ==================================================================== 00275 * The Vovida Software License, Version 1.0 00276 * 00277 * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. 00278 * 00279 * Redistribution and use in source and binary forms, with or without 00280 * modification, are permitted provided that the following conditions 00281 * are met: 00282 * 00283 * 1. Redistributions of source code must retain the above copyright 00284 * notice, this list of conditions and the following disclaimer. 00285 * 00286 * 2. Redistributions in binary form must reproduce the above copyright 00287 * notice, this list of conditions and the following disclaimer in 00288 * the documentation and/or other materials provided with the 00289 * distribution. 00290 * 00291 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00292 * and "Vovida Open Communication Application Library (VOCAL)" must 00293 * not be used to endorse or promote products derived from this 00294 * software without prior written permission. For written 00295 * permission, please contact vocal@vovida.org. 00296 * 00297 * 4. Products derived from this software may not be called "VOCAL", nor 00298 * may "VOCAL" appear in their name, without prior written 00299 * permission of Vovida Networks, Inc. 00300 * 00301 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00302 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00303 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00304 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00305 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00306 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00307 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00308 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00309 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00310 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00311 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00312 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00313 * DAMAGE. 00314 * 00315 * ==================================================================== 00316 * 00317 * This software consists of voluntary contributions made by Vovida 00318 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00319 * Inc. For more information on Vovida Networks, Inc., please see 00320 * <http://www.vovida.org/>. 00321 * 00322 * vi: set shiftwidth=3 expandtab: 00323 */
1.7.5.1