reSIProcate/stack  9694
dumpTls.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #if defined (HAVE_POPT_H) 
00006 #include <popt.h>
00007 #else
00008 #ifndef WIN32
00009 #warning "will not work very well without libpopt"
00010 #endif
00011 #endif
00012 
00013 #include <sys/types.h>
00014 #include <unistd.h> // for sleep 
00015 #include <iostream>
00016 #include <memory>
00017 #include <sys/ioctl.h>
00018 #include <signal.h>
00019 
00020 #ifdef __MINGW32__
00021 #define sleep(x) Sleep((x)*1000)
00022 #endif
00023 
00024 #include "rutil/DnsUtil.hxx"
00025 #include "rutil/Inserter.hxx"
00026 #include "rutil/Logger.hxx"
00027 #include "resip/stack/Helper.hxx"
00028 #include "resip/stack/SipMessage.hxx"
00029 #include "resip/stack/SipStack.hxx"
00030 #include "resip/stack/Uri.hxx"
00031 #include "resip/stack/ShutdownMessage.hxx"
00032 
00033 #include "resip/stack/ssl/Security.hxx"
00034 
00035 using namespace resip;
00036 using namespace std;
00037 
00038 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00039 
00040 int
00041 main(int argc, char* argv[])
00042 {
00043 #ifdef USE_SSL
00044    const char *logType = "cerr";
00045    const char *logLevel = "DEBUG";
00046    const char *certPath = ".";
00047    int  clientPort = 15001;
00048    int  serverPort = 5061;
00049    const char *clientDomain = "example.net";
00050    const char *serverDomain = "example.com";
00051 
00052 #if defined(HAVE_POPT_H)
00053    struct poptOption table[] = {
00054       {"log-type",     'l', POPT_ARG_STRING, &logType,       0, "where to send logging messages", "syslog|cerr|cout"},
00055       {"log-level",    'v', POPT_ARG_STRING, &logLevel,      0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"},
00056       {"cert-path",    'p', POPT_ARG_STRING, &certPath,      0, "path to the server certificates", "."},
00057       {"client-port",  'f', POPT_ARG_INT,    &clientPort,    0, "client port (send request from)", "15001"},
00058       {"server-port",  't', POPT_ARG_INT,    &serverPort,    0, "server port (send request to)", "5061"},
00059       {"client-domain",'c', POPT_ARG_STRING, &clientDomain,  0, "client domain", "example.net"},
00060       {"server-domain",'s', POPT_ARG_STRING, &serverDomain,  0, "server domain", "example.com"},
00061       POPT_AUTOHELP
00062       { NULL, 0, 0, NULL, 0 }
00063    };
00064    
00065    poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0);
00066    poptGetNextOpt(context);
00067 #endif
00068 
00069    Log::initialize(logType, logLevel, argv[0]);
00070 
00071    DebugLog(<< "Logs initialized");
00072    DebugLog(<< "logLevel = " << logLevel);
00073    DebugLog(<< "certPath = " << certPath);
00074 
00075    DebugLog(<< "Starting ssldump");
00076    
00077    int dumpPid = fork();
00078 
00079    if (dumpPid==-1)
00080    {
00081      DebugLog(<< "Can't fork to run ssldump"); exit(-1);
00082    }
00083 
00084    if (dumpPid==0)
00085    {
00086      // todo - make this something that can come on the command line
00087      const char *args[] = { "ssldump","-A","-i","lo0",NULL };
00088      // .kw. execvp takes a 'char* const *' -- for some reason it doesn't
00089      // promise to not modify the strings. Thus shouldn't use static string
00090      // initializers above!
00091      int ret = execvp("ssldump",const_cast<char**>(args));
00092      ErrLog(<< "Can't execvp: return is " << ret <<" errno is " << errno);
00093      exit(-1);
00094    }
00095 
00096    DebugLog(<< "ssldump's pid is " << dumpPid);
00097  
00098    IpVersion version = V4;
00099    Data bindInterface;
00100    //bindInterface = Data( "127.0.0.1" );
00101          
00102    SipStack* clientStack;
00103    SipStack* serverStack;
00104 
00105    Security* clientSecurity = new Security(certPath);
00106    Security* serverSecurity = new Security(certPath);
00107    clientStack = new SipStack(clientSecurity);
00108    serverStack = new SipStack(serverSecurity);
00109 
00110    clientStack->addTransport(TLS, clientPort, version, StunDisabled, bindInterface, clientDomain);
00111    serverStack->addTransport(TLS, serverPort, version, StunDisabled, bindInterface, serverDomain);
00112  
00113    NameAddr target;
00114    target.uri().scheme() = "sip";
00115    target.uri().user() = "fluffy";
00116    target.uri().host() = serverDomain;
00117    target.uri().port() = serverPort;
00118    target.uri().param(p_transport) = "tls";
00119 
00120    NameAddr contact;
00121    contact.uri().scheme() = "sip";
00122    contact.uri().user() = "fluffy";
00123    contact.uri().host() = clientDomain;
00124    contact.uri().port() = clientPort;
00125 
00126    NameAddr from = target;
00127    from.uri().port() = clientPort;
00128    
00129    InfoLog (<< "Starting" );
00130 
00131    SipMessage* msg = Helper::makeRegister( target, from, contact);
00132    clientStack->send(*msg);
00133    delete msg;
00134       
00135    bool done=false;
00136    int rundown = 0;
00137    while ( (!done) || (rundown-- > 0) )
00138    {
00139 
00140       FdSet fdset; 
00141 
00142       clientStack->buildFdSet(fdset);
00143       serverStack->buildFdSet(fdset);
00144 
00145       fdset.selectMilliSeconds(100); 
00146 
00147 
00148       serverStack->process(fdset);
00149       SipMessage *msg = serverStack->receive();
00150       if ( !msg ) 
00151       {
00152           clientStack->process(fdset);
00153           msg = clientStack->receive();
00154       }
00155    
00156       if ( msg )
00157       {
00158          if ( msg->isRequest() )
00159          {  
00160             assert(msg->isRequest());
00161             assert(msg->header(h_RequestLine).getMethod() == REGISTER);
00162             
00163             SipMessage* response = Helper::makeResponse(*msg, 200);
00164             serverStack->send(*response);
00165             delete response;
00166             delete msg;
00167          }
00168          else
00169          { 
00170             assert(msg->isResponse());
00171             assert(msg->header(h_CSeq).method() == REGISTER);
00172             if (msg->header(h_StatusLine).statusCode() < 200)
00173             {
00174               DebugLog(<<"Provisional response to a REGISTER - you're kidding me, right?");
00175             }
00176             else
00177             {
00178               done = true;
00179               rundown = 100;
00180             }
00181             delete msg;
00182          }
00183       }
00184    }
00185    InfoLog (<< "Finished " );
00186    
00187 #if defined(HAVE_POPT_H)
00188    poptFreeContext(context);
00189 #endif
00190    sleep(2);
00191    delete serverStack; //btw - this deletes the security object
00192    delete clientStack;
00193    sleep(5);
00194 
00195    if (dumpPid>0)
00196 
00197    {
00198      DebugLog( << "Trying to kill process id " << dumpPid);
00199      int ret = kill(dumpPid, SIGINT); // ssldump catches INT and does an fflush
00200      DebugLog( << "Kill returned: " << ret);
00201    }
00202 
00203 
00204 #endif
00205    return 0;
00206 }
00207 /* ====================================================================
00208  * The Vovida Software License, Version 1.0 
00209  * 
00210  * Copyright (c) 2008 Robert Sparks.  All rights reserved.
00211  * 
00212  * Redistribution and use in source and binary forms, with or without
00213  * modification, are permitted provided that the following conditions
00214  * are met:
00215  * 
00216  * 1. Redistributions of source code must retain the above copyright
00217  *    notice, this list of conditions and the following disclaimer.
00218  * 
00219  * 2. Redistributions in binary form must reproduce the above copyright
00220  *    notice, this list of conditions and the following disclaimer in
00221  *    the documentation and/or other materials provided with the
00222  *    distribution.
00223  * 
00224  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00225  *    and "Vovida Open Communication Application Library (VOCAL)" must
00226  *    not be used to endorse or promote products derived from this
00227  *    software without prior written permission. For written
00228  *    permission, please contact vocal@vovida.org.
00229  *
00230  * 4. Products derived from this software may not be called "VOCAL", nor
00231  *    may "VOCAL" appear in their name, without prior written
00232  *    permission of Vovida Networks, Inc.
00233  * 
00234  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00235  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00236  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00237  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00238  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00239  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00240  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00241  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00242  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00243  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00244  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00245  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00246  * DAMAGE.
00247  * 
00248  * ====================================================================
00249  *
00250  */