reSIProcate/stack  9694
StatelessHandler.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #ifndef WIN32
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <arpa/inet.h>
00009 #ifndef __CYGWIN__
00010 #  include <netinet/in.h>
00011 #  include <arpa/nameser.h>
00012 #  include <resolv.h>
00013 #endif
00014 #include <netdb.h>
00015 #include <netinet/in.h>
00016 #else
00017 #include <Winsock2.h>
00018 #include <svcguid.h>
00019 #ifdef USE_IPV6
00020 #include <ws2tcpip.h>
00021 #endif
00022 #endif
00023 
00024 #include "rutil/Logger.hxx"
00025 #include "rutil/DnsUtil.hxx"
00026 
00027 #include "resip/stack/TransportSelector.hxx"
00028 #include "resip/stack/DnsResult.hxx"
00029 #include "resip/stack/SipMessage.hxx"
00030 #include "resip/stack/StatelessHandler.hxx"
00031 #include "resip/stack/TransactionController.hxx"
00032 #include "resip/stack/TransportFailure.hxx"
00033 #include "rutil/WinLeakCheck.hxx"
00034 
00035 
00036 
00037 using namespace resip;
00038 
00039 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION
00040 
00041 StatelessHandler::StatelessHandler(TransactionController& c) : mController(c)
00042 {
00043 }
00044 
00045 void 
00046 StatelessHandler::process()
00047 {
00048    Message* msg = mController.mStateMacFifo.getNext();
00049    assert(msg);
00050 
00051    SipMessage* sip = dynamic_cast<SipMessage*>(msg);
00052    TransportFailure* transport = dynamic_cast<TransportFailure*>(msg);
00053    
00054    if (sip)
00055    {
00056       if (sip->const_header(h_Vias).empty())
00057       {
00058          InfoLog(<< "TransactionState::process dropping message with no Via: " << sip->brief());
00059          delete sip;
00060          return;
00061       }
00062       else
00063       {
00064          if (sip->isExternal())
00065          {
00066             DebugLog (<< "Processing sip from wire: " << msg->brief());
00067             Via& via = sip->header(h_Vias).front();
00068             // this is here so that we will reuse the tcp connection
00069             via.param(p_rport).port() = sip->getSource().getPort();
00070             mController.mTuSelector.add(sip, TimeLimitFifo<Message>::InternalElement);            
00071          }
00072          else if (sip->isRequest())
00073          {
00074             if (sip->getDestination().mFlowKey)
00075             {
00076                DebugLog (<< "Processing request from TU : " << msg->brief());
00077                mController.mTransportSelector.transmit(sip, sip->getDestination()); // results not used
00078             }
00079             else
00080             {
00081                DebugLog (<< "Processing request from TU : " << msg->brief());
00082                StatelessMessage* stateless = new StatelessMessage(mController.mTransportSelector, sip);
00083                DnsResult* dnsRes = mController.mTransportSelector.createDnsResult(stateless);      
00084                mController.mTransportSelector.dnsResolve(dnsRes, sip);
00085             }
00086          }
00087          else // no dns for sip responses
00088          {
00089             assert(sip->isResponse());
00090             DebugLog (<< "Processing response from TU: " << msg->brief());
00091             const Via& via = sip->const_header(h_Vias).front();
00092             int port = via.sentPort();
00093             if (sip->hasForceTarget())
00094             {
00095                assert( /*Unimplemented*/ 0 );
00096             }
00097             else
00098             {
00099                 if (via.exists(p_rport) && via.param(p_rport).hasValue())
00100                 {
00101                     port = via.param(p_rport).port();
00102                 }
00103                 Tuple destination(via.param(p_received), port, Tuple::toTransport(via.transport()));
00104                 mController.mTransportSelector.transmit(sip, destination); // results not used
00105             }
00106          }
00107       }
00108    }
00109    else if (transport)
00110    {
00111       DebugLog (<< "Processing Transport result: " << msg->brief());
00112       InfoLog (<< "Not yet supported");
00113    }
00114    else
00115    {
00116       DebugLog (<< "Dropping: " << msg->brief());
00117    }
00118 }
00119 
00120 
00121 StatelessMessage::StatelessMessage(TransportSelector& selector, SipMessage* msg) : mSelector(selector), mMsg(msg)
00122 {
00123 }
00124 
00125 void 
00126 StatelessMessage::rewriteRequest(const Uri& rewrite)
00127 {
00128    assert(mMsg->isRequest());
00129    if (mMsg->const_header(h_RequestLine).uri() != rewrite)
00130    {
00131       InfoLog (<< "Rewriting request-uri to " << rewrite);
00132       mMsg->header(h_RequestLine).uri() = rewrite;
00133    }
00134 }
00135 
00136 
00137 void 
00138 StatelessMessage::handle(DnsResult* result)
00139 {
00140    if (result->available() == DnsResult::Available)
00141    {
00142       Tuple next = result->next();
00143       mSelector.transmit(mMsg, next);
00144    }
00145 
00146    delete this;
00147    result->destroy();
00148 }
00149 /* ====================================================================
00150  * The Vovida Software License, Version 1.0 
00151  * 
00152  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00153  * 
00154  * Redistribution and use in source and binary forms, with or without
00155  * modification, are permitted provided that the following conditions
00156  * are met:
00157  * 
00158  * 1. Redistributions of source code must retain the above copyright
00159  *    notice, this list of conditions and the following disclaimer.
00160  * 
00161  * 2. Redistributions in binary form must reproduce the above copyright
00162  *    notice, this list of conditions and the following disclaimer in
00163  *    the documentation and/or other materials provided with the
00164  *    distribution.
00165  * 
00166  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00167  *    and "Vovida Open Communication Application Library (VOCAL)" must
00168  *    not be used to endorse or promote products derived from this
00169  *    software without prior written permission. For written
00170  *    permission, please contact vocal@vovida.org.
00171  *
00172  * 4. Products derived from this software may not be called "VOCAL", nor
00173  *    may "VOCAL" appear in their name, without prior written
00174  *    permission of Vovida Networks, Inc.
00175  * 
00176  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00177  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00178  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00179  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00180  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00181  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00182  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00183  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00184  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00185  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00186  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00187  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00188  * DAMAGE.
00189  * 
00190  * ====================================================================
00191  * 
00192  * This software consists of voluntary contributions made by Vovida
00193  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00194  * Inc.  For more information on Vovida Networks, Inc., please see
00195  * <http://www.vovida.org/>.
00196  *
00197  */