📄 helper.cxx
字号:
#if defined(HAVE_CONFIG_H)
#include "resip/stack/config.hxx"
#endif
#include <string.h>
#include <iomanip>
#include <algorithm>
#include <memory>
#include "resip/stack/Auth.hxx"
#include "resip/stack/BasicNonceHelper.hxx"
#include "resip/stack/Helper.hxx"
#include "resip/stack/NonceHelper.hxx"
#include "rutil/Coders.hxx"
#include "resip/stack/Uri.hxx"
#include "rutil/Logger.hxx"
#include "rutil/Random.hxx"
#include "rutil/Timer.hxx"
#include "rutil/DataStream.hxx"
#include "rutil/MD5Stream.hxx"
#include "rutil/DnsUtil.hxx"
#include "rutil/compat.hxx"
#include "rutil/ParseBuffer.hxx"
#include "resip/stack/SipMessage.hxx"
#include "resip/stack/Security.hxx"
//#include "resip/stack/SecurityAttributes.hxx"
//#include "resip/stack/Contents.hxx"
#include "resip/stack/Pkcs7Contents.hxx"
#include "resip/stack/MultipartSignedContents.hxx"
#include "resip/stack/MultipartMixedContents.hxx"
#include "resip/stack/MultipartAlternativeContents.hxx"
#include "rutil/WinLeakCheck.hxx"
using namespace resip;
using namespace std;
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
const int Helper::tagSize = 4;
// !jf! this should be settable by the application in case a group of apps
// (e.g. proxies) want to share the same secret
Helper::NonceHelperPtr Helper::mNonceHelperPtr;
SipMessage*
Helper::makeRequest(const NameAddr& target, const NameAddr& from, const NameAddr& contact, MethodTypes method)
{
SipMessage* request = new SipMessage;
RequestLine rLine(method);
rLine.uri() = target.uri();
request->header(h_To) = target;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = method;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = from;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_Contacts).push_back(contact);
request->header(h_CallId).value() = Helper::computeCallId();
//request->header(h_ContentLength).value() = 0;
Via via;
request->header(h_Vias).push_back(via);
return request;
}
SipMessage*
Helper::makeRequest(const NameAddr& target, const NameAddr& from, MethodTypes method)
{
NameAddr contact;
return makeRequest(target, from, contact, method);
}
SipMessage*
Helper::makeRegister(const NameAddr& to, const NameAddr& from)
{
NameAddr contact;
return makeRegister(to, from, contact);
}
SipMessage*
Helper::makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& contact)
{
SipMessage* request = new SipMessage;
RequestLine rLine(REGISTER);
rLine.uri().scheme() = to.uri().scheme();
rLine.uri().host() = to.uri().host();
rLine.uri().port() = to.uri().port();
if (to.uri().exists(p_transport))
{
rLine.uri().param(p_transport) = to.uri().param(p_transport);
}
request->header(h_To) = to;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = REGISTER;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = from;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_CallId).value() = Helper::computeCallId();
assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty());
request->header(h_Contacts).push_back( contact );
Via via;
request->header(h_Vias).push_back(via);
return request;
}
SipMessage*
Helper::makeRegister(const NameAddr& to,const Data& transport)
{
NameAddr contact;
return makeRegister(to, transport, contact);
}
SipMessage*
Helper::makeRegister(const NameAddr& to, const Data& transport, const NameAddr& contact)
{
SipMessage* request = new SipMessage;
RequestLine rLine(REGISTER);
rLine.uri().scheme() = to.uri().scheme();
rLine.uri().host() = to.uri().host();
rLine.uri().port() = to.uri().port();
if (!transport.empty())
{
rLine.uri().param(p_transport) = transport;
}
request->header(h_To) = to;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = REGISTER;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = to;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_CallId).value() = Helper::computeCallId();
assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty());
request->header(h_Contacts).push_back( contact );
Via via;
request->header(h_Vias).push_back(via);
return request;
}
SipMessage*
Helper::makePublish(const NameAddr& target, const NameAddr& from)
{
NameAddr contact;
return makePublish(target, from, contact);
}
SipMessage*
Helper::makePublish(const NameAddr& target, const NameAddr& from, const NameAddr& contact)
{
SipMessage* request = new SipMessage;
RequestLine rLine(PUBLISH);
rLine.uri() = target.uri();
request->header(h_To) = target;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = PUBLISH;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = from;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_CallId).value() = Helper::computeCallId();
assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty());
request->header(h_Contacts).push_back( contact );
Via via;
request->header(h_Vias).push_back(via);
return request;
}
SipMessage*
Helper::makeMessage(const NameAddr& target, const NameAddr& from)
{
NameAddr contact;
return makeMessage(target, from, contact);
}
SipMessage*
Helper::makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr& contact)
{
SipMessage* request = new SipMessage;
RequestLine rLine(MESSAGE);
rLine.uri() = target.uri();
request->header(h_To) = target;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = MESSAGE;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = from;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_CallId).value() = Helper::computeCallId();
assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty());
request->header(h_Contacts).push_back( contact );
Via via;
request->header(h_Vias).push_back(via);
return request;
}
SipMessage*
Helper::makeSubscribe(const NameAddr& target, const NameAddr& from)
{
NameAddr contact;
return makeSubscribe(target, from, contact);
}
SipMessage*
Helper::makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAddr& contact)
{
SipMessage* request = new SipMessage;
RequestLine rLine(SUBSCRIBE);
rLine.uri() = target.uri();
request->header(h_To) = target;
request->header(h_RequestLine) = rLine;
request->header(h_MaxForwards).value() = 70;
request->header(h_CSeq).method() = SUBSCRIBE;
request->header(h_CSeq).sequence() = 1;
request->header(h_From) = from;
request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize);
request->header(h_CallId).value() = Helper::computeCallId();
assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty());
request->header(h_Contacts).push_front( contact );
Via via;
request->header(h_Vias).push_front(via);
return request;
}
int
Helper::jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum)
{
assert(upperPercentage >= lowerPercentage);
if (input < minimum)
{
return input;
}
else if (lowerPercentage == 100 && upperPercentage == 100)
{
return input;
}
else
{
const int rnd = Random::getRandom() % (upperPercentage-lowerPercentage) + lowerPercentage;
return (input * rnd) / 100;
}
}
SipMessage*
Helper::makeInvite(const NameAddr& target, const NameAddr& from)
{
return Helper::makeRequest(target, from, INVITE);
}
SipMessage*
Helper::makeInvite(const NameAddr& target, const NameAddr& from, const NameAddr& contact)
{
return Helper::makeRequest(target, from, contact, INVITE);
}
void
Helper::makeResponse(SipMessage& response,
const SipMessage& request,
int responseCode,
const NameAddr& myContact,
const Data& reason,
const Data& hostname,
const Data& warning)
{
makeResponse(response,request, responseCode, reason,hostname, warning);
// in general, this should not create a Contact header since only requests
// that create a dialog (or REGISTER requests) should produce a response with
// a contact(s).
response.header(h_Contacts).clear();
response.header(h_Contacts).push_back(myContact);
}
void
Helper::makeResponse(SipMessage& response,
const SipMessage& request,
int responseCode,
const Data& reason,
const Data& hostname,
const Data& warning)
{
DebugLog(<< "Helper::makeResponse(" << request.brief() << " code=" << responseCode << " reason=" << reason);
response.header(h_StatusLine).responseCode() = responseCode;
response.header(h_From) = request.header(h_From);
response.header(h_To) = request.header(h_To);
response.header(h_CallId) = request.header(h_CallId);
response.header(h_CSeq) = request.header(h_CSeq);
response.header(h_Vias) = request.header(h_Vias);
if (!warning.empty())
{
WarningCategory warn;
warn.code() = 499;
warn.hostname() = hostname;
warn.text() = warning;
response.header(h_Warnings).push_back(warn);
}
try
{
// Only generate a To: tag if one doesn't exist. Think Re-INVITE.
// No totag for failure responses or 100s
if (!response.header(h_To).exists(p_tag) && responseCode > 100)
{
response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize);
}
}
catch(resip::ParseBuffer::Exception&)
{
// !bwc! Can't add to-tag since To is malformed. Oh well, we tried.
}
response.setRFC2543TransactionId(request.getRFC2543TransactionId());
//response.header(h_ContentLength).value() = 0;
if (responseCode >= 180 && responseCode < 300 && request.exists(h_RecordRoutes))
{
response.header(h_RecordRoutes) = request.header(h_RecordRoutes);
}
// !bwc! If CSeq is malformed, basicCheck would have already attempted to
// parse it, meaning we won't throw here (we never try to parse the same
// thing twice, see LazyParser::checkParsed())
if (responseCode/100 == 2 &&
!response.exists(h_Contacts) &&
!(response.header(h_CSeq).method()==CANCEL) )
{
// in general, this should not create a Contact header since only requests
// that create a dialog (or REGISTER requests) should produce a response with
// a contact(s).
NameAddr contact;
response.header(h_Contacts).push_back(contact);
}
if (request.isExternal())
{
response.setFromTU();
}
else
{
response.setFromExternal();
}
if (reason.size())
{
response.header(h_StatusLine).reason() = reason;
}
else
{
getResponseCodeReason(responseCode, response.header(h_StatusLine).reason());
}
}
SipMessage*
Helper::makeResponse(const SipMessage& request,
int responseCode,
const NameAddr& myContact,
const Data& reason,
const Data& hostname,
const Data& warning)
{
// !bwc! Exception safety. Catch/rethrow is dicey because we can't rethrow
// resip::BaseException, since it is abstract.
std::auto_ptr<SipMessage> response(new SipMessage);
makeResponse(*response, request, responseCode, reason, hostname, warning);
// in general, this should not create a Contact header since only requests
// that create a dialog (or REGISTER requests) should produce a response with
// a contact(s).
response->header(h_Contacts).clear();
response->header(h_Contacts).push_back(myContact);
return response.release();
}
SipMessage*
Helper::makeResponse(const SipMessage& request,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -