📄 sipstack.cxx
字号:
#if defined(HAVE_CONFIG_H)
#include "resip/stack/config.hxx"
#endif
#ifndef WIN32
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "rutil/compat.hxx"
#include "rutil/Data.hxx"
#include "rutil/Fifo.hxx"
#include "rutil/Logger.hxx"
#include "rutil/Random.hxx"
#include "rutil/Socket.hxx"
#include "rutil/Timer.hxx"
#include "resip/stack/Message.hxx"
#include "resip/stack/Security.hxx"
#include "resip/stack/ShutdownMessage.hxx"
#include "resip/stack/SipMessage.hxx"
#include "resip/stack/ApplicationMessage.hxx"
#include "resip/stack/SipStack.hxx"
#include "rutil/Inserter.hxx"
#include "resip/stack/StatisticsManager.hxx"
#include "resip/stack/AsyncProcessHandler.hxx"
#include "resip/stack/TcpTransport.hxx"
#include "resip/stack/TlsTransport.hxx"
#include "resip/stack/UdpTransport.hxx"
#include "resip/stack/DtlsTransport.hxx"
#include "resip/stack/TransactionUser.hxx"
#include "resip/stack/TransactionUserMessage.hxx"
#include "rutil/WinLeakCheck.hxx"
#if defined(WIN32) && !defined(__GNUC__)
#pragma warning( disable : 4355 )
#endif
using namespace resip;
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
SipStack::SipStack(Security* pSecurity,
const DnsStub::NameserverList& additional,
AsyncProcessHandler* handler,
bool stateless,
AfterSocketCreationFuncPtr socketFunc,
Compression *compression
) :
#ifdef USE_SSL
mSecurity( pSecurity ? pSecurity : new Security()),
#else
mSecurity(0),
#endif
mDnsStub(new DnsStub(additional, socketFunc)),
mCompression(compression ? compression : new Compression(Compression::NONE)),
mAsyncProcessHandler(handler),
mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
TransactionController::MaxTUFifoSize),
mAppTimers(mTuSelector),
mStatsManager(*this),
mTransactionController(*this),
mShuttingDown(false),
mStatisticsManagerEnabled(true),
mTuSelector(mTUFifo),
mSocketFunc(socketFunc)
{
Timer::getTimeMs(); // initalize time offsets
Random::initialize();
initNetwork();
if (pSecurity)
{
pSecurity->preload();
}
assert(!mShuttingDown);
}
SipStack::~SipStack()
{
DebugLog (<< "SipStack::~SipStack()");
#ifdef USE_SSL
delete mSecurity;
#endif
delete mCompression;
delete mDnsStub;
}
void
SipStack::shutdown()
{
InfoLog (<< "Shutting down sip stack " << this);
static Mutex shutDownMutex;
{
Lock lock(shutDownMutex);
assert(!mShuttingDown);
mShuttingDown = true;
}
mTransactionController.shutdown();
}
Transport*
SipStack::addTransport( TransportType protocol,
int port,
IpVersion version,
StunSetting stun,
const Data& ipInterface,
const Data& sipDomainname,
const Data& privateKeyPassPhrase,
SecurityTypes::SSLType sslType)
{
assert(!mShuttingDown);
assert( port > 0 );
InternalTransport* transport=0;
Fifo<TransactionMessage>& stateMacFifo = mTransactionController.transportSelector().stateMacFifo();
try
{
switch (protocol)
{
case UDP:
transport = new UdpTransport(stateMacFifo, port, version, stun, ipInterface, mSocketFunc, *mCompression);
break;
case TCP:
transport = new TcpTransport(stateMacFifo, port, version, ipInterface, *mCompression);
break;
case TLS:
#if defined( USE_SSL )
transport = new TlsTransport(stateMacFifo,
port,
version,
ipInterface,
*mSecurity,
sipDomainname,
sslType,
*mCompression);
#else
CritLog (<< "TLS not supported in this stack. You don't have openssl");
assert(0);
#endif
break;
case DTLS:
#if defined( USE_DTLS )
transport = new DtlsTransport(stateMacFifo,
port,
version, // !jf! stun
ipInterface,
*mSecurity,
sipDomainname,
*mCompression);
#else
CritLog (<< "DTLS not supported in this stack.");
assert(0);
#endif
break;
default:
assert(0);
break;
}
}
catch (Transport::Exception& )
{
ErrLog(<< "Failed to create transport: "
<< (version == V4 ? "V4" : "V6") << " "
<< Tuple::toData(protocol) << " " << port << " on "
<< (ipInterface.empty() ? "ANY" : ipInterface.c_str()));
throw;
}
addTransport(std::auto_ptr<Transport>(transport));
return (Transport*)transport;
}
void
SipStack::addTransport( std::auto_ptr<Transport> transport)
{
//.dcm. once addTransport starts throwing, ned to back out alias
if (!transport->interfaceName().empty())
{
addAlias(transport->interfaceName(), transport->port());
}
mTransactionController.transportSelector().addTransport(transport);
}
Fifo<TransactionMessage>&
SipStack::stateMacFifo()
{
return mTransactionController.transportSelector().stateMacFifo();
}
void
SipStack::addAlias(const Data& domain, int port)
{
int portToUse = (port == 0) ? Symbols::DefaultSipPort : port;
DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse);
assert(!mShuttingDown);
mDomains.insert(domain + ":" + Data(portToUse));
}
Data
SipStack::getHostname()
{
// if you change this, please #def old version for windows
char hostName[1024];
int err = gethostname( hostName, sizeof(hostName) );
assert( err == 0 );
struct hostent* hostEnt = gethostbyname( hostName );
if ( !hostEnt )
{
// this can fail when there is no name server
// !cj! - need to decided what error to return
ErrLog( << "gethostbyname failed - name server is probably down" );
return "localhost";
}
assert( hostEnt );
struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0];
assert( addr );
// if you change this, please #def old version for windows
char* addrA = inet_ntoa( *addr );
Data ret(addrA);
Data retHost( hostEnt->h_name );
return retHost;
}
Data
SipStack::getHostAddress()
{
// if you change this, please #def old version for windows
char hostName[1024];
int err = gethostname( hostName, sizeof(hostName) );
assert( err == 0 );
struct hostent* hostEnt = gethostbyname( hostName );
assert( hostEnt );
struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0];
assert( addr );
// if you change this, please #def old version for windows
char* addrA = inet_ntoa( *addr );
Data ret(addrA);
//Data retHost( hostEnt->h_name );
return ret;
}
bool
SipStack::isMyDomain(const Data& domain, int port) const
{
return (mDomains.count(domain + ":" +
Data(port == 0 ? Symbols::DefaultSipPort : port)) != 0);
}
const Uri&
SipStack::getUri() const
{
if (mDomains.empty())
{
CritLog(<< "There are no associated transports");
throw Exception("No associated transports", __FILE__, __LINE__);
}
static Uri myUri("sip:" + *mDomains.begin());
return myUri;
}
void
SipStack::send(const SipMessage& msg, TransactionUser* tu)
{
DebugLog (<< "SEND: " << msg.brief());
//DebugLog (<< msg);
//assert(!mShuttingDown);
SipMessage* toSend = new SipMessage(msg);
if (tu)
{
toSend->setTransactionUser(tu);
}
toSend->setFromTU();
mTransactionController.send(toSend);
checkAsyncProcessHandler();
}
void
SipStack::send(std::auto_ptr<SipMessage> msg, TransactionUser* tu)
{
DebugLog (<< "SEND: " << msg->brief());
if (tu)
{
msg->setTransactionUser(tu);
}
msg->setFromTU();
mTransactionController.send(msg.release());
checkAsyncProcessHandler();
}
void
SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Uri& uri, TransactionUser* tu)
{
if (tu) msg->setTransactionUser(tu);
msg->setForceTarget(uri);
msg->setFromTU();
mTransactionController.send(msg.release());
checkAsyncProcessHandler();
}
void
SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Tuple& destination, TransactionUser* tu)
{
assert(!mShuttingDown);
assert(destination.transport);
if (tu) msg->setTransactionUser(tu);
msg->setDestination(destination);
msg->setFromTU();
mTransactionController.send(msg.release());
checkAsyncProcessHandler();
}
// this is only if you want to send to a destination not in the route. You
// probably don't want to use it.
void
SipStack::sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -