- fixes for Android + ongoing migration to latest resiprocate
This commit is contained in:
parent
0eb5ad7cf7
commit
dd6c01ca0d
|
|
@ -8,7 +8,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cma
|
|||
-DANDROID_NDK=$ANDROID_NDK_HOME \
|
||||
-DANDROID_PLATFORM=24 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DANDROID_ABI="armeabi-v7a" \
|
||||
-DANDROID_ABI="arm64-v8a" \
|
||||
../src
|
||||
|
||||
cmake --build . -j8
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ macro(configure_msvc_runtime)
|
|||
endmacro()
|
||||
|
||||
|
||||
# Rely on C++ 11
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
# Rely on C++ 17
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set (rtphone_libs libs)
|
||||
|
|
@ -70,7 +70,7 @@ if (NOT DEFINED LIB_PLATFORM)
|
|||
endif()
|
||||
|
||||
message("Libraries: ${LIB_PLATFORM}")
|
||||
set (OPENSSL_INCLUDE ${LIB_PLATFORM}/openssl/1.0/include)
|
||||
set (OPENSSL_INCLUDE ${LIB_PLATFORM}/openssl/1.1/include)
|
||||
message ("Using OpenSSL include files from ${OPENSSL_INCLUDE}")
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Windows*")
|
||||
|
|
@ -78,7 +78,7 @@ if (CMAKE_SYSTEM MATCHES "Windows*")
|
|||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Linux*")
|
||||
add_definitions (-DTARGET_LINUX)
|
||||
add_definitions (-DTARGET_LINUX -DHAVE_NETINET_IN_H)
|
||||
endif()
|
||||
|
||||
|
||||
|
|
@ -91,6 +91,7 @@ if (CMAKE_SYSTEM MATCHES "Android")
|
|||
set (OBOE_DIR libs/oboe)
|
||||
add_subdirectory (${OBOE_DIR} ./oboe)
|
||||
include_directories (${OBOE_DIR}/include)
|
||||
add_definitions(-DTARGET_ANDROID -DHAVE_NETINET_IN_H)
|
||||
endif()
|
||||
|
||||
if (USE_MUSL)
|
||||
|
|
@ -184,13 +185,12 @@ add_subdirectory(${rtphone_engine}/audio)
|
|||
add_subdirectory(${rtphone_engine}/media)
|
||||
|
||||
set (LIBS ice_stack jrtplib g729_codec gsm_codec
|
||||
gsmhr_codec g722_codec srtp resiprocate helper_lib audio_lib webrtc speexdsp
|
||||
uuid)
|
||||
gsmhr_codec g722_codec srtp resiprocate helper_lib audio_lib webrtc speexdsp)
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Win*")
|
||||
set (LIBS ${LIBS} )
|
||||
else ()
|
||||
set (LIBS ${LIBS} dl uuid)
|
||||
set (LIBS ${LIBS} dl)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Android")
|
||||
|
|
@ -199,13 +199,6 @@ endif()
|
|||
|
||||
|
||||
target_link_libraries(rtphone
|
||||
ice_stack jrtplib g729_codec gsm_codec
|
||||
gsmhr_codec g722_codec srtp resiprocate
|
||||
helper_lib
|
||||
audio_lib
|
||||
webrtc
|
||||
speexdsp
|
||||
uuid
|
||||
${OPENSSL_SSL}
|
||||
${OPENSSL_CRYPTO}
|
||||
${LIBS} )
|
||||
|
|
|
|||
|
|
@ -365,8 +365,9 @@ void AndroidInputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void *
|
|||
// ------------ AndroidOutputDevice -----------------
|
||||
AndroidOutputDevice::AndroidOutputDevice(int devId)
|
||||
{
|
||||
ICELogDebug(<< "Creating AndroidOutputDevice. This is: " << StringHelper::toHex(this));
|
||||
ICELogDebug(<< "Creating AndroidOutputDevice. This is: " << strx::toHex(this));
|
||||
}
|
||||
|
||||
AndroidOutputDevice::~AndroidOutputDevice()
|
||||
{
|
||||
ICELogDebug(<< "Deleting AndroidOutputDevice.");
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ unsigned TimeSource::time()
|
|||
#if defined(TARGET_ANDROID)
|
||||
assert(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- StubTimer ---
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ set (AUDIOLIB_SOURCES
|
|||
Audio_Null.cpp
|
||||
Audio_CoreAudio.cpp
|
||||
Audio_DirectSound.cpp
|
||||
Audio_Android.cpp
|
||||
Audio_WavFile.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ Account::Account(PVariantMap config, UserAgent& agent)
|
|||
:mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None),
|
||||
mRegistration(NULL)
|
||||
{
|
||||
mProfile = resip::SharedPtr<resip::UserProfile>(new resip::UserProfile(agent.mProfile));
|
||||
mProfile = std::make_shared<resip::UserProfile>(agent.mProfile);
|
||||
mId = Account::generateId();
|
||||
setup(*config);
|
||||
}
|
||||
|
|
@ -201,7 +201,7 @@ void Account::setup(VariantMap &config)
|
|||
}
|
||||
|
||||
// NAT decorator
|
||||
mProfile->setOutboundDecorator(resip::SharedPtr<resip::MessageDecorator>(new NATDecorator(mAgent)));
|
||||
mProfile->setOutboundDecorator(std::make_shared<NATDecorator>(mAgent));
|
||||
|
||||
// Rinstance
|
||||
if (config.exists(CONFIG_INSTANCE_ID))
|
||||
|
|
@ -266,7 +266,7 @@ void Account::start()
|
|||
|
||||
// Create registration
|
||||
mRegistration = new ResipSession(*mAgent.mDum);
|
||||
resip::SharedPtr<resip::SipMessage> regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
|
||||
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
|
||||
|
||||
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
|
||||
|
|
@ -380,7 +380,7 @@ PClientObserver Account::observe(const std::string& target, const std::string& p
|
|||
observer->mSessionId = observer->mSession->sessionId();
|
||||
observer->mPeer = target;
|
||||
|
||||
resip::SharedPtr<resip::SipMessage> msg;
|
||||
std::shared_ptr<resip::SipMessage> msg;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
if (mConfig->exists(CONFIG_SUBSCRIPTION_TIME))
|
||||
expires = CONFIG(CONFIG_SUBSCRIPTION_TIME).asInt();
|
||||
|
|
@ -498,7 +498,7 @@ void Account::prepareIceStack(Session *session, ice::AgentRole icerole)
|
|||
//config.mDetectNetworkChange = true;
|
||||
//config.mNetworkCheckInterval = 5000;
|
||||
|
||||
session->mIceStack = resip::SharedPtr<ice::Stack>(ice::Stack::makeICEBox(config));
|
||||
session->mIceStack = std::shared_ptr<ice::Stack>(ice::Stack::makeICEBox(config));
|
||||
session->mIceStack->setEventHandler(session, this);
|
||||
session->mIceStack->setRole(icerole);
|
||||
}
|
||||
|
|
@ -552,9 +552,8 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
|
|||
mAgent.mDum->addDomain(resip::Data(mExternalAddress.ip()));
|
||||
}
|
||||
|
||||
const resip::Transport* transport = response.getReceivedTransport();
|
||||
mUsedTransport = transport->transport();
|
||||
bool streamTransport = transport->transport() == resip::TCP || transport->transport() == resip::TLS;
|
||||
mUsedTransport = response.getReceivedTransportTuple().getType();
|
||||
bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS;
|
||||
|
||||
// Retry registration for stream based transport too
|
||||
if ( (hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ && mConfig->at(CONFIG_EXTERNALIP).asBool())
|
||||
|
|
@ -596,7 +595,7 @@ void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessa
|
|||
//mProfile->setDefaultFrom(from);
|
||||
}
|
||||
mProfile->setRegId(mConfig->at(CONFIG_REGID).asInt());
|
||||
resip::SharedPtr<resip::SipMessage> regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, UA_REGISTRATION_TIME);
|
||||
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, UA_REGISTRATION_TIME);
|
||||
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
|
||||
|
||||
|
|
@ -740,8 +739,8 @@ Account::UserInfo Account::getUserInfo() const
|
|||
return mUserInfo;
|
||||
}
|
||||
|
||||
resip::AtomicCounter Account::IdGenerator;
|
||||
std::atomic_int Account::IdGenerator;
|
||||
int Account::generateId()
|
||||
{
|
||||
return IdGenerator.increment();
|
||||
return ++IdGenerator;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public:
|
|||
void setup(VariantMap& config);
|
||||
|
||||
/* Returns corresponding resiprocate profile */
|
||||
resip::SharedPtr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
std::shared_ptr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
|
||||
typedef std::map<std::string, std::string> UserInfo;
|
||||
void setUserInfo(const UserInfo& info);
|
||||
|
|
@ -83,7 +83,7 @@ protected:
|
|||
RegistrationState mRegistrationState;
|
||||
|
||||
ice::NetworkAddress mExternalAddress;
|
||||
resip::SharedPtr<resip::UserProfile> mProfile;
|
||||
std::shared_ptr<resip::UserProfile> mProfile;
|
||||
UserAgent& mAgent;
|
||||
bool mPresenceOnline;
|
||||
std::string mPresenceContent;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include "resip/stack/SdpContents.hxx"
|
||||
#include "rutil/SharedPtr.hxx"
|
||||
|
||||
#include "../helper/HL_InternetAddress.h"
|
||||
#include "../helper/HL_NetworkSocket.h"
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ UserAgent::UserAgent()
|
|||
mConfig[CONFIG_RTCP_ATTR] = true;
|
||||
|
||||
// Create master profile
|
||||
mProfile = resip::SharedPtr<resip::MasterProfile>(new resip::MasterProfile());
|
||||
mProfile = std::make_shared<resip::MasterProfile>();
|
||||
mProfile->clearSupportedMethods();
|
||||
mProfile->addSupportedMethod(resip::INVITE);
|
||||
mProfile->addSupportedMethod(resip::BYE);
|
||||
|
|
@ -146,8 +146,8 @@ void UserAgent::start()
|
|||
mTransportList.clear();
|
||||
resip::InternalTransport* t;
|
||||
|
||||
#define ADD_TRANSPORT4(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V4)))) { t->setTransportLogger(this); mTransportList.push_back(t);}
|
||||
#define ADD_TRANSPORT6(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V6)))) { t->setTransportLogger(this); mTransportList.push_back(t);}
|
||||
#define ADD_TRANSPORT4(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V4)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);}
|
||||
#define ADD_TRANSPORT6(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V6)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);}
|
||||
|
||||
switch (mConfig[CONFIG_TRANSPORT].asInt())
|
||||
{
|
||||
|
|
@ -315,7 +315,10 @@ void UserAgent::stop()
|
|||
mTransportList.clear();
|
||||
|
||||
// Dump statistics here
|
||||
ICELogInfo(<< "Remaining " << Session::InstanceCounter.value() << " session(s), " << ResipSession::InstanceCounter.value() << " resip DialogSet(s), " << resip::ClientRegistration::InstanceCounter.value() << " ClientRegistration(s)");
|
||||
ICELogInfo(<< "Remaining "
|
||||
<< Session::InstanceCounter << " session(s), "
|
||||
<< ResipSession::InstanceCounter << " resip DialogSet(s), "
|
||||
<< resip::ClientRegistration::InstanceCounter << " ClientRegistration(s)");
|
||||
|
||||
mDum->shutdown(this);
|
||||
onDumCanBeDeleted();
|
||||
|
|
@ -585,7 +588,7 @@ void UserAgent::sendOffer(Session* session)
|
|||
if (session->mOriginVersion == 1)
|
||||
{
|
||||
// Construct INVITE session
|
||||
resip::SharedPtr<resip::SipMessage> msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession);
|
||||
auto msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession);
|
||||
|
||||
// Include user headers
|
||||
for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin(); iter != session->mUserHeaders.end(); iter++)
|
||||
|
|
@ -655,8 +658,14 @@ void UserAgent::onFailure(resip::ClientRegistrationHandle h, const resip::SipMes
|
|||
|
||||
#pragma endregion
|
||||
|
||||
bool UserAgent::operator()(resip::Log::Level level, const resip::Subsystem& subsystem, const resip::Data& appName, const char* file,
|
||||
int line, const resip::Data& message, const resip::Data& messageWithHeaders)
|
||||
bool UserAgent::operator()(resip::Log::Level level,
|
||||
const resip::Subsystem& subsystem,
|
||||
const resip::Data& appName,
|
||||
const char* file,
|
||||
int line,
|
||||
const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders,
|
||||
const resip::Data& instanceName)
|
||||
{
|
||||
std::string filename = file;
|
||||
std::stringstream ss;
|
||||
|
|
@ -990,7 +999,7 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
|
|||
s->mIceStack->clear();
|
||||
}
|
||||
|
||||
UInt64 version = sdp.session().origin().getVersion();
|
||||
uint64_t version = sdp.session().origin().getVersion();
|
||||
s->mRemoteOriginVersion = version;
|
||||
}
|
||||
|
||||
|
|
@ -1017,10 +1026,10 @@ void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& m
|
|||
|
||||
ice::Stack& ice = *s->mIceStack;
|
||||
|
||||
UInt64 version = sdp.session().origin().getVersion();
|
||||
uint64_t version = sdp.session().origin().getVersion();
|
||||
std::string remoteIp = sdp.session().connection().getAddress().c_str();
|
||||
int code;
|
||||
if ((UInt64)-1 == s->mRemoteOriginVersion)
|
||||
if ((uint64_t)-1 == s->mRemoteOriginVersion)
|
||||
{
|
||||
code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media());
|
||||
}
|
||||
|
|
@ -1564,7 +1573,7 @@ void UserAgent::onSipMessage(int flow, const char* msg, unsigned int length, con
|
|||
ice::NetworkAddress address(*addr, addrlen);
|
||||
std::string addressText = address.toStdString();
|
||||
|
||||
switch (flow)
|
||||
/*switch (flow)
|
||||
{
|
||||
case resip::InternalTransport::TransportLogger::Flow_Received:
|
||||
ICELogDebug(<< "Received from " << addressText << ":" << "\n"
|
||||
|
|
@ -1574,7 +1583,7 @@ void UserAgent::onSipMessage(int flow, const char* msg, unsigned int length, con
|
|||
case resip::InternalTransport::TransportLogger::Flow_Sent:
|
||||
ICELogDebug(<< "Sent to " << addressText << "\n" << strx::prefixLines(d, "<---"));
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
PSession UserAgent::getUserSession(int sessionId)
|
||||
|
|
|
|||
|
|
@ -383,7 +383,8 @@ public:
|
|||
const char* file,
|
||||
int line,
|
||||
const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders) override;
|
||||
const resip::Data& messageWithHeaders,
|
||||
const resip::Data& instanceName) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DnsResultSink implementation
|
||||
|
|
@ -437,7 +438,7 @@ public:
|
|||
|
||||
#pragma region PagerHandler
|
||||
void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents);
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents) override;
|
||||
void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override;
|
||||
#pragma endregion
|
||||
|
||||
|
|
@ -447,7 +448,7 @@ protected:
|
|||
Mutex mGuard;
|
||||
|
||||
// Smart pointer to resiprocate's master profile instance. The stack configuration holds here.
|
||||
resip::SharedPtr<resip::MasterProfile> mProfile;
|
||||
std::shared_ptr<resip::MasterProfile> mProfile;
|
||||
|
||||
// Resiprocate's SIP stack object pointer
|
||||
resip::SipStack* mStack;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void WatcherQueue::process()
|
|||
if (i == mItemList.end())
|
||||
return;
|
||||
|
||||
resip::SharedPtr<resip::SipMessage> msg;
|
||||
std::shared_ptr<resip::SipMessage> msg;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
|
||||
switch (i->mState)
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ ResipSessionAppDialog::~ResipSessionAppDialog()
|
|||
|
||||
#pragma region ResipSession
|
||||
|
||||
resip::AtomicCounter ResipSession::InstanceCounter;
|
||||
std::atomic_int ResipSession::InstanceCounter;
|
||||
|
||||
ResipSession::ResipSession(resip::DialogUsageManager& dum)
|
||||
: resip::AppDialogSet(dum), mUserAgent(NULL), mType(Type_None), mSessionId(0), mSession(0)
|
||||
{
|
||||
ResipSession::InstanceCounter.increment();
|
||||
ResipSession::InstanceCounter++;
|
||||
mTag = NULL;
|
||||
mTerminated = false;
|
||||
mOnWatchingStartSent = false;
|
||||
|
|
@ -62,7 +62,7 @@ ResipSession::~ResipSession()
|
|||
{
|
||||
}
|
||||
|
||||
ResipSession::InstanceCounter.decrement();
|
||||
ResipSession::InstanceCounter--;
|
||||
}
|
||||
|
||||
resip::AppDialog* ResipSession::createAppDialog(const resip::SipMessage& msg)
|
||||
|
|
@ -167,12 +167,12 @@ int ResipSession::sessionId()
|
|||
return mSessionId;
|
||||
}
|
||||
|
||||
void ResipSession::setUASProfile(std::shared_ptr<resip::UserProfile> profile)
|
||||
void ResipSession::setUASProfile(const std::shared_ptr<resip::UserProfile>& profile)
|
||||
{
|
||||
mUASProfile = profile;
|
||||
}
|
||||
|
||||
resip::SharedPtr<resip::UserProfile> ResipSession::selectUASUserProfile(const resip::SipMessage& msg)
|
||||
std::shared_ptr<resip::UserProfile> ResipSession::selectUASUserProfile(const resip::SipMessage& msg)
|
||||
{
|
||||
assert(mUserAgent != nullptr);
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ resip::SharedPtr<resip::UserProfile> ResipSession::selectUASUserProfile(const re
|
|||
else
|
||||
return mUserAgent->mProfile;
|
||||
}
|
||||
return resip::SharedPtr<resip::UserProfile>();
|
||||
return std::shared_ptr<resip::UserProfile>();
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -262,11 +262,11 @@ void Session::Stream::setRtcpMuxAttr(bool value)
|
|||
#pragma endregion
|
||||
|
||||
#pragma region Session
|
||||
resip::AtomicCounter Session::InstanceCounter;
|
||||
std::atomic_int Session::InstanceCounter;
|
||||
|
||||
Session::Session(PAccount account)
|
||||
{
|
||||
InstanceCounter.increment();
|
||||
InstanceCounter++;
|
||||
mAccount = account;
|
||||
mSessionId = Session::generateId();
|
||||
mTag = NULL;
|
||||
|
|
@ -278,7 +278,7 @@ Session::Session(PAccount account)
|
|||
mRole = Acceptor;
|
||||
mGatheredCandidates = false;
|
||||
mTerminated = false;
|
||||
mRemoteOriginVersion = (UInt64)-1;
|
||||
mRemoteOriginVersion = (uint64_t)-1;
|
||||
mResipSession = NULL;
|
||||
mRefCount = 1;
|
||||
mOfferAnswerCounter = 0;
|
||||
|
|
@ -296,7 +296,7 @@ Session::~Session()
|
|||
}
|
||||
catch(...)
|
||||
{}
|
||||
InstanceCounter.decrement();
|
||||
InstanceCounter--;
|
||||
}
|
||||
|
||||
void Session::start(const std::string& peer)
|
||||
|
|
@ -829,10 +829,10 @@ int Session::sessionId()
|
|||
return mSessionId;
|
||||
}
|
||||
|
||||
resip::AtomicCounter Session::IdGenerator;
|
||||
std::atomic_int Session::IdGenerator;
|
||||
int Session::generateId()
|
||||
{
|
||||
return (int)IdGenerator.increment();
|
||||
return ++IdGenerator;
|
||||
}
|
||||
|
||||
std::string Session::remoteAddress() const
|
||||
|
|
@ -914,7 +914,7 @@ void Session::refreshMediaPath()
|
|||
}
|
||||
|
||||
// Received offer with new SDP
|
||||
int Session::processSdp(UInt64 version, bool iceAvailable, std::string icePwd, std::string iceUfrag,
|
||||
int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd, std::string iceUfrag,
|
||||
std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media)
|
||||
{
|
||||
bool iceRestart = false;
|
||||
|
|
|
|||
|
|
@ -213,7 +213,8 @@ public:
|
|||
void refreshMediaPath();
|
||||
|
||||
// Processes new sdp from offer. Returns response code (200 is ok, 488 bad codec, 503 internal error).
|
||||
int processSdp(UInt64 version, bool iceAvailable, std::string icePwd, std::string iceUfrag,
|
||||
// There are passing string objects by value; this is correct; this values will modified on the stack.
|
||||
int processSdp(uint64_t version, bool iceAvailable, std::string icePwd, const std::string iceUfrag,
|
||||
std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media);
|
||||
|
||||
// Session ID
|
||||
|
|
@ -223,7 +224,7 @@ public:
|
|||
std::vector<Stream> mStreamList;
|
||||
|
||||
// Smart pointer to ICE stack. Actually stack is created in CreateICEStack() method
|
||||
resip::SharedPtr<ice::Stack> mIceStack;
|
||||
std::shared_ptr<ice::Stack> mIceStack;
|
||||
|
||||
// Pointer to owner user agent instance
|
||||
UserAgent* mUserAgent;
|
||||
|
|
@ -236,7 +237,7 @@ public:
|
|||
|
||||
// SDP's origin version for sending
|
||||
int mOriginVersion;
|
||||
UInt64 mRemoteOriginVersion;
|
||||
uint64_t mRemoteOriginVersion;
|
||||
|
||||
// SDP's session version
|
||||
int mSessionVersion;
|
||||
|
|
@ -359,7 +360,7 @@ public:
|
|||
ResipSession(resip::DialogUsageManager& dum);
|
||||
virtual ~ResipSession();
|
||||
virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg);
|
||||
virtual resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
virtual std::shared_ptr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
|
||||
void setType(Type type);
|
||||
Type type();
|
||||
|
|
@ -383,7 +384,7 @@ public:
|
|||
|
||||
void runTerminatedEvent(Type type, int code = 0, int reason = 0);
|
||||
|
||||
void setUASProfile(std::shared_ptr<resip::UserProfile> profile);
|
||||
void setUASProfile(const std::shared_ptr<resip::UserProfile>& profile);
|
||||
|
||||
protected:
|
||||
bool mTerminated;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "HL_File.h"
|
||||
#include <fstream>
|
||||
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_OSX)
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_OSX) || defined(TARGET_ANDROID)
|
||||
# include <unistd.h>
|
||||
# include <sys/statvfs.h>
|
||||
# include <memory.h>
|
||||
|
|
@ -34,7 +34,7 @@ void FileHelper::remove(const char* s)
|
|||
|
||||
std::string FileHelper::gettempname()
|
||||
{
|
||||
#if defined(TARGET_LINUX)
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
|
||||
char template_filename[L_tmpnam] = "rtphone_XXXXXXX.tmp";
|
||||
mkstemp(template_filename);
|
||||
return template_filename;
|
||||
|
|
@ -64,7 +64,7 @@ std::string FileHelper::getCurrentDir()
|
|||
return std::string();
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_OSX)
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_OSX) || defined(TARGET_ANDROID)
|
||||
char buf[512];
|
||||
if (getcwd(buf, sizeof buf) != nullptr)
|
||||
return buf;
|
||||
|
|
|
|||
|
|
@ -311,6 +311,8 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
|
|||
return t;
|
||||
}
|
||||
|
||||
#if defined(TARGET_OSX) || defined(TARGET_LINUX)
|
||||
|
||||
pid_t OsProcess::findPid(const std::string& cmdline)
|
||||
{
|
||||
try
|
||||
|
|
@ -332,5 +334,6 @@ void OsProcess::killByPid(pid_t pid)
|
|||
return;
|
||||
execSystem("kill -9 " + std::to_string(pid) + " &");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,13 +17,20 @@
|
|||
# if defined(WINDOWS_RT)
|
||||
# include "ICEWinRtSupport.h"
|
||||
# endif
|
||||
#else
|
||||
#if defined(TARGET_IOS)
|
||||
#elif defined(TARGET_IOS)
|
||||
# include "ICEIosSupport.h"
|
||||
#endif
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# if defined(TARGET_ANDROID)/* || defined(TARGET_LINUX) */
|
||||
# if defined(TARGET_ANDROID) || defined(TARGET_LINUX)
|
||||
# include <linux/if.h>
|
||||
# include <linux/in6.h>
|
||||
# if defined(TARGET_ANDROID)
|
||||
# if __ANDROID_API__ < 24
|
||||
# include "android-ifaddrs/android-ifaddrs.h"
|
||||
# else
|
||||
# include <ifaddrs.h>
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
image: Visual Studio 2015
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
platform:
|
||||
- x64
|
||||
- Win32
|
||||
|
||||
build:
|
||||
parallel: true
|
||||
project: reSIProcate_14_0.sln
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# This file is only looked at when a checked-out SVN
|
||||
# repository is used as the source for a git repo.
|
||||
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
/Makefile
|
||||
/Makefile.in
|
||||
/.deps
|
||||
/.libs
|
||||
/aclocal.m4
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.log
|
||||
/config.status
|
||||
/configure
|
||||
/libtool
|
||||
/m4
|
||||
/stamp-h1
|
||||
/autom4te.cache
|
||||
/build-aux
|
||||
/resiprocate.spec
|
||||
/resiprocate-[0-9]*.tar.gz
|
||||
/resiprocate-[0-9]*.zip
|
||||
/resiprocate-contrib-[0-9]*.tar.gz
|
||||
/resiprocate-contrib-[0-9]*.zip
|
||||
/repro_*.db
|
||||
|
||||
/SVN-VERSION
|
||||
/.make_prefs
|
||||
/build/Makefile.conf
|
||||
tags
|
||||
*build.Linux*
|
||||
.dependlibs
|
||||
bin.debug.*
|
||||
obj.debug.*
|
||||
bin.opt.*
|
||||
obj.opt.*
|
||||
bin.gopt.*
|
||||
obj.gopt.*
|
||||
obj.prof.*
|
||||
bin.prof.*
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
language: cpp
|
||||
dist: bionic
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "MxxolEXPuFJ38hk7lhGqunKwsc8CIMUy8vCoswNDyFvuBm5FEcEaNe/SIjqli8fCXTrWh3LoCIyulezCoFkysjfSSmLFCngoAEvIWTX1hS9rnh+z1g7vUJiIcj1jiYFV+wk5C44IuMDfOEX6FFh4vRiT/IkZsrXf5IbxD08vUW8="
|
||||
before_install:
|
||||
- sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu/ bionic main universe"
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq gperf libboost-all-dev libc-ares-dev libdb++-dev libpopt-dev libssl-dev perl libmysqlclient-dev libpq-dev libcppunit-dev autotools-dev libpcre3-dev libxerces-c-dev curl libcajun-dev libsrtp-dev libgloox-dev libtelepathy-qt5-dev libsnmp-dev
|
||||
- sudo apt-get install -qq debian-archive-keyring
|
||||
- wget -q -O - https://ftp-master.debian.org/keys/release-10.asc | sudo apt-key add -
|
||||
- wget -q -O - https://ftp-master.debian.org/keys/archive-key-10.asc | sudo apt-key add -
|
||||
- sudo add-apt-repository -y "deb http://http.us.debian.org/debian/ buster main"
|
||||
- sudo add-apt-repository -y "deb http://http.us.debian.org/debian/ buster-backports main"
|
||||
- curl -O http://apt.debify.org/debify/pool/main/d/debify-archive-keyring/debify-archive-keyring_2019.01_all.deb
|
||||
- sudo dpkg -i debify-archive-keyring_2019.01_all.deb
|
||||
- sudo add-apt-repository -y "deb http://apt.debify.org/debify debify-buster-backports main"
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq --force-yes -t buster libradcli-dev libsoci-dev libqpid-proton-cpp12-dev libasio-dev python3-dev python3-cxx-dev
|
||||
- sudo apt-get install -qq --force-yes -t debify-buster-backports libsipxtapi-dev
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
script:
|
||||
- ./build/travis/bootstrap
|
||||
- ./build/travis/configure
|
||||
- ./build/travis/build
|
||||
|
||||
# This is not enabled yet, the following issues are pending:
|
||||
# - do we need to use the custom script to exclude builds of pull requests?
|
||||
# see: https://raw.githubusercontent.com/daksheshvyas/MyHelloWorld/master/scan_script.sh
|
||||
# - how to run "make check" after the Coverity scan to ensure builds are faster?
|
||||
# - how to ensure the Coverity scan only runs with the GCC builds and not
|
||||
# the clang builds (to avoid duplication) - we must do clang builds to
|
||||
# ensure code compiles for different compilers
|
||||
# Ideas:
|
||||
# - run the scans on a branch only
|
||||
# - customize the scan_script.sh example from https://github.com/daksheshvyas/MyHelloWorld
|
||||
# - try and revert to the old method of running Coverity scans
|
||||
#addons:
|
||||
# coverity_scan:
|
||||
# project:
|
||||
# name: "resiprocate/resiprocate"
|
||||
# description: "reSIProcate SIP stack"
|
||||
# notification_email: resiprocate-devel@resiprocate.org
|
||||
# build_command_prepend: ./build/travis/bootstrap && ./build/travis/configure
|
||||
# build_command: ./build/travis/build
|
||||
# branch_pattern: master
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
|
||||
Please add your name, email address and if you contribute on
|
||||
behalf of a company, please identity the name of the company,
|
||||
company registration number and the place of incorporation.
|
||||
|
||||
This file identifies the authors/contributors/copyright holders who
|
||||
have contributed works of any kind to the main reSIProcate
|
||||
distribution tarball.
|
||||
|
||||
This file does not cover the material in the contrib/ directory of
|
||||
the source control system, as each of those components is
|
||||
unmodified and distributed with it's own AUTHORS file.
|
||||
|
||||
$ git log | grep ^Author | sort -u | cut -f2 -d' '
|
||||
|
||||
adam
|
||||
adamr
|
||||
alan
|
||||
arosenberg
|
||||
bbramwel
|
||||
bcampen
|
||||
bko
|
||||
bob
|
||||
brocha
|
||||
bryan
|
||||
cbond
|
||||
cisco
|
||||
cktam
|
||||
dabryan
|
||||
daniel
|
||||
danweber
|
||||
Danweber
|
||||
davidb
|
||||
dbozzali
|
||||
dean
|
||||
derek
|
||||
Derek
|
||||
derekm
|
||||
dlb
|
||||
dpetrie
|
||||
dpocock: Daniel Pocock <daniel@pocock.com.au>
|
||||
dragos
|
||||
dsuh
|
||||
duanestorey
|
||||
dworley
|
||||
ekr
|
||||
emcmurry
|
||||
fjoanis
|
||||
fluffy
|
||||
greg
|
||||
jason
|
||||
jdeverick
|
||||
jgeras
|
||||
jmatthewsr
|
||||
jozsef
|
||||
kchmilar
|
||||
kdc
|
||||
kenho
|
||||
ken
|
||||
kittlitz
|
||||
kwhite
|
||||
lowekamp
|
||||
matthias
|
||||
maxb
|
||||
mfroman
|
||||
moetje
|
||||
nagendra
|
||||
nash
|
||||
nils
|
||||
(no
|
||||
partim
|
||||
pckizer
|
||||
rjsparks
|
||||
rohan
|
||||
ronh
|
||||
ryker
|
||||
sailesh
|
||||
satluri
|
||||
schanin
|
||||
sgodin
|
||||
shaun
|
||||
troll
|
||||
vann
|
||||
veer
|
||||
vinit
|
||||
wensong
|
||||
xmlscott
|
||||
|
||||
|
||||
|
|
@ -1,322 +0,0 @@
|
|||
project (resiprocate)
|
||||
|
||||
if (NOT OPENSSL_INCLUDE)
|
||||
message(FATAL_ERROR "OPENSSL_INCLUDE has to be directory with OpenSSL 1.0.x include files.")
|
||||
endif()
|
||||
|
||||
# Rely on C++ 11
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set (DIR_ARES rutil/dns/ares)
|
||||
set (ARES_SOURCES
|
||||
${DIR_ARES}/ares_timeout.c
|
||||
${DIR_ARES}/ares_strerror.c
|
||||
${DIR_ARES}/ares_send.c
|
||||
${DIR_ARES}/ares_search.c
|
||||
${DIR_ARES}/ares_query.c
|
||||
${DIR_ARES}/ares_process.c
|
||||
${DIR_ARES}/ares_parse_ptr_reply.c
|
||||
${DIR_ARES}/ares_parse_a_reply.c
|
||||
${DIR_ARES}/ares_mkquery.c
|
||||
${DIR_ARES}/ares_local.c
|
||||
${DIR_ARES}/ares_init.c
|
||||
${DIR_ARES}/ares_gethostbyname.c
|
||||
${DIR_ARES}/ares_gethostbyaddr.c
|
||||
${DIR_ARES}/ares_free_string.c
|
||||
${DIR_ARES}/ares_free_hostent.c
|
||||
${DIR_ARES}/ares_free_errmem.c
|
||||
${DIR_ARES}/ares_fds.c
|
||||
${DIR_ARES}/ares_expand_name.c
|
||||
${DIR_ARES}/ares_destroy.c
|
||||
${DIR_ARES}/ares__read_line.c
|
||||
${DIR_ARES}/ares__get_hostent.c
|
||||
${DIR_ARES}/ares__close_sockets.c
|
||||
)
|
||||
|
||||
set (STACK_SOURCES
|
||||
resip/stack/Compression.cxx
|
||||
resip/stack/CallId.cxx
|
||||
resip/stack/BranchParameter.cxx
|
||||
resip/stack/BasicNonceHelper.cxx
|
||||
resip/stack/Auth.cxx
|
||||
resip/stack/ApplicationSip.cxx
|
||||
resip/stack/ApiCheck.cxx
|
||||
resip/stack/Aor.cxx
|
||||
resip/stack/DateCategory.cxx
|
||||
resip/stack/DataParameter.cxx
|
||||
resip/stack/CSeqCategory.cxx
|
||||
resip/stack/CpimContents.cxx
|
||||
resip/stack/ContentsFactoryBase.cxx
|
||||
resip/stack/Contents.cxx
|
||||
resip/stack/ConnectionManager.cxx
|
||||
resip/stack/ConnectionBase.cxx
|
||||
resip/stack/Connection.cxx
|
||||
resip/stack/DnsResult.cxx
|
||||
resip/stack/DnsInterface.cxx
|
||||
resip/stack/DeprecatedDialog.cxx
|
||||
resip/stack/GenericUri.cxx
|
||||
resip/stack/GenericContents.cxx
|
||||
resip/stack/FloatParameter.cxx
|
||||
resip/stack/ExternalBodyContents.cxx
|
||||
resip/stack/ExtensionParameter.cxx
|
||||
resip/stack/ExtensionHeader.cxx
|
||||
resip/stack/ExpiresCategory.cxx
|
||||
resip/stack/ExistsParameter.cxx
|
||||
resip/stack/ExistsOrDataParameter.cxx
|
||||
resip/stack/EventStackThread.cxx
|
||||
resip/stack/Embedded.cxx
|
||||
resip/stack/DtlsMessage.cxx
|
||||
# resip/stack/HeaderHash.cxx
|
||||
resip/stack/HeaderFieldValueList.cxx
|
||||
resip/stack/HeaderFieldValue.cxx
|
||||
resip/stack/MsgHeaderScanner.cxx
|
||||
resip/stack/Mime.cxx
|
||||
resip/stack/MethodTypes.cxx
|
||||
# resip/stack/MethodHash.cxx
|
||||
resip/stack/MessageWaitingContents.cxx
|
||||
resip/stack/MessageFilterRule.cxx
|
||||
resip/stack/Message.cxx
|
||||
resip/stack/LazyParser.cxx
|
||||
resip/stack/KeepAliveMessage.cxx
|
||||
resip/stack/InvalidContents.cxx
|
||||
resip/stack/InterruptableStackThread.cxx
|
||||
resip/stack/InteropHelper.cxx
|
||||
resip/stack/InternalTransport.cxx
|
||||
resip/stack/IntegerParameter.cxx
|
||||
resip/stack/IntegerCategory.cxx
|
||||
resip/stack/Helper.cxx
|
||||
resip/stack/HeaderTypes.cxx
|
||||
resip/stack/Headers.cxx
|
||||
# resip/stack/ParameterHash.cxx
|
||||
resip/stack/Parameter.cxx
|
||||
resip/stack/OctetContents.cxx
|
||||
resip/stack/NonceHelper.cxx
|
||||
resip/stack/NameAddr.cxx
|
||||
resip/stack/MultipartSignedContents.cxx
|
||||
resip/stack/MultipartRelatedContents.cxx
|
||||
resip/stack/MultipartMixedContents.cxx
|
||||
resip/stack/MultipartAlternativeContents.cxx
|
||||
resip/stack/SipStack.cxx
|
||||
resip/stack/SipMessage.cxx
|
||||
resip/stack/SipFrag.cxx
|
||||
resip/stack/SERNonceHelper.cxx
|
||||
resip/stack/SecurityAttributes.cxx
|
||||
resip/stack/SdpContents.cxx
|
||||
resip/stack/RportParameter.cxx
|
||||
resip/stack/Rlmi.cxx
|
||||
resip/stack/RequestLine.cxx
|
||||
resip/stack/RAckCategory.cxx
|
||||
resip/stack/QValueParameter.cxx
|
||||
resip/stack/QValue.cxx
|
||||
resip/stack/QuotedDataParameter.cxx
|
||||
resip/stack/PrivacyCategory.cxx
|
||||
resip/stack/PlainContents.cxx
|
||||
resip/stack/Pkcs8Contents.cxx
|
||||
resip/stack/Pkcs7Contents.cxx
|
||||
resip/stack/Pidf.cxx
|
||||
resip/stack/ParserContainerBase.cxx
|
||||
resip/stack/ParserCategory.cxx
|
||||
resip/stack/ParserCategories.cxx
|
||||
resip/stack/ParameterTypes.cxx
|
||||
resip/stack/X509Contents.cxx
|
||||
resip/stack/WarningCategory.cxx
|
||||
resip/stack/Via.cxx
|
||||
resip/stack/Uri.cxx
|
||||
resip/stack/UnknownParameter.cxx
|
||||
resip/stack/UInt32Parameter.cxx
|
||||
resip/stack/UInt32Category.cxx
|
||||
resip/stack/UdpTransport.cxx
|
||||
resip/stack/TuSelector.cxx
|
||||
resip/stack/TupleMarkManager.cxx
|
||||
resip/stack/Tuple.cxx
|
||||
resip/stack/TuIM.cxx
|
||||
resip/stack/TransportThread.cxx
|
||||
resip/stack/TransportSelector.cxx
|
||||
resip/stack/TransportFailure.cxx
|
||||
resip/stack/Transport.cxx
|
||||
resip/stack/TransactionUserMessage.cxx
|
||||
resip/stack/TransactionUser.cxx
|
||||
resip/stack/TransactionState.cxx
|
||||
resip/stack/TransactionMap.cxx
|
||||
resip/stack/TransactionController.cxx
|
||||
resip/stack/Token.cxx
|
||||
resip/stack/TimerQueue.cxx
|
||||
resip/stack/TimerMessage.cxx
|
||||
resip/stack/TimeAccumulate.cxx
|
||||
resip/stack/TcpTransport.cxx
|
||||
resip/stack/TcpConnection.cxx
|
||||
resip/stack/TcpBaseTransport.cxx
|
||||
resip/stack/Symbols.cxx
|
||||
resip/stack/StringCategory.cxx
|
||||
resip/stack/StatusLine.cxx
|
||||
resip/stack/StatisticsMessage.cxx
|
||||
resip/stack/StatisticsManager.cxx
|
||||
resip/stack/StatisticsHandler.cxx
|
||||
resip/stack/StatelessHandler.cxx
|
||||
resip/stack/StackThread.cxx
|
||||
resip/stack/ssl/Security.cxx
|
||||
#resip/stack/ssl/MacSecurity.cxx
|
||||
#resip/stack/ssl/WinSecurity.cxx
|
||||
resip/stack/ssl/TlsConnection.cxx
|
||||
resip/stack/ssl/TlsTransport.cxx
|
||||
)
|
||||
|
||||
set (DUM_SOURCES
|
||||
resip/dum/DialogUsageManager.cxx
|
||||
resip/dum/DialogUsage.cxx
|
||||
resip/dum/DialogSetId.cxx
|
||||
resip/dum/DialogSet.cxx
|
||||
resip/dum/DialogId.cxx
|
||||
resip/dum/DialogEventStateManager.cxx
|
||||
resip/dum/DialogEventInfo.cxx
|
||||
resip/dum/Dialog.cxx
|
||||
resip/dum/DestroyUsage.cxx
|
||||
resip/dum/DefaultServerReferHandler.cxx
|
||||
resip/dum/ContactInstanceRecord.cxx
|
||||
resip/dum/ClientSubscription.cxx
|
||||
resip/dum/ClientRegistration.cxx
|
||||
resip/dum/ClientPublication.cxx
|
||||
resip/dum/ClientPagerMessage.cxx
|
||||
resip/dum/ClientOutOfDialogReq.cxx
|
||||
resip/dum/ClientInviteSession.cxx
|
||||
resip/dum/ClientAuthManager.cxx
|
||||
resip/dum/ClientAuthExtension.cxx
|
||||
resip/dum/ChallengeInfo.cxx
|
||||
resip/dum/CertMessage.cxx
|
||||
resip/dum/BaseUsage.cxx
|
||||
resip/dum/BaseSubscription.cxx
|
||||
resip/dum/BaseCreator.cxx
|
||||
resip/dum/AppDialogSetFactory.cxx
|
||||
resip/dum/AppDialogSet.cxx
|
||||
resip/dum/AppDialog.cxx
|
||||
resip/dum/KeepAliveTimeout.cxx
|
||||
resip/dum/KeepAliveManager.cxx
|
||||
resip/dum/InviteSessionHandler.cxx
|
||||
resip/dum/InviteSessionCreator.cxx
|
||||
resip/dum/InviteSession.cxx
|
||||
resip/dum/InMemorySyncRegDb.cxx
|
||||
resip/dum/InMemoryRegistrationDatabase.cxx
|
||||
resip/dum/IdentityHandler.cxx
|
||||
resip/dum/HttpProvider.cxx
|
||||
resip/dum/HttpGetMessage.cxx
|
||||
resip/dum/HandleManager.cxx
|
||||
resip/dum/HandleException.cxx
|
||||
resip/dum/Handled.cxx
|
||||
resip/dum/Handle.cxx
|
||||
resip/dum/EncryptionRequest.cxx
|
||||
resip/dum/DumTimeout.cxx
|
||||
resip/dum/DumThread.cxx
|
||||
resip/dum/DumProcessHandler.cxx
|
||||
resip/dum/DumHelper.cxx
|
||||
resip/dum/DumFeatureMessage.cxx
|
||||
resip/dum/DumFeatureChain.cxx
|
||||
resip/dum/DumFeature.cxx
|
||||
resip/dum/DumDecrypted.cxx
|
||||
resip/dum/ServerSubscription.cxx
|
||||
resip/dum/ServerRegistration.cxx
|
||||
resip/dum/ServerPublication.cxx
|
||||
resip/dum/ServerPagerMessage.cxx
|
||||
resip/dum/ServerOutOfDialogReq.cxx
|
||||
resip/dum/ServerInviteSession.cxx
|
||||
resip/dum/ServerAuthManager.cxx
|
||||
resip/dum/RegistrationHandler.cxx
|
||||
resip/dum/RegistrationCreator.cxx
|
||||
resip/dum/RedirectManager.cxx
|
||||
resip/dum/RADIUSServerAuthManager.cxx
|
||||
resip/dum/PublicationCreator.cxx
|
||||
resip/dum/Profile.cxx
|
||||
resip/dum/PagerMessageCreator.cxx
|
||||
resip/dum/OutOfDialogReqCreator.cxx
|
||||
resip/dum/OutgoingEvent.cxx
|
||||
resip/dum/NonDialogUsage.cxx
|
||||
resip/dum/NetworkAssociation.cxx
|
||||
resip/dum/MergedRequestRemovalCommand.cxx
|
||||
resip/dum/MergedRequestKey.cxx
|
||||
resip/dum/MasterProfile.cxx
|
||||
resip/dum/UserProfile.cxx
|
||||
resip/dum/UserAuthInfo.cxx
|
||||
resip/dum/TlsPeerAuthManager.cxx
|
||||
resip/dum/TargetCommand.cxx
|
||||
resip/dum/SubscriptionState.cxx
|
||||
resip/dum/SubscriptionHandler.cxx
|
||||
resip/dum/SubscriptionCreator.cxx
|
||||
resip/dum/ssl/EncryptionManager.cxx
|
||||
)
|
||||
|
||||
SET (RUTIL_SOURCES
|
||||
rutil/FileSystem.cxx
|
||||
rutil/FdPoll.cxx
|
||||
rutil/DnsUtil.cxx
|
||||
rutil/ssl/OpenSSLInit.cxx
|
||||
rutil/ssl/SHA1Stream.cxx
|
||||
rutil/dns/RRVip.cxx
|
||||
rutil/dns/RROverlay.cxx
|
||||
rutil/dns/RRList.cxx
|
||||
rutil/dns/RRCache.cxx
|
||||
rutil/dns/QueryTypes.cxx
|
||||
rutil/dns/LocalDns.cxx
|
||||
rutil/dns/ExternalDnsFactory.cxx
|
||||
rutil/dns/DnsThread.cxx
|
||||
rutil/dns/DnsStub.cxx
|
||||
rutil/dns/DnsSrvRecord.cxx
|
||||
rutil/dns/DnsResourceRecord.cxx
|
||||
rutil/dns/DnsNaptrRecord.cxx
|
||||
rutil/dns/DnsHostRecord.cxx
|
||||
rutil/dns/DnsCnameRecord.cxx
|
||||
rutil/dns/DnsAAAARecord.cxx
|
||||
rutil/dns/AresDns.cxx
|
||||
rutil/DataStream.cxx
|
||||
rutil/Data.cxx
|
||||
rutil/CountStream.cxx
|
||||
rutil/ConfigParse.cxx
|
||||
rutil/Condition.cxx
|
||||
rutil/Coders.cxx
|
||||
rutil/BaseException.cxx
|
||||
rutil/AbstractFifo.cxx
|
||||
rutil/XMLCursor.cxx
|
||||
rutil/vmd5.cxx
|
||||
rutil/TransportType.cxx
|
||||
rutil/Timer.cxx
|
||||
rutil/Time.cxx
|
||||
rutil/ThreadIf.cxx
|
||||
rutil/SysLogStream.cxx
|
||||
rutil/SysLogBuf.cxx
|
||||
rutil/Subsystem.cxx
|
||||
rutil/stun/Udp.cxx
|
||||
rutil/stun/Stun.cxx
|
||||
rutil/Socket.cxx
|
||||
rutil/ServerProcess.cxx
|
||||
rutil/SelectInterruptor.cxx
|
||||
rutil/RWMutex.cxx
|
||||
rutil/resipfaststreams.cxx
|
||||
rutil/RecursiveMutex.cxx
|
||||
rutil/Random.cxx
|
||||
rutil/RADIUSDigestAuthenticator.cxx
|
||||
rutil/PoolBase.cxx
|
||||
rutil/Poll.cxx
|
||||
rutil/ParseException.cxx
|
||||
rutil/ParseBuffer.cxx
|
||||
rutil/Mutex.cxx
|
||||
rutil/MD5Stream.cxx
|
||||
rutil/Log.cxx
|
||||
rutil/Lock.cxx
|
||||
rutil/KeyValueStore.cxx
|
||||
rutil/HeapInstanceCounter.cxx
|
||||
rutil/GeneralCongestionManager.cxx
|
||||
# rutil/AtomicCounter.cxx
|
||||
# rutil/WinCompat.cxx
|
||||
)
|
||||
|
||||
|
||||
add_library(resiprocate ${ARES_SOURCES} ${RUTIL_SOURCES} ${STACK_SOURCES} ${DUM_SOURCES})
|
||||
|
||||
target_include_directories(resiprocate PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${DIR_ARES}
|
||||
${OPENSSL_INCLUDE}
|
||||
)
|
||||
target_compile_definitions(resiprocate PUBLIC -DUSE_ARES -DUSE_SSL)
|
||||
#add_library(resiprocate_lite ${RUTIL_SOURCES} ${STACK_SOURCES})
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
License note:
|
||||
- each source file has a license enclosed, usually in comments at
|
||||
the end of the file
|
||||
- individual authors have not always used an identical license
|
||||
block in their code, yet all the license blocks are for most
|
||||
purposes equivalent and compatible with the standard 3 clause
|
||||
BSD license
|
||||
- the bulk of the code is licensed under the terms of the Vovida
|
||||
license, which is like the BSD license with a 4th clause
|
||||
added restricting the use of the term VOCAL in the name
|
||||
of any derivative work. A full copy of the Vovida license
|
||||
is presented below.
|
||||
|
||||
|
||||
|
||||
The Vovida Software License, Version 1.0
|
||||
|
||||
Copyright (c) 2000-2008 Vovida Networks, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
not be used to endorse or promote products derived from this
|
||||
software without prior written permission. For written
|
||||
permission, please contact vocal@vovida.org.
|
||||
|
||||
4. Products derived from this software may not be called "VOCAL", nor
|
||||
may "VOCAL" appear in their name, without prior written
|
||||
permission of Vovida Networks, Inc.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
|
@ -1,538 +0,0 @@
|
|||
= Release Notes v 1.12 =
|
||||
|
||||
==1.12 Changes==
|
||||
*added Visual Studio 2017 Solutions and Project files
|
||||
*added OpenSSL 1.1.1 Support
|
||||
*added LibreSSL Support
|
||||
*added new reConServer application - B2BUA using recon
|
||||
*rutil: fix bug in SHA1 implementation
|
||||
*resip/stack: Uri: Fix potential out of bounds read
|
||||
*resip/stack: SdpContents: Reject malformed IP Address
|
||||
*rutil: ares: Fix heap overflow in ares_mkquery like c-ares does
|
||||
*resip/stack: Fix: Adding too many media connections may lead to memory exhaustion.
|
||||
*rutil: DnsUtil: Fix potential out of bounds access
|
||||
*rutil: cares use only: Missing handling of timers can cause 100% load in dns-thread if no answer is received from server
|
||||
*resip/dum: added support for reception of UPDATE (no SDP / target refresh) requests in early UAS dialog states
|
||||
*resip/dum: be tolerant of illegal subsequent SDP's in UAC PRACK flows as recommended by RFC6337 Section 3.1.1 and 3.1.2
|
||||
*resip/stack: ensure the buffered producer state machine fifo in the transports is flushed when operations are completed, so that getNextProcessTime API's will behave correctly
|
||||
*resip/stack: make DNS greylist duration configurable
|
||||
*repro: expose a new config setting in repro for DNS greylist duration
|
||||
*resip/dum: MasterProfile: added a removeSupportedMethod to remove a specific SIP method from thos available to profile.
|
||||
*resip/stack: fix: if IP Address routing fails over UDP and also fails over TCP, such that both UDP and TCP tuples are greylisted, then revert to using UDP (instead of TCP) until the greylisted entries expire
|
||||
*resip/dum: Added BaseUsage::postDum convenience method
|
||||
*resip/dum: modified DialogUsageManager::requestMergedRequestRemoval to not bother queuing a delayed merge request removal if the stack is shutting down. Helps to be less sensitive the order of object deletion at app exit time
|
||||
*rutil: ParseBuffer: Do not read past the buffer.
|
||||
*resip/stack: Security.cxx: Add support for ip address in subjectAltName
|
||||
*resip/dum: fix crash in ServerSubscription::shouldDestroyAfterSendingFailure
|
||||
*repro/resip/stack: fix an uncaught exception when loading certificates that can cause repro no to start is_directory can throw. This can happen when interrogating a broken link in linux.
|
||||
*repro: fix presence server so that NOTIFY messages are not sent out for publication refreshes that don't update the presence document
|
||||
*resip/stack: fix for WSS transports when reading large messages
|
||||
*resip/stack: fix for potential crash if Connection::processReads deletes the connection
|
||||
*resip/stack: fix NameAddr operator== so that an AllContact NameAddr is NOT equal to an empty NameAddr
|
||||
*rutil: Fix XMLCursor memory leak when ctor throws
|
||||
*repro: add new repro setting (AllowInboundFlowTokensForNonDirectClients) that works in-conjunction with RRTokenHack / EnableFlowTokens setting that allows inbound flow tokens to be used for connections that come from non-directly connected clients
|
||||
*resip/stack: fixed an issue where the stack could crash if a TCP based sender sends a Content-Length that is less that the actual SIP body transmitted
|
||||
*return: update ASIO drop from version 1.10.6 to 1.12.1
|
||||
*resip/dum/TlsPeerAuthManager and repro/monkeys/CertificateAuthenticator: add more debug logging
|
||||
*resip/dum repro: certificate authentication: async DB lookups
|
||||
*resip/stack/repro: More flexible domain matching is now supported
|
||||
*resip/stack: TuSelector: allow TUs to be inserted at front of list
|
||||
*resip/stack: Added ability to add non standard child elements to the Dialog package document Dialog element.
|
||||
*repro: update for qpid-prton 0.22.0
|
||||
|
||||
==1.11 (Beta) Changes==
|
||||
*resip/stack: implement http://tools.ietf.org/html/rfc3261#section-18.1.1, paragraph 8 (Server error conditions)
|
||||
*resip/stack: added TransactionUser::removeDomain API
|
||||
*rutil: fixed issue with DNS logic if we switch from DNS over UDP to DNS over TCP, which can occur when the DNS result is greater than 512 bytes
|
||||
*resip/stack: fixed up RFC4373 requires parameter - it is an exists parameter and not a Data parameter
|
||||
*resip/stack: added the ability to retrieve a list of simple presence info from a GenericPidfContents
|
||||
*rutil: improve the log output of DNS records
|
||||
*resip/recon: make sure we look at rinstance header, if it is present, when looking up the incoming conversation profile
|
||||
*resip/recon: added logic to detect if a TCP connection is terminated. This makes TCP registration errors detected much faster.
|
||||
*recon/MOHServer: multi-tenancy support. Allow registering more than one MOH AOR with it's own music file
|
||||
*recon/MOHServer: added certificate path setting
|
||||
*repro: added route order to key, so that you can have multiple routes with the same matching pattern and different destinations, as long as they use a different order value
|
||||
*resip/stack: added a reloadDnsServers API to SipStack
|
||||
*repro: added a Reload DNS Servers button to repro settings GUI
|
||||
*resip/stack: added ECONNABORTED to Windows TCP connection timeout processing for WSAPoll implementation
|
||||
*repro: changes to allow repro to run with outbound support behind a NAT device. Use configured transport specific record-routes in all cases
|
||||
*resip/stack: update TlsConnection.cxx to add TLS SNI extension in Client Hello
|
||||
*resip/dum: added new method to ClientRegistration class so that applications can check if a registration operation is currently in progress or not
|
||||
*resip/recon: send presence mechanism through PUBLISH message
|
||||
*resip/recon: send/receive text message with MESSAGE request
|
||||
*return/resip/repro: Use SSLv23 instead of TLSv1 when using OpenSSL for better TLS version capability
|
||||
*resip/dum: added ability for DialogUsage's (ie: InviteSessionHandle) to query the route set from the stored Dialog Info
|
||||
*resip/dum: added missing UAC_SentUpdateEarlyGlare state to the InviteSession::isEarly implementation
|
||||
*repro: added support for HOMER / HEP
|
||||
*resip/stack: added the ability to update QOS to a new value on existing stack managed sockets, without needing to restart the SipStack. Note: DNS sockets are not currently supported
|
||||
*resip/stack: fixed bug with SipStack::removeTransport method - transport selector maps could get out of sync and cause existing transports to not get used correctly after a runtime removal
|
||||
*resip/stack: added DialogInfoContents for handling of dialog-info+xml bodies
|
||||
*resip/dum: fixes to DUM's DialogEventStateManager implementation
|
||||
**fixed a bug in DialogEventStateManager that could tag as call as replaced in a dialog info event, even though it will get denied because it is in the incorrect state
|
||||
**fixed up DialogEventStateManager so that the onConfirmed callback will occur for any mid-dialog SDP changes
|
||||
**added accessor to DialogEventStateManager to be able return the DialogStateInfos for a particular Uri, instead of returning all DialogInfo's in memory
|
||||
**added missing DialogEventStateManager onTerminated callback for when we reject a UAS call
|
||||
*reflow resip/recon: add ForceCOMedia for NAT users / comedia behavior
|
||||
*repro: only bind HTTP and command ports to localhost by default
|
||||
*resip/recon: ensure G.722 sample rate is advertised as 8000 in local capabilities
|
||||
*resip/recon: warn about peers offering G.722 with sample rate other than 8000
|
||||
*resip repro: add AssumeFirstHopSupportsFlowTokens option
|
||||
*resip/stack resip/dum: InteropHelper: add option to enable/disable adding rport to Via
|
||||
*repro: add config option AddViaRport
|
||||
*resip/stack: fix for TCP timeout handling, ensure TransportFailure code is used so that the next DNS entry will be tried
|
||||
*resip/stack: removed use of USE_DNS_VIP preprocessor define and use a runtime setting instead. Runtime setting is a new parameter passed into one of the two SipStack constructors.
|
||||
*resip/recon: UserAgent: add method getConversationProfileByMediaAddress
|
||||
*rutil: GenericIPAddress: implement stream operator
|
||||
*reTurn: StunTuple: add method getSockaddr
|
||||
*reflow: add RTCPEventLoggingHandler API
|
||||
*rutil: OpenSSLInit: fix code to free compression methods
|
||||
*resip/dum: UserProfile: log a warning when no digest credentials available
|
||||
*ensure 503 and 408 blacklist and greylist logic is working correctly for Client Invite transactions on unreliable transports
|
||||
*repro: RegSyncServer: send reg sync XML messages to AMQP topic with Qpid Proton
|
||||
*resip/stack: DnsResult: add some debug messages when transport not supported
|
||||
*repro: make sure we create a DiaglogUsageManager if PresenseServer is enabled, could crash on startup otherwise
|
||||
*repro: RFC3326 (The Reason Header Field) Support in repro
|
||||
**When a forked call is answered by one leg the other legs are canceled. These cancel messages will now go out with a Reason header on them: Reason: SIP;cause=200;text=Call completed elsewhere
|
||||
**Repro will copy reason headers from Cancel message it receives from the caller to the Cancel messages that are sent to each leg.
|
||||
**If one of the call legs returns a 6xx global response code, then the other call legs are canceled. This CANCEL message will contain a reason header with the 6xx cause code and reason text in the reason header.
|
||||
**resip/dum: fix to ensure Privacy headers don't grow with each mid-dialog re-invite (if present)
|
||||
*repro / reTurn: Use systemd to restart if process stops unexpectedly
|
||||
|
||||
==1.10.2 Changes==
|
||||
*changes to support Windows 10 IOT ARM (RaspPi2)
|
||||
*VS2015 build support
|
||||
*cleanup some warnings
|
||||
*rutil: fix ARM / GCC 6 build issue with signed char[]
|
||||
*resip/stack: fix issue with ACK/non-200 transport selection for client transactions over WSS transports
|
||||
*repro: SQL backends: singleResultQuery: distinguish error from empty result set
|
||||
*repro: fix for OutboundTargets added by LocationServer - first parameter should be an AOR and not an instance Id
|
||||
*resip/dum: added convenience API's to DialogUsageManager for ending all ServerSubsciptions and ServerPublications to aid in graceful DUM shutdown
|
||||
*repro: fix for OutboundTargets added by LocationServer - first parameter should be an AOR and not an instance Id
|
||||
*resip/dum: fixed issue with DUM ServerInviteSession not automatically re-issuing an INVITE after received a 491. Also added tfdum test.
|
||||
*resip/stack: fix InternalTransport::bind to work when binding to port 0 when using an IPv6 interface
|
||||
*repro: update drop of GeoIP library to latest 1.6.9 version
|
||||
*return/recon: update ASIO drop from 1.10.1 to 1.10.6
|
||||
*resip/dum: ServerSubscription: fix reason text in responses
|
||||
|
||||
==1.10.1 Changes==
|
||||
*resip/stack: TLS: make the path argument of the Security class constructor more versatile
|
||||
*rutil, dum: RADIUS: support for radcli instead of freeradius-client
|
||||
*build: add more Visual Studio artifacts
|
||||
|
||||
==1.10.0 Changes==
|
||||
*repro: added a full presence server
|
||||
*resip/stack: WebSocket authentication may now use URL parameters instead of cookies
|
||||
*repro: added support for PostgreSQL and indexed database definitions
|
||||
*repro: can include multiple files into repro.config using Include
|
||||
*resip/stack: TLS: perfect forward secrecy (PFS) support using DH or ECDH
|
||||
*resip/stack: TLS compatibility and cipher strength improvements
|
||||
*resip/stack: TLS: support for passphrases used to encrypt private key files for domain certificates
|
||||
*rutil: better Syslog support (now sets severity correctly)
|
||||
*rutil: allow customization of assert() behavior using resip_assert(), improves diagnosis of crashes
|
||||
*resip/stack: added Poll(WSAPoll) implementation for event loop - allows Windows to support thousands of TCP connections instead of only ~60 (FD_SETSIZE)
|
||||
*resip/stack: added ability to remove transports at runtime
|
||||
*resip/stack: added netns (linux network namespace) support to stack
|
||||
|
||||
==1.9.11 Changes==
|
||||
*resip/stack: change TLS cipher suites to use -COMPLEMENTOFDEFAULT
|
||||
*repro: change TLS cipher suites to use -COMPLEMENTOFDEFAULT
|
||||
*repro: CommonNameMappings: detect repeated common names in config file
|
||||
*resip/stack: fix buffer management bug in WebSocket transport
|
||||
*rutil: XMLCursor: support whitespace before first XML element
|
||||
*resip/stack: Helper: fix for an auth validation issue
|
||||
*reTurn: add psql-user-extract script
|
||||
*resip/dum: DialogUsage: added logic to avoid trapping if mAppDialogSet is 0
|
||||
*resip/dum: DialogSet: Added handling for non-invite dialogs
|
||||
*resip/stack: ConnectionBase: increase max headers from 256 to 1024
|
||||
*rutil/dns/ares: fix for uninitialized pointer
|
||||
*rutil/dns/ares: remove cache-sensitive logic from caching algorithm
|
||||
*rutil/stun: Qualify bind to prevent clang from using std::bind
|
||||
*resip/stack/SdpContents: add some static codec definitions and new methods
|
||||
|
||||
==1.9.10 Changes==
|
||||
*resip/stack: support for OpenSSL versions that don't have all option names
|
||||
*resip/stack: lower severity of some log messages when TLS connections close
|
||||
*resip/stack: make ensureWriteable more tolerant during TLS handshakes, resolves crashes
|
||||
*resip/stack: add support for CA root cert bundle files
|
||||
*resip/stack: use StrongestSuite as default cipher list
|
||||
*resip/dum: challenge with correct realm when from and req URI domains don't match
|
||||
*rpm: update Wants and After details in unit files
|
||||
|
||||
==1.9.9 Changes==
|
||||
*resip/stack: only support SSL_OP_SAFARI_ECDHE_ECDSA_BUG as configuration string with compatible OpenSSL versions
|
||||
|
||||
==1.9.8 Changes==
|
||||
*resip/stack: add static fields on BaseSecurity for setting OpenSSL CTX options
|
||||
*resip/stack: explicitly disable SSLv2 and SSLv3 by default when using SSLv23
|
||||
*resip/stack: allow application to provide OpenSSL certificate verification callback
|
||||
*repro: change default OpenSSL method from TLSv1_method to SSLv23_method (enables TLS v1.1 and v1.2)
|
||||
*repro: add configuration options OpenSSLCTXSetOptions and OpenSSLCTXClearOptions to control OpenSSL CTX options
|
||||
*repro: add configuration OpenSSLCipherList to manually configure the OpenSSL cipher list
|
||||
==1.9.7 Changes==
|
||||
*rpm: Indicate that b2bua package is obsolete
|
||||
*resip/stack: TlsConnection: correctly handle OpenSSL error queue after SSL_read
|
||||
*resip/stack: fix for forced target routing in TransactionState - thanks to John Gregg for this
|
||||
*rutil: enhance command line parsing exceptions with additional details - thanks to John Gregg for initial contribution
|
||||
*rutil: if a v6 address is passed to the GenericIPAddress sockaddr constructor, ensure the entire v6 address is copied over properly. Note: sockaddr is smaller than sockaddr_in6 - Thanks to Bjorn A for this fix
|
||||
*rutil: accept case insensitive log level strings
|
||||
*resip/dum: fix obscure bug in basicClient where if we don't use a threaded stack processing does not function correctly - required PollGrp to be passed to SipStack constructor
|
||||
*resip/stack: fix for a use-after-free bug when adding multi-headers to a list that has been copied, and then one of the headers is accessed (but not necessarily parsed) - thanks to Byron Campen for this fix!
|
||||
*resip/stack: Added accessor for TransactionUser FIFO so to obtain stats
|
||||
*resip/stack: additional OpenSSL cleanup fn - reordered functions to match order used in this post: http://openssl.6102.n7.nabble.com/Cleanup-procedure-missing-some-calls-td37441.html
|
||||
*reTurn: modified asio and boost include file ordering to avoid multiply defined symbol errors on linking
|
||||
*resip/recon: remove extra sleep definitions
|
||||
*resip/stack: fix a bug with Keepalive processing that causes transaction state leakage and potential traps
|
||||
*rutil: syslog: use LOG_PID, avoid sending redundant data in log string.
|
||||
|
||||
==1.9.6 Changes==
|
||||
*resip/recon: fixes a bug that makes it impossible to use codecs with RTP clock rates other than 8000, makes Opus support possible
|
||||
*autotools: minor tweaks to reduce warnings during build/linking
|
||||
|
||||
==1.9.5 Changes==
|
||||
*resip/recon: do not send DTMF as inband audio, can be troublesome as sipXtapi echoes it back to caller (note: requires latest sipXtapi code with startChannelTone patch)
|
||||
*resip/recon: SipXHelper: map log entries from sipXtapi to reSIProcate logger
|
||||
*resip/recon: safety checks when using dynamic_cast with ConversationProfile
|
||||
*resip/recon: avoid changing payload IDs in the default ConversationProfile
|
||||
|
||||
==1.9.4 Changes==
|
||||
*resip/recon: ensure libraries link with sipXtapi libs
|
||||
*resip/recon: fix for case where DialogSet Profile is not an instance of ConversationProfile
|
||||
*resip/recon: per-participant tone support
|
||||
*resip/recon: clarify DTMF API: tones represented by event code, API-user durations in milliseconds
|
||||
|
||||
==1.9.3 Changes==
|
||||
*reTurn: TurnAsyncSocket: fix for sending when not using TURN
|
||||
*resip/stack: added allowed events to 489 errors
|
||||
*resip/stack: Support for dtmf-relay content parsing for SIP INFO messages
|
||||
*resip/recon: call onDtmfEvent when SIP INFO received, just as for RFC2833 DTMF
|
||||
*resip/recon: call acceptNIT()/rejectNIT() after handling INFO message
|
||||
*resip/recon: support for changing internal sample rate of sipXtapi
|
||||
*resip/recon: allow UserProfile and extension headers to be specified when creating a new remote participant
|
||||
|
||||
==1.9.2 Changes==
|
||||
*rutil/dns: fix for Windows DNS Server use. Ignore Link Local DNS Server entries.
|
||||
*rutil: add extra ParseBuffer constructor for const char*
|
||||
*rutil: Data: ust strncmp in comparisons with const char*
|
||||
|
||||
==1.9.1 Changes==
|
||||
*adapt to work with asio v1.10.1 (still works with v1.4.x too)
|
||||
*fix for spinning in DnsThread
|
||||
*ensure mPollGrp is set before accessing it in AresDnsPollItem::resetPollGrp
|
||||
*fix RegSyncClient so that it detects breaks in the socket connection to the server - by using keepalives
|
||||
*made EGAIN and EWOULDBLOCK processing the same in a few additional spots
|
||||
*add WinLeakCheck header to some new Websocket class files to aid in leak detection on windows
|
||||
*stop trying to write cert files in various places
|
||||
*repro:
|
||||
**WebAdmin: catch and log exceptions when starting
|
||||
**fix issue with CommandServerList being deleted when not newed if startup fails due to transport exception
|
||||
**fixed up StackStatistics handling for when multiple command servers are running (ie: v4 and v6 CommandServers)
|
||||
**ensure we use the ServerText config setting to set the server text headers in requests that traverse repro
|
||||
*use threadsafe variant of localtime (localtime_r) on non-windows based platforms
|
||||
|
||||
==1.9.0 Changes since 1.8.0==
|
||||
==Highlights==
|
||||
*Session/registration accounting
|
||||
*SIP over WebSocket support for WebRTC, with cookie authentication option
|
||||
*Python scripting for repro routes
|
||||
*repro dynamically-loaded routing plugins
|
||||
*UAS PRACK
|
||||
*Improvements to daemon processes for UNIX/Linux users
|
||||
*Android support
|
||||
*Multiple users in reTurn
|
||||
*Many stability/bug fixes
|
||||
|
||||
==General Changes==
|
||||
===New features===
|
||||
*added CAJUN (header file only library) source to contrib for JSON encoding/decoding support - now also a Debian/Ubuntu/Fedora package
|
||||
*added last release of GPLed opensigcomp project to contrib tree, since it can't be found on internet any longer
|
||||
*updated libSRTP drop to latest 1.4.4 version
|
||||
*updated to asio 1.4.8
|
||||
|
||||
==Build system==
|
||||
===New features===
|
||||
*VS2010 project file enhancements
|
||||
**Modified project settings to allow x86 and x64 builds in the same source tree
|
||||
**Output Directory for all projects and for all configuration/platform combinations changed to $(SolutionDir)$(Platform)\$(Configuration)\
|
||||
**Intermediate Directory for all projects changed to $(Platform)\$(Configuration)\
|
||||
**Added _CRT_SECURE_NO_WARNINGS to projects where it was still missing in order to reduce the amount of warnings. There are less than 30 warnings now, so one can concentrate on those warnings that might really matter instead of just ignoring a large warning list
|
||||
**Removed Manifest Tool Command Line additional option "validate_manifest" for [repro-x64-Debug-SSL]. This switch makes the MT.exe only parse the input but does not generate output and can lead to a build error.
|
||||
**Removed all Property Pages “Upgrade from VC 7.1”. The sole purpose of this is to introduce the preprocessor directive "_VC80_UPGRADE=0x0710" which has no practical use at all
|
||||
**There’s a bug in Visual Studio 2010 when Visual Studio 2012 is installed also. As a result, the Setup projects detect a dependency on the .NET Framework for a C++ project even if it does not use .NET. It can be cured by adding “<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>” to the project file. After doing so I could remove the incorrectly added LaunchCondition in the setup projects. Details can be found here: http://connect.microsoft.com/VisualStudio/feedback/details/746328/after-installing-vs-11-rc-vs-10-setup-projects-require-the-net-framework
|
||||
**Added a new file VisualStudioReadme.htm with some information about the Visual Studio build
|
||||
**reTurn: Changed boost include folder from ./contrib/boost_1_34_0 to ./contrib/boost
|
||||
*add 64-bit VS2010 project settings for reTurn
|
||||
*added configure-android.sh for building with Android NDK
|
||||
*rend: added autotools support
|
||||
*rpm: various fixes for RHEL6 and Fedora builds
|
||||
|
||||
|
||||
==rutil==
|
||||
===New features===
|
||||
*avoiding truncating the log file
|
||||
*add directory create API to rutil/FileSystem
|
||||
*WIN32 - added better logging to WinCompat::determineSourceInterfaceWithoutIPv6
|
||||
*Data: add fromHex method
|
||||
*Data: import capacity of pre-allocated buffers
|
||||
*Data: improve buffer size allocation in base64encode
|
||||
*dns/ares: add support for DNS server discovery on Android
|
||||
*add support for Android logging / logcat utility
|
||||
*add FileSystem::Exception, check stat() return value
|
||||
*FileSystem: check results of readdir calls
|
||||
*Add support for FreeRADIUS client (radiusclient-ng is deprecated but still supported for now)
|
||||
*Tuple: provide method for copying out sockaddr
|
||||
*ConfigParse: add support for reading sets
|
||||
*ConfigParse: give precedence to options on command line
|
||||
*ConfigParse: reject duplicate values from any given config source
|
||||
*ConfigParse: throw exceptions rather than immediately exiting on error
|
||||
*added preprocessor conditional compile option for Windows source interface selection to avoid using adapter addresses tagged as Transient. Transient addresses include those that are used for Virtual IP addresses and tagged with SkipAsSource (also used in Windows Clustering solutions)
|
||||
*added Sha1 implementation for when OpenSSL is not available
|
||||
*ServerProcess: change logfile and PID file ownership when dropping privileges
|
||||
|
||||
===Bug fixes===
|
||||
*WIN32 - WinCompat::determineSourceInterfaceWithoutIPv6: throw transport exception if new fails or if second call to GetIpAddrTable fails
|
||||
**have seen one case where 2nd call to GetIpAddrTable returned 232 (ERROR_NO_DATA) for some unexplained reason, and Contact and Via headers would end up getting populated with 0.0.0.0 address
|
||||
*WIN32 - WinCompat: make sure all IPHLPAPI fns are run from the runtime loaded library
|
||||
*WIN32 - WinCompat: move static Mutex outside of WinCompat::instance() fn definition to avoid race conditions
|
||||
*MD5 code: more checks for big endian environments (gcc __BYTE_ORDER__)
|
||||
*Data::sizeEqualCaseInsensitiveTokenCompare: Fixing a goof that was causing later code to operate on unaligned data as if it were aligned, which was causing the code to malfunction on many non-x86 platforms.
|
||||
*Android cross-compile: fix compile issues
|
||||
*fix Data for big endian builds
|
||||
*DnsUtil - handle potential truncation in gethostname()
|
||||
*fix for build on GNU HURD
|
||||
*DnsUtil: support HURD net device interface names with leading slash
|
||||
*FileSystem: add support for full filename in iterator, fix problem with using stat() on relative path
|
||||
*fixed up AresDns::checkDnsChange to be able to compare IPv6 DNS servers instead of just V4 servers
|
||||
*WIN32 - ares_init: modified API used to retrieve DNS servers for Windows systems from GetNetworkParams to GetAdapterAddresses (supported on Windows XP / Server 2003 and above)
|
||||
**will fallback to GetNetworkParams if unable to retrieve servers via GetAdapterAddresses (this will happen on Windows 98 and Server 2000 machines)
|
||||
**GetNetworkParams issues:
|
||||
***does not support IPv6
|
||||
***was exhibiting a MS bug that could cause 0 DNS servers to be returned if many ares instances where init'd at the same time (ie: could happen when creating many SipStack instances at the same time)
|
||||
**more efficient lookup when ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3 ares option is used - no need to lookup the physical address of each DNS server separately
|
||||
*RADIUS: correctly distinguish access denied from server error
|
||||
*RADIUS: don't behave badly if multiple calls to init() are made
|
||||
|
||||
|
||||
==stack==
|
||||
===New features===
|
||||
*added WS (WebSocket) and WSS (Secure WebSocket) transport support for WebRTC compatibility
|
||||
**added WebSocket handshake cookie parsing and validation
|
||||
*added build-in "cause" parameter parsing for Reason header (RFC3326) parsing
|
||||
*added missing header parameters for RFC4244 and RFC4244-bis (index, rc, mp, and np)
|
||||
*define max message size in a variable, allow compile time default with RESIP_SIP_MSG_MAX_BYTES and runtime config setting
|
||||
*SipMessage: range check on addHeader
|
||||
*added a MD5 hash comparison equals operator to Content class - needed by upcoming UAS Prack implementation
|
||||
*TcpBaseTransport: ensure outgoing TCP-based connections originate from configured interface address
|
||||
*DTLS support for certificate chains
|
||||
*TLS: more verbose certificate errors
|
||||
*add support for more aggressive garbage collection, MinimumGcHeadroom
|
||||
*added option to control if the DNS resolver will allow sip:<ip-address> to resolve to UDP, TCP, or TLS, in that order of priority (existing behaviour) - vs - UDP only
|
||||
|
||||
===Bug fixes===
|
||||
*Helper::getClientPublicAddress and isClientBehindNAT - don't create a Tuple out of a hostname if it isn't an IP address - can trap
|
||||
*don't assert in Tuple constructors that take printable addresses, since these addresses can come from the wire or from configuration
|
||||
*SigComp - fix memory leak in ConnectionBase: use delete[] for arrays
|
||||
*ensure we can send a 100 Trying for NonInviteTransaction retransmissions after one has already been sent - previously an assert would be triggered
|
||||
*Fixed issues with pre-mature TCP socket teardown: treat EGAIN and EWOULDBLOCK the same
|
||||
*fixed incorrect placement of #ifndef RESIP_USE_STIL_STREAMS
|
||||
*If TimerCleanup fires before Timer D for a cancelled ClientInvite transaction then we try to log out mNextTransmission regardless of the transaction state. However the transaction state may have advanced to the Completed state and mNextTransmission will be null, so we shouldn't be trying to log it
|
||||
*Tuple: fix mask comparison for some platforms with 64 bit long
|
||||
*remove use of RSA_generate_key for newer OpenSSL versions
|
||||
*Android cross-compile: fix compile issues / fcntl.h
|
||||
*fix an issue with TCP connections on Windows when TCP socket buffer fills up. Connection would have been terminated before - we were not properly handling WSAWOULDBLOCK response. We were relying on errno / getErrno to be accurate a number of calls after the write failure.
|
||||
*fix support for intermediate certificate chains
|
||||
*fix some potential mem leaks found by coverity in DtlsTransport::_read
|
||||
|
||||
|
||||
==DUM==
|
||||
===New features===
|
||||
*Added full support for PRACK - previously only supported UAC PRACK, UAS PRACK Support is added in this release
|
||||
*added in support for UAC Prack to be able to send an offer in the first PRACK response (must call provideOffer from onAnswer callback)
|
||||
*TlsPeerAuthManager: add support for statically configured mappings of TLS common names to permitted From: addresses
|
||||
*ServerAuthManager: add new option to not challenge third parties ("From" header not a local domain)
|
||||
*add additional accessor to ClientPagerMessage to retrieve the stored request message as a SharedPtr instead of a reference. This allows the caller to adorn the message and then call DialogUsageManager::send safely (if queueing and/or message bodies are not desired when sending a SIP MESSAGE request)
|
||||
*resip ClientPagerMessage - modified to allow onSuccess and onFailure callbacks even if queue of message contents is not used - allows you to call ClientPagerMessage::getMessageRequest, build the request yourself (even one without a body), send using DUM::send and still have your callbacks invoked
|
||||
*Added ServerSubscriptionHandler::onNotifyAccepted callback.
|
||||
*Profile: allow AllowEvents to be an advertised capability
|
||||
*remove randomized addition of time to stale call timer - not sure why this was there in the first place
|
||||
*RADIUSServerAuthManager: allow RADIUS client configuration file to be specified
|
||||
*Deprecated addTransport on DialogUsageManager object: SipStack has the exact same interface
|
||||
*dum/test/basicClient - use stack in multi-threaded mode
|
||||
*dum/test/basicClient - use EventStackThread instead of InterruptableStackThread - enables Epoll support on platforms that support it
|
||||
*dum/test/basicClient - enabled UAS PRACK
|
||||
*add support for statically configured auth realm
|
||||
|
||||
===Bug fixes===
|
||||
*InviteSession: fixed recursive calls to refer (w/ sessionToReplace) when using referCommand and InviteSessionReferExCommand.
|
||||
*TlsPeerAuthManager: explicitly skip authorization logic if TLS mode is optional or transport is not TLS
|
||||
*ClientRegistration: modified whenExpires to return the number of seconds when the registration will actually expire, as opposed to the number seconds until our next refresh message is supposed to go out
|
||||
*ClientRegistration: ensure that we don't try to unregister if ClientRegistration::end is called and we never successfully registered (or all current registrations are currently expired)
|
||||
**also includes case where we need to wait for an operation to finish before we can end
|
||||
*ClientRegistration: no-op subsequent calls to ClientRegistration::end after initial call
|
||||
*fixed issue with over active 1xx retransmissions
|
||||
*ClientRegistration: If we are unregistering all contacts as the initial registration message then don't bother storing in mMyContacts - allows add Binding to be called later to add a registration
|
||||
*fixed update glare handling for UAC prack
|
||||
*fixed missing break in ClientInviteSession::dispatchReceivedUpdateEarly
|
||||
*RADIUSServerAuthManager: cease mangling usernames passed to RADIUS
|
||||
*Security: stop trying to write PEM file in addDomainCertPEM
|
||||
*dum/test/basicClient - ensure shutdown works if initial registration attempt is in progress
|
||||
*fixed some transaction state memory leaks in DUM - resulting from race conditions in DUM Cancel handling
|
||||
**Race#1 - DialogSet.cxx - if Dialogset is still around, but dialog is gone (potentially BYE'd). Need to respond to CANCEL in order for transaction in stack to go away
|
||||
**Race#2 - ServerAuthManager - if we are waiting for an async user auth info to arrive on an INVITE with credentials when a CANCEL arrives, we did not correctly respond to the CANCEL
|
||||
***DialogUsageManager - needed a change to handle the User Auth info arriving after destroying the feature chain due to a CANCEL
|
||||
|
||||
==repro==
|
||||
===New features===
|
||||
*added WS (WebSocket) and WSS (Secure WebSocket) transport support for WebRTC compatibility
|
||||
**add specific support for authenticating users based on HTTP cookies authenticated by a shared secret/HMAC scheme
|
||||
*Add registration and call/session accounting
|
||||
**configured/enabled via configuration file
|
||||
**Session Accounting - When enabled resiprocate will push a JSON formatted events for sip session related messaging that the proxy receives, to a persistent message queue that uses berkeleydb backed storage.
|
||||
**The following call events are logged:
|
||||
***SessionCreated - INVITE passing authentiation was received
|
||||
***SessionRouted - received INVITE was forward to a target
|
||||
***SessionRedirected - session was 3xx redirected or REFERed
|
||||
***SessionEstablished - there was 2xx answer to an INVITE (only generate for first 2xx)
|
||||
***SessionCancelled - CANCEL was received
|
||||
***SessionEnded - BYE was received from either end
|
||||
***SessionError - a 4xx, 5xx, or 6xx response was sent to invitor
|
||||
**Registration Accounting - When enabled resiprocate will push a JSON formatted events for every registration, re-registration, and unregistration message received to a persistent message queue that uses berkeleydb backed storage.
|
||||
**The following registration events are logged:
|
||||
***RegistrationAdded - initial registration received
|
||||
***RegistrationRefreshed - registration refresh received / re-register
|
||||
***RegistrationRemoved - registration removed by client / un-register
|
||||
***RegistrationRemovedAll - all contacts registration remove / unregister received
|
||||
**Consuming Accounting Events: Users must ensure that the message queues are consumed, or they will grow without bound. A queuetostream consumer process is provided, that will consume the events from the message queue and stream them to stdout. This output stream can be consumed by linux scripting tools and converted to database records or some other relevant representation of the data.
|
||||
*add plugin DSO support (non-Windows platforms only)
|
||||
*add support for using Python scripts to perform routing
|
||||
*made static instance of the GeoIP library
|
||||
**allows static geoIPLookup method for other components of repro to access geoip library
|
||||
**reduces memory in cases where multiple instances of GeoProximityTargetSorter are needed (take care if creating multiple instances since static initialization is not mutexed)
|
||||
*print MaxMind GeoIP database information to resip logs
|
||||
*StaticRoute: allow routing of messages when CertificateAuthenticator passed
|
||||
*CertificateAuthenticator: add support for statically configured mappings of TLS common names to permitted From: addresses
|
||||
**add CommonNameMappings config option to load CN mappings from a text file
|
||||
*Added options to disable DIGEST challenge of third parties in DUM auth when mutual TLS in use
|
||||
*added support for WebAdmin and CommandServer binding to specific IP addresses
|
||||
*enable IPv6 by default
|
||||
*allow specification of arbitrary domain cert/key PEM files
|
||||
*make the CertificatePath optional with no default
|
||||
*WIN32 -delay load libmysql.dll so that it is not required unless MySQL is enabled in repro
|
||||
*config: support non-consecutive transport numbering in advanced transport spec
|
||||
*move authenticator creation code into a common factory class
|
||||
*add TlsTrustedPeers config option
|
||||
*send an alert to syslog when config parsing fails
|
||||
*configure User-Agent header for registrar, set default value with PACKAGE_VERSION
|
||||
*add TCPConnectionGCAge config option for garbage collection
|
||||
*add support for TCPMinimumGCHeadroom
|
||||
*add RADIUS support
|
||||
*add config option ChallengeThirdPartiesCallingLocalDomains
|
||||
*add StaticRealm config option to always challenge using a specified realm value
|
||||
*reset logger / rotate log files when HUP received
|
||||
*added ability to change log level from web admin
|
||||
*take HttpAdminPassword out of repro.config, use a htdigest file
|
||||
*rpm: configure repro and reTurn not to fork under systemd in Fedora
|
||||
|
||||
===Bug fixes===
|
||||
*move TLS client auth feature/monkey after DIGEST, so that TLS client auth can know if the peer passed DIGEST
|
||||
*CertificateAuthenticator: explicitly skip authorization logic if TLS mode is optional or transport is not TLS
|
||||
*fixed CommandServer being created even though listener bind failed
|
||||
*fix bug that causes assert if you try to configure repro registrar and authentication disabled
|
||||
*don't strip authorization headers if the request is going to spiral / loop back to us, only strip if routing outside our domain
|
||||
*if we receive a response that has messed with the vias and we don't have a stored bestResponse then send a 500
|
||||
*make sure multiple RegSync Servers can be added and dispatched to -fixes repro bug when starting both IPv4 and IPv6 regsync servers
|
||||
*fixup reprocmd so that it works properly for commands with arguments ie: SetCongestionTolerances - now requires a '/' in front of the actual command
|
||||
*respond with an error code when invalid pages requested
|
||||
|
||||
|
||||
==reTurn==
|
||||
===New features===
|
||||
*reTurn Server: improved diagnostics in RequestHandler - print senders tuple with errors
|
||||
*reTurn Server: detect port in use errors when creating relay
|
||||
*reTurn Server: TurnAllocation/UdpRelayServer - added flags so that some errors only log a Warning level once, then will log at Debug level after - this helps to avoid flooding logs with Warning level messages
|
||||
*reTurn Server: track allocations per connection - reduces map sizes and lookups when TCP/TLS client connections are used
|
||||
*reTurn Server: read user/password data from a file specified by UserDatabaseFile
|
||||
*reTurn Server: optimization to not calculateHmacKey multiple times
|
||||
*reTurn Server: if return config file location contains a base path, then append this path to other filename settings if an absolute path isn't already specified
|
||||
*reTurn Server: short term authentication makes no sense for a TURN server, since credential information needs to be exchanged out of band (ie. as with ICE) - remove short term auth option from return server - Long Term authentication is enabled by default
|
||||
*reTurn Server: listen on IPv6 as well as IPv4
|
||||
*reTurn Server: more verbose warning when user or realm unrecognised
|
||||
*reTurn Server: add support for TLS private key in standalone file
|
||||
*reTurn Server: periodically check for updates to the user database file
|
||||
*reTurn Server: support for hashed passwords in user database file
|
||||
*reTurn Server: add support for configuring software name header in STUN packets
|
||||
*reTurn Server: reload users.txt and reset logger on HUP signal
|
||||
*reTurn Client API enhancements
|
||||
**upped receive buffer size from 2048 to 4096
|
||||
**OS level Udp socket receive buffer size set to 66560
|
||||
**TurnAsyncSocketBase - use dispatch instead of post for send API for increased efficiency
|
||||
**TurnAsyncSocket - new client side APIs
|
||||
***setLocalPassword for checking integrity of incoming STUN messages
|
||||
***connectivityCheck for ICE connectivity checks
|
||||
***setOnBeforeSocketClosedFp for QOS cleanup (windows)
|
||||
***send API now split into send(To)Framed and send(To)Unframed
|
||||
***Queue of guards modified to use a weak functor template instead
|
||||
***onBindFailure and onBindSuccess now return the Tuple that failed or succeeded
|
||||
***onChannelBindRequestSent - new
|
||||
***onChannelBindSuccess - new
|
||||
***onChannelBindFailure - new
|
||||
**DataBuffer improvements
|
||||
**StunMessage - added ice attributes
|
||||
*TestRtpLoad change to use OS selected port for relay port instead of hardcoded 2000
|
||||
|
||||
===Bug fixes===
|
||||
*reTurn Server: fix bugs with port allocation logic
|
||||
**properly detect wrap around when end of range is max ushort = 65535
|
||||
**properly allocate even or odd port after wrap around from end of range
|
||||
*TCP/TLS Server classes - ensure we try to accept future connections if we receive an error indicating we ran out of file descriptors
|
||||
*TLS/UDP Servers classes - throw on errors in constructor
|
||||
*fixup stunTestVectors.cxx now that ice parameters are parsed
|
||||
*Client API: fix for requestTimeout - handle case where close is called in handlers and it is invalidated
|
||||
*stunTestVectors: correct test case for network byte order
|
||||
*reTurn Server: only try to start TLS transport when port is non-zero
|
||||
|
||||
|
||||
==recon==
|
||||
===New features===
|
||||
*modified recon/reflow DtlsSocket to work with DTLS-SRTP from OpenSSL 1.0.1 - patched version of OpenSSL no longer required
|
||||
*modified DTLS-SRTP fingerprint to be SHA-256 instead of SHA-1 for better web-rtc interop
|
||||
*recon: look for dynamic codec modules in default location if none are statically linked
|
||||
*improved error logging in RemoteParticipant::adjustRTPStreams
|
||||
*reflow: emit warning when socket is not available
|
||||
|
||||
===Bug fixes===
|
||||
*reflow: ensure proper initialization of policy structure
|
||||
|
||||
|
||||
==tfm (repro)==
|
||||
===New features===
|
||||
*added VS2010 project files
|
||||
*added ability for tfm repro to be run in interactive mode with a -i command line option
|
||||
*added ability for tfm repro to be able to disable digest authentication if required for some test cases
|
||||
*enabled over 60 additional tfm repro test cases that required digest auth to be disabled
|
||||
*enabled record routing on repro test instance in tfm repro and tfm dum
|
||||
*modified tfm/Sequence and tfm/SequenceSet to support newer versions of boost
|
||||
*disable Invite loop test since all platforms will fail when record-routing is enabled - it causes the message size to exceed 8k
|
||||
|
||||
===Bug fixes===
|
||||
*update root CA cert and domain cert used in tfm repro TLS testing - old ones had expired
|
||||
*fixup some test cases testAttendedExtensionToExtensionTransfer, testBlindTransferExtensionToExtensionHangupImmediately, testConferenceConferencorHangup
|
||||
*fix for testAck200ReflectedAsInvite test case - reflected INVITE wasn't tracked and it would use first request in map - which would sometime be the wrong invite
|
||||
|
||||
|
||||
==tfm (dum)==
|
||||
===New features===
|
||||
*added VS2010 project files
|
||||
*added 24 new tests cases to tfm dum for PRACK testing (dumTests.cxx)
|
||||
*modified tfm dum TestSipEndPoint::Prack to be able to send PRACKS from TestSipEndpoint
|
||||
*modified tfm dum TestSipEndPoint::Invite to be able to enable PRACK on outbound invites
|
||||
*modified tfm dum to be able to store relrespinfo on 18xrel for generating PRACKs
|
||||
*added interactive mode (-i) flag to tfmdum so that tests can be run either automated or with a test selector menu
|
||||
|
||||
===Bug fixes===
|
||||
*fixed up TFM DUM test cases that required digest to be disabled and ones that required record-routing to be turned on, and ones that were looking for rinstance parameter (instance id is now used)
|
||||
|
||||
|
||||
==nICEr==
|
||||
===Bug fixes===
|
||||
*Fix some 32/64 issues and an edge case where no ICE attributes are provided
|
||||
*Numerous improvements and fixes from Mozilla WebRTC project
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
|
||||
|
||||
a) If using source code from the repository (not a tarball download),
|
||||
you must bootstrap the source tree:
|
||||
|
||||
autoreconf --install
|
||||
|
||||
This must be done:
|
||||
- after checking out the code for the first time
|
||||
- after changing configure.ac or any Makefile.am file
|
||||
|
||||
NOTE: the bootstrap process only works reliably when using the same
|
||||
(or a very similar) version of autotools as the officially
|
||||
tested reSIProcate releases. The official releases are
|
||||
bootstrapped using autotools on a Debian 6.0 (squeeze) system.
|
||||
|
||||
b) Run configure:
|
||||
|
||||
e.g. on a Debian system:
|
||||
|
||||
./configure --with-ssl --with-mysql --with-c-ares \
|
||||
CXXFLAGS="-DRESIP_FIXED_POINT"
|
||||
|
||||
NOTE: some things (e.g. reTurnServer) will ONLY build if you
|
||||
specify --with-ssl to link against SSL libraries
|
||||
|
||||
A more complete example, with tfm:
|
||||
|
||||
./configure \
|
||||
--with-ssl --with-mysql --with-radius --with-tfm \
|
||||
--enable-ipv6 \
|
||||
CXXFLAGS="-I`pwd`/contrib/Netxx-0.3.2/include" \
|
||||
LDFLAGS="-L`pwd`/contrib/Netxx-0.3.2/src"
|
||||
|
||||
(hint: if it fails to link against libNetxx.so, create a symlink, or
|
||||
delete libNetxx.so and it should link against libNetxx.a)
|
||||
|
||||
OR (using contrib/ares)
|
||||
|
||||
./configure --with-ssl --with-mysql --enable-ipv6 --with-popt"
|
||||
|
||||
c) Build everything:
|
||||
|
||||
make
|
||||
|
||||
or to build just one thing:
|
||||
|
||||
make -C rutil
|
||||
|
||||
and if you have multiple CPUs/CPU-cores/hyper-threading, you can build
|
||||
faster by telling make to use them in parallel, e.g.:
|
||||
|
||||
make -j 12
|
||||
|
||||
d) Test it, e.g. to test rutil:
|
||||
|
||||
make -C rutil check
|
||||
|
||||
e) Install somewhere:
|
||||
|
||||
mkdir /tmp/my-resip && make DESTDIR=/tmp/my-resip install
|
||||
|
||||
Supported Systems
|
||||
-----------------
|
||||
|
||||
Supported Platforms: (to add new platform support see build/Makefile.osarch)
|
||||
FreeBSD
|
||||
Linux
|
||||
QNX
|
||||
SunOS
|
||||
Mac
|
||||
cygwin
|
||||
|
||||
Supported toolchains: (to add new toolchain support see build/Makefile.tools)
|
||||
gnu (g++)
|
||||
Intel (icc)
|
||||
ARM cross-compiler (arm-linux-g++)
|
||||
Sunpro (CC)
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign dist-zip
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = rutil
|
||||
SUBDIRS += resip
|
||||
if BUILD_REPRO
|
||||
SUBDIRS += repro
|
||||
endif
|
||||
if BUILD_TFM
|
||||
SUBDIRS += tfm
|
||||
endif
|
||||
|
||||
# The Makefiles for these don't separate SSL stuff yet...
|
||||
if USE_SSL
|
||||
if BUILD_RETURN
|
||||
SUBDIRS += reTurn
|
||||
if BUILD_RECON
|
||||
SUBDIRS += reflow
|
||||
SUBDIRS += resip/recon
|
||||
endif
|
||||
endif
|
||||
if BUILD_P2P
|
||||
SUBDIRS += p2p/s2c/s2c p2p
|
||||
endif
|
||||
endif
|
||||
|
||||
if BUILD_APPS
|
||||
SUBDIRS += apps
|
||||
endif
|
||||
|
||||
#EXTRA_DIST = build-contrib.sh
|
||||
|
||||
EXTRA_DIST = *.sln
|
||||
|
||||
EXTRA_DIST += resiprocate.spec
|
||||
|
||||
EXTRA_DIST += RELEASE-PROCESS.txt
|
||||
EXTRA_DIST += build/configure-android.sh
|
||||
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
|
||||
-----------------------------------------------------------
|
||||
|
||||
IMPORTANT
|
||||
|
||||
- the notes below relate to the legacy build
|
||||
system from reSIProcate <= 1.7.x
|
||||
|
||||
- now, with reSIProcate 1.8.x and beyond,
|
||||
please see:
|
||||
|
||||
http://www.resiprocate.org/AutotoolsBuild
|
||||
|
||||
and
|
||||
|
||||
http://www.resiprocate.org/Configuration_Options
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Notes for the legacy build system:
|
||||
|
||||
|
||||
The legacy reSIProcate build system is derived from
|
||||
the VOCAL build system (http://www.vovida.org).
|
||||
|
||||
Adding New Files to a module
|
||||
----------------------------
|
||||
|
||||
Example: Adding a new file Foo.cxx to the stack
|
||||
|
||||
1) Edit resip/stack/Makefile
|
||||
2) Add Foo.cxx to the SRC list
|
||||
|
||||
Example: Adding a new file Bar.cxx to rutil
|
||||
1) Edit rutil/Makefile
|
||||
2) Add Bar.cxx to the SRC list
|
||||
|
||||
Notes:
|
||||
- All files noted in SRC list will be added to the target library
|
||||
- Adding a new header file does not need to be noted in the Makefile
|
||||
- To add something to the compile line add to CXXFLAGS.
|
||||
e.g. CXXFLAGS += -DMYSPECIALDEFINE
|
||||
- To add something to the link line add to LDFLAGS and/or LDLIBS
|
||||
e.g. LDFLAGS += -L/usr/local/myspeciallibdir
|
||||
e.g. LDLIBS += -lmyspeciallib
|
||||
|
||||
Creating an application based on the stack:
|
||||
|
||||
Option 1: (Using the resip build system)
|
||||
For example applications using the resip build system look at resip/stack/test or at repro.
|
||||
|
||||
###########################################################################################
|
||||
# Create a Makefile in the directory with the units with the following template
|
||||
# This should be the path to the build directory of resip (in the sip subdirectory)
|
||||
BUILD = ../../build
|
||||
|
||||
# Includes macros
|
||||
include $(BUILD)/Makefile.pre
|
||||
|
||||
# Add any options that need to be passed to the C++ compiler here
|
||||
#CXXFLAGS += -DMYSPECIALDEFINE
|
||||
|
||||
# Add any options that need to be passed to the C compiler here
|
||||
#CFLAGS += -DMYOTHERDEFINE
|
||||
|
||||
# Add any options that need to be passed to the linker here
|
||||
#LDFLAGS += -L/usr/local/mydir
|
||||
|
||||
# Add any libraries that need to be passed to the linker here
|
||||
#LDLIBS += -lmylib
|
||||
|
||||
# All of these packages are prerequisites for resiprocate
|
||||
PACKAGES += RESIP RUTIL OPENSSL ARES PTHREAD
|
||||
|
||||
# Add an entry to TESTPROGRAMS for each target that has a main in it
|
||||
# On linux this will generate an executable in bin.debug.Linux.i686/main
|
||||
TESTPROGRAMS += main.cxx
|
||||
|
||||
# Add each of the C++ or C files that other than the main
|
||||
# Each main target (from TESTPROGRAMS) will be linked with all of the files in SRC
|
||||
SRC = TestSupport.cxx
|
||||
|
||||
# Includes macros
|
||||
include $(BUILD)/Makefile.post
|
||||
###########################################################################################
|
||||
|
||||
Option 2: (Using a third party build system)
|
||||
|
||||
Prerequisites:
|
||||
- Install ares library from contrib/ares
|
||||
- cd contrib/ares
|
||||
- ./configure
|
||||
- make
|
||||
- make install
|
||||
|
||||
Pass the following flags to C++ compiler:
|
||||
Assumptions:
|
||||
- have pthreads
|
||||
- have openssl installed
|
||||
- have ares installed
|
||||
- resiprocate library is built and installed
|
||||
|
||||
# Linux Example
|
||||
CXXFLAGS += -Wall -fPIC -Wno-deprecated -march=i686 \
|
||||
-D_REENTRANT -DUSE_SSL -DNEW_MSG_HEADER_SCANNER -DUSE_IPV6 -DUSE_ARES \
|
||||
-I/usr/kerberos/include -I$(RESIP_DIR)/lib.debug.Linux.i686
|
||||
LDFLAGS += -L$(RESIP_DIR)/lib.debug.Linux.i686
|
||||
LDLIBS += -lresip -lrutil -lssl -lcrypto -lares -lpthread
|
||||
|
||||
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
|
||||
reSIProcate release process
|
||||
===========================
|
||||
|
||||
This document explains the process for building a release of the
|
||||
reSIProcate software.
|
||||
|
||||
Deliverables
|
||||
------------
|
||||
|
||||
The only official deliverable is the tarball, for example,
|
||||
|
||||
resiprocate-1.8.0.tar.gz
|
||||
|
||||
As a courtesy to users, a contrib tarball is also produced,
|
||||
containing some third party code:
|
||||
|
||||
resiprocate-contrib-1.8.0.tar.gz
|
||||
|
||||
Building of binary packages (e.g. for Debian, RPM, OpenCSW) is
|
||||
done after the tarball release. That is not covered here.
|
||||
|
||||
Workspace
|
||||
---------
|
||||
|
||||
Obtain a release branch from the Git repository.
|
||||
|
||||
git clone -b release/1.8 https://github.com/resiprocate/resiprocate resip-1.8
|
||||
cd resip-1.8
|
||||
|
||||
If this is the beginning of a release branch, manually copy the ChangeLog
|
||||
file from the previous release branch and then add the new entries.
|
||||
|
||||
Version/tag
|
||||
-----------
|
||||
|
||||
Here we give an example for building the release v1.8.5:
|
||||
|
||||
Update version information and tag it:
|
||||
|
||||
vi configure.ac (update the version and ABIVERSION numbers)
|
||||
|
||||
git add configure.ac
|
||||
git commit -m 'release: Update for 1.8.5'
|
||||
git tag -s -m 'release: Tag 1.8.5'
|
||||
|
||||
git push (send changes back to Git)
|
||||
|
||||
Bootstrap
|
||||
---------
|
||||
|
||||
The bootstrap must always be done on the same version of autotools
|
||||
for consistency. The currently endorsed version is the autotools
|
||||
distributed in Debian 10.0 (buster). If another version is to be used,
|
||||
it should be discussed on the mailing list and noted in this document.
|
||||
|
||||
autoreconf --install
|
||||
|
||||
Make a tarball
|
||||
--------------
|
||||
|
||||
build/release-tarball.sh
|
||||
|
||||
* this script will call configure && make dist
|
||||
* any previous configure settings will be overridden, so you
|
||||
may want to preserve a copy of config.status and config.log
|
||||
or just do this operation from a workspace that is independent
|
||||
of your normal development workspace
|
||||
|
||||
Make the contrib tarball
|
||||
------------------------
|
||||
|
||||
build/contrib-tarball.sh
|
||||
|
||||
Sanity check on tarball
|
||||
-----------------------
|
||||
|
||||
Extract the tarball to /tmp/some-folder/resiprocate-1.8.5
|
||||
|
||||
cd /tmp/some-folder/resiprocate-1.8.5
|
||||
./configure && make -j 12 check
|
||||
|
||||
Distribute the tarball
|
||||
----------------------
|
||||
|
||||
sha256sum resiprocate-1.8.5.tar.gz
|
||||
|
||||
Upload the tarball to the pre-release section of the web site
|
||||
|
||||
Send a PGP signed email to the developers list announcing that
|
||||
a release candidate has been built. Other developers may test the tarball.
|
||||
|
||||
Include the SHA-256 checksum in the PGP signed email.
|
||||
|
||||
Confirm the release
|
||||
-------------------
|
||||
|
||||
Upload the tarball to the official download page
|
||||
|
||||
Send a PGP signed email to the resip-announce and users lists
|
||||
announcing that the release candidate is now an official release.
|
||||
|
||||
Include the SHA-256 checksum in the PGP signed email.
|
||||
|
||||
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
<head>
|
||||
<title>Untitled Page</title>
|
||||
<style type="text/css">
|
||||
body
|
||||
{
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
h1
|
||||
{
|
||||
color: #0066CC;
|
||||
}
|
||||
h2
|
||||
{
|
||||
color: #00246F;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>
|
||||
Building resiprocate with Visual Studio</h1>
|
||||
<h2>
|
||||
Dependencies</h2>
|
||||
<p>
|
||||
When checked out from SVN, all dependent libraries are included with one
|
||||
exception: You need to download openSSL. You can either download the source and
|
||||
build it or download the precompiled binaries from
|
||||
<a href="http://slproweb.com/products/Win32OpenSSL.html">
|
||||
http://slproweb.com/products/Win32OpenSSL.html</a>. You need to download the
|
||||
full versions, the light versions are not sufficient. If you want to build for
|
||||
x64 you need to download the x64 version. </p>
|
||||
<p>
|
||||
Please note that the x64 version can be installed on x64 machines, but you can
|
||||
copy the install folder to a 32bit system and cross-compile for x64. The openssl
|
||||
install folders need to be renamed and put at the following locations:</p>
|
||||
<ul>
|
||||
<li>Solution Folder<ul>
|
||||
<li>contrib<ul>
|
||||
<li>openssl (for Win32)</li>
|
||||
<li>opensslx64 (for x64)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Additionally, in order to compile reTurn, it is required to have boost in the
|
||||
contrib\boost folder.</p>
|
||||
<h2>
|
||||
Configurations and Platforms</h2>
|
||||
<p>
|
||||
There are eight possible configuration/platform combinations: SSL/non-SSL *
|
||||
Debug/Release * x86/x64 = 8</p>
|
||||
<p>
|
||||
The output of all projects is created in a single folder for each
|
||||
configuration/platform combinations. The output is organized as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li> Solution Folder<ul>
|
||||
<li>Win32<ul>
|
||||
<li>Debug</li>
|
||||
<li>Release</li>
|
||||
<li>SSL-Debug</li>
|
||||
<li>SSL-Release</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>X64<ul>
|
||||
<li>Debug</li>
|
||||
<li>Release</li>
|
||||
<li>SSL-Debug</li>
|
||||
<li>SSL-Release </li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>
|
||||
Batch Builds</h2>
|
||||
<p>
|
||||
The Visual Studio Batch Build feature does not work with the current
|
||||
configuration. This is due to a bug in Visual Studio 2010 when project
|
||||
references are used. It could be solved by removing project references, adding
|
||||
project dependencies instead and specifying all generated import libraries
|
||||
directly in the linker configuration. This would practically resemble the way
|
||||
this was done in pre-VS10 environments, but it would involve a bit of
|
||||
configuration work.</p>
|
||||
<p>
|
||||
More info on this bug can be found here:</p>
|
||||
<ul>
|
||||
<li><a href="http://connect.microsoft.com/VisualStudio/feedback/details/636636/batch-build-does-not-work-as-expected">
|
||||
http://connect.microsoft.com/VisualStudio/feedback/details/636636/batch-build-does-not-work-as-expected</a></li>
|
||||
<li><a href="http://connect.microsoft.com/VisualStudio/feedback/details/633270/link-library-dependencies-for-c-does-not-work-with-batch-build">
|
||||
http://connect.microsoft.com/VisualStudio/feedback/details/633270/link-library-dependencies-for-c-does-not-work-with-batch-build</a></li>
|
||||
<li><a href="http://qualapps.blogspot.de/2010/04/static-library-dependencies-in-visual.html">
|
||||
http://qualapps.blogspot.de/2010/04/static-library-dependencies-in-visual.html</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
SUBDIRS = clicktocall
|
||||
SUBDIRS += sipdial
|
||||
if BUILD_ICHAT_GW
|
||||
SUBDIRS += ichat-gw
|
||||
endif
|
||||
if BUILD_TELEPATHY_CM
|
||||
SUBDIRS += telepathy
|
||||
endif
|
||||
if BUILD_RECON
|
||||
SUBDIRS += reConServer
|
||||
endif
|
||||
if BUILD_QPID_PROTON
|
||||
if USE_NETSNMP
|
||||
SUBDIRS += registration-agent
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
|
||||
/clicktocall
|
||||
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
|
||||
#include "rutil/Logger.hxx"
|
||||
#include "rutil/ParseBuffer.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "rutil/WinLeakCheck.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
AddressTranslator::AddressTranslator()
|
||||
{
|
||||
}
|
||||
|
||||
AddressTranslator::~AddressTranslator()
|
||||
{
|
||||
// Destroy all of the filters
|
||||
for(FilterOpList::iterator it = mFilterOperators.begin(); it != mFilterOperators.end(); it++)
|
||||
{
|
||||
if ( it->preq )
|
||||
{
|
||||
regfree ( it->preq );
|
||||
delete it->preq;
|
||||
it->preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.clear();
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression)
|
||||
{
|
||||
InfoLog( << "Add translation " << matchingPattern << " -> " << rewriteExpression);
|
||||
|
||||
FilterOp filter;
|
||||
filter.mMatchingPattern = matchingPattern;
|
||||
filter.mRewriteExpression = rewriteExpression;
|
||||
|
||||
if( !filter.mMatchingPattern.empty() )
|
||||
{
|
||||
int flags = REG_EXTENDED;
|
||||
if( filter.mRewriteExpression.find("$") == Data::npos )
|
||||
{
|
||||
flags |= REG_NOSUB;
|
||||
}
|
||||
filter.preq = new regex_t;
|
||||
int ret = regcomp( filter.preq, filter.mMatchingPattern.c_str(), flags );
|
||||
if( ret != 0 )
|
||||
{
|
||||
delete filter.preq;
|
||||
ErrLog( << "Translation has invalid match expression: "
|
||||
<< filter.mMatchingPattern );
|
||||
filter.preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.push_back( filter );
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::removeTranslation(const resip::Data& matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator it = mFilterOperators.begin();
|
||||
while ( it != mFilterOperators.end() )
|
||||
{
|
||||
if ( it->mMatchingPattern == matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator i = it;
|
||||
it++;
|
||||
if ( i->preq )
|
||||
{
|
||||
regfree ( i->preq );
|
||||
delete i->preq;
|
||||
i->preq = 0;
|
||||
}
|
||||
mFilterOperators.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AddressTranslator::translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule)
|
||||
{
|
||||
bool rc=false;
|
||||
DebugLog( << "Translating "<< address);
|
||||
|
||||
for (FilterOpList::iterator it = mFilterOperators.begin();
|
||||
it != mFilterOperators.end(); it++)
|
||||
{
|
||||
Data rewrite = it->mRewriteExpression;
|
||||
Data& match = it->mMatchingPattern;
|
||||
if ( it->preq )
|
||||
{
|
||||
int ret;
|
||||
|
||||
const int nmatch=10;
|
||||
regmatch_t pmatch[nmatch];
|
||||
|
||||
ret = regexec(it->preq, address.c_str(), nmatch, pmatch, 0/*eflags*/);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
// did not match
|
||||
DebugLog( << " Skipped translation "<< address << " did not match " << match );
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugLog( << " Matched translation "<< address << " matched " << match );
|
||||
translation = rewrite;
|
||||
rc=true;
|
||||
if ( rewrite.find("$") != Data::npos )
|
||||
{
|
||||
for ( int i=1; i<nmatch; i++)
|
||||
{
|
||||
if ( pmatch[i].rm_so != -1 )
|
||||
{
|
||||
Data subExp(address.substr(pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo-pmatch[i].rm_so));
|
||||
DebugLog( << " subExpression[" <<i <<"]="<< subExp );
|
||||
|
||||
Data result;
|
||||
{
|
||||
DataStream s(result);
|
||||
|
||||
ParseBuffer pb(translation);
|
||||
|
||||
while (true)
|
||||
{
|
||||
const char* a = pb.position();
|
||||
pb.skipToChars( Data("$") + char('0'+i) );
|
||||
if ( pb.eof() )
|
||||
{
|
||||
s << pb.data(a);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << pb.data(a);
|
||||
pb.skipN(2);
|
||||
s << subExp;
|
||||
}
|
||||
}
|
||||
s.flush();
|
||||
}
|
||||
translation = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
translation = rewrite;
|
||||
rc = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a translation and we are not suppossed to fail, then just return address
|
||||
if(!rc && !failIfNoRule)
|
||||
{
|
||||
rc = true;
|
||||
translation = address;
|
||||
}
|
||||
|
||||
InfoLog( << "Translated "<< address << " to " << translation);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#if !defined(AddressTranslator_hxx)
|
||||
#define AddressTranslator_hxx
|
||||
|
||||
#include <list>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcreposix.h>
|
||||
#else
|
||||
#include <regex.h>
|
||||
#endif
|
||||
#include "rutil/Data.hxx"
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class AddressTranslator
|
||||
{
|
||||
public:
|
||||
AddressTranslator();
|
||||
~AddressTranslator();
|
||||
|
||||
void addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression);
|
||||
|
||||
void removeTranslation(const resip::Data& matchingPattern);
|
||||
|
||||
bool translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
private:
|
||||
class FilterOp
|
||||
{
|
||||
public:
|
||||
resip::Data mMatchingPattern;
|
||||
resip::Data mRewriteExpression;
|
||||
regex_t *preq;
|
||||
};
|
||||
|
||||
typedef std::list<FilterOp> FilterOpList;
|
||||
FilterOpList mFilterOperators;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#include "AppSubsystem.hxx"
|
||||
|
||||
AppSubsystem AppSubsystem::CLICKTOCALL("CLICKTOCALL");
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#if !defined(AppSubsystem_hxx)
|
||||
#define AppSubsystem_hxx
|
||||
|
||||
#include <iostream>
|
||||
#include <rutil/Subsystem.hxx>
|
||||
|
||||
/**
|
||||
This class is used in the logging subsystem to identify
|
||||
logging messages generated from the ClickToCall server.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class AppSubsystem : public resip::Subsystem
|
||||
{
|
||||
public:
|
||||
// Add new systems below
|
||||
static AppSubsystem CLICKTOCALL;
|
||||
|
||||
private:
|
||||
explicit AppSubsystem(const char* rhs) : resip::Subsystem(rhs) {};
|
||||
explicit AppSubsystem(const resip::Data& rhs);
|
||||
AppSubsystem& operator=(const resip::Data& rhs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,995 +0,0 @@
|
|||
#include "B2BSession.hxx"
|
||||
#include "Server.hxx"
|
||||
#include "AppSubsystem.hxx"
|
||||
|
||||
#include <resip/stack/PlainContents.hxx>
|
||||
#include <resip/stack/SdpContents.hxx>
|
||||
#include <resip/stack/SipFrag.hxx>
|
||||
#include <resip/dum/ServerInviteSession.hxx>
|
||||
#include <resip/dum/ClientInviteSession.hxx>
|
||||
#include <resip/dum/ClientSubscription.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
#ifdef BRIEF_MSG_LOGGING
|
||||
#define LOG_MSG msg.brief()
|
||||
#define LOG_MSG_WITH_SDP msg.brief() << ", sdp=" << sdp
|
||||
#define LOG_MSGP msg->brief()
|
||||
#else
|
||||
#define LOG_MSG endl << msg
|
||||
#define LOG_MSG_WITH_SDP endl << msg
|
||||
#define LOG_MSGP endl << *msg
|
||||
#endif
|
||||
#define B2BLOG_PREFIX << "B2BSession[" << mHandle << "] "
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
B2BSession::B2BSession(Server& server) :
|
||||
AppDialogSet(server.getDialogUsageManager()),
|
||||
mServer(server),
|
||||
mDum(server.getDialogUsageManager()),
|
||||
mPeer(0),
|
||||
mUACConnectedDialogId(Data::Empty, Data::Empty, Data::Empty),
|
||||
mWaitingOfferFromPeer(false),
|
||||
mWaitingAnswerFromPeer(false),
|
||||
mWaitingNitAnswerFromPeer(false),
|
||||
mClickToCallState(Undefined),
|
||||
mClickToCallAnchorEnabled(false),
|
||||
mClickToCallInitiator(false)
|
||||
{
|
||||
mHandle = mServer.registerB2BSession(this);
|
||||
}
|
||||
|
||||
B2BSession::~B2BSession()
|
||||
{
|
||||
endPeer();
|
||||
mServer.unregisterB2BSession(mHandle);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::setPeer(B2BSession* peer)
|
||||
{
|
||||
mPeer = peer;
|
||||
}
|
||||
|
||||
B2BSession*
|
||||
B2BSession::getPeer()
|
||||
{
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::stealPeer(B2BSession* victimSession)
|
||||
{
|
||||
// Assume Peer mapping of victim - and copy some settings
|
||||
setPeer(victimSession->getPeer());
|
||||
if(mPeer)
|
||||
{
|
||||
mPeer->setPeer(this);
|
||||
}
|
||||
|
||||
// Clear peer mapping in victim session
|
||||
victimSession->setPeer(0);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::startCall(const Uri& destinationUri, const NameAddr& from, const SdpContents *sdp)
|
||||
{
|
||||
// Create a UserProfile for new call
|
||||
SharedPtr<UserProfile> userProfile(new UserProfile(mServer.getMasterProfile()));
|
||||
|
||||
// Set the From address
|
||||
userProfile->setDefaultFrom(from);
|
||||
userProfile->getDefaultFrom().remove(p_tag); // Remove tag (if it exists)
|
||||
|
||||
// Create the invite message
|
||||
SharedPtr<SipMessage> invitemsg = mDum.makeInviteSession(
|
||||
NameAddr(destinationUri),
|
||||
userProfile,
|
||||
sdp,
|
||||
this);
|
||||
|
||||
// Send the invite message
|
||||
mDum.send(invitemsg);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::clickToCall(const resip::Uri& initiator, const resip::Uri& destination, bool anchorCall, const XmlRpcInfo& xmlRpcInfo)
|
||||
{
|
||||
resip_assert(mClickToCallState == Undefined);
|
||||
|
||||
// Store Click-To-Call request info
|
||||
mClickToCallInitiator = true;
|
||||
mClickToCallDestination = destination;
|
||||
mClickToCallAnchorEnabled = anchorCall;
|
||||
mXmlRpcInfo = xmlRpcInfo;
|
||||
transitionClickToCallState(Setup);
|
||||
|
||||
// Create local sdp offer
|
||||
SdpContents sdp;
|
||||
if(!buildLocalOffer(sdp))
|
||||
{
|
||||
ErrLog(<< "B2BSession::clickToCall: unable to build local offer.");
|
||||
return;
|
||||
}
|
||||
|
||||
NameAddr from = mServer.getMasterProfile()->getDefaultFrom();
|
||||
from.displayName() = "Click-To-Call: " + destination.user();
|
||||
startCall(initiator, from, &sdp);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::startClickToCallAnchorLeg(const NameAddr& initiator, const Uri& destination, const XmlRpcInfo& xmlRpcInfo)
|
||||
{
|
||||
// Create B2BCall
|
||||
InfoLog(B2BLOG_PREFIX << "B2BSession::startClickToCallAnchorLeg: Starting second leg of click to call to " << destination);
|
||||
|
||||
mXmlRpcInfo = xmlRpcInfo;
|
||||
transitionClickToCallState(Setup);
|
||||
startCall(destination, initiator, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
B2BSession::buildLocalOffer(SdpContents& offer)
|
||||
{
|
||||
// Build s=, o=, t=, and c= lines
|
||||
UInt64 currentTime = Timer::getTimeMicroSec();
|
||||
|
||||
unsigned int port=8000; // Placeholder port
|
||||
|
||||
// Note: The outbound decorator will take care of filling in the correct IP address before the message is sent
|
||||
// to the wire.
|
||||
SdpContents::Session::Origin origin("clicktocall", currentTime /* sessionId */, currentTime /* version */, SdpContents::IP4, "0.0.0.0"); // o=
|
||||
SdpContents::Session session(0, origin, "-" /* s= */);
|
||||
session.connection() = SdpContents::Session::Connection(SdpContents::IP4, "0.0.0.0"); // c=
|
||||
session.addTime(SdpContents::Session::Time(0, 0));
|
||||
|
||||
// Build Codecs and media offering
|
||||
SdpContents::Session::Medium medium("audio", port, 1, "RTP/AVP");
|
||||
SdpContents::Session::Codec g711ucodec("PCMU", 8000);
|
||||
g711ucodec.payloadType() = 0; /* RFC3551 */ ;
|
||||
medium.addCodec(g711ucodec);
|
||||
medium.addAttribute("inactive");
|
||||
session.addMedium(medium);
|
||||
|
||||
offer.session() = session;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::endPeer()
|
||||
{
|
||||
if(mPeer)
|
||||
{
|
||||
mPeer->setPeer(0);
|
||||
mPeer->end(); // send cancel or bye appropriately
|
||||
mPeer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
B2BSession::isUACConnected()
|
||||
{
|
||||
return !mUACConnectedDialogId.getCallId().empty();
|
||||
}
|
||||
|
||||
bool
|
||||
B2BSession::isStaleFork(const DialogId& dialogId)
|
||||
{
|
||||
return (!mUACConnectedDialogId.getCallId().empty() && dialogId != mUACConnectedDialogId);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::processReferNotify(const SipMessage& notify)
|
||||
{
|
||||
unsigned int code = 400; // Bad Request - default if for some reason a valid sipfrag is not present
|
||||
|
||||
SipFrag* frag = dynamic_cast<SipFrag*>(notify.getContents());
|
||||
if (frag)
|
||||
{
|
||||
// Get StatusCode from SipFrag
|
||||
if (frag->message().isResponse())
|
||||
{
|
||||
code = frag->message().header(h_StatusLine).statusCode();
|
||||
}
|
||||
}
|
||||
|
||||
// If subscription is terminated, due to timeout and we don't have a final response in the SipFrag - treat as error
|
||||
if(notify.exists(h_SubscriptionState) &&
|
||||
isEqualNoCase(notify.header(h_SubscriptionState).value(), Symbols::Terminated) &&
|
||||
notify.header(h_SubscriptionState).exists(p_reason) &&
|
||||
isEqualNoCase(notify.header(h_SubscriptionState).param(p_reason), getTerminateReasonString(Timeout)) &&
|
||||
code < 200)
|
||||
{
|
||||
// failure
|
||||
transitionClickToCallState(ReferToDestinationFailed, 408);
|
||||
end();
|
||||
}
|
||||
// Check if success or failure response code was in SipFrag
|
||||
else if(code >= 180 && code < 200)
|
||||
{
|
||||
// proceeding
|
||||
transitionClickToCallState(ReferToDestinationProceeding);
|
||||
}
|
||||
else if(code >= 200 && code < 300)
|
||||
{
|
||||
// success
|
||||
transitionClickToCallState(ReferToDestinationConnected);
|
||||
end();
|
||||
}
|
||||
else if(code >= 300)
|
||||
{
|
||||
// failure
|
||||
transitionClickToCallState(ReferToDestinationFailed, code);
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::transitionClickToCallState(ClickToCallState newState, unsigned int statusCode)
|
||||
{
|
||||
if(newState != mClickToCallState)
|
||||
{
|
||||
unsigned int resultCode = 0;
|
||||
Data resultText;
|
||||
Data leg = mClickToCallInitiator ? "Initiator" : "Destination";
|
||||
switch(newState)
|
||||
{
|
||||
case Setup:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=Setup, initiator=" << mClickToCallInitiator);
|
||||
break;
|
||||
case Proceeding:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=Proceeding, initiator=" << mClickToCallInitiator);
|
||||
resultCode = 180;
|
||||
resultText = mClickToCallInitiator ? "Ringing initiator" : "Ringing destination";
|
||||
break;
|
||||
case Connected:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=Connected, initiator=" << mClickToCallInitiator);
|
||||
resultCode = 200;
|
||||
resultText = mClickToCallInitiator ? "Connected to initiator" : "Connected to destination";
|
||||
break;
|
||||
case Failed:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=Failed, initiator=" << mClickToCallInitiator);
|
||||
resultCode = statusCode;
|
||||
resultText = mClickToCallInitiator ? "Failed to connect to initiator" : "Failed to connect to destination";
|
||||
break;
|
||||
case ReferToDestinationProceeding:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=ReferToDestinationProceeding, initiator=" << mClickToCallInitiator);
|
||||
leg = "Destination";
|
||||
resultCode = 180;
|
||||
resultText = "Ringing destination";
|
||||
break;
|
||||
case ReferToDestinationConnected:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=ReferToDestinationConnected, initiator=" << mClickToCallInitiator);
|
||||
leg = "Destination";
|
||||
resultCode = 200;
|
||||
resultText = "Connected to destination";
|
||||
break;
|
||||
case ReferToDestinationFailed:
|
||||
InfoLog(B2BLOG_PREFIX << "transitionClickToCallState: newState=ReferToDestinationFailed, initiator=" << mClickToCallInitiator);
|
||||
leg = "Destination";
|
||||
resultCode = statusCode;
|
||||
resultText = "Failed to connect to destination";
|
||||
break;
|
||||
default:
|
||||
resip_assert(false);
|
||||
}
|
||||
mClickToCallState = newState;
|
||||
|
||||
if(mXmlRpcInfo.mXmlRpcServer && resultCode != 0)
|
||||
{
|
||||
mXmlRpcInfo.mXmlRpcServer->sendResponse(mXmlRpcInfo.mConnectionId, mXmlRpcInfo.mRequestId, Data::Empty, resultCode, resultText, leg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// InviteSessionHandler ///////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
B2BSession::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onNewSession(ClientInviteSessionHandle): msg=" << LOG_MSG);
|
||||
mInviteSessionHandle = h->getSessionHandle();
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
|
||||
{
|
||||
WarningLog(B2BLOG_PREFIX << "onNewSession(ServerInviteSessionHandle): ClickToCall server does not accept inbound calls - rejecting.");
|
||||
|
||||
mInviteSessionHandle = h->getSessionHandle();
|
||||
|
||||
h->reject(403 /* Forbidden */);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
// Note: Teardown of peer is handled in destructor
|
||||
InfoLog(B2BLOG_PREFIX << "onFailure: msg=" << LOG_MSG);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onEarlyMedia: msg=" << LOG_MSG_WITH_SDP);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onProvisional: msg=" << LOG_MSG);
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
if(msg.header(h_StatusLine).responseCode() >= 180 && mClickToCallState == Setup)
|
||||
{
|
||||
transitionClickToCallState(Proceeding);
|
||||
}
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mPeer->mInviteSessionHandle.get());
|
||||
if(sis && !sis->isAccepted())
|
||||
{
|
||||
sis->provisional(msg.header(h_StatusLine).responseCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onConnected: msg=" << LOG_MSG);
|
||||
if(!isUACConnected())
|
||||
{
|
||||
// It is possible in forking scenarios to get multiple 200 responses, if this is
|
||||
// our first 200 response, then this is the leg we accept, store the connected DialogId
|
||||
mUACConnectedDialogId = h->getDialogId();
|
||||
|
||||
// Note: each forked leg will update mInviteSessionHandle (in onNewSession call) - need to set mInviteSessionHandle for final answering leg on 200
|
||||
mInviteSessionHandle = h->getSessionHandle();
|
||||
|
||||
if(mClickToCallState == Setup || mClickToCallState == Proceeding)
|
||||
{
|
||||
transitionClickToCallState(Connected);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We already have a connected leg - end this one with a BYE
|
||||
h->end();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onConnected(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onConnected: msg=" << LOG_MSG);
|
||||
if(mClickToCallState == Setup || mClickToCallState == Proceeding)
|
||||
{
|
||||
transitionClickToCallState(Connected);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onStaleCallTimeout(ClientInviteSessionHandle h)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onStaleCallTimeout:");
|
||||
endPeer();
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
|
||||
{
|
||||
Data reasonData;
|
||||
switch(reason)
|
||||
{
|
||||
case InviteSessionHandler::RemoteBye:
|
||||
reasonData = "received a BYE from peer";
|
||||
break;
|
||||
case InviteSessionHandler::RemoteCancel:
|
||||
reasonData = "received a CANCEL from peer";
|
||||
break;
|
||||
case InviteSessionHandler::Rejected:
|
||||
reasonData = "received a rejection from peer";
|
||||
break;
|
||||
case InviteSessionHandler::LocalBye:
|
||||
reasonData = "ended locally via BYE";
|
||||
break;
|
||||
case InviteSessionHandler::LocalCancel:
|
||||
reasonData = "ended locally via CANCEL";
|
||||
break;
|
||||
case InviteSessionHandler::Replaced:
|
||||
reasonData = "ended due to being replaced";
|
||||
break;
|
||||
case InviteSessionHandler::Referred:
|
||||
reasonData = "ended due to being reffered";
|
||||
break;
|
||||
case InviteSessionHandler::Error:
|
||||
reasonData = "ended due to an error";
|
||||
break;
|
||||
case InviteSessionHandler::Timeout:
|
||||
reasonData = "ended due to a timeout";
|
||||
break;
|
||||
default:
|
||||
resip_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if(msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onTerminated: reason=" << reasonData << ", msg=" << LOG_MSGP);
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onTerminated: reason=" << reasonData);
|
||||
}
|
||||
|
||||
unsigned int statusCode = 603;
|
||||
if(msg)
|
||||
{
|
||||
if(msg->isResponse())
|
||||
{
|
||||
statusCode = msg->header(h_StatusLine).responseCode();
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a referred call and the refer is still around - then switch back to referrer (ie. failed transfer recovery)
|
||||
if(mReferringAppDialogSet.isValid() && mPeer)
|
||||
{
|
||||
B2BSession* session = (B2BSession*)mReferringAppDialogSet.get();
|
||||
session->stealPeer(this);
|
||||
}
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
// If we have a peer that hasn't been accepted yet - then pass back terminated code, by calling reject now
|
||||
if(mPeer && mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mPeer->mInviteSessionHandle.get());
|
||||
if(sis && !sis->isAccepted())
|
||||
{
|
||||
sis->reject(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
if(mClickToCallState == Setup || mClickToCallState == Proceeding)
|
||||
{
|
||||
transitionClickToCallState(Failed, statusCode);
|
||||
}
|
||||
|
||||
endPeer();
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
// We will recurse on redirect requests, so nothing to do here
|
||||
InfoLog(B2BLOG_PREFIX << "onRedirected: msg=" << LOG_MSG);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onAnswer: msg=" << LOG_MSG_WITH_SDP);
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
if(mPeer->mWaitingAnswerFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->provideAnswer(sdp);
|
||||
mPeer->mWaitingAnswerFromPeer = false;
|
||||
}
|
||||
else if(mPeer->mWaitingOfferFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->provideOffer(sdp);
|
||||
mPeer->mWaitingOfferFromPeer = false;
|
||||
}
|
||||
|
||||
ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mPeer->mInviteSessionHandle.get());
|
||||
if(sis && !sis->isAccepted())
|
||||
{
|
||||
sis->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mClickToCallInitiator && (mClickToCallState == Setup || mClickToCallState == Proceeding))
|
||||
{
|
||||
if(mClickToCallAnchorEnabled)
|
||||
{
|
||||
// We are anchoring (B2B'ing) the call - time to start second leg
|
||||
mPeer = new B2BSession(mServer);
|
||||
mPeer->setPeer(this);
|
||||
mPeer->startClickToCallAnchorLeg(msg.header(h_To), mClickToCallDestination, mXmlRpcInfo);
|
||||
mWaitingOfferFromPeer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ClickToCall, but do not anchor call - send REFER here instead
|
||||
h->refer(NameAddr(mClickToCallDestination));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onOffer: msg=" << LOG_MSG_WITH_SDP);
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
mPeer->mInviteSessionHandle->provideOffer(sdp);
|
||||
mPeer->mWaitingOfferFromPeer = false;
|
||||
mWaitingAnswerFromPeer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resip_assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog(B2BLOG_PREFIX << "onOffer: No peer, rejecting with 501.");
|
||||
h->reject(501 /* Not Implemented */);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onOfferRequired: msg=" << LOG_MSG);
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
mPeer->mInviteSessionHandle->requestOffer();
|
||||
mWaitingOfferFromPeer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resip_assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog(B2BLOG_PREFIX << "onOfferRequired: No peer, rejecting with 501.");
|
||||
h->reject(501 /* Not Implemented */);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
|
||||
{
|
||||
int statusCode = 488;
|
||||
WarningCategory* warning=0;
|
||||
|
||||
if(isStaleFork(h->getDialogId())) return;
|
||||
|
||||
if(msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onOfferRejected: msg=" << LOG_MSGP);
|
||||
if(msg->exists(h_Warnings))
|
||||
{
|
||||
warning = (WarningCategory*)&msg->header(h_Warnings).back();
|
||||
}
|
||||
if(msg->isResponse())
|
||||
{
|
||||
statusCode = msg->header(h_StatusLine).responseCode();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onOfferRejected:");
|
||||
}
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingAnswerFromPeer)
|
||||
{
|
||||
mPeer->mWaitingAnswerFromPeer = false;
|
||||
mPeer->mInviteSessionHandle->reject(statusCode, warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onOfferRequestRejected: msg=" << LOG_MSG);
|
||||
// This is called when we are waiting to resend a INVITE with no sdp after a glare condition, and we
|
||||
// instead receive an inbound INVITE or UPDATE
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingOfferFromPeer)
|
||||
{
|
||||
// Return glare to peer
|
||||
mPeer->mInviteSessionHandle->reject(491);
|
||||
mPeer->mWaitingOfferFromPeer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
|
||||
{
|
||||
/// called when a modified SDP is received in a 2xx response to a
|
||||
/// session-timer reINVITE. Under normal circumstances where the response
|
||||
/// SDP is unchanged from current remote SDP no handler is called
|
||||
/// There is not much we can do about this. If session timers are used then they are managed seperately per leg
|
||||
/// and we have no real mechanism to notify the other peer of new SDP without starting a new offer/answer negotiation
|
||||
InfoLog(B2BLOG_PREFIX << "onRemoteSdpChanged: msg=" << LOG_MSG_WITH_SDP);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onInfo(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onInfo: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && msg.getContents())
|
||||
{
|
||||
mPeer->mInviteSessionHandle->info(*msg.getContents());
|
||||
mWaitingNitAnswerFromPeer = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h->acceptNIT();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onInfoSuccess: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingNitAnswerFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->acceptNIT(msg.header(h_StatusLine).responseCode(), msg.getContents());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onInfoFailure(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onInfoFailure: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingNitAnswerFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->rejectNIT(msg.header(h_StatusLine).responseCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ss, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onRefer: msg=" << LOG_MSG);
|
||||
|
||||
// If no peer (for some reason), then reject request
|
||||
if(!mPeer)
|
||||
{
|
||||
ss->send(ss->reject(403));
|
||||
return;
|
||||
}
|
||||
|
||||
// Recurse on the REFER - do not pass to other leg
|
||||
try
|
||||
{
|
||||
// Accept the Refer
|
||||
ss->send(ss->accept(202 /* Refer Accepted */));
|
||||
|
||||
B2BSession* newPeer = new B2BSession(mServer);
|
||||
|
||||
mPeer->mWaitingOfferFromPeer = true;
|
||||
|
||||
// Map other leg to this new one
|
||||
newPeer->stealPeer(this);
|
||||
newPeer->mReferringAppDialogSet = getHandle();
|
||||
|
||||
SharedPtr<SipMessage> invitemsg = mDum.makeInviteSessionFromRefer(msg, ss->getHandle(), 0 /* SdpOffer */, newPeer);
|
||||
mDum.send(invitemsg);
|
||||
}
|
||||
catch(BaseException &e)
|
||||
{
|
||||
WarningLog(B2BLOG_PREFIX << "onRefer exception: " << e);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
WarningLog(B2BLOG_PREFIX << "onRefer unknown exception");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onReferAccepted: msg=" << LOG_MSG);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onReferRejected(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onReferRejected: msg=" << LOG_MSG);
|
||||
|
||||
// Endpoint doesn't support REFER - Fallback to anchoring Click-To-Call
|
||||
mClickToCallAnchorEnabled = true;
|
||||
mPeer = new B2BSession(mServer);
|
||||
mPeer->setPeer(this);
|
||||
mPeer->startClickToCallAnchorLeg(msg.header(h_From), mClickToCallDestination, mXmlRpcInfo);
|
||||
mWaitingOfferFromPeer = true;
|
||||
}
|
||||
|
||||
bool
|
||||
B2BSession::doReferNoSub(const SipMessage& msg)
|
||||
{
|
||||
// If no peer (for some reason), then return false
|
||||
if(!mPeer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
B2BSession* newPeer = new B2BSession(mServer);
|
||||
|
||||
|
||||
mPeer->mWaitingOfferFromPeer = true;
|
||||
|
||||
// Map other leg to this new one
|
||||
newPeer->stealPeer(this);
|
||||
newPeer->mReferringAppDialogSet = getHandle();
|
||||
|
||||
// Build the Invite
|
||||
SharedPtr<SipMessage> invitemsg = mDum.makeInviteSessionFromRefer(msg, getUserProfile(), 0 /* Sdp Offer */, newPeer);
|
||||
mDum.send(invitemsg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onReferNoSub(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onReferNoSub: msg=" << LOG_MSG);
|
||||
|
||||
// If no peer (for some reason), then reject request
|
||||
if(!mPeer)
|
||||
{
|
||||
h->rejectReferNoSub(403);
|
||||
return;
|
||||
}
|
||||
|
||||
// Accept the Refer
|
||||
h->acceptReferNoSub(202 /* Refer Accepted */);
|
||||
|
||||
doReferNoSub(msg);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onMessage(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onMessage: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && msg.getContents())
|
||||
{
|
||||
mPeer->mInviteSessionHandle->message(*msg.getContents());
|
||||
mWaitingNitAnswerFromPeer = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h->acceptNIT();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onMessageSuccess: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingNitAnswerFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->acceptNIT(msg.header(h_StatusLine).responseCode(), msg.getContents());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onMessageFailure(InviteSessionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onMessageFailure: msg=" << LOG_MSG);
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid() && mPeer->mWaitingNitAnswerFromPeer)
|
||||
{
|
||||
mPeer->mInviteSessionHandle->rejectNIT(msg.header(h_StatusLine).responseCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onForkDestroyed(ClientInviteSessionHandle h)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onForkDestroyed:");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DialogSetHandler ///////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
B2BSession::onTrying(AppDialogSetHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onTrying: msg=" << LOG_MSG);
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onNonDialogCreatingProvisional: msg=" << LOG_MSG);
|
||||
|
||||
if(isUACConnected()) return;
|
||||
|
||||
if(mPeer)
|
||||
{
|
||||
if(mPeer->mInviteSessionHandle.isValid())
|
||||
{
|
||||
ServerInviteSession* sis = dynamic_cast<ServerInviteSession*>(mPeer->mInviteSessionHandle.get());
|
||||
if(sis && !sis->isAccepted())
|
||||
{
|
||||
sis->provisional(msg.header(h_StatusLine).responseCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
B2BSession::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onUpdatePending(ClientSubscriptionHandle): " << LOG_MSG);
|
||||
if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
|
||||
{
|
||||
h->acceptUpdate();
|
||||
processReferNotify(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
h->rejectUpdate(400, Data("Only notifies for refers are allowed."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onUpdateActive(ClientSubscriptionHandle): " << LOG_MSG);
|
||||
if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
|
||||
{
|
||||
h->acceptUpdate();
|
||||
processReferNotify(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
h->rejectUpdate(400, Data("Only notifies for refers are allowed."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onUpdateExtension(ClientSubscriptionHandle): " << LOG_MSG);
|
||||
if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
|
||||
{
|
||||
h->acceptUpdate();
|
||||
processReferNotify(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
h->rejectUpdate(400, Data("Only notifies for refers are allowed."));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onNotifyNotReceived(resip::ClientSubscriptionHandle h)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onNotifyNotReceived(ClientSubscriptionHandle)");
|
||||
transitionClickToCallState(ReferToDestinationFailed, 408);
|
||||
end();
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg)
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onTerminated(ClientSubscriptionHandle): " << LOG_MSGP);
|
||||
//Note: Final notify is sometimes only passed in the onTerminated callback
|
||||
if (msg->isRequest() && msg->exists(h_Event) && msg->header(h_Event).value() == "refer")
|
||||
{
|
||||
processReferNotify(*msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onTerminated(ClientSubscriptionHandle)");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
B2BSession::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onNewSubscription(ClientSubscriptionHandle): " << LOG_MSG);
|
||||
}
|
||||
|
||||
int
|
||||
B2BSession::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(B2BLOG_PREFIX << "onRequestRetry(ClientSubscriptionHandle): " << LOG_MSG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
#if !defined(B2BSession_hxx)
|
||||
#define B2BSession_hxx
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/AppDialogSet.hxx>
|
||||
|
||||
#include "XmlRpcServer.hxx"
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class Server;
|
||||
|
||||
typedef unsigned int B2BSessionHandle;
|
||||
|
||||
class B2BSession : public resip::AppDialogSet
|
||||
{
|
||||
public:
|
||||
B2BSession(Server& server);
|
||||
virtual ~B2BSession();
|
||||
|
||||
void setPeer(B2BSession* peer);
|
||||
B2BSession* getPeer();
|
||||
void stealPeer(B2BSession* victimSession);
|
||||
|
||||
B2BSessionHandle getB2BSessionHandle() const { return mHandle; }
|
||||
|
||||
void clickToCall(const resip::Uri& initiator, const resip::Uri& destination, bool anchorCall, const XmlRpcInfo& xmlRpcInfo);
|
||||
void startCall(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
|
||||
protected:
|
||||
friend class Server;
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual bool doReferNoSub(const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onNotifyNotReceived(resip::ClientSubscriptionHandle h);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
private:
|
||||
bool buildLocalOffer(resip::SdpContents& sdp);
|
||||
void startClickToCallAnchorLeg(const resip::NameAddr& initiator, const resip::Uri& destination, const XmlRpcInfo& xmlRpcInfo);
|
||||
void endPeer();
|
||||
bool isUACConnected();
|
||||
bool isStaleFork(const resip::DialogId& dialogId);
|
||||
void processReferNotify(const resip::SipMessage& notify);
|
||||
|
||||
Server& mServer;
|
||||
resip::DialogUsageManager& mDum;
|
||||
B2BSession* mPeer;
|
||||
resip::InviteSessionHandle mInviteSessionHandle;
|
||||
B2BSessionHandle mHandle;
|
||||
resip::AppDialogSetHandle mReferringAppDialogSet;
|
||||
|
||||
// State information
|
||||
resip::DialogId mUACConnectedDialogId;
|
||||
bool mWaitingOfferFromPeer;
|
||||
bool mWaitingAnswerFromPeer;
|
||||
bool mWaitingNitAnswerFromPeer;
|
||||
|
||||
// Click-to-Call Info
|
||||
typedef enum
|
||||
{
|
||||
Undefined, // Not used
|
||||
Setup,
|
||||
Proceeding,
|
||||
Connected,
|
||||
Failed,
|
||||
ReferToDestinationProceeding,
|
||||
ReferToDestinationConnected,
|
||||
ReferToDestinationFailed
|
||||
} ClickToCallState;
|
||||
ClickToCallState mClickToCallState;
|
||||
void transitionClickToCallState(ClickToCallState newState, unsigned int statusCode=0);
|
||||
|
||||
resip::Uri mClickToCallDestination;
|
||||
bool mClickToCallAnchorEnabled;
|
||||
bool mClickToCallInitiator;
|
||||
XmlRpcInfo mXmlRpcInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#if !defined(ClickToCallCmds_hxx)
|
||||
#define ClickToCallCmds_hxx
|
||||
|
||||
#include <resip/dum/DumCommand.hxx>
|
||||
|
||||
#include "Server.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
/**
|
||||
The classes defined here are used to pass commands from the
|
||||
application thread to the DUM thread (process loop).
|
||||
This ensures thread safety of the external Server methods.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
class ClickToCallCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
ClickToCallCmd(Server& server, const resip::Uri& initiator, const resip::Uri& destination, bool anchorCall,
|
||||
const XmlRpcInfo& xmlRpcInfo)
|
||||
: mServer(server), mInitiator(initiator), mDestination(destination), mAnchorCall(anchorCall),
|
||||
mXmlRpcInfo(xmlRpcInfo) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.clickToCallImpl(mInitiator, mDestination, mAnchorCall, mXmlRpcInfo);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " ClickToCallCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
resip::Uri mInitiator;
|
||||
resip::Uri mDestination;
|
||||
bool mAnchorCall;
|
||||
XmlRpcInfo mXmlRpcInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
#include "ConfigParser.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
ConfigParser::ConfigParser(int argc, char** argv) :
|
||||
// Defaults
|
||||
mSipPort(5072),
|
||||
mTlsPort(5073),
|
||||
mTlsDomain(DnsUtil::getLocalHostName()),
|
||||
mKeepAlives(true),
|
||||
mLogLevel("INFO"),
|
||||
mLogFilename("clicktocall.log"),
|
||||
mLogFileMaxLines(50000), // 50000 is about 5M size
|
||||
mXmlRpcPort(5094),
|
||||
mHttpPort(5095),
|
||||
mHttpAuth(false),
|
||||
mHttpAuthPwd("admin")
|
||||
{
|
||||
// Parse config file first
|
||||
parseConfigFile("clicktocall.config");
|
||||
|
||||
// Parse command line options
|
||||
// Note: command line overrides config file setting
|
||||
parseCommandLine(argc, argv);
|
||||
}
|
||||
|
||||
ConfigParser::~ConfigParser()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseCommandLine(int argc, char** argv)
|
||||
{
|
||||
// Loop through command line arguments and process them
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
Data commandName(argv[i]);
|
||||
|
||||
// Process all commandNames that don't take values
|
||||
if(isEqualNoCase(commandName, "-?") ||
|
||||
isEqualNoCase(commandName, "--?") ||
|
||||
isEqualNoCase(commandName, "--help") ||
|
||||
isEqualNoCase(commandName, "/?"))
|
||||
{
|
||||
cout << "Command line options are:" << endl;
|
||||
cout << " -a <IP Address> - bind SIP transports to this IP address" << endl;
|
||||
cout << " -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list" << endl;
|
||||
cout << " -ci <ClickToCall identity> - used in From header of click-to-call requests to initiator" << endl;
|
||||
cout << " -sp <port num> - local port number to use for SIP messaging (UDP/TCP)" << endl;
|
||||
cout << " -tp <port num> - local port number to use for TLS SIP messaging" << endl;
|
||||
cout << " -td <domain name> - domain name to use for TLS server connections" << endl;
|
||||
cout << " -nk - no keepalives, set this to disable sending of keepalives" << endl;
|
||||
cout << " -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy" << endl;
|
||||
cout << " -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl;
|
||||
cout << endl;
|
||||
cout << "Sample Command line:" << endl;
|
||||
cout << "clicktocall -a 192.168.1.100 -l DEBUG" << endl;
|
||||
exit(0);
|
||||
}
|
||||
else if(isEqualNoCase(commandName, "-nk"))
|
||||
{
|
||||
mKeepAlives = false;
|
||||
}
|
||||
else if(commandName.at(0) == '-')
|
||||
{
|
||||
commandName = commandName.substr(1); // Remove -
|
||||
|
||||
// Process commands that have values
|
||||
Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty);
|
||||
if(commandValue.empty() || commandValue.at(0) == '-')
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
i++; // increment argument
|
||||
|
||||
//cout << "Command Line Name='" << commandName << "' value='" << commandValue << "'" << endl;
|
||||
if(!processOption(commandName.lowercase(), commandValue))
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseConfigFile(const Data& filename)
|
||||
{
|
||||
ifstream configFile(filename.c_str());
|
||||
|
||||
string sline;
|
||||
while(getline(configFile, sline))
|
||||
{
|
||||
Data line(sline);
|
||||
Data name;
|
||||
Data value;
|
||||
ParseBuffer pb(line);
|
||||
|
||||
pb.skipWhitespace();
|
||||
const char * anchor = pb.position();
|
||||
if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it
|
||||
// Look for =
|
||||
pb.skipToOneOf("= \t");
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.data(name,anchor);
|
||||
if(*pb.position()!='=')
|
||||
{
|
||||
pb.skipToChar('=');
|
||||
}
|
||||
pb.skipChar('=');
|
||||
pb.skipWhitespace();
|
||||
anchor = pb.position();
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipToEnd();
|
||||
pb.data(value, anchor);
|
||||
}
|
||||
//cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
|
||||
processOption(name.lowercase(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::processOption(const Data& name, const Data& value)
|
||||
{
|
||||
bool result = true;
|
||||
if(name == "a" || name == "ipaddress")
|
||||
{
|
||||
mAddress = value;
|
||||
}
|
||||
else if(name == "d" || name == "dnsservers")
|
||||
{
|
||||
if(!value.empty()) mDnsServers.clear(); // allow command line to override config file, since list is added to
|
||||
|
||||
// DNS Servers
|
||||
ParseBuffer pb(value);
|
||||
Data dnsServer;
|
||||
while(!value.empty() && !pb.eof())
|
||||
{
|
||||
pb.skipWhitespace();
|
||||
const char *start = pb.position();
|
||||
pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space
|
||||
pb.data(dnsServer, start);
|
||||
if(DnsUtil::isIpV4Address(dnsServer))
|
||||
{
|
||||
mDnsServers.push_back(Tuple(dnsServer, 0, UNKNOWN_TRANSPORT).toGenericIPAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Tried to add dns server, but invalid format: " << value << endl;
|
||||
result = false;
|
||||
}
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(name == "ci" || name == "clicktocallidentity")
|
||||
{
|
||||
result = assignNameAddr("click to call identity", value, mClickToCallIdentity);
|
||||
}
|
||||
else if(name == "sp" || name == "udptcpport")
|
||||
{
|
||||
mSipPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "tp" || name == "tlsport")
|
||||
{
|
||||
mTlsPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "td" || name == "tlsdomain")
|
||||
{
|
||||
mTlsDomain = value;
|
||||
}
|
||||
else if(name == "keepalives")
|
||||
{
|
||||
if(value == "1" || value == "true" || value == "on" || value == "enable")
|
||||
{
|
||||
mKeepAlives = true;
|
||||
}
|
||||
else if(value == "0" || value == "false" || value == "off" || value == "disable")
|
||||
{
|
||||
mKeepAlives = false;
|
||||
}
|
||||
}
|
||||
else if(name == "op" || name == "outboundproxy")
|
||||
{
|
||||
result = assignNameAddr("outbound proxy", value, mOutboundProxy);
|
||||
}
|
||||
else if(name == "l" || name == "loglevel")
|
||||
{
|
||||
mLogLevel = value;
|
||||
}
|
||||
else if(name == "logfilename")
|
||||
{
|
||||
mLogFilename = value;
|
||||
}
|
||||
else if(name == "logfilemaxlines")
|
||||
{
|
||||
mLogFileMaxLines = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "xmlrpcport")
|
||||
{
|
||||
mXmlRpcPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpport")
|
||||
{
|
||||
mHttpPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpauth")
|
||||
{
|
||||
if(value == "1" || value == "true" || value == "on" || value == "enable")
|
||||
{
|
||||
mHttpAuth = true;
|
||||
}
|
||||
else if(value == "0" || value == "false" || value == "off" || value == "disable")
|
||||
{
|
||||
mHttpAuth = false;
|
||||
}
|
||||
}
|
||||
else if(name == "httpauthpwd")
|
||||
{
|
||||
mHttpAuthPwd = value;
|
||||
}
|
||||
else if(name == "translationpattern")
|
||||
{
|
||||
mAddressTranslations.push_back(std::make_pair(value, Data::Empty));
|
||||
}
|
||||
else if(name == "translationoutput")
|
||||
{
|
||||
if(!mAddressTranslations.empty())
|
||||
{
|
||||
mAddressTranslations.back().second = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::assignNameAddr(const Data& settingName, const Data& settingValue, NameAddr& nameAddr)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!settingValue.empty())
|
||||
{
|
||||
NameAddr tempNameAddr(settingValue);
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
// Try adding sip: to address to see if it will be valid
|
||||
try
|
||||
{
|
||||
NameAddr tempNameAddr(Data("sip:" + settingValue));
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
catch(resip::BaseException&)
|
||||
{
|
||||
cerr << "Invalid " << settingName << " NameAddr format=" << settingValue << ": " << e << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#if !defined(ConfigParser_hxx)
|
||||
#define ConfigParser_hxx
|
||||
|
||||
#include <list>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <rutil/dns/DnsStub.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class ConfigParser
|
||||
{
|
||||
public:
|
||||
ConfigParser(int argc, char** argv);
|
||||
virtual ~ConfigParser();
|
||||
|
||||
void parseCommandLine(int argc, char** argv);
|
||||
void parseConfigFile(const resip::Data& filename);
|
||||
bool processOption(const resip::Data& name, const resip::Data& value);
|
||||
bool assignNameAddr(const resip::Data& settingName, const resip::Data& settingValue, resip::NameAddr& nameAddr);
|
||||
|
||||
resip::Data mAddress;
|
||||
resip::DnsStub::NameserverList mDnsServers;
|
||||
resip::NameAddr mClickToCallIdentity;
|
||||
unsigned short mSipPort;
|
||||
unsigned short mTlsPort;
|
||||
resip::Data mTlsDomain;
|
||||
resip::NameAddr mOutboundProxy;
|
||||
bool mKeepAlives;
|
||||
resip::Data mLogLevel;
|
||||
resip::Data mLogFilename;
|
||||
unsigned int mLogFileMaxLines;
|
||||
unsigned short mXmlRpcPort;
|
||||
unsigned short mHttpPort;
|
||||
bool mHttpAuth;
|
||||
resip::Data mHttpAuthPwd;
|
||||
typedef std::list<std::pair<resip::Data,resip::Data> > TranslationList;
|
||||
TranslationList mAddressTranslations;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "HttpBase.hxx"
|
||||
#include "HttpConnection.hxx"
|
||||
#include "WebAdmin.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
|
||||
HttpBase::~HttpBase()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(mFd);
|
||||
#else
|
||||
close(mFd);
|
||||
#endif
|
||||
mFd=0;
|
||||
for( int i=0; i<MaxConnections; i++)
|
||||
{
|
||||
if ( mConnection[i] )
|
||||
{
|
||||
delete mConnection[i] ; mConnection[i]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HttpBase::HttpBase( int port, IpVersion ipVer, const Data& realm ):
|
||||
mRealm(realm),
|
||||
nextConnection(0),
|
||||
mTuple(Data::Empty,port,ipVer,TCP,Data::Empty)
|
||||
{
|
||||
sane = true;
|
||||
|
||||
for ( int i=0 ; i<MaxConnections; i++)
|
||||
{
|
||||
mConnection[i]=0;
|
||||
}
|
||||
|
||||
#ifdef USE_IPV6
|
||||
mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0);
|
||||
#else
|
||||
mFd = ::socket(PF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
|
||||
if ( mFd == INVALID_SOCKET )
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<< "Failed to create socket: " << strerror(e));
|
||||
sane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog (<< "Creating fd=" << (int)mFd
|
||||
<< (ipVer == V4 ? " V4/" : " V6/") );
|
||||
|
||||
int on = 1;
|
||||
#if !defined(WIN32)
|
||||
if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) )
|
||||
#else
|
||||
if ( ::setsockopt ( mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) )
|
||||
#endif
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<< "Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e));
|
||||
sane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple));
|
||||
|
||||
if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
if ( e == EADDRINUSE )
|
||||
{
|
||||
ErrLog (<< mTuple << " already in use ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog (<< "Could not bind to " << mTuple);
|
||||
}
|
||||
sane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = makeSocketNonBlocking(mFd);
|
||||
if ( !ok )
|
||||
{
|
||||
ErrLog (<< "Could not make HTTP socket non-blocking " << port );
|
||||
sane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// do the listen, seting the maximum queue size for compeletly established
|
||||
// sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete
|
||||
// queue size(see man listen)
|
||||
int e = listen(mFd,5 );
|
||||
|
||||
if (e != 0 )
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "Failed listen " << strerror(e));
|
||||
sane = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpBase::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
fdset.setRead( mFd );
|
||||
|
||||
for( int i=0; i<MaxConnections; i++)
|
||||
{
|
||||
if ( mConnection[i] )
|
||||
{
|
||||
mConnection[i]->buildFdSet(fdset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpBase::process(FdSet& fdset)
|
||||
{
|
||||
if (fdset.readyToRead(mFd))
|
||||
{
|
||||
Tuple tuple(mTuple);
|
||||
struct sockaddr& peer = tuple.getMutableSockaddr();
|
||||
socklen_t peerLen = tuple.length();
|
||||
Socket sock = accept( mFd, &peer, &peerLen);
|
||||
if ( sock == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
switch (e)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
return;
|
||||
default:
|
||||
ErrLog(<< "Some error reading from socket: " << e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
makeSocketNonBlocking(sock);
|
||||
|
||||
int c = nextConnection;
|
||||
nextConnection = ( nextConnection+1 ) % MaxConnections;
|
||||
|
||||
if ( mConnection[c] )
|
||||
{
|
||||
delete mConnection[c]; mConnection[c] = 0;
|
||||
}
|
||||
|
||||
mConnection[c] = new HttpConnection(*this,sock);
|
||||
|
||||
DebugLog (<< "Received TCP connection as connection=" << c << " fd=" << (int)sock);
|
||||
}
|
||||
|
||||
for( int i=0; i<MaxConnections; i++)
|
||||
{
|
||||
if ( mConnection[i] )
|
||||
{
|
||||
bool ok = mConnection[i]->process(fdset);
|
||||
if ( !ok )
|
||||
{
|
||||
delete mConnection[i]; mConnection[i]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HttpBase::setPage( const Data& page, int pageNumber, int response, const Mime& type )
|
||||
{
|
||||
for ( int i=0 ; i<MaxConnections; i++)
|
||||
{
|
||||
if ( mConnection[i] )
|
||||
{
|
||||
if ( mConnection[i]->mPageNumber == pageNumber )
|
||||
{
|
||||
mConnection[i]->setPage( page,response,type );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HttpBase::isSane()
|
||||
{
|
||||
return sane;
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
#if !defined(HttpBase_hxx)
|
||||
#define HttpBase_hxx
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <resip/stack/Mime.hxx>
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class HttpConnection;
|
||||
|
||||
class HttpBase
|
||||
{
|
||||
friend class HttpConnection;
|
||||
|
||||
public:
|
||||
HttpBase( int port, resip::IpVersion version, const resip::Data& realm );
|
||||
virtual ~HttpBase();
|
||||
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
void process(resip::FdSet& fdset);
|
||||
|
||||
bool isSane();
|
||||
|
||||
protected:
|
||||
virtual void buildPage( const resip::Data& uri,
|
||||
int pageNumber,
|
||||
const resip::Data& user,
|
||||
const resip::Data& password )=0;
|
||||
void setPage( const resip::Data& page,
|
||||
int pageNumber,
|
||||
int response=200,
|
||||
const resip::Mime& pType = resip::Mime("text","html") );
|
||||
|
||||
const resip::Data mRealm;
|
||||
|
||||
private:
|
||||
static const int MaxConnections = 30;
|
||||
|
||||
resip::Socket mFd;
|
||||
int nextConnection;
|
||||
resip::Tuple mTuple;
|
||||
|
||||
bool sane;
|
||||
|
||||
HttpConnection* mConnection[MaxConnections];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,421 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
|
||||
#include "Version.hxx"
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "Server.hxx"
|
||||
#include "HttpBase.hxx"
|
||||
#include "HttpConnection.hxx"
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
int HttpConnection::nextPageNumber=1;
|
||||
|
||||
|
||||
HttpConnection::HttpConnection( HttpBase& base, resip::Socket pSock ):
|
||||
mHttpBase( base ),
|
||||
mPageNumber(nextPageNumber++),
|
||||
mSock(pSock),
|
||||
mParsedRequest(false)
|
||||
{
|
||||
resip_assert( mSock > 0 );
|
||||
}
|
||||
|
||||
|
||||
HttpConnection::~HttpConnection()
|
||||
{
|
||||
resip_assert( mSock > 0 );
|
||||
#ifdef WIN32
|
||||
closesocket(mSock); mSock=0;
|
||||
#else
|
||||
close(mSock); mSock=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpConnection::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
if ( !mTxBuffer.empty() )
|
||||
{
|
||||
fdset.setWrite(mSock);
|
||||
}
|
||||
fdset.setRead(mSock);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HttpConnection::process(FdSet& fdset)
|
||||
{
|
||||
if ( fdset.hasException(mSock) )
|
||||
{
|
||||
int errNum = 0;
|
||||
int errNumSize = sizeof(errNum);
|
||||
getsockopt(mSock,SOL_SOCKET,SO_ERROR,(char *)&errNum,(socklen_t *)&errNumSize);
|
||||
InfoLog (<< "Exception reading from socket "
|
||||
<< (int)mSock << " code: " << errNum << "; closing connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( fdset.readyToRead( mSock ) )
|
||||
{
|
||||
bool ok = processSomeReads();
|
||||
if ( !ok )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( (!mTxBuffer.empty()) && fdset.readyToWrite( mSock ) )
|
||||
{
|
||||
bool ok = processSomeWrites();
|
||||
if ( !ok )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpConnection::setPage(const Data& pPage,int response,const Mime& pType)
|
||||
{
|
||||
Data page(pPage);
|
||||
|
||||
switch (response)
|
||||
{
|
||||
case 401:
|
||||
{
|
||||
mTxBuffer += "HTTP/1.0 401 Unauthorized"; mTxBuffer += Symbols::CRLF;
|
||||
|
||||
page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
|
||||
"<html><head>"
|
||||
"<title>401 Unauthorized</title>"
|
||||
"</head><body>"
|
||||
"<h1>Unauthorized</h1>"
|
||||
"</body></html>" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 404:
|
||||
{
|
||||
mTxBuffer += "HTTP/1.0 404 Not Found"; mTxBuffer += Symbols::CRLF;
|
||||
|
||||
page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
|
||||
"<html><head>"
|
||||
"<title>404 Not Found</title>"
|
||||
"</head><body>"
|
||||
"<h1>Unauthorized</h1>"
|
||||
"</body></html>" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 301:
|
||||
{
|
||||
mTxBuffer += "HTTP/1.0 301 Moved Permanently"; mTxBuffer += Symbols::CRLF;
|
||||
mTxBuffer += "Location: http:/index.html"; mTxBuffer += Symbols::CRLF;
|
||||
|
||||
page = ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
|
||||
"<html><head>"
|
||||
"<title>301 Moved Permanently</title>"
|
||||
"</head><body>"
|
||||
"<h1>Moved</h1>"
|
||||
"</body></html>" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 200:
|
||||
{
|
||||
mTxBuffer += "HTTP/1.0 200 OK" ; mTxBuffer += Symbols::CRLF;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
resip_assert(0);
|
||||
|
||||
Data resp;
|
||||
{
|
||||
DataStream s(resp);
|
||||
s << response;
|
||||
s.flush();
|
||||
}
|
||||
|
||||
mTxBuffer += "HTTP/1.0 ";
|
||||
mTxBuffer += resp;
|
||||
mTxBuffer += "OK" ; mTxBuffer += Symbols::CRLF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Data len;
|
||||
{
|
||||
DataStream s(len);
|
||||
s << page.size();
|
||||
s.flush();
|
||||
}
|
||||
|
||||
mTxBuffer += "WWW-Authenticate: Basic realm=\"";
|
||||
if ( mHttpBase.mRealm.empty() )
|
||||
{
|
||||
mTxBuffer += resip::DnsUtil::getLocalHostName();
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxBuffer += mHttpBase.mRealm;
|
||||
}
|
||||
mTxBuffer += "\" ";
|
||||
mTxBuffer += Symbols::CRLF;
|
||||
|
||||
mTxBuffer += "Server: clicktocall " ;
|
||||
mTxBuffer += Data(CLICKTOCALL_VERSION_STRING);
|
||||
mTxBuffer += Symbols::CRLF;
|
||||
mTxBuffer += "Mime-version: 1.0 " ; mTxBuffer += Symbols::CRLF;
|
||||
mTxBuffer += "Pragma: no-cache " ; mTxBuffer += Symbols::CRLF;
|
||||
mTxBuffer += "Content-Length: "; mTxBuffer += len; mTxBuffer += Symbols::CRLF;
|
||||
|
||||
mTxBuffer += "Content-Type: " ;
|
||||
mTxBuffer += pType.type() ;
|
||||
mTxBuffer +="/" ;
|
||||
mTxBuffer += pType.subType() ; mTxBuffer += Symbols::CRLF;
|
||||
|
||||
mTxBuffer += Symbols::CRLF;
|
||||
|
||||
mTxBuffer += page;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HttpConnection::processSomeReads()
|
||||
{
|
||||
const int bufSize = 8000;
|
||||
char buf[bufSize];
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
int bytesRead = ::recv(mSock, buf, bufSize, 0);
|
||||
#else
|
||||
int bytesRead = ::read(mSock, buf, bufSize);
|
||||
#endif
|
||||
|
||||
if (bytesRead == INVALID_SOCKET)
|
||||
{
|
||||
int e = getErrno();
|
||||
switch (e)
|
||||
{
|
||||
case EAGAIN:
|
||||
InfoLog (<< "No data ready to read");
|
||||
return true;
|
||||
case EINTR:
|
||||
InfoLog (<< "The call was interrupted by a signal before any data was read.");
|
||||
break;
|
||||
case EIO:
|
||||
InfoLog (<< "I/O error");
|
||||
break;
|
||||
case EBADF:
|
||||
InfoLog (<< "fd is not a valid file descriptor or is not open for reading.");
|
||||
break;
|
||||
case EINVAL:
|
||||
InfoLog (<< "fd is attached to an object which is unsuitable for reading.");
|
||||
break;
|
||||
case EFAULT:
|
||||
InfoLog (<< "buf is outside your accessible address space.");
|
||||
break;
|
||||
default:
|
||||
InfoLog (<< "Some other error");
|
||||
break;
|
||||
}
|
||||
InfoLog (<< "Failed read on " << (int)mSock << " " << strerror(e));
|
||||
return false;
|
||||
}
|
||||
else if (bytesRead == 0)
|
||||
{
|
||||
InfoLog (<< "Connection closed by remote " );
|
||||
return false;
|
||||
}
|
||||
|
||||
//DebugLog (<< "HttpConnection::processSomeReads() "
|
||||
// << " read=" << bytesRead);
|
||||
|
||||
mRxBuffer += Data( buf, bytesRead );
|
||||
|
||||
tryParse();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpConnection::tryParse()
|
||||
{
|
||||
//DebugLog (<< "parse " << mRxBuffer );
|
||||
|
||||
ParseBuffer pb(mRxBuffer);
|
||||
|
||||
pb.skipToChar(Symbols::SPACE[0]);
|
||||
const char* start = pb.skipWhitespace();
|
||||
pb.skipToChar(Symbols::SPACE[0]);
|
||||
|
||||
if (pb.eof())
|
||||
{
|
||||
// parse failed - just return
|
||||
return;
|
||||
}
|
||||
|
||||
Data uri;
|
||||
pb.data( uri, start );
|
||||
|
||||
DebugLog (<< "parse found URI " << uri );
|
||||
mParsedRequest = true;
|
||||
|
||||
|
||||
Data user;
|
||||
Data password;
|
||||
|
||||
try
|
||||
{
|
||||
pb.skipToChars( "Authorization" );
|
||||
if ( !pb.eof() )
|
||||
{
|
||||
if ( pb.eof() ) DebugLog( << "Did not find Authorization header" );
|
||||
pb.skipToChars( "Basic" ); pb.skipN(6);
|
||||
if ( pb.eof() ) DebugLog( << "Did not find Authorization basic " );
|
||||
pb.skipWhitespace();
|
||||
if ( pb.eof() ) DebugLog( << "Something weird in Auhtorization header " );
|
||||
if ( !pb.eof() )
|
||||
{
|
||||
const char* a = pb.position();
|
||||
pb.skipNonWhitespace();
|
||||
Data buf = pb.data(a);
|
||||
|
||||
DebugLog (<< "parse found basic base64 auth data of " << buf );
|
||||
Data auth = buf.base64decode();
|
||||
|
||||
//DebugLog (<< "parse found basic auth data of " << auth );
|
||||
|
||||
ParseBuffer p(auth);
|
||||
const char* a1 = p.position();
|
||||
p.skipToChar(':');
|
||||
user = p.data(a1);
|
||||
const char* a2 = p.skipChar(':');
|
||||
p.skipToEnd();
|
||||
password = p.data(a2);
|
||||
|
||||
//DebugLog (<< "parse found basic auth data with user=" << user
|
||||
// << " password=" << password );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
ErrLog (<< "Some problem finding Authorization header in HTTP request" );
|
||||
}
|
||||
|
||||
mHttpBase.buildPage(uri,mPageNumber,user,password);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HttpConnection::processSomeWrites()
|
||||
{
|
||||
if ( mTxBuffer.empty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//DebugLog (<< "Writing " << mTxBuffer );
|
||||
|
||||
#if defined(WIN32)
|
||||
int bytesWritten = ::send( mSock, mTxBuffer.data(), (int)mTxBuffer.size(), 0);
|
||||
#else
|
||||
int bytesWritten = ::write(mSock, mTxBuffer.data(), mTxBuffer.size() );
|
||||
#endif
|
||||
|
||||
if (bytesWritten == INVALID_SOCKET)
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "HttpConnection failed write on " << mSock << " " << strerror(e));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bytesWritten == (int)mTxBuffer.size() )
|
||||
{
|
||||
DebugLog (<< "Wrote it all" );
|
||||
mTxBuffer = Data::Empty;
|
||||
|
||||
return false; // return false causes connection to close and clean up
|
||||
}
|
||||
else
|
||||
{
|
||||
Data rest = mTxBuffer.substr(bytesWritten);
|
||||
mTxBuffer = rest;
|
||||
DebugLog( << "Wrote " << bytesWritten << " bytes - still need to do " << mTxBuffer );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#if !defined(HttpConnection_hxx)
|
||||
#define HttpConnection_hxx
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <resip/stack/Mime.hxx>
|
||||
|
||||
#include "HttpBase.hxx"
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class HttpConnection
|
||||
{
|
||||
friend class HttpBase;
|
||||
|
||||
public:
|
||||
HttpConnection( HttpBase& webAdmin, resip::Socket pSock );
|
||||
~HttpConnection();
|
||||
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
bool process(resip::FdSet& fdset);
|
||||
|
||||
void setPage(const resip::Data& page,
|
||||
int response,
|
||||
const resip::Mime& pType );
|
||||
|
||||
private:
|
||||
bool processSomeReads();
|
||||
bool processSomeWrites();
|
||||
void tryParse();
|
||||
|
||||
HttpBase& mHttpBase;
|
||||
const int mPageNumber;
|
||||
static int nextPageNumber;
|
||||
|
||||
resip::Socket mSock;
|
||||
resip::Data mRxBuffer;
|
||||
resip::Data mTxBuffer;
|
||||
bool mParsedRequest;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
# $Id$
|
||||
|
||||
EXTRA_DIST = clicktocall.config
|
||||
EXTRA_DIST += doc
|
||||
EXTRA_DIST += *.sln
|
||||
EXTRA_DIST += *.vcproj
|
||||
|
||||
SUBDIRS = .
|
||||
SUBDIRS += test
|
||||
|
||||
#AM_CXXFLAGS = -DUSE_ARES
|
||||
|
||||
sbin_PROGRAMS = clicktocall
|
||||
clicktocall_LDADD = ../../resip/dum/libdum.la
|
||||
clicktocall_LDADD += ../../resip/stack/libresip.la ../../rutil/librutil.la
|
||||
clicktocall_LDADD += @LIBSSL_LIBADD@ -lpcre @LIBPTHREAD_LIBADD@
|
||||
|
||||
clicktocall_SOURCES = \
|
||||
AddressTranslator.cxx \
|
||||
AppSubsystem.cxx \
|
||||
B2BSession.cxx \
|
||||
clicktocall.cxx \
|
||||
ConfigParser.cxx \
|
||||
HttpBase.cxx \
|
||||
HttpConnection.cxx \
|
||||
Server.cxx \
|
||||
WebAdmin.cxx \
|
||||
WebAdminThread.cxx \
|
||||
XmlRpcConnection.cxx \
|
||||
XmlRpcServerBase.cxx \
|
||||
XmlRpcServer.cxx \
|
||||
XmlRpcServerThread.cxx
|
||||
|
||||
|
||||
clicktocallincludedir = $(includedir)/clicktocall
|
||||
nobase_clicktocallinclude_HEADERS = ConfigParser.hxx \
|
||||
Version.hxx \
|
||||
WebAdminThread.hxx \
|
||||
XmlRpcServerBase.hxx \
|
||||
HttpBase.hxx \
|
||||
XmlRpcConnection.hxx \
|
||||
AppSubsystem.hxx \
|
||||
XmlRpcServerThread.hxx \
|
||||
B2BSession.hxx \
|
||||
AddressTranslator.hxx \
|
||||
WebAdmin.hxx \
|
||||
XmlRpcServer.hxx \
|
||||
HttpConnection.hxx \
|
||||
Server.hxx \
|
||||
ClickToCallCmds.hxx
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# The Vovida Software License, Version 1.0
|
||||
# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
# and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
# not be used to endorse or promote products derived from this
|
||||
# software without prior written permission. For written
|
||||
# permission, please contact vocal@vovida.org.
|
||||
#
|
||||
# 4. Products derived from this software may not be called "VOCAL", nor
|
||||
# may "VOCAL" appear in their name, without prior written
|
||||
# permission of Vovida Networks, Inc.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
# DAMAGE.
|
||||
#
|
||||
# ====================================================================
|
||||
#
|
||||
# This software consists of voluntary contributions made by Vovida
|
||||
# Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
# Inc. For more information on Vovida Networks, Inc., please see
|
||||
# <http://www.vovida.org/>.
|
||||
#
|
||||
##############################################################################
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,270 +0,0 @@
|
|||
#if !defined(Server_hxx)
|
||||
#define Server_hxx
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <resip/stack/TransactionUser.hxx>
|
||||
#include <resip/stack/InterruptableStackThread.hxx>
|
||||
#include <rutil/SelectInterruptor.hxx>
|
||||
#include <resip/stack/UdpTransport.hxx>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <resip/dum/DumShutdownHandler.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/OutOfDialogHandler.hxx>
|
||||
#include <resip/dum/RedirectHandler.hxx>
|
||||
#include <resip/dum/SubscriptionHandler.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <rutil/Mutex.hxx>
|
||||
|
||||
#include "ConfigParser.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "WebAdmin.hxx"
|
||||
#include "WebAdminThread.hxx"
|
||||
#include "XmlRpcServer.hxx"
|
||||
#include "XmlRpcServerThread.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class ShutdownCmd;
|
||||
class B2BSession;
|
||||
|
||||
class Server : public ConfigParser,
|
||||
public resip::DumShutdownHandler,
|
||||
public resip::InviteSessionHandler,
|
||||
public resip::DialogSetHandler,
|
||||
public resip::OutOfDialogHandler,
|
||||
public resip::RedirectHandler,
|
||||
public resip::ClientSubscriptionHandler,
|
||||
public resip::ServerSubscriptionHandler
|
||||
{
|
||||
public:
|
||||
Server(int argc, char** argv);
|
||||
virtual ~Server();
|
||||
|
||||
/**
|
||||
Starts the SIP stack thread.
|
||||
|
||||
@note This should be called before calling process() in a loop
|
||||
*/
|
||||
void startup();
|
||||
|
||||
/**
|
||||
This should be called in a loop to give process cycles to the server.
|
||||
|
||||
@param timeoutMs Will return after timeoutMs if nothing to do.
|
||||
Application can do some work, but should call
|
||||
process again ASAP.
|
||||
*/
|
||||
void process(int timeoutMs); // call this in a loop
|
||||
|
||||
/**
|
||||
Used to initiate a shutdown of the server. This function blocks
|
||||
until the shutdown is complete.
|
||||
|
||||
@note There should not be an active process request when this
|
||||
is called.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
// Utility Methods ////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
SubsystemAll,
|
||||
SubsystemContents,
|
||||
SubsystemDns,
|
||||
SubsystemDum,
|
||||
SubsystemSdp,
|
||||
SubsystemSip,
|
||||
SubsystemTransaction,
|
||||
SubsystemTransport,
|
||||
SubsystemStats,
|
||||
SubsystemClickToCall
|
||||
} LoggingSubsystem;
|
||||
|
||||
/**
|
||||
Static method that sets the logging level for a particular subsystem,
|
||||
or all subsystems.
|
||||
|
||||
@param level Logging level to set
|
||||
@param subsystem Subsystem to set level on
|
||||
|
||||
@note: Use Server::SubsystemAll to set the logging level on all
|
||||
subsystems
|
||||
*/
|
||||
static void setLogLevel(resip::Log::Level level, LoggingSubsystem subsystem=SubsystemAll);
|
||||
|
||||
/**
|
||||
Click-To-Call - Requests server to place a call first to the initiator, once the initiator
|
||||
answers the call the destination is contacted. If anchorCall is true, then the server
|
||||
stays in the call path (B2BUA). If anchorCall is false then a REFER message is sent
|
||||
to the initiator once answered, to direct the endpoint to the destination outside of
|
||||
this server.
|
||||
|
||||
@param initiator First party contacted
|
||||
@param destination Second part contacted
|
||||
@param anchorCall Set to true to keep server in call path
|
||||
@param xmlRpcInfo Set to non-zero if request was received from XML RPC interface - used for progress notification
|
||||
*/
|
||||
void clickToCall(const resip::Uri& initiator, const resip::Uri& destination, bool anchorCall, XmlRpcInfo* xmlRpcServer = 0);
|
||||
|
||||
bool translateAddress(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
protected:
|
||||
resip::SharedPtr<resip::MasterProfile>& getMasterProfile() { return mProfile; }
|
||||
|
||||
// Shutdown Handler ////////////////////////////////////////////////////////////
|
||||
void onDumCanBeDeleted();
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onNotifyNotReceived(resip::ClientSubscriptionHandle h);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
// ServerSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onNewSubscriptionFromRefer(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onRefresh(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onTerminated(resip::ServerSubscriptionHandle);
|
||||
virtual void onNotifyRejected(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onExpiredByClient(resip::ServerSubscriptionHandle, const resip::SipMessage& sub, resip::SipMessage& notify);
|
||||
virtual void onExpired(resip::ServerSubscriptionHandle, resip::SipMessage& notify);
|
||||
virtual bool hasDefaultExpires() const;
|
||||
virtual UInt32 getDefaultExpires() const;
|
||||
|
||||
// OutOfDialogHandler //////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onReceivedRequest(resip::ServerOutOfDialogReqHandle, const resip::SipMessage& request);
|
||||
|
||||
// RedirectHandler /////////////////////////////////////////////////////////////
|
||||
virtual void onRedirectReceived(resip::AppDialogSetHandle, const resip::SipMessage& response);
|
||||
virtual bool onTryingNextTarget(resip::AppDialogSetHandle, const resip::SipMessage& request);
|
||||
|
||||
private:
|
||||
friend class ShutdownCmd;
|
||||
friend class B2BSession;
|
||||
|
||||
resip::DialogUsageManager& getDialogUsageManager();
|
||||
|
||||
void post(resip::ApplicationMessage& message, unsigned int ms=0);
|
||||
void shutdownImpl();
|
||||
|
||||
friend class ClickToCallCmd;
|
||||
void clickToCallImpl(const resip::Uri& initiator, const resip::Uri& destination, bool anchorCall, const XmlRpcInfo& xmlRpcInfo);
|
||||
|
||||
resip::SharedPtr<resip::MasterProfile> mProfile;
|
||||
resip::Security* mSecurity;
|
||||
resip::SelectInterruptor mSelectInterruptor;
|
||||
resip::SipStack mStack;
|
||||
resip::DialogUsageManager mDum;
|
||||
resip::InterruptableStackThread mStackThread;
|
||||
volatile bool mDumShutdown;
|
||||
|
||||
typedef std::map<B2BSessionHandle, B2BSession*> B2BSessionMap;
|
||||
B2BSessionMap mB2BSessions;
|
||||
B2BSessionHandle mCurrentB2BSessionHandle;
|
||||
B2BSession* getB2BSession(const B2BSessionHandle& handle) const;
|
||||
B2BSessionHandle registerB2BSession(B2BSession *);
|
||||
void unregisterB2BSession(const B2BSessionHandle& handle);
|
||||
|
||||
bool mIsV6Avail;
|
||||
|
||||
WebAdmin* mWebAdminV4;
|
||||
WebAdmin* mWebAdminV6;
|
||||
WebAdminThread* mWebAdminThread;
|
||||
|
||||
XmlRpcServer* mXmlRpcServerV4;
|
||||
XmlRpcServer* mXmlRpcServerV6;
|
||||
XmlRpcServerThread* mXmlRpcServerThread;
|
||||
|
||||
AddressTranslator mAddressTranslator;
|
||||
std::map<resip::DialogSetId,B2BSession*> mActiveSessions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#define CLICKTOCALL_VERSION_STRING "0.1"
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
#include <time.h>
|
||||
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/MD5Stream.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/Timer.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "HttpBase.hxx"
|
||||
#include "HttpConnection.hxx"
|
||||
#include "WebAdmin.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
|
||||
WebAdmin::WebAdmin(Server& server,
|
||||
bool noChal,
|
||||
const Data& realm, // this realm is used for http challenges
|
||||
const Data& adminPassword,
|
||||
int port,
|
||||
IpVersion version ):
|
||||
HttpBase(port, version, realm),
|
||||
mServer(server),
|
||||
mNoWebChallenges(noChal),
|
||||
mAdminPassword(adminPassword)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebAdmin::buildPage( const Data& uri,
|
||||
int pageNumber,
|
||||
const resip::Data& pUser,
|
||||
const resip::Data& pPassword )
|
||||
{
|
||||
ParseBuffer pb(uri);
|
||||
|
||||
DebugLog (<< "Parsing URL" << uri );
|
||||
|
||||
const char* anchor = pb.skipChar('/');
|
||||
pb.skipToChar('?');
|
||||
Data pageName;
|
||||
pb.data(pageName,anchor);
|
||||
|
||||
DebugLog (<< " got page name: " << pageName );
|
||||
|
||||
// if this is not a valid page, redirect it
|
||||
if (pageName != Data("index.html") &&
|
||||
pageName != Data("clicktocall.html"))
|
||||
{
|
||||
setPage( resip::Data::Empty, pageNumber, 301 );
|
||||
return;
|
||||
}
|
||||
|
||||
// pages anyone can use
|
||||
if ( pageName == Data("index.html") )
|
||||
{
|
||||
setPage( buildDefaultPage(), pageNumber, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
Data authenticatedUser;
|
||||
if (mNoWebChallenges)
|
||||
{
|
||||
// don't do authentication - give everyone admin privilages
|
||||
authenticatedUser = Data("admin");
|
||||
}
|
||||
else
|
||||
{
|
||||
// all pages after this, user must authenticate
|
||||
if ( pUser.empty() )
|
||||
{
|
||||
setPage( resip::Data::Empty, pageNumber,401 );
|
||||
return;
|
||||
}
|
||||
|
||||
MD5Stream dba1;
|
||||
dba1 << "admin" // username
|
||||
<< Symbols::COLON
|
||||
<< Data::Empty // realm
|
||||
<< Symbols::COLON
|
||||
<< mAdminPassword;
|
||||
Data dbA1 = dba1.getHex();
|
||||
|
||||
if ( !dbA1.empty() )
|
||||
{
|
||||
MD5Stream a1;
|
||||
a1 << pUser // username
|
||||
<< Symbols::COLON
|
||||
<< Data::Empty // realm
|
||||
<< Symbols::COLON
|
||||
<< pPassword;
|
||||
Data compA1 = a1.getHex();
|
||||
|
||||
if ( dbA1 == compA1 )
|
||||
{
|
||||
authenticatedUser = pUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog( << "user " << pUser << " failed to authenticate to web server" );
|
||||
DebugLog( << " compA1="<<compA1<< " dbA1="<<dbA1 );
|
||||
setPage( resip::Data::Empty, pageNumber,401 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else //No A1, so we must assume this user does not exist.
|
||||
{
|
||||
setPage( "User does not exist.", pageNumber,401 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// parse any URI tags from form entry
|
||||
mHttpParams.clear();
|
||||
|
||||
if (!pb.eof())
|
||||
{
|
||||
pb.skipChar('?');
|
||||
|
||||
while ( !pb.eof() )
|
||||
{
|
||||
const char* anchor1 = pb.position();
|
||||
pb.skipToChar('=');
|
||||
Data key;
|
||||
pb.data(key,anchor1);
|
||||
|
||||
const char* anchor2 = pb.skipChar('=');
|
||||
pb.skipToChar('&');
|
||||
Data value;
|
||||
pb.data(value,anchor2);
|
||||
|
||||
if ( !pb.eof() )
|
||||
{
|
||||
pb.skipChar('&');
|
||||
}
|
||||
|
||||
if ( !key.empty() && !value.empty() ) // make sure both exist
|
||||
{
|
||||
DebugLog (<< " key=" << key << " value=" << value << " & unencoded form: " << value.urlDecoded() );
|
||||
mHttpParams[key] = value.urlDecoded(); // add other parameters to the Map
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DebugLog( << "building page for user=" << authenticatedUser );
|
||||
|
||||
Data page;
|
||||
if ( authenticatedUser == Data("admin") )
|
||||
{
|
||||
DataStream s(page);
|
||||
buildPageOutlinePre(s);
|
||||
|
||||
// admin only pages
|
||||
if ( pageName == Data("clicktocall.html")) buildClickToCallPage(s);
|
||||
|
||||
buildPageOutlinePost(s);
|
||||
s.flush();
|
||||
}
|
||||
|
||||
resip_assert( !authenticatedUser.empty() );
|
||||
resip_assert( !page.empty() );
|
||||
|
||||
setPage( page, pageNumber,200 );
|
||||
}
|
||||
|
||||
|
||||
Data
|
||||
WebAdmin::buildDefaultPage()
|
||||
{
|
||||
Data ret;
|
||||
{
|
||||
DataStream s(ret);
|
||||
|
||||
s <<
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl <<
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl <<
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl <<
|
||||
"<head>" << endl <<
|
||||
"<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />" << endl <<
|
||||
"<title>ClickToCall Server Login</title>" << endl <<
|
||||
"</head>" << endl <<
|
||||
|
||||
"<body bgcolor=\"#ffffff\">" << endl <<
|
||||
" <p>Click-To-Call HTML Server</p>" << endl <<
|
||||
"</body>" << endl <<
|
||||
"</html>" << endl;
|
||||
|
||||
s.flush();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
WebAdmin::buildPageOutlinePre(DataStream& s)
|
||||
{
|
||||
s <<
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl <<
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl <<
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl <<
|
||||
"<head>" << endl <<
|
||||
"<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />" << endl <<
|
||||
"<title>ClickToCall Server</title>" << endl <<
|
||||
"</head>" << endl <<
|
||||
|
||||
"<body bgcolor=\"#ffffff\">" << endl;
|
||||
}
|
||||
|
||||
void
|
||||
WebAdmin::buildPageOutlinePost(DataStream& s)
|
||||
{
|
||||
s << "</body>" << endl <<
|
||||
"</html>" << endl;
|
||||
}
|
||||
|
||||
void
|
||||
WebAdmin::buildClickToCallPage(DataStream& s)
|
||||
{
|
||||
Data initiator;
|
||||
Data destination;
|
||||
bool anchor = false;
|
||||
Dictionary::iterator pos;
|
||||
pos = mHttpParams.find("initiator");
|
||||
if (pos != mHttpParams.end())
|
||||
{
|
||||
initiator = pos->second;
|
||||
}
|
||||
pos = mHttpParams.find("destination");
|
||||
if (pos != mHttpParams.end())
|
||||
{
|
||||
destination = pos->second;
|
||||
}
|
||||
pos = mHttpParams.find("anchor");
|
||||
if (pos != mHttpParams.end())
|
||||
{
|
||||
if(isEqualNoCase(pos->second, "true"))
|
||||
{
|
||||
anchor = true;
|
||||
}
|
||||
}
|
||||
|
||||
s << "<p><em>ClickToCall:</em> initiator=" << initiator << ", destination=" << destination << (anchor ? " (anchored)" : "") << "</p>" << endl;
|
||||
if(!initiator.empty() && !destination.empty())
|
||||
{
|
||||
Data initiatorTranslation;
|
||||
Data destinationTranslation;
|
||||
|
||||
if(mServer.translateAddress(initiator, initiatorTranslation, true /* fail if no rule */) &&
|
||||
mServer.translateAddress(destination, destinationTranslation, true /* fail if no rule */))
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri initiatorUri(initiatorTranslation);
|
||||
Uri destinationUri(destinationTranslation);
|
||||
|
||||
mServer.clickToCall(initiatorUri, destinationUri, anchor);
|
||||
s << "<p>Initiating ClickToCall from " << initiatorUri << "(" << initiator << ") to " << destinationUri << "(" << destination << (anchor ? ") (anchored)" : ") (unanchored)") << "...</p>" << endl;
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
s << "<p>Invalid URI format in initiator " << initiatorTranslation << "(" << initiator << ") or destination " << destinationTranslation << "(" << destination << "): " << e << "</p>" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "<p>No translation rule for either initiator " << initiator << " or destination " << destination << ".</p>" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "<p>Missing initiator or destination URL parameters.</p>" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*/
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
#if !defined(WebAdmin_hxx)
|
||||
#define WebAdmin_hxx
|
||||
|
||||
#include <map>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
#include "HttpBase.hxx"
|
||||
|
||||
namespace resip
|
||||
{
|
||||
class DataStream;
|
||||
}
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class Server;
|
||||
|
||||
typedef std::map<resip::Data, resip::Data> Dictionary;
|
||||
|
||||
class WebAdmin: public HttpBase
|
||||
{
|
||||
public:
|
||||
WebAdmin(Server& server,
|
||||
bool noWebChallenges,
|
||||
const resip::Data& realm,
|
||||
const resip::Data& adminPassword,
|
||||
int port=5090,
|
||||
resip::IpVersion version=resip::V4);
|
||||
|
||||
protected:
|
||||
virtual void buildPage( const resip::Data& uri,
|
||||
int pageNumber,
|
||||
const resip::Data& user,
|
||||
const resip::Data& password);
|
||||
|
||||
private:
|
||||
resip::Data buildDefaultPage();
|
||||
|
||||
void buildPageOutlinePre(resip::DataStream& s);
|
||||
void buildPageOutlinePost(resip::DataStream& s);
|
||||
|
||||
void buildClickToCallPage(resip::DataStream& s);
|
||||
|
||||
Server& mServer;
|
||||
|
||||
bool mNoWebChallenges;
|
||||
resip::Data mAdminPassword;
|
||||
|
||||
Dictionary mHttpParams;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "WebAdmin.hxx"
|
||||
#include "WebAdminThread.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
|
||||
WebAdminThread::WebAdminThread(const std::list<WebAdmin*>& webAdminList)
|
||||
: mWebAdminList(webAdminList)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebAdminThread::thread()
|
||||
{
|
||||
while (!isShutdown())
|
||||
{
|
||||
try
|
||||
{
|
||||
FdSet fdset;
|
||||
|
||||
std::list<WebAdmin*>::iterator it = mWebAdminList.begin();
|
||||
for(;it!=mWebAdminList.end();it++)
|
||||
{
|
||||
(*it)->buildFdSet(fdset);
|
||||
}
|
||||
fdset.selectMilliSeconds( 10*1000 );
|
||||
|
||||
it = mWebAdminList.begin();
|
||||
for(;it!=mWebAdminList.end();it++)
|
||||
{
|
||||
(*it)->process(fdset);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ErrLog (<< "Unhandled exception: " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
#if !defined(WebAdminThread_hxx)
|
||||
#define WebAdminThread_hxx
|
||||
|
||||
#include <list>
|
||||
#include <rutil/ThreadIf.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class WebAdmin;
|
||||
|
||||
class WebAdminThread : public resip::ThreadIf
|
||||
{
|
||||
public:
|
||||
WebAdminThread(const std::list<WebAdmin*>& webAdminList);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
std::list<WebAdmin*> mWebAdminList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
* The Vovida Software License, Version 1.0
|
||||
*
|
||||
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
* and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact vocal@vovida.org.
|
||||
*
|
||||
* 4. Products derived from this software may not be called "VOCAL", nor
|
||||
* may "VOCAL" appear in their name, without prior written
|
||||
* permission of Vovida Networks, Inc.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by Vovida
|
||||
* Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
* Inc. For more information on Vovida Networks, Inc., please see
|
||||
* <http://www.vovida.org/>.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
|
||||
#include "Version.hxx"
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "Server.hxx"
|
||||
#include "XmlRpcServerBase.hxx"
|
||||
#include "XmlRpcConnection.hxx"
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
unsigned int XmlRpcConnection::NextConnectionId = 1;
|
||||
|
||||
|
||||
XmlRpcConnection::XmlRpcConnection(XmlRpcServerBase& server, resip::Socket sock):
|
||||
mXmlRcpServer(server),
|
||||
mConnectionId(NextConnectionId++),
|
||||
mNextRequestId(1),
|
||||
mSock(sock)
|
||||
{
|
||||
resip_assert(mSock > 0);
|
||||
}
|
||||
|
||||
|
||||
XmlRpcConnection::~XmlRpcConnection()
|
||||
{
|
||||
resip_assert(mSock > 0);
|
||||
#ifdef WIN32
|
||||
closesocket(mSock);
|
||||
#else
|
||||
close(mSock);
|
||||
#endif
|
||||
mSock=0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlRpcConnection::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
if (!mTxBuffer.empty())
|
||||
{
|
||||
fdset.setWrite(mSock);
|
||||
}
|
||||
fdset.setRead(mSock);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XmlRpcConnection::process(FdSet& fdset)
|
||||
{
|
||||
if (fdset.hasException(mSock))
|
||||
{
|
||||
int errNum = 0;
|
||||
int errNumSize = sizeof(errNum);
|
||||
getsockopt(mSock,SOL_SOCKET,SO_ERROR,(char *)&errNum,(socklen_t *)&errNumSize);
|
||||
InfoLog (<< "XmlRpcConnection::process: Exception reading from socket "
|
||||
<< (int)mSock << " code: " << errNum << "; closing connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fdset.readyToRead(mSock))
|
||||
{
|
||||
bool ok = processSomeReads();
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((!mTxBuffer.empty()) && fdset.readyToWrite(mSock))
|
||||
{
|
||||
bool ok = processSomeWrites();
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
XmlRpcConnection::processSomeReads()
|
||||
{
|
||||
const int bufSize = 8000;
|
||||
char buf[bufSize];
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
int bytesRead = ::recv(mSock, buf, bufSize, 0);
|
||||
#else
|
||||
int bytesRead = ::read(mSock, buf, bufSize);
|
||||
#endif
|
||||
|
||||
if (bytesRead == INVALID_SOCKET)
|
||||
{
|
||||
int e = getErrno();
|
||||
XmlRpcServerBase::logSocketError(e);
|
||||
InfoLog (<< "XmlRpcConnection::processSomeReads: Failed read on " << (int)mSock);
|
||||
return false;
|
||||
}
|
||||
else if(bytesRead == 0)
|
||||
{
|
||||
InfoLog (<< "XmlRpcConnection::processSomeReads: Connection closed by remote");
|
||||
return false;
|
||||
}
|
||||
|
||||
//DebugLog (<< "XmlRpcConnection::processSomeReads: read=" << bytesRead);
|
||||
|
||||
mRxBuffer += Data( buf, bytesRead );
|
||||
|
||||
while(tryParse());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XmlRpcConnection::tryParse()
|
||||
{
|
||||
ParseBuffer pb(mRxBuffer);
|
||||
Data initialTag;
|
||||
const char* start = pb.position();
|
||||
pb.skipWhitespace();
|
||||
pb.skipToChar('<');
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
const char* anchor = pb.position();
|
||||
pb.skipToChar('>');
|
||||
if(!pb.eof())
|
||||
{
|
||||
initialTag = pb.data(anchor);
|
||||
// Find end of initial tag
|
||||
pb.skipToChars("</" + initialTag + ">");
|
||||
if (!pb.eof())
|
||||
{
|
||||
pb.skipN(initialTag.size() + 3); // Skip past </InitialTag>
|
||||
mRequests[mNextRequestId] = pb.data(start);
|
||||
mXmlRcpServer.handleRequest(mConnectionId, mNextRequestId, mRequests[mNextRequestId]);
|
||||
mNextRequestId++;
|
||||
|
||||
// Remove processed data from RxBuffer
|
||||
pb.skipWhitespace();
|
||||
if(!pb.eof())
|
||||
{
|
||||
anchor = pb.position();
|
||||
pb.skipToEnd();
|
||||
mRxBuffer = pb.data(anchor);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRxBuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
XmlRpcConnection::processSomeWrites()
|
||||
{
|
||||
if (mTxBuffer.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//DebugLog (<< "XmlRpcConnection::processSomeWrites: Writing " << mTxBuffer );
|
||||
|
||||
#if defined(WIN32)
|
||||
int bytesWritten = ::send(mSock, mTxBuffer.data(), (int)mTxBuffer.size(), 0);
|
||||
#else
|
||||
int bytesWritten = ::write(mSock, mTxBuffer.data(), mTxBuffer.size() );
|
||||
#endif
|
||||
|
||||
if (bytesWritten == INVALID_SOCKET)
|
||||
{
|
||||
int e = getErrno();
|
||||
XmlRpcServerBase::logSocketError(e);
|
||||
InfoLog (<< "XmlRpcConnection::processSomeWrites - failed write on " << mSock << " " << strerror(e));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bytesWritten == (int)mTxBuffer.size())
|
||||
{
|
||||
DebugLog (<< "XmlRpcConnection::processSomeWrites - Wrote it all" );
|
||||
mTxBuffer = Data::Empty;
|
||||
|
||||
//return false; // return false causes connection to close and clean up
|
||||
return true; // keep connection up
|
||||
}
|
||||
else
|
||||
{
|
||||
Data rest = mTxBuffer.substr(bytesWritten);
|
||||
mTxBuffer = rest;
|
||||
DebugLog( << "XmlRpcConnection::processSomeWrites - Wrote " << bytesWritten << " bytes - still need to do " << mTxBuffer );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
XmlRpcConnection::sendResponse(unsigned int requestId, const Data& responseData, bool isFinal)
|
||||
{
|
||||
RequestMap::iterator it = mRequests.find(requestId);
|
||||
if(it != mRequests.end())
|
||||
{
|
||||
Data& request = it->second;
|
||||
Data response(request.size() + responseData.size() + 30, Data::Preallocate);
|
||||
ParseBuffer pb(request);
|
||||
|
||||
// A response is formed by starting with the request and inserting the
|
||||
// ResponseData between <Response> tags at the same level as the <Request> tags
|
||||
const char* start = pb.position();
|
||||
pb.skipToChars("</Request>");
|
||||
if (!pb.eof())
|
||||
{
|
||||
pb.skipN(10); // Skip past </Request>
|
||||
pb.skipWhitespace();
|
||||
|
||||
// Response starts with request message up to end of Request tag
|
||||
response = pb.data(start);
|
||||
|
||||
// Add in response data
|
||||
response += Symbols::CRLF;
|
||||
response += " <Response>" + responseData + " </Response>";
|
||||
response += Symbols::CRLF;
|
||||
|
||||
// Add remainder of request message
|
||||
start = pb.position();
|
||||
pb.skipToEnd();
|
||||
response += pb.data(start);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Request in message - just send bare response
|
||||
response = "<Response>" + responseData + "</Response>";
|
||||
}
|
||||
mTxBuffer += response;
|
||||
if(isFinal)
|
||||
{
|
||||
mRequests.erase(it);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
#if !defined(XmlRpcConnection_hxx)
|
||||
#define XmlRpcConnection_hxx
|
||||
|
||||
#include <map>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
#include "XmlRpcServerBase.hxx"
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
|
||||
class XmlRpcConnection
|
||||
{
|
||||
friend class XmlRpcServerBase;
|
||||
|
||||
public:
|
||||
XmlRpcConnection(XmlRpcServerBase& server, resip::Socket sock);
|
||||
~XmlRpcConnection();
|
||||
|
||||
unsigned int getConnectionId() const { return mConnectionId; }
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
bool process(resip::FdSet& fdset);
|
||||
|
||||
virtual bool sendResponse(unsigned int requestId, const resip::Data& responseData, bool isFinal);
|
||||
|
||||
private:
|
||||
bool processSomeReads();
|
||||
bool processSomeWrites();
|
||||
bool tryParse(); // returns true if we processed something and there is more data in the buffer
|
||||
|
||||
XmlRpcServerBase& mXmlRcpServer;
|
||||
const unsigned int mConnectionId;
|
||||
static unsigned int NextConnectionId;
|
||||
|
||||
unsigned int mNextRequestId;
|
||||
typedef std::map<unsigned int, resip::Data> RequestMap;
|
||||
RequestMap mRequests;
|
||||
|
||||
resip::Socket mSock;
|
||||
resip::Data mRxBuffer;
|
||||
resip::Data mTxBuffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
#include <sstream>
|
||||
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "XmlRpcServerBase.hxx"
|
||||
#include "XmlRpcConnection.hxx"
|
||||
#include "XmlRpcServer.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
|
||||
XmlRpcServer::XmlRpcServer(Server& server,
|
||||
int port,
|
||||
IpVersion version ) :
|
||||
XmlRpcServerBase(port, version),
|
||||
mServer(server)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpcServer::sendResponse(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const Data& responseData,
|
||||
unsigned int resultCode,
|
||||
const Data& resultText,
|
||||
const Data& leg)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << Symbols::CRLF << responseData << " <Result Code=\"" << resultCode << "\"";
|
||||
if(!leg.empty())
|
||||
{
|
||||
ss << " Leg=\"" << leg << "\"";
|
||||
}
|
||||
ss << ">" << resultText << "</Result>" << Symbols::CRLF;
|
||||
bool isFinal = resultCode >= 300 || (leg=="Destination" && resultCode >= 200);
|
||||
XmlRpcServerBase::sendResponse(connectionId, requestId, ss.str().c_str(), isFinal);
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpcServer::handleRequest(unsigned int connectionId, unsigned int requestId, const resip::Data& request)
|
||||
{
|
||||
InfoLog (<< "XmlRpcServer::handleRequest: connectionId=" << connectionId << ", requestId=" << requestId << ", request=" << request);
|
||||
|
||||
try
|
||||
{
|
||||
ParseBuffer pb(request);
|
||||
XMLCursor xml(pb);
|
||||
|
||||
if(isEqualNoCase(xml.getTag(), "ClickToCall"))
|
||||
{
|
||||
handleClickToCallRequest(connectionId, requestId, xml);
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(<< "XmlRpcServer::handleRequest: Received XML message with unknown method: " << xml.getTag());
|
||||
sendResponse(connectionId, requestId, Data::Empty, 400, "Unknown method");
|
||||
}
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
InfoLog(<< "XmlRpcServer::handleRequest: ParseException: " << e);
|
||||
sendResponse(connectionId, requestId, Data::Empty, 400, "Parse error");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpcServer::handleClickToCallRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml)
|
||||
{
|
||||
Data initiator;
|
||||
Data destination;
|
||||
bool anchor = false;
|
||||
|
||||
if(xml.firstChild())
|
||||
{
|
||||
if(isEqualNoCase(xml.getTag(), "Request"))
|
||||
{
|
||||
if(xml.firstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if(isEqualNoCase(xml.getTag(), "Initiator"))
|
||||
{
|
||||
if(xml.firstChild())
|
||||
{
|
||||
initiator = xml.getValue();
|
||||
xml.parent();
|
||||
}
|
||||
}
|
||||
else if(isEqualNoCase(xml.getTag(), "Destination"))
|
||||
{
|
||||
if(xml.firstChild())
|
||||
{
|
||||
destination = xml.getValue();
|
||||
xml.parent();
|
||||
}
|
||||
}
|
||||
else if(isEqualNoCase(xml.getTag(), "AnchorCall"))
|
||||
{
|
||||
if(xml.firstChild())
|
||||
{
|
||||
if(isEqualNoCase(xml.getValue(), "true"))
|
||||
{
|
||||
anchor = true;
|
||||
}
|
||||
xml.parent();
|
||||
}
|
||||
}
|
||||
} while(xml.nextSibling());
|
||||
xml.parent();
|
||||
}
|
||||
}
|
||||
xml.parent();
|
||||
}
|
||||
|
||||
if(!initiator.empty() && !destination.empty())
|
||||
{
|
||||
Data initiatorTranslation;
|
||||
Data destinationTranslation;
|
||||
|
||||
if(mServer.translateAddress(initiator, initiatorTranslation, true /* fail if no rule */) &&
|
||||
mServer.translateAddress(destination, destinationTranslation, true /* fail if no rule */))
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri initiatorUri(initiatorTranslation);
|
||||
Uri destinationUri(destinationTranslation);
|
||||
XmlRpcInfo info(connectionId, requestId, this);
|
||||
mServer.clickToCall(initiatorUri, destinationUri, anchor, &info);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << " <TranslatedInitiator>" << initiatorUri << "</TranslatedInitiator>" << Symbols::CRLF;
|
||||
ss << " <TranslatedDestination>" << destinationUri << "</TranslatedDestination>" << Symbols::CRLF;
|
||||
sendResponse(connectionId, requestId, ss.str().c_str(), 100, "In progress");
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Invalid URI format in initiator " << initiatorTranslation << "(" << initiator << ") or destination " << destinationTranslation << "(" << destination << "): " << e;
|
||||
sendResponse(connectionId, requestId, Data::Empty, 400, ss.str().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "No translation rule for either initiator " << initiator << " or destination " << destination;
|
||||
sendResponse(connectionId, requestId, Data::Empty, 400, ss.str().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendResponse(connectionId, requestId, Data::Empty, 400, "Missing initiator and/or destination tags");
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#if !defined(XmlRpcServer_hxx)
|
||||
#define XmlRpcServer_hxx
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/XMLCursor.hxx>
|
||||
|
||||
#include "XmlRpcServerBase.hxx"
|
||||
|
||||
namespace resip
|
||||
{
|
||||
class DataStream;
|
||||
}
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class Server;
|
||||
class XmlRpcServer;
|
||||
|
||||
class XmlRpcInfo
|
||||
{
|
||||
public:
|
||||
XmlRpcInfo(unsigned int connectionId, unsigned int requestId, XmlRpcServer* xmlRpcServer) :
|
||||
mConnectionId(connectionId), mRequestId(requestId), mXmlRpcServer(xmlRpcServer) {}
|
||||
XmlRpcInfo() : mConnectionId(0), mRequestId(0), mXmlRpcServer(0) {}
|
||||
unsigned int mConnectionId;
|
||||
unsigned int mRequestId;
|
||||
XmlRpcServer* mXmlRpcServer;
|
||||
};
|
||||
|
||||
class XmlRpcServer: public XmlRpcServerBase
|
||||
{
|
||||
public:
|
||||
XmlRpcServer(Server& server,
|
||||
int port,
|
||||
resip::IpVersion version);
|
||||
|
||||
// thread safe
|
||||
virtual void sendResponse(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const resip::Data& responseData,
|
||||
unsigned int resultCode,
|
||||
const resip::Data& resultText,
|
||||
const resip::Data& leg = resip::Data::Empty);
|
||||
|
||||
protected:
|
||||
virtual void handleRequest(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const resip::Data& request);
|
||||
|
||||
private:
|
||||
void handleClickToCallRequest(unsigned int connectionId, unsigned int requestId, resip::XMLCursor& xml);
|
||||
|
||||
Server& mServer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,395 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "XmlRpcServerBase.hxx"
|
||||
#include "XmlRpcConnection.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
|
||||
XmlRpcServerBase::XmlRpcServerBase(int port, IpVersion ipVer) :
|
||||
mTuple(Data::Empty,port,ipVer,TCP,Data::Empty),
|
||||
mSane(true)
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
mFd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0);
|
||||
#else
|
||||
mFd = ::socket(PF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
|
||||
if (mFd == INVALID_SOCKET)
|
||||
{
|
||||
int e = getErrno();
|
||||
logSocketError(e);
|
||||
ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Failed to create socket: " << strerror(e));
|
||||
mSane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog (<< "XmlRpcServerBase::XmlRpcServerBase: Creating fd=" << (int)mFd
|
||||
<< (ipVer == V4 ? " V4/" : " V6/") );
|
||||
|
||||
int on = 1;
|
||||
#if !defined(WIN32)
|
||||
if (::setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
|
||||
#else
|
||||
if (::setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)))
|
||||
#endif
|
||||
{
|
||||
int e = getErrno();
|
||||
logSocketError(e);
|
||||
ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Couldn't set sockoptions SO_REUSEPORT | SO_REUSEADDR: " << strerror(e));
|
||||
mSane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog(<< "XmlRpcServerBase::XmlRpcServerBase: Binding to " << Tuple::inet_ntop(mTuple));
|
||||
|
||||
if (::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
logSocketError(e);
|
||||
if (e == EADDRINUSE)
|
||||
{
|
||||
ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: " << mTuple << " already in use ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Could not bind to " << mTuple);
|
||||
}
|
||||
mSane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = makeSocketNonBlocking(mFd);
|
||||
if (!ok)
|
||||
{
|
||||
int e = getErrno();
|
||||
logSocketError(e);
|
||||
ErrLog(<< "XmlRpcServerBase::XmlRpcServerBase: Could not make HTTP socket non-blocking " << port);
|
||||
mSane = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// do the listen, seting the maximum queue size for compeletly established
|
||||
// sockets -- on linux, tcp_max_syn_backlog should be used for the incomplete
|
||||
// queue size(see man listen)
|
||||
int e = listen(mFd,5);
|
||||
|
||||
if (e != 0)
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog(<< "XmlRpcServerBase::XmlRpcServerBase: Failed listen " << strerror(e));
|
||||
mSane = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XmlRpcServerBase::~XmlRpcServerBase()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(mFd);
|
||||
#else
|
||||
close(mFd);
|
||||
#endif
|
||||
mFd = 0;
|
||||
ConnectionMap::iterator it = mConnections.begin();
|
||||
for(; it != mConnections.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlRpcServerBase::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
mSelectInterruptor.buildFdSet(fdset);
|
||||
|
||||
fdset.setRead(mFd); // listen socket for server
|
||||
|
||||
ConnectionMap::iterator it = mConnections.begin();
|
||||
for(; it != mConnections.end(); it++)
|
||||
{
|
||||
it->second->buildFdSet(fdset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlRpcServerBase::process(FdSet& fdset)
|
||||
{
|
||||
// Process Response fifo first
|
||||
while (mResponseFifo.messageAvailable())
|
||||
{
|
||||
ResponseInfo* responseInfo = mResponseFifo.getNext();
|
||||
ConnectionMap::iterator it = mConnections.find(responseInfo->getConnectionId());
|
||||
if(it != mConnections.end())
|
||||
{
|
||||
it->second->sendResponse(responseInfo->getRequestId(), responseInfo->getResponseData(), responseInfo->getIsFinal());
|
||||
delete responseInfo;
|
||||
}
|
||||
}
|
||||
|
||||
mSelectInterruptor.process(fdset);
|
||||
|
||||
if (fdset.readyToRead(mFd))
|
||||
{
|
||||
Tuple tuple(mTuple);
|
||||
struct sockaddr& peer = tuple.getMutableSockaddr();
|
||||
socklen_t peerLen = tuple.length();
|
||||
Socket sock = accept( mFd, &peer, &peerLen);
|
||||
if (sock == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
switch (e)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
return;
|
||||
default:
|
||||
logSocketError(e);
|
||||
ErrLog(<< "XmlRpcServerBase::process: Some error reading from socket: " << e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
makeSocketNonBlocking(sock);
|
||||
|
||||
if(mConnections.size() == MaxConnections)
|
||||
{
|
||||
closeOldestConnection();
|
||||
}
|
||||
|
||||
XmlRpcConnection* connection = new XmlRpcConnection(*this,sock);
|
||||
mConnections[connection->getConnectionId()] = connection;
|
||||
|
||||
DebugLog (<< "XmlRpcServerBase::process: Received TCP connection as connection=" << connection->getConnectionId() << " fd=" << (int)sock);
|
||||
}
|
||||
|
||||
// Call process on each connection
|
||||
ConnectionMap::iterator it = mConnections.begin();
|
||||
for(; it != mConnections.end(); )
|
||||
{
|
||||
bool ok = it->second->process(fdset);
|
||||
if (!ok)
|
||||
{
|
||||
delete it->second;
|
||||
mConnections.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlRpcServerBase::sendResponse(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const Data& responseData,
|
||||
bool isFinal)
|
||||
{
|
||||
mResponseFifo.add(new ResponseInfo(connectionId, requestId, responseData, isFinal));
|
||||
mSelectInterruptor.interrupt();
|
||||
}
|
||||
|
||||
bool
|
||||
XmlRpcServerBase::isSane()
|
||||
{
|
||||
return mSane;
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpcServerBase::closeOldestConnection()
|
||||
{
|
||||
if(mConnections.empty()) return;
|
||||
|
||||
// Oldest Connection is the one with the lowest Id
|
||||
ConnectionMap::iterator lowestConnectionIdIt = mConnections.end();
|
||||
ConnectionMap::iterator it = mConnections.begin();
|
||||
for(; it != mConnections.end(); it++)
|
||||
{
|
||||
if(it->second->getConnectionId() < lowestConnectionIdIt->second->getConnectionId())
|
||||
{
|
||||
lowestConnectionIdIt = it;
|
||||
}
|
||||
}
|
||||
delete lowestConnectionIdIt->second;
|
||||
mConnections.erase(lowestConnectionIdIt);
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpcServerBase::logSocketError(int e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case EAGAIN:
|
||||
InfoLog (<< "No data ready to read" << strerror(e));
|
||||
break;
|
||||
case EINTR:
|
||||
InfoLog (<< "The call was interrupted by a signal before any data was read : " << strerror(e));
|
||||
break;
|
||||
case EIO:
|
||||
InfoLog (<< "I/O error : " << strerror(e));
|
||||
break;
|
||||
case EBADF:
|
||||
InfoLog (<< "fd is not a valid file descriptor or is not open for reading : " << strerror(e));
|
||||
break;
|
||||
case EINVAL:
|
||||
InfoLog (<< "fd is attached to an object which is unsuitable for reading : " << strerror(e));
|
||||
break;
|
||||
case EFAULT:
|
||||
InfoLog (<< "buf is outside your accessible address space : " << strerror(e));
|
||||
break;
|
||||
|
||||
#if defined(WIN32)
|
||||
case WSAENETDOWN:
|
||||
InfoLog (<<" The network subsystem has failed. ");
|
||||
break;
|
||||
case WSAEFAULT:
|
||||
InfoLog (<<" The buf or from parameters are not part of the user address space, "
|
||||
"or the fromlen parameter is too small to accommodate the peer address. ");
|
||||
break;
|
||||
case WSAEINTR:
|
||||
InfoLog (<<" The (blocking) call was canceled through WSACancelBlockingCall. ");
|
||||
break;
|
||||
case WSAEINPROGRESS:
|
||||
InfoLog (<<" A blocking Windows Sockets 1.1 call is in progress, or the "
|
||||
"service provider is still processing a callback function. ");
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
InfoLog (<<" The socket has not been bound with bind, or an unknown flag was specified, "
|
||||
"or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, "
|
||||
"or (for byte stream-style sockets only) len was zero or negative. ");
|
||||
break;
|
||||
case WSAEISCONN :
|
||||
InfoLog (<<"The socket is connected. This function is not permitted with a connected socket, "
|
||||
"whether the socket is connection-oriented or connectionless. ");
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
InfoLog (<<" The connection has been broken due to the keep-alive activity "
|
||||
"detecting a failure while the operation was in progress. ");
|
||||
break;
|
||||
case WSAENOTSOCK :
|
||||
InfoLog (<<"The descriptor is not a socket. ");
|
||||
break;
|
||||
case WSAEOPNOTSUPP:
|
||||
InfoLog (<<" MSG_OOB was specified, but the socket is not stream-style such as type "
|
||||
"SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, "
|
||||
"or the socket is unidirectional and supports only send operations. ");
|
||||
break;
|
||||
case WSAESHUTDOWN:
|
||||
InfoLog (<<"The socket has been shut down; it is not possible to recvfrom on a socket after "
|
||||
"shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH. ");
|
||||
break;
|
||||
case WSAEMSGSIZE:
|
||||
InfoLog (<<" The message was too large to fit into the specified buffer and was truncated. ");
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
InfoLog (<<" The connection has been dropped, because of a network failure or because the "
|
||||
"system on the other end went down without notice. ");
|
||||
break;
|
||||
case WSAECONNRESET :
|
||||
InfoLog (<<"Connection reset ");
|
||||
break;
|
||||
|
||||
case WSAEWOULDBLOCK:
|
||||
DebugLog (<<"Would Block ");
|
||||
break;
|
||||
|
||||
case WSAEHOSTUNREACH:
|
||||
InfoLog (<<"A socket operation was attempted to an unreachable host ");
|
||||
break;
|
||||
case WSANOTINITIALISED:
|
||||
InfoLog (<<"Either the application has not called WSAStartup or WSAStartup failed. "
|
||||
"The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks),"
|
||||
"or WSACleanup has been called too many times. ");
|
||||
break;
|
||||
case WSAEACCES:
|
||||
InfoLog (<<"An attempt was made to access a socket in a way forbidden by its access permissions ");
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
InfoLog (<<"An operation on a socket could not be performed because the system lacked sufficient "
|
||||
"buffer space or because a queue was full");
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
InfoLog (<<"A request to send or receive data was disallowed because the socket is not connected "
|
||||
"and (when sending on a datagram socket using sendto) no address was supplied");
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
InfoLog (<<"An established connection was aborted by the software in your host computer, possibly "
|
||||
"due to a data transmission time-out or protocol error");
|
||||
break;
|
||||
case WSAEADDRNOTAVAIL:
|
||||
InfoLog (<<"The requested address is not valid in its context. This normally results from an attempt to "
|
||||
"bind to an address that is not valid for the local computer");
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
InfoLog (<<"An address incompatible with the requested protocol was used");
|
||||
break;
|
||||
case WSAEDESTADDRREQ:
|
||||
InfoLog (<<"A required address was omitted from an operation on a socket");
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
InfoLog (<<"A socket operation was attempted to an unreachable network");
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
InfoLog (<< "Some other error (" << e << "): " << strerror(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
#if !defined(XmlRpcServerBase_hxx)
|
||||
#define XmlRpcServerBase_hxx
|
||||
|
||||
#include <map>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Fifo.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/SelectInterruptor.hxx>
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class XmlRpcConnection;
|
||||
|
||||
class ResponseInfo
|
||||
{
|
||||
public:
|
||||
ResponseInfo(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const resip::Data& responseData,
|
||||
bool isFinal) :
|
||||
mConnectionId(connectionId),
|
||||
mRequestId(requestId),
|
||||
mResponseData(responseData),
|
||||
mIsFinal(isFinal) {}
|
||||
|
||||
~ResponseInfo() {}
|
||||
|
||||
unsigned int getConnectionId() const { return mConnectionId; }
|
||||
unsigned int getRequestId() const { return mRequestId; }
|
||||
const resip::Data& getResponseData() const { return mResponseData; }
|
||||
bool getIsFinal() const { return mIsFinal; }
|
||||
|
||||
private:
|
||||
unsigned int mConnectionId;
|
||||
unsigned int mRequestId;
|
||||
resip::Data mResponseData;
|
||||
bool mIsFinal;
|
||||
};
|
||||
|
||||
class XmlRpcServerBase
|
||||
{
|
||||
friend class XmlRpcConnection;
|
||||
|
||||
public:
|
||||
XmlRpcServerBase(int port, resip::IpVersion version);
|
||||
virtual ~XmlRpcServerBase();
|
||||
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
void process(resip::FdSet& fdset);
|
||||
|
||||
bool isSane();
|
||||
static void logSocketError(int e);
|
||||
|
||||
// thread safe - uses fifo
|
||||
void sendResponse(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const resip::Data& responseData,
|
||||
bool isFinal=true);
|
||||
|
||||
protected:
|
||||
virtual void handleRequest(unsigned int connectionId,
|
||||
unsigned int requestId,
|
||||
const resip::Data& request) = 0;
|
||||
|
||||
private:
|
||||
static const unsigned int MaxConnections = 60; // Note: use caution if making this any bigger, default fd_set size in windows is 64
|
||||
|
||||
resip::Socket mFd;
|
||||
resip::Tuple mTuple;
|
||||
bool mSane;
|
||||
|
||||
typedef std::map<unsigned int, XmlRpcConnection*> ConnectionMap;
|
||||
ConnectionMap mConnections;
|
||||
void closeOldestConnection();
|
||||
|
||||
resip::Fifo<ResponseInfo> mResponseFifo;
|
||||
resip::SelectInterruptor mSelectInterruptor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "XmlRpcServer.hxx"
|
||||
#include "XmlRpcServerThread.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
|
||||
XmlRpcServerThread::XmlRpcServerThread(const std::list<XmlRpcServer*>& xmlRpcServerList)
|
||||
: mXmlRpcServerList(xmlRpcServerList)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlRpcServerThread::thread()
|
||||
{
|
||||
while (!isShutdown())
|
||||
{
|
||||
try
|
||||
{
|
||||
FdSet fdset;
|
||||
|
||||
std::list<XmlRpcServer*>::iterator it = mXmlRpcServerList.begin();
|
||||
for(;it!=mXmlRpcServerList.end();it++)
|
||||
{
|
||||
(*it)->buildFdSet(fdset);
|
||||
}
|
||||
fdset.selectMilliSeconds( 10*1000 );
|
||||
|
||||
it = mXmlRpcServerList.begin();
|
||||
for(;it!=mXmlRpcServerList.end();it++)
|
||||
{
|
||||
(*it)->process(fdset);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ErrLog (<< "XmlRpcServerThread::thread: Unhandled exception: " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#if !defined(XmlRpcServerThread_hxx)
|
||||
#define XmlRpcServerThread_hxx
|
||||
|
||||
#include <list>
|
||||
#include <rutil/ThreadIf.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
|
||||
namespace clicktocall
|
||||
{
|
||||
class XmlRpcServer;
|
||||
|
||||
class XmlRpcServerThread : public resip::ThreadIf
|
||||
{
|
||||
public:
|
||||
XmlRpcServerThread(const std::list<XmlRpcServer*>& xmlRpcServerList);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
std::list<XmlRpcServer*> mXmlRpcServerList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
########################################################
|
||||
# click to call server configuration file
|
||||
########################################################
|
||||
|
||||
|
||||
########################################################
|
||||
# SIP settings
|
||||
########################################################
|
||||
|
||||
# Local IP Address to bind SIP transports to. If left blank
|
||||
# ichat-gw will bind to all adapters.
|
||||
#IPAddress = 192.168.1.106
|
||||
#IPAddress = 2001:5c0:1000:a::6d
|
||||
IPAddress =
|
||||
|
||||
# Comma separated list of DNS servers, overrides default OS detected list (leave blank for default)
|
||||
DNSServers =
|
||||
|
||||
# Used in From header of SIP calls, when calling initiator. Value must be a valid formatted SIP Uri
|
||||
ClickToCallIdentity = sip:click2call@blitzzgod.com
|
||||
|
||||
# Local port to listen on for SIP messages over UDP or TCP
|
||||
UDPTCPPort = 5072
|
||||
|
||||
# Local port to listen on for SIP messages over TLS
|
||||
TLSPort = 5073
|
||||
|
||||
# TLS domain name for this server (note: domain cert for this domain must be present)
|
||||
TLSDomainName =
|
||||
|
||||
# Enable/Disable TCP/UDP CRLFCRLF keepalive packets for SIP endpoints
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
KeepAlives = enable
|
||||
|
||||
# URI of a proxy server to use a SIP outbound proxy. This setting should not be required if
|
||||
# proper DNS based SIP routing is operational.
|
||||
OutboundProxy =
|
||||
|
||||
|
||||
########################################################
|
||||
# General settings
|
||||
########################################################
|
||||
|
||||
# Logging level: NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK
|
||||
LogLevel = INFO
|
||||
|
||||
# Log Filename
|
||||
LogFilename = clicktocall.log
|
||||
|
||||
# Log file Max Lines
|
||||
LogFileMaxLines = 50000
|
||||
|
||||
# Port to listen for XML RPC requests on. Set to 0 to disable.
|
||||
# Note: clicktocall will listen on this port for all interfaces, for both IPv4
|
||||
# and IPv6 (if available).
|
||||
XmlRpcPort = 5094
|
||||
|
||||
# Port to listen on for HTTP messaging (ie. Click-to-call). Set to 0 to disable.
|
||||
# Note: clicktocall will listen on this port for all interfaces, for both IPv4
|
||||
# and IPv6 (if available).
|
||||
HttpPort = 5090
|
||||
|
||||
# Enable/Disable HTTP Digest authentication: 1|true|on to enable
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
HttpAuth = enable
|
||||
|
||||
# Password required if HttpAuth is enabled: Note: auth user is always "admin"
|
||||
HttpAuthPwd = admin
|
||||
|
||||
|
||||
########################################################
|
||||
# Address Translation Rules (must be listed in pairs)
|
||||
########################################################
|
||||
|
||||
# Rule for mapping any non-sip address to appropriate SIP URI
|
||||
TranslationPattern=^(.*)$
|
||||
TranslationOutput=sip:$1@blitzzgod.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
#include <signal.h>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/Time.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/BaseException.hxx>
|
||||
#include <resip/stack/NameAddr.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace clicktocall;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::CLICKTOCALL
|
||||
|
||||
static bool finished = false;
|
||||
|
||||
static void
|
||||
signalHandler(int signo)
|
||||
{
|
||||
std::cerr << "Shutting down..." << endl;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGPIPE" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
#if defined(_DEBUG) && defined(LEAK_CHECK)
|
||||
resip::FindMemoryLeaks fml;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( signal( SIGINT, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGINT" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( signal( SIGTERM, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGTERM" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
initNetwork();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Create Server
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
Server server(argc, argv);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Startup and run...
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
server.startup();
|
||||
|
||||
while(true)
|
||||
{
|
||||
server.process(50);
|
||||
if(finished) break;
|
||||
}
|
||||
|
||||
server.shutdown();
|
||||
}
|
||||
|
||||
InfoLog(<< "ClickToCall server is shutdown.");
|
||||
sleepSeconds(2);
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clicktocall", "clicktocall_9_0.vcproj", "{8BA87397-9B42-4820-BA53-62FF35C22CAE}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A}
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216} = {12720B4D-F4FC-4502-8FA9-589BF5166216}
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58} = {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1}
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_9_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\..\resip\stack\resiprocate_9_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\..\resip\dum\dum_9_0.vcproj", "{12720B4D-F4FC-4502-8FA9-589BF5166216}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\rutil\dns\ares\ares_9_0.vcproj", "{96CD935E-1951-43B8-AF75-F1C06B3778C1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_9_0.vcproj", "{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clicktocallxml", "test\clicktocallxml_9_0.vcproj", "{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A}
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAE} = {8BA87397-9B42-4820-BA53-62FF35C22CAE}
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1}
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAE}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAE}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAE}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.Build.0 = Release|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.Build.0 = Release|Win32
|
||||
{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,312 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="clicktocall"
|
||||
ProjectGUID="{8BA87397-9B42-4820-BA53-62FF35C22CAE}"
|
||||
RootNamespace="clicktocall"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../";"$(ProjectDir)../../contrib/openssl/include";"$(ProjectDir)../../contrib/openssl/inc32";"$(ProjectDir)../../contrib/pcre""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6;LEAK_CHECK"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib" "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib""
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../";"$(ProjectDir)../../contrib/openssl/include";"$(ProjectDir)../../contrib/openssl/inc32";"$(ProjectDir)../../contrib/pcre""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib" "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib""
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AddressTranslator.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AppSubsystem.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\B2BSession.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\clicktocall.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigParser.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HttpBase.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HttpConnection.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Server.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WebAdmin.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WebAdminThread.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcConnection.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServer.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServerBase.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServerThread.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AddressTranslator.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AppSubsystem.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\B2BSession.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ClickToCallCmds.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigParser.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HttpBase.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HttpConnection.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Server.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Version.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WebAdmin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WebAdminThread.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcConnection.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServer.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServerBase.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XmlRpcServerThread.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
|
||||
EXTRA_DIST = clicktocallxml_9_0.vcproj
|
||||
|
||||
# This test case is not run automatically
|
||||
# because it requires command line arguments
|
||||
#TESTS = clicktocallxml
|
||||
|
||||
check_PROGRAMS = clicktocallxml
|
||||
|
||||
clicktocallxml_SOURCES = clicktocallxml.cxx
|
||||
clicktocallxml_LDADD = ../../../rutil/librutil.la
|
||||
clicktocallxml_LDADD += @LIBPTHREAD_LIBADD@
|
||||
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/BaseException.hxx>
|
||||
#include <rutil/XMLCursor.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM Subsystem::TEST
|
||||
|
||||
void sleepSeconds(unsigned int seconds)
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep(seconds*1000);
|
||||
#else
|
||||
sleep(seconds);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
#ifdef WIN32
|
||||
initNetwork();
|
||||
#endif
|
||||
|
||||
int sd, rc;
|
||||
struct sockaddr_in localAddr, servAddr;
|
||||
struct hostent *h;
|
||||
|
||||
if(argc != 6)
|
||||
{
|
||||
ErrLog(<< "usage: " << argv[0] <<" <server> <port> <initiator> <destination> <anchor 0|1>");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
h = gethostbyname(argv[1]);
|
||||
if(h==0)
|
||||
{
|
||||
ErrLog(<< "unknown host " << argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
servAddr.sin_family = h->h_addrtype;
|
||||
memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
|
||||
servAddr.sin_port = htons(atoi(argv[2]));
|
||||
|
||||
// Create TCP Socket
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sd < 0)
|
||||
{
|
||||
ErrLog(<< "cannot open socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// bind to any local interface/port
|
||||
localAddr.sin_family = AF_INET;
|
||||
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
localAddr.sin_port = 0;
|
||||
|
||||
rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
|
||||
if(rc < 0)
|
||||
{
|
||||
ErrLog(<<"error binding locally");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Connect to server
|
||||
rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
|
||||
if(rc < 0)
|
||||
{
|
||||
ErrLog(<< "error connecting");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Data request(
|
||||
"<ClickToCall>\r\n"
|
||||
" <Request>\r\n"
|
||||
" <Initiator>" + Data(argv[3]) + "</Initiator>\r\n"
|
||||
" <Destination>" + Data(argv[4]) + "</Destination>\r\n"
|
||||
" <AnchorCall>" + Data(argv[5][0] == '0' ? "false" : "true") + "</AnchorCall>\r\n"
|
||||
" </Request>\r\n"
|
||||
"</ClickToCall>\r\n");
|
||||
rc = send(sd, request.c_str(), request.size(), 0);
|
||||
if(rc < 0)
|
||||
{
|
||||
ErrLog(<< "error sending");
|
||||
close(sd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char readBuffer[8000];
|
||||
while(rc > 0)
|
||||
{
|
||||
rc = recv(sd, (char*)&readBuffer, sizeof(readBuffer), 0);
|
||||
if(rc < 0)
|
||||
{
|
||||
ErrLog(<< "error receiving");
|
||||
close(sd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(rc > 0)
|
||||
{
|
||||
Data response(Data::Borrow, (const char*)&readBuffer, rc);
|
||||
InfoLog(<< "Received response: \r\n" << response.c_str());
|
||||
ParseBuffer pb(response);
|
||||
XMLCursor xml(pb);
|
||||
if(xml.firstChild())
|
||||
{
|
||||
if(xml.nextSibling())
|
||||
{
|
||||
if(xml.firstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if(xml.getTag() == "Result")
|
||||
{
|
||||
XMLCursor::AttributeMap attribs = xml.getAttributes();
|
||||
XMLCursor::AttributeMap::iterator it = attribs.find("Code");
|
||||
if(it != attribs.end())
|
||||
{
|
||||
unsigned long statusCode = it->second.convertUnsignedLong();
|
||||
if(statusCode >= 200 && statusCode < 300)
|
||||
{
|
||||
it = attribs.find("Leg");
|
||||
if(it != attribs.end())
|
||||
{
|
||||
if(it->second == "Destination")
|
||||
{
|
||||
// Successfully connected to destination - break out
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(statusCode >=300)
|
||||
{
|
||||
// Failed - break out
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while(xml.nextSibling());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sleepSeconds(5);
|
||||
InfoLog(<< "xmlrpcclient done.");
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="clicktocallxml"
|
||||
ProjectGUID="{9F820A51-A2FF-4EB6-ACB7-F0402E8D5CEC}"
|
||||
RootNamespace="clicktocallxml"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../../""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib" "$(ProjectDir)..\..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib""
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../../""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\..\contrib\openssl\lib\vc\static\libeay32MD.lib" "$(ProjectDir)..\..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib""
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\clicktocallxml.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
/.dirstamp
|
||||
|
||||
/ichat-gw
|
||||
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
|
||||
#include "rutil/Logger.hxx"
|
||||
#include "rutil/ParseBuffer.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "rutil/WinLeakCheck.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
AddressTranslator::AddressTranslator()
|
||||
{
|
||||
}
|
||||
|
||||
AddressTranslator::~AddressTranslator()
|
||||
{
|
||||
// Destroy all of the filters
|
||||
for(FilterOpList::iterator it = mFilterOperators.begin(); it != mFilterOperators.end(); it++)
|
||||
{
|
||||
if ( it->preq )
|
||||
{
|
||||
regfree ( it->preq );
|
||||
delete it->preq;
|
||||
it->preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.clear();
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression)
|
||||
{
|
||||
InfoLog( << "Add translation " << matchingPattern << " -> " << rewriteExpression);
|
||||
|
||||
FilterOp filter;
|
||||
filter.mMatchingPattern = matchingPattern;
|
||||
filter.mRewriteExpression = rewriteExpression;
|
||||
|
||||
if( !filter.mMatchingPattern.empty() )
|
||||
{
|
||||
int flags = REG_EXTENDED;
|
||||
if( filter.mRewriteExpression.find("$") == Data::npos )
|
||||
{
|
||||
flags |= REG_NOSUB;
|
||||
}
|
||||
filter.preq = new regex_t;
|
||||
int ret = regcomp( filter.preq, filter.mMatchingPattern.c_str(), flags );
|
||||
if( ret != 0 )
|
||||
{
|
||||
delete filter.preq;
|
||||
ErrLog( << "Translation has invalid match expression: "
|
||||
<< filter.mMatchingPattern );
|
||||
filter.preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.push_back( filter );
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::removeTranslation(const resip::Data& matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator it = mFilterOperators.begin();
|
||||
while ( it != mFilterOperators.end() )
|
||||
{
|
||||
if ( it->mMatchingPattern == matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator i = it;
|
||||
it++;
|
||||
if ( i->preq )
|
||||
{
|
||||
regfree ( i->preq );
|
||||
delete i->preq;
|
||||
i->preq = 0;
|
||||
}
|
||||
mFilterOperators.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AddressTranslator::translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule)
|
||||
{
|
||||
bool rc=false;
|
||||
DebugLog( << "Translating "<< address);
|
||||
|
||||
for (FilterOpList::iterator it = mFilterOperators.begin();
|
||||
it != mFilterOperators.end(); it++)
|
||||
{
|
||||
Data rewrite = it->mRewriteExpression;
|
||||
Data& match = it->mMatchingPattern;
|
||||
if ( it->preq )
|
||||
{
|
||||
int ret;
|
||||
|
||||
const int nmatch=10;
|
||||
regmatch_t pmatch[nmatch];
|
||||
|
||||
ret = regexec(it->preq, address.c_str(), nmatch, pmatch, 0/*eflags*/);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
// did not match
|
||||
DebugLog( << " Skipped translation "<< address << " did not match " << match );
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugLog( << " Matched translation "<< address << " matched " << match );
|
||||
translation = rewrite;
|
||||
rc=true;
|
||||
if ( rewrite.find("$") != Data::npos )
|
||||
{
|
||||
for ( int i=1; i<nmatch; i++)
|
||||
{
|
||||
if ( pmatch[i].rm_so != -1 )
|
||||
{
|
||||
Data subExp(address.substr(pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo-pmatch[i].rm_so));
|
||||
DebugLog( << " subExpression[" <<i <<"]="<< subExp );
|
||||
|
||||
Data result;
|
||||
{
|
||||
DataStream s(result);
|
||||
|
||||
ParseBuffer pb(translation);
|
||||
|
||||
while (true)
|
||||
{
|
||||
const char* a = pb.position();
|
||||
pb.skipToChars( Data("$") + char('0'+i) );
|
||||
if ( pb.eof() )
|
||||
{
|
||||
s << pb.data(a);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << pb.data(a);
|
||||
pb.skipN(2);
|
||||
s << subExp;
|
||||
}
|
||||
}
|
||||
s.flush();
|
||||
}
|
||||
translation = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
translation = rewrite;
|
||||
rc = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a translation and we are not suppossed to fail, then just return address
|
||||
if(!rc && !failIfNoRule)
|
||||
{
|
||||
rc = true;
|
||||
translation = address;
|
||||
}
|
||||
|
||||
InfoLog( << "Translated "<< address << " to " << translation);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#if !defined(AddressTranslator_hxx)
|
||||
#define AddressTranslator_hxx
|
||||
|
||||
#include <list>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcreposix.h>
|
||||
#else
|
||||
#include <regex.h>
|
||||
#endif
|
||||
#include "rutil/Data.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class AddressTranslator
|
||||
{
|
||||
public:
|
||||
AddressTranslator();
|
||||
~AddressTranslator();
|
||||
|
||||
void addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression);
|
||||
|
||||
void removeTranslation(const resip::Data& matchingPattern);
|
||||
|
||||
bool translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
private:
|
||||
class FilterOp
|
||||
{
|
||||
public:
|
||||
resip::Data mMatchingPattern;
|
||||
resip::Data mRewriteExpression;
|
||||
regex_t *preq;
|
||||
};
|
||||
|
||||
typedef std::list<FilterOp> FilterOpList;
|
||||
FilterOpList mFilterOperators;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#include "AppSubsystem.hxx"
|
||||
|
||||
AppSubsystem AppSubsystem::GATEWAY("GATEWAY");
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#if !defined(AppSubsystem_hxx)
|
||||
#define AppSubsystem_hxx
|
||||
|
||||
#include <iostream>
|
||||
#include <rutil/Subsystem.hxx>
|
||||
|
||||
/**
|
||||
This class is used in the logging subsystem to identify
|
||||
logging messages generated from the iChat Gateway.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class AppSubsystem : public resip::Subsystem
|
||||
{
|
||||
public:
|
||||
// Add new systems below
|
||||
static AppSubsystem GATEWAY;
|
||||
|
||||
private:
|
||||
explicit AppSubsystem(const char* rhs) : resip::Subsystem(rhs) {};
|
||||
explicit AppSubsystem(const resip::Data& rhs);
|
||||
AppSubsystem& operator=(const resip::Data& rhs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,175 +0,0 @@
|
|||
#if !defined(B2BSession_hxx)
|
||||
#define B2BSession_hxx
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/AppDialogSet.hxx>
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class Server;
|
||||
class IChatIPPortData;
|
||||
|
||||
typedef unsigned int B2BSessionHandle;
|
||||
|
||||
class B2BSession : public resip::AppDialogSet
|
||||
{
|
||||
public:
|
||||
B2BSession(Server& server, bool hasDialogSet=true);
|
||||
virtual ~B2BSession();
|
||||
|
||||
virtual void end();
|
||||
|
||||
void setPeer(B2BSession* peer);
|
||||
B2BSession* getPeer();
|
||||
void stealPeer(B2BSession* victimSession);
|
||||
|
||||
B2BSessionHandle getB2BSessionHandle() const { return mHandle; }
|
||||
|
||||
void initiateIChatCallRequest(const std::string& to, const std::string& from);
|
||||
bool createNewPeer(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
void startIChatCall(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
void startSIPCall(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
bool checkIChatCallMatch(const resip::SipMessage& msg);
|
||||
|
||||
// iChat call notifications from Jabber Component
|
||||
void notifyIChatCallCancelled();
|
||||
void notifyIChatCallProceeding(const std::string& to);
|
||||
void notifyIChatCallFailed(unsigned int statusCode);
|
||||
void continueIChatCall(const std::string& remoteIPPortListBlob);
|
||||
void timeoutIChatCall();
|
||||
|
||||
// IPC messages for Jabber Component
|
||||
void initiateIChatCall();
|
||||
void cancelIChatCall();
|
||||
void proceedingIChatCall();
|
||||
void acceptIChatCall();
|
||||
void rejectIChatCall();
|
||||
|
||||
protected:
|
||||
friend class Server;
|
||||
|
||||
virtual resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual bool doReferNoSub(const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
private:
|
||||
bool buildLocalOffer(resip::SdpContents& sdp);
|
||||
bool buildLocalAnswer(resip::SdpContents& sdp);
|
||||
bool provideLocalAnswer(void);
|
||||
void endPeer();
|
||||
bool isUACConnected();
|
||||
bool isStaleFork(const resip::DialogId& dialogId);
|
||||
void fixupSdp(const resip::SdpContents& origSdp, resip::SdpContents& fixedSdp);
|
||||
unsigned int mapRejectionCodeForIChat(unsigned int statusCode);
|
||||
|
||||
Server& mServer;
|
||||
bool mHasDialogSet;
|
||||
resip::DialogUsageManager& mDum;
|
||||
B2BSession* mPeer;
|
||||
resip::InviteSessionHandle mInviteSessionHandle;
|
||||
B2BSessionHandle mHandle;
|
||||
resip::AppDialogSetHandle mReferringAppDialogSet;
|
||||
|
||||
// State information
|
||||
resip::DialogId mUACConnectedDialogId;
|
||||
bool mWaitingOfferFromPeer;
|
||||
bool mWaitingAnswerFromPeer;
|
||||
bool mWaitingNitAnswerFromPeer;
|
||||
bool mAnchorMedia;
|
||||
unsigned short mMediaRelayPort;
|
||||
|
||||
// IChat specific endpoint info
|
||||
bool mIChatEndpoint;
|
||||
bool mIChatWaitingToAccept;
|
||||
bool mIChatWaitingToProceed;
|
||||
bool mIChatWaitingToContinue;
|
||||
resip::Uri mIChatDestination;
|
||||
resip::NameAddr mIChatFrom;
|
||||
resip::SdpContents* mIChatSdp;
|
||||
std::string mIChatCallToJID;
|
||||
std::string mIChatCallFromJID;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,443 +0,0 @@
|
|||
#include "ConfigParser.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
ConfigParser::ConfigParser(int argc, char** argv) :
|
||||
// Defaults
|
||||
mSipPort(5070),
|
||||
mTlsPort(5071),
|
||||
mTlsDomain(DnsUtil::getLocalHostName()),
|
||||
mRegistrationTime(3600),
|
||||
mRegistrationRetryTime(120),
|
||||
mKeepAlives(true),
|
||||
mLogLevel("INFO"),
|
||||
mLogFilename("ichat-gw.log"),
|
||||
mLogFileMaxLines(50000), // 50000 is about 5M size
|
||||
mGatewayIPCPort(2078),
|
||||
mJabberConnectorIPCPort(2079),
|
||||
mHttpPort(5090),
|
||||
mHttpAuth(false),
|
||||
mHttpAuthPwd("admin"),
|
||||
mIChatProceedingTimeout(5000),
|
||||
mAlwaysRelayIChatMedia(true),
|
||||
mPreferIPv6(false),
|
||||
mSkipFirstIChatAddress(false),
|
||||
mMediaRelayPortRangeMin(8000),
|
||||
mMediaRelayPortRangeMax(9999),
|
||||
mJabberComponentPort(5275),
|
||||
mJabberServerPingDuration(60) // 1 min
|
||||
{
|
||||
// Parse config file first
|
||||
parseConfigFile("ichat-gw.config");
|
||||
|
||||
// Parse command line options
|
||||
// Note: command line overrides config file setting
|
||||
parseCommandLine(argc, argv);
|
||||
}
|
||||
|
||||
ConfigParser::~ConfigParser()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseCommandLine(int argc, char** argv)
|
||||
{
|
||||
// Loop through command line arguments and process them
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
Data commandName(argv[i]);
|
||||
|
||||
// Process all commandNames that don't take values
|
||||
if(isEqualNoCase(commandName, "-?") ||
|
||||
isEqualNoCase(commandName, "--?") ||
|
||||
isEqualNoCase(commandName, "--help") ||
|
||||
isEqualNoCase(commandName, "/?"))
|
||||
{
|
||||
cout << "Command line options are:" << endl;
|
||||
cout << " -a <IP Address> - bind SIP transports to this IP address" << endl;
|
||||
cout << " -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list" << endl;
|
||||
cout << " -gi <Gateway identity> - used in From header of click-to-call requests to initiator" << endl;
|
||||
cout << " -sp <port num> - local port number to use for SIP messaging (UDP/TCP)" << endl;
|
||||
cout << " -tp <port num> - local port number to use for TLS SIP messaging" << endl;
|
||||
cout << " -td <domain name> - domain name to use for TLS server connections" << endl;
|
||||
cout << " -nk - no keepalives, set this to disable sending of keepalives" << endl;
|
||||
cout << " -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy" << endl;
|
||||
cout << " -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl;
|
||||
cout << endl;
|
||||
cout << "Sample Command line:" << endl;
|
||||
cout << "ichat-gw -a 192.168.1.100 -l DEBUG" << endl;
|
||||
exit(0);
|
||||
}
|
||||
else if(isEqualNoCase(commandName, "-nk"))
|
||||
{
|
||||
mKeepAlives = false;
|
||||
}
|
||||
else if(commandName.at(0) == '-')
|
||||
{
|
||||
commandName = commandName.substr(1); // Remove -
|
||||
|
||||
// Process commands that have values
|
||||
Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty);
|
||||
if(commandValue.empty() || commandValue.at(0) == '-')
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
i++; // increment argument
|
||||
|
||||
//cout << "Command Line Name='" << commandName << "' value='" << commandValue << "'" << endl;
|
||||
if(!processOption(commandName.lowercase(), commandValue))
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseConfigFile(const Data& filename)
|
||||
{
|
||||
ifstream configFile(filename.c_str());
|
||||
|
||||
string sline;
|
||||
while(getline(configFile, sline))
|
||||
{
|
||||
Data line(sline);
|
||||
Data name;
|
||||
Data value;
|
||||
ParseBuffer pb(line);
|
||||
|
||||
pb.skipWhitespace();
|
||||
const char * anchor = pb.position();
|
||||
if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it
|
||||
// Look for =
|
||||
pb.skipToOneOf("= \t");
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.data(name,anchor);
|
||||
if(*pb.position()!='=')
|
||||
{
|
||||
pb.skipToChar('=');
|
||||
}
|
||||
pb.skipChar('=');
|
||||
pb.skipWhitespace();
|
||||
anchor = pb.position();
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipToEnd();
|
||||
pb.data(value, anchor);
|
||||
}
|
||||
//cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
|
||||
processOption(name.lowercase(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::assignOnOffSetting(const Data& value, bool& setting)
|
||||
{
|
||||
if(value == "1" || value == "true" || value == "on" || value == "enable")
|
||||
{
|
||||
setting = true;
|
||||
return true;
|
||||
}
|
||||
else if(value == "0" || value == "false" || value == "off" || value == "disable")
|
||||
{
|
||||
setting = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::processOption(const Data& name, const Data& value)
|
||||
{
|
||||
bool result = true;
|
||||
if(name == "a" || name == "ipaddress")
|
||||
{
|
||||
mAddress = value;
|
||||
}
|
||||
else if(name == "d" || name == "dnsservers")
|
||||
{
|
||||
if(!value.empty()) mDnsServers.clear(); // allow command line to override config file, since list is added to
|
||||
|
||||
// DNS Servers
|
||||
ParseBuffer pb(value);
|
||||
Data dnsServer;
|
||||
while(!value.empty() && !pb.eof())
|
||||
{
|
||||
pb.skipWhitespace();
|
||||
const char *start = pb.position();
|
||||
pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space
|
||||
pb.data(dnsServer, start);
|
||||
if(DnsUtil::isIpV4Address(dnsServer))
|
||||
{
|
||||
mDnsServers.push_back(Tuple(dnsServer, 0, UNKNOWN_TRANSPORT).toGenericIPAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Tried to add dns server, but invalid format: " << value << endl;
|
||||
result = false;
|
||||
}
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(name == "gi" || name == "sipgatewayidentity")
|
||||
{
|
||||
result = assignNameAddr("sip gateway identity", value, mGatewayIdentity);
|
||||
}
|
||||
else if(name == "sp" || name == "udptcpport")
|
||||
{
|
||||
mSipPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "tp" || name == "tlsport")
|
||||
{
|
||||
mTlsPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "td" || name == "tlsdomain")
|
||||
{
|
||||
mTlsDomain = value;
|
||||
}
|
||||
else if(name == "keepalives")
|
||||
{
|
||||
assignOnOffSetting(value, mKeepAlives);
|
||||
}
|
||||
else if(name == "op" || name == "outboundproxy")
|
||||
{
|
||||
result = assignNameAddr("outbound proxy", value, mOutboundProxy);
|
||||
}
|
||||
else if(name == "registrationtime")
|
||||
{
|
||||
mRegistrationTime = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "registrationretrytime")
|
||||
{
|
||||
mRegistrationRetryTime = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "l" || name == "loglevel")
|
||||
{
|
||||
mLogLevel = value;
|
||||
}
|
||||
else if(name == "logfilename")
|
||||
{
|
||||
mLogFilename = value;
|
||||
}
|
||||
else if(name == "logfilemaxlines")
|
||||
{
|
||||
mLogFileMaxLines = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "gatewayipcport")
|
||||
{
|
||||
mGatewayIPCPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabberconnectoripcport")
|
||||
{
|
||||
mJabberConnectorIPCPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpport")
|
||||
{
|
||||
mHttpPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpauth")
|
||||
{
|
||||
assignOnOffSetting(value, mHttpAuth);
|
||||
}
|
||||
else if(name == "httpauthpwd")
|
||||
{
|
||||
mHttpAuthPwd = value;
|
||||
}
|
||||
else if(name == "ichatproceedingtimeout")
|
||||
{
|
||||
mIChatProceedingTimeout = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "alwaysrelayichatmedia")
|
||||
{
|
||||
assignOnOffSetting(value, mAlwaysRelayIChatMedia);
|
||||
}
|
||||
else if(name == "preferipv6")
|
||||
{
|
||||
assignOnOffSetting(value, mPreferIPv6);
|
||||
}
|
||||
else if(name == "skipfirstichataddress")
|
||||
{
|
||||
assignOnOffSetting(value, mSkipFirstIChatAddress);
|
||||
}
|
||||
else if(name == "codecidfilterlist")
|
||||
{
|
||||
ParseBuffer pb(value);
|
||||
Data codecId;
|
||||
while(!value.empty() && !pb.eof())
|
||||
{
|
||||
pb.skipWhitespace();
|
||||
const char *start = pb.position();
|
||||
pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space
|
||||
pb.data(codecId, start);
|
||||
mCodecIdFilterList.insert((unsigned short)codecId.convertUnsignedLong());
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(name == "mediarelayportrangemin")
|
||||
{
|
||||
mMediaRelayPortRangeMin = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "mediarelayportrangemax")
|
||||
{
|
||||
mMediaRelayPortRangeMax = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "translationpattern")
|
||||
{
|
||||
mAddressTranslations.push_back(std::make_pair(value, Data::Empty));
|
||||
}
|
||||
else if(name == "translationoutput")
|
||||
{
|
||||
if(!mAddressTranslations.empty())
|
||||
{
|
||||
mAddressTranslations.back().second = value;
|
||||
}
|
||||
}
|
||||
else if(name == "jabberserver")
|
||||
{
|
||||
mJabberServer = value;
|
||||
}
|
||||
else if(name == "jabbercomponentname")
|
||||
{
|
||||
mJabberComponentName = value;
|
||||
}
|
||||
else if(name == "jabbercomponentpassword")
|
||||
{
|
||||
mJabberComponentPassword = value;
|
||||
}
|
||||
else if(name == "jabbercomponentport")
|
||||
{
|
||||
mJabberComponentPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabberserverpingduration")
|
||||
{
|
||||
mJabberServerPingDuration = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabbercontrolusername")
|
||||
{
|
||||
mJabberControlUsername = value;
|
||||
}
|
||||
else if(name == "tlsdhparamsfilename")
|
||||
{
|
||||
mTLSDHParamsFilename = value;
|
||||
}
|
||||
else if(name == "tlscertificate")
|
||||
{
|
||||
mTLSCertificate = value;
|
||||
}
|
||||
else if(name == "tlsprivateKey")
|
||||
{
|
||||
mTLSPrivateKey = value;
|
||||
}
|
||||
else if(name == "tlsprivatekeypassphrase")
|
||||
{
|
||||
mTLSPrivateKeyPassPhrase = value;
|
||||
}
|
||||
else if(name == "ichatjabberconnectorpath")
|
||||
{
|
||||
mIchatJabberConnectorPath = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::assignNameAddr(const Data& settingName, const Data& settingValue, NameAddr& nameAddr)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!settingValue.empty())
|
||||
{
|
||||
NameAddr tempNameAddr(settingValue);
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
// Try adding sip: to address to see if it will be valid
|
||||
try
|
||||
{
|
||||
NameAddr tempNameAddr(Data("sip:" + settingValue));
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
catch(resip::BaseException&)
|
||||
{
|
||||
cerr << "Invalid " << settingName << " NameAddr format=" << settingValue << ": " << e << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
#if !defined(ConfigParser_hxx)
|
||||
#define ConfigParser_hxx
|
||||
|
||||
#include <list>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <rutil/dns/DnsStub.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class ConfigParser
|
||||
{
|
||||
public:
|
||||
ConfigParser(int argc, char** argv);
|
||||
virtual ~ConfigParser();
|
||||
|
||||
resip::Data mAddress;
|
||||
resip::DnsStub::NameserverList mDnsServers;
|
||||
resip::NameAddr mGatewayIdentity;
|
||||
unsigned short mSipPort;
|
||||
unsigned short mTlsPort;
|
||||
resip::Data mTlsDomain;
|
||||
resip::NameAddr mOutboundProxy;
|
||||
unsigned int mRegistrationTime;
|
||||
unsigned int mRegistrationRetryTime;
|
||||
bool mKeepAlives;
|
||||
resip::Data mLogLevel;
|
||||
resip::Data mLogFilename;
|
||||
unsigned int mLogFileMaxLines;
|
||||
unsigned short mGatewayIPCPort;
|
||||
unsigned short mJabberConnectorIPCPort;
|
||||
unsigned short mHttpPort;
|
||||
bool mHttpAuth;
|
||||
resip::Data mHttpAuthPwd;
|
||||
unsigned int mIChatProceedingTimeout;
|
||||
bool mAlwaysRelayIChatMedia;
|
||||
bool mPreferIPv6;
|
||||
bool mSkipFirstIChatAddress; // (for testing): skipping the first IPV4 NAT mapped address (on systems with one interface) causes the local address to be used
|
||||
typedef std::set<unsigned short> CodecIdList;
|
||||
CodecIdList mCodecIdFilterList;
|
||||
unsigned short mMediaRelayPortRangeMin;
|
||||
unsigned short mMediaRelayPortRangeMax;
|
||||
typedef std::list<std::pair<resip::Data,resip::Data> > TranslationList;
|
||||
TranslationList mAddressTranslations;
|
||||
|
||||
// Jabber specific settings
|
||||
resip::Data mJabberServer;
|
||||
resip::Data mJabberComponentName;
|
||||
resip::Data mJabberComponentPassword;
|
||||
unsigned short mJabberComponentPort;
|
||||
unsigned int mJabberServerPingDuration;
|
||||
resip::Data mJabberControlUsername;
|
||||
|
||||
// TLS specific settings
|
||||
resip::Data mTLSDHParamsFilename;
|
||||
resip::Data mTLSCertificate;
|
||||
resip::Data mTLSPrivateKey;
|
||||
resip::Data mTLSPrivateKeyPassPhrase;
|
||||
|
||||
// iChat Jabber Connector file path
|
||||
resip::Data mIchatJabberConnectorPath;
|
||||
|
||||
private:
|
||||
void parseCommandLine(int argc, char** argv);
|
||||
void parseConfigFile(const resip::Data& filename);
|
||||
bool processOption(const resip::Data& name, const resip::Data& value);
|
||||
bool assignNameAddr(const resip::Data& settingName, const resip::Data& settingValue, resip::NameAddr& nameAddr);
|
||||
bool assignOnOffSetting(const resip::Data& value, bool& setting);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
#if !defined(IChatGatewayCmds_hxx)
|
||||
#define IChatGatewayCmds_hxx
|
||||
|
||||
#include <resip/dum/DumCommand.hxx>
|
||||
|
||||
#include "Server.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
/**
|
||||
The classes defined here are used to pass commands from the
|
||||
application thread to the DUM thread (process loop).
|
||||
This ensures thread safety of the external Server methods.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class NotifyIChatCallRequestCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallRequestCmd(Server& server, const std::string& to, const std::string& from)
|
||||
: mServer(server), mTo(to), mFrom(from) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallRequestImpl(mTo, mFrom);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallRequestCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mTo;
|
||||
std::string mFrom;
|
||||
};
|
||||
|
||||
class NotifyIChatCallCancelledCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallCancelledCmd(Server& server, const B2BSessionHandle& handle)
|
||||
: mServer(server), mHandle(handle) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallCancelledImpl(mHandle);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallCancelledCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
};
|
||||
|
||||
class NotifyIChatCallProceedingCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallProceedingCmd(Server& server, const B2BSessionHandle& handle, const std::string& to)
|
||||
: mServer(server), mHandle(handle), mTo(to) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallProceedingImpl(mHandle, mTo);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallProceedingCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
std::string mTo;
|
||||
};
|
||||
|
||||
class NotifyIChatCallFailedCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallFailedCmd(Server& server, const B2BSessionHandle& handle, unsigned int statusCode)
|
||||
: mServer(server), mHandle(handle), mStatusCode(statusCode) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallFailedImpl(mHandle, mStatusCode);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallFailedCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
unsigned int mStatusCode;
|
||||
};
|
||||
|
||||
class ContinueIChatCallCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
ContinueIChatCallCmd(Server& server, const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob)
|
||||
: mServer(server), mHandle(handle), mRemoteIPPortListBlob(remoteIPPortListBlob) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.continueIChatCallImpl(mHandle, mRemoteIPPortListBlob);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " ContinueIChatCallCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
std::string mRemoteIPPortListBlob;
|
||||
};
|
||||
|
||||
class SipRegisterJabberUserCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
SipRegisterJabberUserCmd(Server& server, const std::string& jidToRegister)
|
||||
: mServer(server), mJidToRegister(jidToRegister) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.sipRegisterJabberUserImpl(mJidToRegister);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " SipRegisterJabberUserCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mJidToRegister;
|
||||
};
|
||||
|
||||
class SipUnregisterJabberUserCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
SipUnregisterJabberUserCmd(Server& server, const std::string& jidToUnregister)
|
||||
: mServer(server), mJidToUnregister(jidToUnregister) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.sipUnregisterJabberUserImpl(mJidToUnregister);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " SipUnregisterJabberUserCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mJidToUnregister;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Helper.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "IChatIPPortData.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short initialPad;
|
||||
unsigned short family;
|
||||
char interfaceName[16];
|
||||
char ipAddress[16];
|
||||
unsigned short port;
|
||||
unsigned short finalPad;
|
||||
} IPPortDataBlob;
|
||||
|
||||
IChatIPPortData::IChatIPPortData()
|
||||
{
|
||||
}
|
||||
|
||||
IChatIPPortData::IChatIPPortData(const std::string& hexblob) : mHexBlob(hexblob)
|
||||
{
|
||||
unsigned int pad = 0;
|
||||
// Note: gloox passes us an initial line feed, so be tollerant of this
|
||||
if(hexblob.at(0) == 0xa)
|
||||
{
|
||||
pad = 1;
|
||||
}
|
||||
|
||||
// Convert hexblob to binary blob
|
||||
if(((hexblob.size()-pad) % 40) != 0)
|
||||
{
|
||||
ErrLog(<< "Data size provided for IChatIPPortData is not correct, size=" << hexblob.size());
|
||||
return;
|
||||
}
|
||||
Data blob((unsigned int)hexblob.size()-1 / 2, Data::Preallocate);
|
||||
for(unsigned int i = pad; i < hexblob.size(); i=i+8)
|
||||
{
|
||||
unsigned int block = ntohl(Helper::hex2integer(&hexblob.at(i)));
|
||||
blob.append((const char*)&block, 4);
|
||||
}
|
||||
|
||||
for(unsigned int j = 0; j < blob.size(); j=j+40)
|
||||
{
|
||||
IPPortDataBlob* ipPortDataBlob = (IPPortDataBlob*)(blob.data()+j);
|
||||
|
||||
if(ipPortDataBlob->family == V4)
|
||||
{
|
||||
in_addr addr;
|
||||
memcpy(&addr, ipPortDataBlob->ipAddress, 4);
|
||||
addIPPortData(Data(ipPortDataBlob->interfaceName), Tuple(addr,ntohs(ipPortDataBlob->port),UDP));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
in6_addr addr;
|
||||
memcpy(&addr, ipPortDataBlob->ipAddress, 16);
|
||||
addIPPortData(Data(ipPortDataBlob->interfaceName), Tuple(addr,ntohs(ipPortDataBlob->port),UDP));
|
||||
#else
|
||||
ErrLog(<< "IPv6 support not enabled at compile time.");
|
||||
resip_assert(0);
|
||||
#endif
|
||||
}
|
||||
InfoLog(<< "IChatIPPortData: name=" << mIPPortDataList.back().first << " addr=" << mIPPortDataList.back().second);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IChatIPPortData::addIPPortData(const Data& name, const Tuple& ipPortData)
|
||||
{
|
||||
mIPPortDataList.push_back(std::make_pair(name, ipPortData));
|
||||
mHexBlob.clear(); // clear any existing blob string - it will now need to be re-generated if requested
|
||||
}
|
||||
|
||||
std::string&
|
||||
IChatIPPortData::hexBlob()
|
||||
{
|
||||
if(mHexBlob.empty())
|
||||
{
|
||||
Data dataBlob((int)mIPPortDataList.size() * sizeof(IPPortDataBlob), Data::Preallocate);
|
||||
IPPortDataList::const_iterator it;
|
||||
for(it = mIPPortDataList.begin(); it != mIPPortDataList.end(); it++)
|
||||
{
|
||||
IPPortDataBlob ipPortDataBlob;
|
||||
memset(&ipPortDataBlob, 0, sizeof(ipPortDataBlob));
|
||||
memcpy(ipPortDataBlob.interfaceName, it->first.data(), it->first.size() < 16 ? it->first.size() : 16);
|
||||
ipPortDataBlob.port = htons(it->second.getPort());
|
||||
if(it->second.ipVersion() == V4)
|
||||
{
|
||||
ipPortDataBlob.family = V4;
|
||||
memcpy(ipPortDataBlob.ipAddress, &reinterpret_cast<const sockaddr_in&>(it->second.getSockaddr()).sin_addr, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipPortDataBlob.family = V6;
|
||||
memcpy(ipPortDataBlob.ipAddress, &reinterpret_cast<const sockaddr_in6&>(it->second.getSockaddr()).sin6_addr, 16);
|
||||
}
|
||||
dataBlob.append((const char*)&ipPortDataBlob, sizeof(ipPortDataBlob));
|
||||
}
|
||||
|
||||
// Hexify
|
||||
for(unsigned int i = 0; i < dataBlob.size(); i=i+4)
|
||||
{
|
||||
unsigned int block;
|
||||
memcpy(&block, dataBlob.data()+i, 4);
|
||||
char hexBlock[8];
|
||||
Helper::integer2hex(hexBlock, htonl(block));
|
||||
mHexBlob.append(hexBlock, 8);
|
||||
}
|
||||
}
|
||||
return mHexBlob;
|
||||
}
|
||||
|
||||
const IChatIPPortData::IPPortDataList&
|
||||
IChatIPPortData::getIPPortDataList() const
|
||||
{
|
||||
return mIPPortDataList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
#if !defined(IChatIPPortData_hxx)
|
||||
#define IChatIPPortData_hxx
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "rutil/Data.hxx"
|
||||
#include "resip/stack/Tuple.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class IChatIPPortData
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::pair<resip::Data,resip::Tuple> > IPPortDataList;
|
||||
|
||||
IChatIPPortData();
|
||||
IChatIPPortData(const std::string& hexblob);
|
||||
|
||||
void addIPPortData(const resip::Data& name, const resip::Tuple& ipPortData);
|
||||
std::string& hexBlob();
|
||||
const IPPortDataList& getIPPortDataList() const;
|
||||
|
||||
private:
|
||||
IPPortDataList mIPPortDataList;
|
||||
std::string mHexBlob;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,281 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "IPCThread.hxx"
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
|
||||
IPCThread::IPCThread(unsigned short localPort, unsigned short remotePort, IPCHandler* handler, IPCMutex* mutex) :
|
||||
mLocalPort(localPort),
|
||||
mRemotePort(remotePort),
|
||||
mHandler(handler),
|
||||
mMutex(mutex)
|
||||
{
|
||||
resip_assert(handler!=0);
|
||||
mSocket = createIPCSocket("127.0.0.1",mLocalPort);
|
||||
if(mSocket == INVALID_SOCKET)
|
||||
{
|
||||
cerr << "IPCThread::IPCThread - could not create IPC udp socket on port=" << mLocalPort << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set RemoteSockaddr to be same as local but with remote port
|
||||
memcpy(&mRemoteSockaddr, &mLocalSockaddr, sizeof(mRemoteSockaddr));
|
||||
sockaddr_in* anonv4 = (sockaddr_in*)&mRemoteSockaddr;
|
||||
anonv4->sin_port = htons(remotePort);
|
||||
|
||||
cout << "IPCThread::IPCThread: local port=" << mLocalPort << ", remote port=" << remotePort << endl;
|
||||
}
|
||||
}
|
||||
|
||||
IPCThread::~IPCThread()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(mSocket);
|
||||
#else
|
||||
close(mSocket);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::sendIPCMsg(IPCMsg& msg)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
msg.encode(oss);
|
||||
mMutex->lock();
|
||||
mDataToSend.push(oss.str());
|
||||
mMutex->unlock();
|
||||
}
|
||||
|
||||
Socket
|
||||
IPCThread::createIPCSocket(const std::string& printableAddr, unsigned int port)
|
||||
{
|
||||
Socket fd;
|
||||
sockaddr_in* anonv4 = (sockaddr_in*)&mLocalSockaddr;
|
||||
|
||||
fd = ::socket(PF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if ( fd == INVALID_SOCKET )
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr << "IPCThread::createIPCSocket - Failed to create socket: error=" << e << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
memset(anonv4, 0, sizeof(anonv4));
|
||||
anonv4->sin_family = AF_INET;
|
||||
anonv4->sin_port = htons(port);
|
||||
if (printableAddr.empty())
|
||||
{
|
||||
anonv4->sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
anonv4->sin_addr.s_addr = inet_addr(printableAddr.c_str());
|
||||
}
|
||||
|
||||
//cout << "IPCThread::createIPCSocket - Creating fd=" << (int)fd
|
||||
// << ", Binding to " << printableAddr << ":" << port << endl;
|
||||
|
||||
if ( ::bind( fd, &mLocalSockaddr, sizeof(mLocalSockaddr)) == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
if ( e == EADDRINUSE )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - " << printableAddr << ":" << port << " already in use" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not bind to " << printableAddr << ":" << port << ", error=" << e << endl;
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(port == 0)
|
||||
{
|
||||
// If we used port 0, then query what port the OS allocated for us
|
||||
socklen_t len = sizeof(mLocalSockaddr);
|
||||
if(::getsockname(fd, &mLocalSockaddr, &len) == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr <<"IPCThread::createIPCSocket - getsockname failed, error=" << e << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
unsigned long noBlock = 1;
|
||||
int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock );
|
||||
if ( errNoBlock != 0 )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not make socket non-blocking" << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
int flags = fcntl( fd, F_GETFL, 0);
|
||||
int errNoBlock = fcntl(fd, F_SETFL, flags | O_NONBLOCK );
|
||||
if ( errNoBlock != 0 )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not make socket non-blocking" << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::thread()
|
||||
{
|
||||
fd_set read;
|
||||
fd_set write;
|
||||
fd_set except;
|
||||
struct timeval tv;
|
||||
|
||||
if(mSocket == INVALID_SOCKET) return;
|
||||
|
||||
while (!isShutdown())
|
||||
{
|
||||
tv.tv_sec = 1; // Note: calling select on linux based systems can cause the contents of the passed in timeval struct to be modified, so we need to reset the time on each loop iteration
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&read);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&except);
|
||||
|
||||
FD_SET(mSocket, &read);
|
||||
FD_SET(mSocket, &except);
|
||||
|
||||
if(!mDataToSend.empty())
|
||||
{
|
||||
FD_SET(mSocket, &write);
|
||||
}
|
||||
|
||||
int ret = ::select(mSocket+1, &read, &write, &except, &tv);
|
||||
if (ret > 0)
|
||||
{
|
||||
process(read, write);
|
||||
}
|
||||
}
|
||||
cout << "IPCThread::thread - IPCThread shutdown." << endl;
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::process(fd_set& read_fdset, fd_set& write_fdset)
|
||||
{
|
||||
// If data to send and write has signalled
|
||||
if(!mDataToSend.empty() && (FD_ISSET(mSocket, &write_fdset) != 0))
|
||||
{
|
||||
int count;
|
||||
mMutex->lock();
|
||||
std::string& dataToSend = mDataToSend.front();
|
||||
count = sendto(mSocket,
|
||||
dataToSend.data(),
|
||||
dataToSend.size(),
|
||||
0, // flags
|
||||
&mRemoteSockaddr, sizeof(mRemoteSockaddr));
|
||||
mDataToSend.pop();
|
||||
mMutex->unlock();
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr << "IPCThread::process - Failed (" << e << ") sending." << endl;
|
||||
}
|
||||
}
|
||||
if((FD_ISSET(mSocket, &read_fdset) != 0))
|
||||
{
|
||||
sockaddr readAddr;
|
||||
bool success = true;
|
||||
|
||||
socklen_t slen = sizeof(readAddr);
|
||||
int len = recvfrom(mSocket,
|
||||
mReadBuffer,
|
||||
UDP_IPC_BUFFER_SIZE,
|
||||
0 /*flags */,
|
||||
&readAddr,
|
||||
&slen);
|
||||
if ( len == SOCKET_ERROR )
|
||||
{
|
||||
int err = getErrno();
|
||||
if ( err != EWOULDBLOCK )
|
||||
{
|
||||
cerr << "IPCThread::process - Error calling recvfrom: " << err << endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0 || len == SOCKET_ERROR)
|
||||
{
|
||||
cerr << "IPCThread::process - No data calling recvfrom: len=" << len << endl;
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (len+1 >= UDP_IPC_BUFFER_SIZE)
|
||||
{
|
||||
cerr << "IPCThread::process - Datagram exceeded max length "<<UDP_IPC_BUFFER_SIZE << endl;
|
||||
success = false;
|
||||
}
|
||||
|
||||
if(success)
|
||||
{
|
||||
//cout << "IPCThread::process - Received a datagram of size=" << len << endl;
|
||||
IPCMsg msg(std::string(mReadBuffer, len));
|
||||
mHandler->onNewIPCMsg(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
#if !defined(IPCThread_hxx)
|
||||
#define IPCThread_hxx
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef WIN32
|
||||
# include <sys/socket.h>
|
||||
# include <sys/select.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "Thread.hxx"
|
||||
|
||||
#define UDP_IPC_BUFFER_SIZE 4192
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
#ifndef WIN32
|
||||
typedef int Socket;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKET_ERROR (-1)
|
||||
inline int getErrno() { return errno; }
|
||||
#else
|
||||
typedef SOCKET Socket;
|
||||
inline int getErrno() { return WSAGetLastError(); }
|
||||
#endif
|
||||
|
||||
class IPCMutex
|
||||
{
|
||||
public:
|
||||
IPCMutex() {}
|
||||
virtual ~IPCMutex() {}
|
||||
virtual void lock() = 0;
|
||||
virtual void unlock() = 0;
|
||||
};
|
||||
|
||||
class IPCMsg
|
||||
{
|
||||
public:
|
||||
IPCMsg() {};
|
||||
IPCMsg(const std::string& msg)
|
||||
{
|
||||
unsigned int start = 0;
|
||||
for(unsigned int i = 0; i < msg.size(); i++)
|
||||
{
|
||||
if(msg.at(i) == '\r')
|
||||
{
|
||||
mArgs.push_back(msg.substr(start,i-start));
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void addArg(const std::string& arg) { mArgs.push_back(arg); }
|
||||
void addArg(unsigned int arg)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << arg;
|
||||
mArgs.push_back(oss.str());
|
||||
}
|
||||
std::ostream& encode(std::ostream& strm) const
|
||||
{
|
||||
std::vector<std::string>::const_iterator it = mArgs.begin();
|
||||
for(;it != mArgs.end();it++)
|
||||
{
|
||||
strm << *it << "\r"; // Note: using /r since there is a /n character at the start of the iChat call blob
|
||||
}
|
||||
strm.flush();
|
||||
return strm;
|
||||
}
|
||||
const std::vector<std::string>& getArgs() const { return mArgs; }
|
||||
private:
|
||||
std::vector<std::string> mArgs;
|
||||
};
|
||||
|
||||
class IPCHandler
|
||||
{
|
||||
public:
|
||||
virtual ~IPCHandler() {}
|
||||
virtual void onNewIPCMsg(const IPCMsg& msg) = 0;
|
||||
};
|
||||
|
||||
class IPCThread : public Thread
|
||||
{
|
||||
public:
|
||||
IPCThread(unsigned short localPort, unsigned short remotePort, IPCHandler* handler, IPCMutex* mutex);
|
||||
virtual ~IPCThread();
|
||||
|
||||
void sendIPCMsg(IPCMsg& msg);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
|
||||
void process(fd_set& read_fdset, fd_set& write_fdset);
|
||||
|
||||
Socket createIPCSocket(const std::string& printableAddr, unsigned int port);
|
||||
char mReadBuffer[UDP_IPC_BUFFER_SIZE+1];
|
||||
|
||||
sockaddr mLocalSockaddr;
|
||||
sockaddr mRemoteSockaddr;
|
||||
Socket mSocket;
|
||||
unsigned short mLocalPort;
|
||||
unsigned short mRemotePort;
|
||||
//resip::Mutex mIPCMutex;
|
||||
std::queue<std::string> mDataToSend;
|
||||
|
||||
IPCHandler* mHandler;
|
||||
IPCMutex* mMutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
# $Id$
|
||||
|
||||
EXTRA_DIST = ichat-gw.config
|
||||
EXTRA_DIST += doc
|
||||
EXTRA_DIST += *.sln
|
||||
EXTRA_DIST += *.vcproj
|
||||
|
||||
SUBDIRS = .
|
||||
# this has more external dependencies, it has been adapted
|
||||
# for autotools and can be enabled manually if the deps
|
||||
# are available
|
||||
SUBDIRS += jabberconnector
|
||||
|
||||
#AM_CXXFLAGS = -DUSE_ARES
|
||||
|
||||
sbin_PROGRAMS = ichat-gw
|
||||
ichat_gw_LDADD = ../../resip/dum/libdum.la
|
||||
ichat_gw_LDADD += ../../resip/stack/libresip.la ../../rutil/librutil.la
|
||||
ichat_gw_LDADD += @LIBSSL_LIBADD@ -lpcre @LIBPTHREAD_LIBADD@
|
||||
|
||||
ichat_gw_SOURCES = \
|
||||
AddressTranslator.cxx \
|
||||
AppSubsystem.cxx \
|
||||
B2BSession.cxx \
|
||||
ConfigParser.cxx \
|
||||
ichat-gw.cxx \
|
||||
IChatIPPortData.cxx \
|
||||
IPCThread.cxx \
|
||||
MediaRelay.cxx \
|
||||
MediaRelayPort.cxx \
|
||||
Server.cxx \
|
||||
SipRegistration.cxx \
|
||||
Thread.cxx
|
||||
|
||||
ichat_gwincludedir = $(includedir)/ichat-gw
|
||||
nobase_ichat_gwinclude_HEADERS = AddressTranslator.hxx \
|
||||
AppSubsystem.hxx \
|
||||
B2BSession.hxx \
|
||||
ConfigParser.hxx \
|
||||
IChatGatewayCmds.hxx \
|
||||
IChatIPPortData.hxx \
|
||||
IPCThread.hxx \
|
||||
MediaRelay.hxx \
|
||||
MediaRelayPort.hxx \
|
||||
Server.hxx \
|
||||
SipRegistration.hxx \
|
||||
Thread.hxx \
|
||||
Version.hxx
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# The Vovida Software License, Version 1.0
|
||||
# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
# and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
# not be used to endorse or promote products derived from this
|
||||
# software without prior written permission. For written
|
||||
# permission, please contact vocal@vovida.org.
|
||||
#
|
||||
# 4. Products derived from this software may not be called "VOCAL", nor
|
||||
# may "VOCAL" appear in their name, without prior written
|
||||
# permission of Vovida Networks, Inc.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
# DAMAGE.
|
||||
#
|
||||
# ====================================================================
|
||||
#
|
||||
# This software consists of voluntary contributions made by Vovida
|
||||
# Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
# Inc. For more information on Vovida Networks, Inc., please see
|
||||
# <http://www.vovida.org/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
|
@ -1,651 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/Timer.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/Random.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "MediaRelay.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
#ifdef WIN32
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short versionExtPayloadTypeAndMarker;
|
||||
unsigned short sequenceNumber;
|
||||
unsigned int timestamp;
|
||||
unsigned int ssrc;
|
||||
} RtpHeader;
|
||||
|
||||
|
||||
MediaRelay::MediaRelay(bool isV6Avail, unsigned short portRangeMin, unsigned short portRangeMax) :
|
||||
mIsV6Avail(isV6Avail)
|
||||
{
|
||||
if(portRangeMax < portRangeMin) portRangeMax = portRangeMin; // saftey check
|
||||
for(unsigned int i = portRangeMin; i <= portRangeMax; i++)
|
||||
{
|
||||
mFreeRelayPortList.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
MediaRelay::~MediaRelay()
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_CREATE_TRIES 10 // Number of times to try to allocate a port, since port may be in use by another application
|
||||
bool
|
||||
MediaRelay::createRelay(unsigned short& port)
|
||||
{
|
||||
for(unsigned int i = 0; i < NUM_CREATE_TRIES; i++)
|
||||
{
|
||||
if(createRelayImpl(port)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaRelay::createRelayImpl(unsigned short& port)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
if(mFreeRelayPortList.empty()) return false;
|
||||
|
||||
unsigned short trialPort = mFreeRelayPortList.front();
|
||||
mFreeRelayPortList.pop_front();
|
||||
|
||||
Tuple v4tuple(Data::Empty,trialPort,V4,UDP,Data::Empty);
|
||||
resip::Socket v4fd = createRelaySocket(v4tuple);
|
||||
|
||||
if(v4fd == INVALID_SOCKET)
|
||||
{
|
||||
mFreeRelayPortList.push_back(trialPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(mIsV6Avail)
|
||||
{
|
||||
Tuple v6tuple(Data::Empty,trialPort,V6,UDP,Data::Empty);
|
||||
resip::Socket v6fd = createRelaySocket(v6tuple);
|
||||
|
||||
if(v6fd != INVALID_SOCKET)
|
||||
{
|
||||
port = trialPort;
|
||||
|
||||
mRelays[port] = new MediaRelayPort(v4fd, v4tuple, v6fd, v6tuple);
|
||||
InfoLog(<< "MediaRelay::createRelayImpl - Media relay started for port " << port);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
closesocket(v4fd);
|
||||
#else
|
||||
close(v4fd);
|
||||
#endif
|
||||
|
||||
mFreeRelayPortList.push_back(trialPort);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only V4 is available
|
||||
port = trialPort;
|
||||
|
||||
mRelays[port] = new MediaRelayPort(v4fd, v4tuple);
|
||||
InfoLog(<< "MediaRelay::createRelayImpl - Media relay started for port " << port);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::destroyRelay(unsigned short port)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.find(port);
|
||||
if(it != mRelays.end())
|
||||
{
|
||||
InfoLog(<< "MediaRelay::destroyRelay - port=" << port);
|
||||
delete it->second;
|
||||
mRelays.erase(it);
|
||||
mFreeRelayPortList.push_back(port);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::primeNextEndpoint(unsigned short& port, resip::Tuple& destinationIPPort)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.find(port);
|
||||
if(it != mRelays.end())
|
||||
{
|
||||
if(it->second->mFirstEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::primeNextEndpoint - sender=first, port=" << port << ", addr=" << destinationIPPort);
|
||||
it->second->mFirstEndpoint.mTuple = destinationIPPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(<< "MediaRelay::primeNextEndpoint - sender=second, port=" << port << ", addr=" << destinationIPPort);
|
||||
it->second->mSecondEndpoint.mTuple = destinationIPPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resip::Socket
|
||||
MediaRelay::createRelaySocket(resip::Tuple& tuple)
|
||||
{
|
||||
resip::Socket fd;
|
||||
|
||||
#ifdef USE_IPV6
|
||||
fd = ::socket(tuple.ipVersion() == V4 ? PF_INET : PF_INET6, SOCK_DGRAM, 0);
|
||||
#else
|
||||
fd = ::socket(PF_INET, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
if ( fd == INVALID_SOCKET )
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Failed to create socket: " << strerror(e));
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
DebugLog (<< "MediaRelay::createRelaySocket - Creating fd=" << (int)fd
|
||||
<< (tuple.ipVersion() == V4 ? " V4" : " V6")
|
||||
<< ", Binding to " << Tuple::inet_ntop(tuple));
|
||||
|
||||
if ( ::bind( fd, &tuple.getSockaddr(), tuple.length()) == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
if ( e == EADDRINUSE )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - " << tuple << " already in use ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Could not bind to " << tuple << ", error=" << e);
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(tuple.getPort() == 0)
|
||||
{
|
||||
// If we used port 0, then query what port the OS allocated for us
|
||||
socklen_t len = tuple.length();
|
||||
if(::getsockname(fd, &tuple.getMutableSockaddr(), &len) == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<<"MediaRelay::createRelaySocket - getsockname failed, error=" << e);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = makeSocketNonBlocking(fd);
|
||||
if ( !ok )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Could not make socket non-blocking");
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::thread()
|
||||
{
|
||||
while (!isShutdown())
|
||||
{
|
||||
try
|
||||
{
|
||||
if(mRelays.size() == 0)
|
||||
{
|
||||
// No relays yet - just wait
|
||||
sleepMs(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
resip::FdSet fdset;
|
||||
buildFdSet(fdset);
|
||||
int ret = fdset.selectMilliSeconds(50);
|
||||
if (ret > 0)
|
||||
{
|
||||
process(fdset);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BaseException& e)
|
||||
{
|
||||
ErrLog (<< "MediaRelay::thread - Unhandled exception: " << e);
|
||||
}
|
||||
}
|
||||
WarningLog (<< "MediaRelay::thread - shutdown");
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
// Add read fd's
|
||||
fdset.setRead(it->second->mV4Fd);
|
||||
if(mIsV6Avail) fdset.setRead(it->second->mV6Fd);
|
||||
fdset.setExcept(it->second->mV4Fd);
|
||||
if(mIsV6Avail) fdset.setExcept(it->second->mV6Fd);
|
||||
|
||||
checkKeepalives(it->second);
|
||||
|
||||
// Add write fd's if there is data to write
|
||||
if((it->second->mFirstEndpoint.mRelayDatagram.get() != 0 && it->second->mFirstEndpoint.mTuple.ipVersion() == V4) ||
|
||||
(it->second->mSecondEndpoint.mRelayDatagram.get() != 0 && it->second->mSecondEndpoint.mTuple.ipVersion() == V4))
|
||||
{
|
||||
fdset.setWrite(it->second->mV4Fd);
|
||||
}
|
||||
if(mIsV6Avail &&
|
||||
((it->second->mFirstEndpoint.mRelayDatagram.get() != 0 && it->second->mFirstEndpoint.mTuple.ipVersion() == V6) ||
|
||||
(it->second->mSecondEndpoint.mRelayDatagram.get() != 0 && it->second->mSecondEndpoint.mTuple.ipVersion() == V6)))
|
||||
{
|
||||
fdset.setWrite(it->second->mV6Fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define KEEPALIVETIMEOUTMS 1000
|
||||
#define KEEPALIVEMS 20
|
||||
#define STALEENDPOINTTIMEOUTMS 2000
|
||||
void
|
||||
MediaRelay::checkKeepalives(MediaRelayPort* relayPort)
|
||||
{
|
||||
UInt64 now = Timer::getTimeMs();
|
||||
|
||||
// See if First Endpoint is stale (ie. hasn't received data in STALEENDPOINTTIMEOUTMS ms)
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() != 0 &&
|
||||
(now - relayPort->mFirstEndpoint.mRecvTimeMs) > STALEENDPOINTTIMEOUTMS)
|
||||
{
|
||||
relayPort->mFirstEndpoint.reset();
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", haven't recevied data from first endpoint in " << STALEENDPOINTTIMEOUTMS << "ms - reseting endpoint.");
|
||||
}
|
||||
|
||||
// See if Second Endpoint is stale (ie. hasn't received data in STALEENDPOINTTIMEOUTMS ms)
|
||||
if(relayPort->mSecondEndpoint.mTuple.getPort() != 0 &&
|
||||
(now - relayPort->mSecondEndpoint.mRecvTimeMs) > STALEENDPOINTTIMEOUTMS)
|
||||
{
|
||||
relayPort->mSecondEndpoint.reset();
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", haven't recevied data from second endpoint in " << STALEENDPOINTTIMEOUTMS << "ms - reseting endpoint.");
|
||||
}
|
||||
|
||||
//if(relayPort->mFirstEndpoint.mTuple.getPort() != 0)
|
||||
//{
|
||||
//InfoLog(<< "MediaRelay::checkKeepalives - port=" << relayPort->mFirstEndpoint.mTuple.getPort() << ", dataToSend=" <<
|
||||
// (relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 ? "no" : "yes") << ", time since last send=" <<
|
||||
// (now - relayPort->mFirstEndpoint.mSendTimeMs));
|
||||
//}
|
||||
|
||||
// See if keepalive needs to be sent to First Endpoint
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() != 0 &&
|
||||
relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 &&
|
||||
((!relayPort->mFirstEndpoint.mKeepaliveMode && (now - relayPort->mFirstEndpoint.mSendTimeMs) > KEEPALIVETIMEOUTMS) ||
|
||||
(relayPort->mFirstEndpoint.mKeepaliveMode && (now - relayPort->mFirstEndpoint.mSendTimeMs) > KEEPALIVEMS)))
|
||||
{
|
||||
RtpHeader keepalive; // Create an empty G711 packet to keep iChat happy
|
||||
keepalive.versionExtPayloadTypeAndMarker = htons(0x8000);
|
||||
keepalive.sequenceNumber = 0;
|
||||
keepalive.timestamp = 0;
|
||||
keepalive.ssrc = relayPort->mFirstEndpoint.mSsrc;
|
||||
|
||||
if(!relayPort->mFirstEndpoint.mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching initial RTP keepalive to first sender!");
|
||||
relayPort->mFirstEndpoint.mKeepaliveMode = true;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching subsequent RTP keepalive to first sender!");
|
||||
//}
|
||||
|
||||
// Add message to buffer
|
||||
std::auto_ptr<char> buffer(new char[sizeof(RtpHeader)]);
|
||||
memcpy(buffer.get(), &keepalive, sizeof(RtpHeader));
|
||||
|
||||
relayPort->mFirstEndpoint.mRelayDatagram = buffer;
|
||||
relayPort->mFirstEndpoint.mRelayDatagramLen = sizeof(RtpHeader);
|
||||
}
|
||||
|
||||
// See if keepalive needs to be sent to Second Endpoint
|
||||
if(relayPort->mSecondEndpoint.mTuple.getPort() != 0 &&
|
||||
relayPort->mSecondEndpoint.mRelayDatagram.get() == 0 &&
|
||||
((!relayPort->mSecondEndpoint.mKeepaliveMode && (now - relayPort->mSecondEndpoint.mSendTimeMs) > KEEPALIVETIMEOUTMS) ||
|
||||
(relayPort->mSecondEndpoint.mKeepaliveMode && (now - relayPort->mSecondEndpoint.mSendTimeMs) > KEEPALIVEMS)))
|
||||
{
|
||||
RtpHeader keepalive; // Create an empty G711 packet to keep iChat happy
|
||||
keepalive.versionExtPayloadTypeAndMarker = htons(0x8000);
|
||||
keepalive.sequenceNumber = 0;
|
||||
keepalive.timestamp = 0;
|
||||
keepalive.ssrc = relayPort->mSecondEndpoint.mSsrc;
|
||||
|
||||
if(!relayPort->mSecondEndpoint.mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching initial RTP keepalive to second sender!");
|
||||
relayPort->mSecondEndpoint.mKeepaliveMode = true;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching subsequent RTP keepalive to second sender!");
|
||||
//}
|
||||
|
||||
// Add message to buffer
|
||||
std::auto_ptr<char> buffer(new char[sizeof(RtpHeader)]);
|
||||
memcpy(buffer.get(), &keepalive, sizeof(RtpHeader));
|
||||
|
||||
relayPort->mSecondEndpoint.mRelayDatagram = buffer;
|
||||
relayPort->mSecondEndpoint.mRelayDatagramLen = sizeof(RtpHeader);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::process(FdSet& fdset)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
if(processWrites(fdset, it->second))
|
||||
{
|
||||
// If all writes have been processed, process reads
|
||||
processReads(fdset, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MediaRelay::processWrites(FdSet& fdset, MediaRelayPort* relayPort)
|
||||
{
|
||||
resip::Socket fd = INVALID_SOCKET;
|
||||
Tuple tuple;
|
||||
std::auto_ptr<char> buffer;
|
||||
int len;
|
||||
|
||||
// If we have data to write to first sender then check if readyToWrite
|
||||
if(relayPort->mFirstEndpoint.mRelayDatagram.get() != 0)
|
||||
{
|
||||
if(relayPort->mFirstEndpoint.mTuple.ipVersion() == V4 &&
|
||||
fdset.readyToWrite(relayPort->mV4Fd))
|
||||
{
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mFirstEndpoint.mTuple;
|
||||
buffer = relayPort->mFirstEndpoint.mRelayDatagram;
|
||||
len = relayPort->mFirstEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
else if(mIsV6Avail &&
|
||||
relayPort->mFirstEndpoint.mTuple.ipVersion() == V6 &&
|
||||
fdset.readyToWrite(relayPort->mV6Fd))
|
||||
{
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mFirstEndpoint.mTuple;
|
||||
buffer = relayPort->mFirstEndpoint.mRelayDatagram;
|
||||
len = relayPort->mFirstEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
}
|
||||
|
||||
// If anything to send to first sender then do it
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
int count;
|
||||
count = sendto(fd,
|
||||
buffer.get(),
|
||||
len,
|
||||
0, // flags
|
||||
&tuple.getMutableSockaddr(), tuple.length());
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "MediaRelay::processWrites: port=" << relayPort->mLocalV4Tuple.getPort() << ", Failed (" << e << ") sending to " << tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
// InfoLog(<< len << " bytes of data sent to " << tuple);
|
||||
relayPort->mFirstEndpoint.mSendTimeMs = Timer::getTimeMs();
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have data to write to second sender then check if readyToWrite
|
||||
fd = INVALID_SOCKET; // reset
|
||||
if(relayPort->mSecondEndpoint.mRelayDatagram.get() != 0)
|
||||
{
|
||||
if(relayPort->mSecondEndpoint.mTuple.ipVersion() == V4 &&
|
||||
fdset.readyToWrite(relayPort->mV4Fd))
|
||||
{
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mSecondEndpoint.mTuple;
|
||||
buffer = relayPort->mSecondEndpoint.mRelayDatagram;
|
||||
len = relayPort->mSecondEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
else if(mIsV6Avail &&
|
||||
relayPort->mSecondEndpoint.mTuple.ipVersion() == V6 &&
|
||||
fdset.readyToWrite(relayPort->mV6Fd))
|
||||
{
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mSecondEndpoint.mTuple;
|
||||
buffer = relayPort->mSecondEndpoint.mRelayDatagram;
|
||||
len = relayPort->mSecondEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
}
|
||||
|
||||
// If anything to send to sender sender then do it
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
int count;
|
||||
count = sendto(fd,
|
||||
buffer.get(),
|
||||
len,
|
||||
0, // flags
|
||||
&tuple.getMutableSockaddr(), tuple.length());
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "MediaRelay::processWrites: port=" << relayPort->mLocalV4Tuple.getPort() << ", Failed (" << e << ") sending to " << tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
//InfoLog(<< len << " bytes of data sent to " << tuple);
|
||||
relayPort->mSecondEndpoint.mSendTimeMs = Timer::getTimeMs();
|
||||
}
|
||||
}
|
||||
|
||||
return relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 &&
|
||||
relayPort->mSecondEndpoint.mRelayDatagram.get() == 0;
|
||||
}
|
||||
|
||||
#define UDP_BUFFER_SIZE 1000
|
||||
void
|
||||
MediaRelay::processReads(FdSet& fdset, MediaRelayPort* relayPort)
|
||||
{
|
||||
resip::Socket fd = INVALID_SOCKET;
|
||||
Tuple tuple;
|
||||
|
||||
if(fdset.readyToRead(relayPort->mV4Fd))
|
||||
{
|
||||
//InfoLog(<<"V4 socket is ready to read.");
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mLocalV4Tuple;
|
||||
}
|
||||
else if(mIsV6Avail && fdset.readyToRead(relayPort->mV6Fd))
|
||||
{
|
||||
//InfoLog(<<"V6 socket is ready to read.");
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mLocalV6Tuple;
|
||||
}
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
std::auto_ptr<char> buffer(new char[UDP_BUFFER_SIZE+1]);
|
||||
|
||||
socklen_t slen = tuple.length();
|
||||
int len = recvfrom( fd,
|
||||
buffer.get(),
|
||||
UDP_BUFFER_SIZE,
|
||||
0 /*flags */,
|
||||
&tuple.getMutableSockaddr(),
|
||||
&slen);
|
||||
if ( len == SOCKET_ERROR )
|
||||
{
|
||||
int err = getErrno();
|
||||
if ( err != EWOULDBLOCK )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", Error calling recvfrom: " << err);
|
||||
}
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
ErrLog (<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", No data calling recvfrom: len=" << len);
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if (len+1 >= UDP_BUFFER_SIZE)
|
||||
{
|
||||
InfoLog(<<"MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", Datagram exceeded max length "<<UDP_BUFFER_SIZE);
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if(buffer.get() != 0)
|
||||
{
|
||||
UInt64 now = Timer::getTimeMs();
|
||||
RtpHeader* rtpHeader = (RtpHeader*)buffer.get();
|
||||
//InfoLog(<< "Received a datagram of size=" << len << " from=" << tuple);
|
||||
MediaEndpoint* pReceivingEndpoint = 0;
|
||||
MediaEndpoint* pSendingEndpoint = 0;
|
||||
|
||||
// First check if packet is from first endpoint
|
||||
if(tuple == relayPort->mFirstEndpoint.mTuple)
|
||||
{
|
||||
pReceivingEndpoint = &relayPort->mFirstEndpoint;
|
||||
pSendingEndpoint = &relayPort->mSecondEndpoint;
|
||||
}
|
||||
// Next check if packet is from second endpoint
|
||||
else if(tuple == relayPort->mSecondEndpoint.mTuple)
|
||||
{
|
||||
pReceivingEndpoint = &relayPort->mSecondEndpoint;
|
||||
pSendingEndpoint = &relayPort->mFirstEndpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// See if we can store this new sender in First Endpoint
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", First packet received from First Endpoint " << tuple);
|
||||
pReceivingEndpoint = &relayPort->mFirstEndpoint;
|
||||
pSendingEndpoint = &relayPort->mSecondEndpoint;
|
||||
}
|
||||
else if(relayPort->mSecondEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", First packet received from Second Endpoint " << tuple);
|
||||
pReceivingEndpoint = &relayPort->mSecondEndpoint;
|
||||
pSendingEndpoint = &relayPort->mFirstEndpoint;
|
||||
}
|
||||
else // We already have 2 endpoints - this would be a third
|
||||
{
|
||||
// We have a third sender - for now drop, if one of the other senders stops sending data for 2 seconds then we will start picking up this sender
|
||||
WarningLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", MediaRelay on " << relayPort->mLocalV4Tuple.getPort() << " has seen a third sender " << tuple << " - not implemented yet - ignoring packet");
|
||||
}
|
||||
if(pReceivingEndpoint)
|
||||
{
|
||||
pReceivingEndpoint->mTuple = tuple;
|
||||
pReceivingEndpoint->mSendTimeMs = now;
|
||||
pReceivingEndpoint->mRecvTimeMs = now;
|
||||
}
|
||||
}
|
||||
|
||||
if(pReceivingEndpoint)
|
||||
{
|
||||
pReceivingEndpoint->mRecvTimeMs = now;
|
||||
if(pSendingEndpoint && pSendingEndpoint->mTuple.getPort() != 0)
|
||||
{
|
||||
if(ntohs(rtpHeader->versionExtPayloadTypeAndMarker) & 0x8000) // RTP Version 2
|
||||
{
|
||||
// Adjust ssrc
|
||||
rtpHeader->ssrc = pSendingEndpoint->mSsrc;
|
||||
|
||||
// relay packet to second sender
|
||||
resip_assert(pSendingEndpoint->mRelayDatagram.get() == 0);
|
||||
pSendingEndpoint->mRelayDatagram = buffer;
|
||||
pSendingEndpoint->mRelayDatagramLen = len;
|
||||
if(pSendingEndpoint->mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", received packet to forward, turning off keepalive mode for " << pSendingEndpoint->mTuple);
|
||||
pSendingEndpoint->mKeepaliveMode = false;
|
||||
}
|
||||
|
||||
//InfoLog(<< "Relaying packet from=" << tuple << " to " << pSendingEndpoint->mTuple);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", discarding received packet with unknown RTP version from " << tuple);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
#if !defined(MediaRelay_hxx)
|
||||
#define MediaRelay_hxx
|
||||
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/ThreadIf.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
#include "MediaRelayPort.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class MediaRelay : public resip::ThreadIf
|
||||
{
|
||||
public:
|
||||
MediaRelay(bool isV6Avail, unsigned short portRangeMin, unsigned short portRangeMax);
|
||||
virtual ~MediaRelay();
|
||||
|
||||
bool createRelay(unsigned short& port);
|
||||
void destroyRelay(unsigned short port);
|
||||
|
||||
void primeNextEndpoint(unsigned short& port, resip::Tuple& destinationIPPort);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
void checkKeepalives(MediaRelayPort* relayPort);
|
||||
void process(resip::FdSet& fdset);
|
||||
bool processWrites(resip::FdSet& fdset, MediaRelayPort* relayPort); // return true if all writes are complete
|
||||
void processReads(resip::FdSet& fdset, MediaRelayPort* relayPort);
|
||||
|
||||
bool createRelayImpl(unsigned short& port);
|
||||
resip::Socket createRelaySocket(resip::Tuple& tuple);
|
||||
|
||||
typedef std::map<unsigned short, MediaRelayPort*> RelayPortList;
|
||||
RelayPortList mRelays;
|
||||
resip::Mutex mRelaysMutex;
|
||||
bool mIsV6Avail;
|
||||
|
||||
std::deque<unsigned int> mFreeRelayPortList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
//#include <rutil/DnsUtil.hxx>
|
||||
//#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "MediaRelayPort.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
MediaRelayPort::MediaRelayPort() : mV4Fd(INVALID_SOCKET), mV6Fd(INVALID_SOCKET)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple, resip::Socket& v6fd, resip::Tuple& v6tuple) :
|
||||
mV4Fd(v4fd), mLocalV4Tuple(v4tuple),
|
||||
mV6Fd(v6fd), mLocalV6Tuple(v6tuple)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple) :
|
||||
mV4Fd(v4fd), mLocalV4Tuple(v4tuple),
|
||||
mV6Fd(INVALID_SOCKET)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::~MediaRelayPort()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
if(mV4Fd != INVALID_SOCKET) closesocket(mV4Fd);
|
||||
if(mV6Fd != INVALID_SOCKET) closesocket(mV6Fd);
|
||||
#else
|
||||
if(mV4Fd != INVALID_SOCKET) close(mV4Fd);
|
||||
if(mV6Fd != INVALID_SOCKET) close(mV6Fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
#if !defined(MediaRelayPort_hxx)
|
||||
#define MediaRelayPort_hxx
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Random.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class MediaEndpoint
|
||||
{
|
||||
public:
|
||||
MediaEndpoint() : mSsrc(resip::Random::getRandom()), mRelayDatagramLen(0), mSendTimeMs(0), mRecvTimeMs(0), mKeepaliveMode(false) {}
|
||||
|
||||
resip::Tuple mTuple;
|
||||
unsigned int mSsrc;
|
||||
std::auto_ptr<char> mRelayDatagram;
|
||||
int mRelayDatagramLen;
|
||||
UInt64 mSendTimeMs;
|
||||
UInt64 mRecvTimeMs;
|
||||
bool mKeepaliveMode;
|
||||
|
||||
void reset()
|
||||
{
|
||||
mTuple = resip::Tuple();
|
||||
mRelayDatagram.release();
|
||||
mRelayDatagramLen = 0;
|
||||
mKeepaliveMode = false;
|
||||
}
|
||||
};
|
||||
|
||||
class MediaRelayPort
|
||||
{
|
||||
public:
|
||||
MediaRelayPort();
|
||||
MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple, resip::Socket& v6fd, resip::Tuple& v6tuple);
|
||||
MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple);
|
||||
~MediaRelayPort();
|
||||
|
||||
// V4 and V6 fd's and tuples
|
||||
resip::Socket mV4Fd;
|
||||
resip::Tuple mLocalV4Tuple;
|
||||
|
||||
resip::Socket mV6Fd;
|
||||
resip::Tuple mLocalV6Tuple;
|
||||
|
||||
// Sender data
|
||||
MediaEndpoint mFirstEndpoint;
|
||||
MediaEndpoint mSecondEndpoint;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,360 +0,0 @@
|
|||
#if !defined(Server_hxx)
|
||||
#define Server_hxx
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <resip/stack/TransactionUser.hxx>
|
||||
#include <resip/stack/InterruptableStackThread.hxx>
|
||||
#include <rutil/SelectInterruptor.hxx>
|
||||
#include <resip/stack/UdpTransport.hxx>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <resip/dum/DumShutdownHandler.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/OutOfDialogHandler.hxx>
|
||||
#include <resip/dum/RedirectHandler.hxx>
|
||||
#include <resip/dum/SubscriptionHandler.hxx>
|
||||
#include <resip/dum/RegistrationHandler.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <rutil/Mutex.hxx>
|
||||
|
||||
#include "ConfigParser.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
#include "SipRegistration.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "MediaRelay.hxx"
|
||||
#include "IChatIPPortData.hxx"
|
||||
#include "IPCThread.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
#define SDP_ICHATGW_ORIGIN_USER "iChat-gw"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class ShutdownCmd;
|
||||
class B2BSession;
|
||||
|
||||
class Server : public ConfigParser,
|
||||
public IPCHandler,
|
||||
public resip::DumShutdownHandler,
|
||||
public resip::InviteSessionHandler,
|
||||
public resip::DialogSetHandler,
|
||||
public resip::OutOfDialogHandler,
|
||||
public resip::RedirectHandler,
|
||||
public resip::ClientSubscriptionHandler,
|
||||
public resip::ServerSubscriptionHandler,
|
||||
public resip::ClientRegistrationHandler,
|
||||
public resip::ExternalUnknownDatagramHandler
|
||||
{
|
||||
public:
|
||||
Server(int argc, char** argv);
|
||||
virtual ~Server();
|
||||
|
||||
/**
|
||||
Starts the SIP stack thread.
|
||||
|
||||
@note This should be called before calling process() in a loop
|
||||
*/
|
||||
void startup();
|
||||
|
||||
/**
|
||||
This should be called in a loop to give process cycles to the server.
|
||||
|
||||
@param timeoutMs Will return after timeoutMs if nothing to do.
|
||||
Application can do some work, but should call
|
||||
process again ASAP.
|
||||
*/
|
||||
void process(int timeoutMs); // call this in a loop
|
||||
|
||||
/**
|
||||
Used to initiate a shutdown of the server. This function blocks
|
||||
until the shutdown is complete.
|
||||
|
||||
@note There should not be an active process request when this
|
||||
is called.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
// Utility Methods ////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
SubsystemAll,
|
||||
SubsystemContents,
|
||||
SubsystemDns,
|
||||
SubsystemDum,
|
||||
SubsystemSdp,
|
||||
SubsystemSip,
|
||||
SubsystemTransaction,
|
||||
SubsystemTransport,
|
||||
SubsystemStats,
|
||||
SubsystemGateway
|
||||
} LoggingSubsystem;
|
||||
|
||||
/**
|
||||
Static method that sets the logging level for a particular subsystem,
|
||||
or all subsystems.
|
||||
|
||||
@param level Logging level to set
|
||||
@param subsystem Subsystem to set level on
|
||||
|
||||
@note: Use Server::SubsystemAll to set the logging level on all
|
||||
subsystems
|
||||
*/
|
||||
static void setLogLevel(resip::Log::Level level, LoggingSubsystem subsystem=SubsystemAll);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify SIP side of iChat call request.
|
||||
|
||||
@param to Bare JID of endpoint we are proceeding to ring
|
||||
@param from Full JID of endpoint requesting the call
|
||||
*/
|
||||
void notifyIChatCallRequest(const std::string& to, const std::string& from);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify SIP side of cancelled iChat call request.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
*/
|
||||
void notifyIChatCallCancelled(const B2BSessionHandle& handle);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call is proceeding.
|
||||
This call will cause a timeout timer to be deactiviated.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param to Full JID of endpoint we are proceeding to ring
|
||||
*/
|
||||
void notifyIChatCallProceeding(const B2BSessionHandle& handle, const std::string& to);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call has failed.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param statusCode Code representing the reason for the failure
|
||||
*/
|
||||
void notifyIChatCallFailed(const B2BSessionHandle& handle, unsigned int statusCode);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call setup
|
||||
has completed on the Jabber side, and that it now needs to continue via SIP.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param remoteIPPortListBlob List of transports received from the iChat client via
|
||||
Jabber messaging - in proprietary iChat blob format
|
||||
*/
|
||||
void continueIChatCall(const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to request that a jabber user be registered on the
|
||||
configured SIP server. Note: The jabber user's JID is first transformed into a
|
||||
SIP URI using the configured translation rules. Note: calling this multiple times
|
||||
with the same jidToRegister is safe and will result in a no op.
|
||||
|
||||
@param jidToRegister - Jabber user's JID to register on the SIP server.
|
||||
*/
|
||||
void sipRegisterJabberUser(const std::string& jidToRegister);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to request that a jabber user be unregistered from the
|
||||
configured SIP server. Note: The jabber user's JID is first transformed into a
|
||||
SIP URI using the configured translation rules.
|
||||
|
||||
@param jidToUnregister - Jabber user's JID to unregister from the SIP server.
|
||||
*/
|
||||
void sipUnregisterJabberUser(const std::string& jidToUnregister);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to check if the JID to be subscribed will pass the
|
||||
translation rules.
|
||||
|
||||
@param to - JID of address being subscribed to
|
||||
@param from - JID of subscriber
|
||||
*/
|
||||
void checkSubscription(const std::string& to, const std::string& from);
|
||||
|
||||
B2BSession* findMatchingIChatB2BSession(const resip::SipMessage& msg);
|
||||
|
||||
protected:
|
||||
resip::SharedPtr<resip::MasterProfile>& getMasterProfile() { return mProfile; }
|
||||
bool translateAddress(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
// IPC Handler
|
||||
virtual void onNewIPCMsg(const IPCMsg& msg);
|
||||
|
||||
// External Unknown Packet Handler//////////////////////////////////////////////
|
||||
virtual void operator()(resip::UdpTransport* transport, const resip::Tuple& source, std::auto_ptr<resip::Data> unknownPacket);
|
||||
|
||||
// Shutdown Handler ////////////////////////////////////////////////////////////
|
||||
void onDumCanBeDeleted();
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
// ServerSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onNewSubscriptionFromRefer(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onRefresh(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onTerminated(resip::ServerSubscriptionHandle);
|
||||
virtual void onReadyToSend(resip::ServerSubscriptionHandle, resip::SipMessage&);
|
||||
virtual void onNotifyRejected(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onExpiredByClient(resip::ServerSubscriptionHandle, const resip::SipMessage& sub, resip::SipMessage& notify);
|
||||
virtual void onExpired(resip::ServerSubscriptionHandle, resip::SipMessage& notify);
|
||||
virtual bool hasDefaultExpires() const;
|
||||
virtual UInt32 getDefaultExpires() const;
|
||||
|
||||
// OutOfDialogHandler //////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onReceivedRequest(resip::ServerOutOfDialogReqHandle, const resip::SipMessage& request);
|
||||
|
||||
// RedirectHandler /////////////////////////////////////////////////////////////
|
||||
virtual void onRedirectReceived(resip::AppDialogSetHandle, const resip::SipMessage& response);
|
||||
virtual bool onTryingNextTarget(resip::AppDialogSetHandle, const resip::SipMessage& request);
|
||||
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg);
|
||||
|
||||
private:
|
||||
friend class ShutdownCmd;
|
||||
friend class B2BSession;
|
||||
friend class IChatCallTimeout;
|
||||
|
||||
resip::DialogUsageManager& getDialogUsageManager();
|
||||
|
||||
void post(resip::ApplicationMessage& message, unsigned int ms=0);
|
||||
void shutdownImpl();
|
||||
|
||||
friend class NotifyIChatCallRequestCmd;
|
||||
void notifyIChatCallRequestImpl(const std::string& to, const std::string& from);
|
||||
friend class NotifyIChatCallCancelledCmd;
|
||||
void notifyIChatCallCancelledImpl(const B2BSessionHandle& handle);
|
||||
friend class NotifyIChatCallProceedingCmd;
|
||||
void notifyIChatCallProceedingImpl(const B2BSessionHandle& handle, const std::string& to);
|
||||
friend class NotifyIChatCallFailedCmd;
|
||||
void notifyIChatCallFailedImpl(const B2BSessionHandle& handle, unsigned int statusCode);
|
||||
friend class ContinueIChatCallCmd;
|
||||
void continueIChatCallImpl(const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob);
|
||||
friend class SipRegisterJabberUserCmd;
|
||||
void sipRegisterJabberUserImpl(const std::string& jidToRegister);
|
||||
friend class SipUnregisterJabberUserCmd;
|
||||
void sipUnregisterJabberUserImpl(const std::string& jidToUnregister);
|
||||
|
||||
resip::SharedPtr<resip::MasterProfile> mProfile;
|
||||
resip::Security* mSecurity;
|
||||
resip::SelectInterruptor mSelectInterruptor;
|
||||
resip::SipStack mStack;
|
||||
resip::DialogUsageManager mDum;
|
||||
resip::InterruptableStackThread mStackThread;
|
||||
volatile bool mDumShutdown;
|
||||
|
||||
typedef std::map<B2BSessionHandle, B2BSession*> B2BSessionMap;
|
||||
B2BSessionMap mB2BSessions;
|
||||
B2BSessionHandle mCurrentB2BSessionHandle;
|
||||
B2BSession* getB2BSession(const B2BSessionHandle& handle) const;
|
||||
B2BSessionHandle registerB2BSession(B2BSession *);
|
||||
void unregisterB2BSession(const B2BSessionHandle& handle);
|
||||
|
||||
friend class SipRegistration;
|
||||
typedef std::map<resip::Uri, SipRegistration*> RegistrationMap;
|
||||
RegistrationMap mRegistrations;
|
||||
void registerRegistration(SipRegistration *);
|
||||
void unregisterRegistration(SipRegistration *);
|
||||
|
||||
bool mIsV6Avail;
|
||||
IChatIPPortData mLocalIPPortData;
|
||||
|
||||
MediaRelay* mMediaRelay;
|
||||
|
||||
IPCThread* mIPCThread;
|
||||
|
||||
AddressTranslator mAddressTranslator;
|
||||
std::map<resip::DialogSetId,B2BSession*> mActiveSessions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
#include "Server.hxx"
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "SipRegistration.hxx"
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/ClientRegistration.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
SipRegistration::SipRegistration(Server& server, DialogUsageManager& dum, Uri& aor)
|
||||
: AppDialogSet(dum),
|
||||
mServer(server),
|
||||
mDum(dum),
|
||||
mAor(aor),
|
||||
mEnded(false)
|
||||
{
|
||||
mServer.registerRegistration(this);
|
||||
}
|
||||
|
||||
SipRegistration::~SipRegistration()
|
||||
{
|
||||
mServer.unregisterRegistration(this);
|
||||
}
|
||||
|
||||
const resip::Uri&
|
||||
SipRegistration::getAor()
|
||||
{
|
||||
return mAor;
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::end()
|
||||
{
|
||||
if(!mEnded)
|
||||
{
|
||||
mEnded = true;
|
||||
if(mRegistrationHandle.isValid())
|
||||
{
|
||||
try
|
||||
{
|
||||
// If ended - then just shutdown registration - likely due to shutdown
|
||||
mRegistrationHandle->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NameAddrs&
|
||||
SipRegistration::getContactAddresses()
|
||||
{
|
||||
static NameAddrs empty;
|
||||
if(mRegistrationHandle.isValid())
|
||||
{
|
||||
return mRegistrationHandle->allContacts(); // .slg. note: myContacts is not sufficient, since they do not contain the stack populated transport address
|
||||
}
|
||||
else
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
SipRegistration::onSuccess(ClientRegistrationHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onSuccess(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
if(!mEnded)
|
||||
{
|
||||
mRegistrationHandle = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// If ended - then just shutdown registration - likely due to shutdown
|
||||
h->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::onFailure(ClientRegistrationHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onFailure(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
if(!mEnded)
|
||||
{
|
||||
mRegistrationHandle = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we don't have a handle - then just shutdown registration - likely due to shutdown
|
||||
h->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::onRemoved(ClientRegistrationHandle h, const SipMessage&msg)
|
||||
{
|
||||
InfoLog(<< "onRemoved(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
}
|
||||
|
||||
int
|
||||
SipRegistration::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onRequestRetry(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
return -1; // Let Profile retry setting take effect
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
#if !defined(SipRegistration_hxx)
|
||||
#define SipRegistration_hxx
|
||||
|
||||
#include <resip/dum/AppDialogSet.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/SubscriptionHandler.hxx>
|
||||
|
||||
#include "Server.hxx"
|
||||
|
||||
namespace resip
|
||||
{
|
||||
class DialogUsageManager;
|
||||
class SipMessage;
|
||||
}
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
class Server;
|
||||
|
||||
/**
|
||||
This class is used to manage active SIP registrations.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class SipRegistration : public resip::AppDialogSet
|
||||
{
|
||||
public:
|
||||
SipRegistration(Server& server, resip::DialogUsageManager& dum, resip::Uri& aor);
|
||||
virtual ~SipRegistration();
|
||||
|
||||
virtual void end();
|
||||
|
||||
const resip::Uri& getAor();
|
||||
const resip::NameAddrs& getContactAddresses();
|
||||
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg);
|
||||
|
||||
private:
|
||||
Server &mServer;
|
||||
resip::DialogUsageManager &mDum;
|
||||
resip::Uri mAor;
|
||||
bool mEnded;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include "Thread.hxx"
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <time.h>
|
||||
#include <process.h> // for _beginthreadex()
|
||||
typedef unsigned(__stdcall *THREAD_START_ROUTINE)(void*);
|
||||
#endif
|
||||
|
||||
#include "rutil/ResipAssert.h"
|
||||
#include <iostream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void*
|
||||
#ifdef WIN32
|
||||
__stdcall
|
||||
#endif
|
||||
threadWrapper( void* parm )
|
||||
{
|
||||
resip_assert( parm );
|
||||
Thread* t = static_cast < Thread* > ( parm );
|
||||
|
||||
resip_assert( t );
|
||||
t->thread();
|
||||
#ifdef WIN32
|
||||
_endthreadex(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Thread::Thread() :
|
||||
#ifdef WIN32
|
||||
mThread(0),
|
||||
#endif
|
||||
mId(0), mShutdown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
shutdown();
|
||||
join();
|
||||
}
|
||||
|
||||
void
|
||||
Thread::run()
|
||||
{
|
||||
resip_assert(mId == 0);
|
||||
|
||||
#if defined(WIN32)
|
||||
mThread =
|
||||
(HANDLE)_beginthreadex
|
||||
(
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
|
||||
0, // DWORD dwStackSize, // initial thread stack size
|
||||
THREAD_START_ROUTINE
|
||||
(threadWrapper), // LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
|
||||
this, //LPVOID lpParameter, // argument for new thread
|
||||
0, //DWORD dwCreationFlags, // creation flags
|
||||
&mId// LPDWORD lpThreadId // pointer to receive thread ID
|
||||
);
|
||||
resip_assert( mThread != 0 );
|
||||
#else
|
||||
// spawn the thread
|
||||
if ( int retval = pthread_create( &mId, 0, threadWrapper, this) )
|
||||
{
|
||||
std::cerr << "Failed to spawn thread: " << retval << std::endl;
|
||||
resip_assert(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Thread::join()
|
||||
{
|
||||
if (mId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
DWORD exitCode;
|
||||
while (true)
|
||||
{
|
||||
if (GetExitCodeThread(mThread,&exitCode) != 0)
|
||||
{
|
||||
if (exitCode != STILL_ACTIVE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(mThread,INFINITE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(mThread);
|
||||
mThread=0;
|
||||
#else
|
||||
void* stat;
|
||||
if (mId != pthread_self())
|
||||
{
|
||||
int r = pthread_join( mId , &stat );
|
||||
if ( r != 0 )
|
||||
{
|
||||
cerr << "Internal error: pthread_join() returned " << r << endl;
|
||||
resip_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
mId = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Thread::shutdown()
|
||||
{
|
||||
mShutdown = true;
|
||||
}
|
||||
|
||||
bool
|
||||
Thread::isShutdown() const
|
||||
{
|
||||
return mShutdown;
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
#if !defined(Thread_hxx)
|
||||
#define Thread_hxx
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# include <winsock2.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread();
|
||||
virtual ~Thread();
|
||||
|
||||
virtual void run();
|
||||
void join();
|
||||
virtual void shutdown();
|
||||
bool isShutdown() const;
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned int Id;
|
||||
#else
|
||||
typedef pthread_t Id;
|
||||
#endif
|
||||
|
||||
virtual void thread() = 0;
|
||||
|
||||
protected:
|
||||
#ifdef WIN32
|
||||
HANDLE mThread;
|
||||
#endif
|
||||
Id mId;
|
||||
volatile bool mShutdown;
|
||||
|
||||
private:
|
||||
// Suppress copying
|
||||
Thread(const Thread &);
|
||||
const Thread & operator=(const Thread &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#define ICHATGW_VERSION_STRING "0.1"
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,154 +0,0 @@
|
|||
########################################################
|
||||
# ichat-gw configuration file
|
||||
########################################################
|
||||
|
||||
|
||||
########################################################
|
||||
# SIP settings
|
||||
########################################################
|
||||
|
||||
# Local IP Address to bind SIP transports to. If left blank
|
||||
# ichat-gw will bind to all adapters.
|
||||
#IPAddress = 192.168.1.106
|
||||
#IPAddress = 2001:5c0:1000:a::6d
|
||||
IPAddress =
|
||||
|
||||
# Comma separated list of DNS servers, overrides default OS detected list (leave blank for default)
|
||||
DNSServers =
|
||||
|
||||
# Used in From header of SIP calls, when caller is unknown. Value must be a valid formatted SIP
|
||||
# NameAddr. Ie. “{displayname}” <{SIP URI}>. Currently this setting is only used when
|
||||
# calling iChat endpoints and is never displayed to the end user.
|
||||
SIPGatewayIdentity = "iChat-gw" <sip:ichat-gw@blitzzgod.com>
|
||||
|
||||
# Local port to listen on for SIP messages over UDP or TCP
|
||||
UDPTCPPort = 5070
|
||||
|
||||
# Local port to listen on for SIP messages over TLS
|
||||
TLSPort = 5071
|
||||
|
||||
# TLS domain name for this server (note: domain cert for this domain must be present)
|
||||
TLSDomain =
|
||||
|
||||
# Enable/Disable TCP/UDP CRLFCRLF keepalive packets for SIP endpoints
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
KeepAlives = enable
|
||||
|
||||
# URI of a proxy server to use a SIP outbound proxy. This setting should not be required if
|
||||
# proper DNS based SIP routing is operational.
|
||||
OutboundProxy =
|
||||
|
||||
# SIP Registration Time - the requested amount of seconds between SIP re-registration requests
|
||||
# Set to 0, to instruct the iChat gateway not to perform any registrations
|
||||
RegistrationTime = 3600
|
||||
|
||||
# SIP Registration Retry Time - the requested amount of seconds between retrying SIP registration
|
||||
# requests after a registration failure.
|
||||
RegistrationRetryTime = 120
|
||||
|
||||
|
||||
########################################################
|
||||
# General settings
|
||||
########################################################
|
||||
|
||||
# Logging level: NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK
|
||||
LogLevel = INFO
|
||||
|
||||
# Log Filename
|
||||
LogFilename = ichat-gw.log
|
||||
|
||||
# Log file Max Lines
|
||||
LogFileMaxLines = 50000
|
||||
|
||||
# Gateway IPC Port - for IPC UDP socket bound to 127.0.0.1
|
||||
GatewayIPCPort = 2078
|
||||
|
||||
# Jabber Connector IPC Port - for IPC UDP socket bound to 127.0.0.1
|
||||
JabberConnectorIPCPort = 2079
|
||||
|
||||
# Timeout for obtaining iChat Resources when an iChat user is called.
|
||||
IChatProceedingTimeout = 5000
|
||||
|
||||
# If enabled then any time an IChat endpoint is involved then the media relay will be used.
|
||||
# If disabled then the media relay is only used if iChat is originator of a Click-to-dial call.
|
||||
# Note: The media relay MUST be used to perform RTP IPV4<->IPV6 translation and to avoid
|
||||
# media stream timeout during a SIP phone hold.
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
AlwaysRelayIChatMedia = true
|
||||
|
||||
# Prefer IPv6 over IPv4 - this setting controls which IP address we select when presented
|
||||
# with the list of IP addresses for an iChat endpoint
|
||||
PreferIPv6 = true
|
||||
|
||||
# Comma separated codec ID filter list - specifies non-interopable codecs that should
|
||||
# be filtered from Sdp Offers.
|
||||
# Note: Default is 3 (GSM), since it has proven non-interopable between iChat and SNOM phones
|
||||
CodecIdFilterList = 3
|
||||
|
||||
# Media relay port range min/max settings. These settings define the range of ports that will be used
|
||||
# by the media relay.
|
||||
MediaRelayPortRangeMin = 8000
|
||||
MediaRelayPortRangeMax = 9999
|
||||
|
||||
|
||||
########################################################
|
||||
# Jabber settings
|
||||
########################################################
|
||||
|
||||
# Hostname or IP address of the Jabber server to connect to
|
||||
JabberServer = jabber.blitzzgod.com
|
||||
|
||||
# Identity of this component - note: domain suffix should match Jabber server domain
|
||||
JabberComponentName = ichat-gw.jabber.blitzzgod.com
|
||||
|
||||
# Jabber Component Password required in order to connect to Jabber server as a component
|
||||
JabberComponentPassword = password
|
||||
|
||||
# Jabber Component Port - port on Jabber server that accepts component connections
|
||||
JabberComponentPort = 5275
|
||||
|
||||
# Duration between Jabber ping messages sent to the server, in order to keep the component connection alive
|
||||
JabberServerPingDuration = 60
|
||||
|
||||
# Username for the iChat Gateway control user - Note: iChat users of the Gateway must add this user to their roster
|
||||
JabberControlUsername = control
|
||||
|
||||
|
||||
########################################################
|
||||
# Address Translation Rules (must be listed in pairs)
|
||||
########################################################
|
||||
|
||||
# Rule for mapping any sip address to appropriate jabber JID/domain
|
||||
TranslationPattern=^sip:(.*)@(.*)$
|
||||
TranslationOutput=xmpp:$1@jabber.blitzzgod.com
|
||||
|
||||
#Rule for mapping any xmpp address to appropriate SIP URI/domain
|
||||
TranslationPattern=^xmpp:(.*)@(.*)$
|
||||
TranslationOutput=sip:$1@blitzzgod.com
|
||||
|
||||
|
||||
########################################################
|
||||
# TLS Configurations
|
||||
########################################################
|
||||
|
||||
#Local path to DH Parameters file
|
||||
TLSDHParamsFilename =
|
||||
|
||||
# Local path to TLS Certificate
|
||||
TLSCertificate =
|
||||
|
||||
# Local path to Private key file
|
||||
TLSPrivateKey =
|
||||
|
||||
# Pass phrase of private key file (can be left blank)
|
||||
TLSPrivateKeyPassPhrase =
|
||||
|
||||
########################################################
|
||||
# iChat Jabber Connector Settings
|
||||
########################################################
|
||||
|
||||
# Path to iChat jabber connector (ichat-gw-jc) executable
|
||||
IchatJabberConnectorPath = ichat-gw-jc
|
||||
|
||||
#For Windows
|
||||
#IchatJabberConnectorPath = ichat-gw-jc.exe
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue