|
reSIProcate/stack
9694
|
An aggregation of useful static functions. More...
#include <Helper.hxx>

Classes | |
| struct | ContentsSecAttrs |
| class | NonceHelperPtr |
Public Types | |
| enum | AuthResult { Failed = 1, Authenticated, Expired, BadlyFormed } |
| enum | FailureMessageEffect { DialogTermination, TransactionTermination, UsageTermination, RetryAfter, OptionalRetryAfter, ApplicationDependant } |
Static Public Member Functions | |
| template<typename T > | |
| static T | aBitSmallerThan (T secs) |
| Used by Registration, Publication and Subscription refreshes, to calculate the time at which a refresh should be performed (which is some time, that is a bit smaller than the Expiration interval). | |
| static void | integer2hex (char *_d, unsigned int _s, bool _l=true) |
| Converts an interger in a character string containing the hexidecimal representation of the integer. | |
| static unsigned int | hex2integer (const char *_s) |
| Converts a character string containing a hexidecimal value into an unsigned int. | |
| static int | jitterValue (int input, int lowerPercentage, int upperPercentage, int minimum=0) |
| Used to jitter the expires in a SUBSCRIBE or REGISTER expires header. | |
| static SipMessage * | makeInvite (const NameAddr &target, const NameAddr &from) |
| Make an invite request - Empty Contact and Via is added and will be populated by the stack when sent. | |
| static SipMessage * | makeInvite (const NameAddr &target, const NameAddr &from, const NameAddr &contact) |
| Make an invite request using a overridden contact header - Empty Via is added and will be populated by the stack when sent. | |
| static void | makeResponse (SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty) |
| Make a response to a provided request. | |
| static void | makeResponse (SipMessage &response, const SipMessage &request, int responseCode, const NameAddr &myContact, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty) |
| Make a response to a provided request with an overridden Contact. | |
| static SipMessage * | makeResponse (const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty) |
| Make a new response to a provided request. | |
| static SipMessage * | makeResponse (const SipMessage &request, int responseCode, const NameAddr &myContact, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty) |
| Make a new response to a provided request with an overridden Contact. | |
| static void | makeRawResponse (Data &rawBuffer, const SipMessage &request, int responseCode, const Data &additionalHeaders=Data::Empty, const Data &body=Data::Empty) |
| static SipMessage * | make405 (const SipMessage &request, const int *allowedMethods=0, int nMethods=-1) |
| Make a 405 response to a provided request. | |
| static void | getResponseCodeReason (int responseCode, Data &reason) |
| Returns the default reason string for a particular response code. | |
| static SipMessage * | makeRequest (const NameAddr &target, const NameAddr &from, const NameAddr &contact, MethodTypes method) |
| Make a new request with a overridden Contact. | |
| static SipMessage * | makeRequest (const NameAddr &target, const NameAddr &from, MethodTypes method) |
| Make a new request. | |
| static SipMessage * | makeCancel (const SipMessage &request) |
| Make a new Cancel request for the specified request. | |
| static SipMessage * | makeRegister (const NameAddr &to, const NameAddr &from, const NameAddr &contact) |
| Create a Register request with an overriden Contact. See makeRequest. | |
| static SipMessage * | makeRegister (const NameAddr &to, const NameAddr &from) |
| Create a Register request with an empty Contact. See makeRequest. | |
| static SipMessage * | makeRegister (const NameAddr &to, const Data &transport, const NameAddr &contact) |
| Create a Register request with an overriden Contact, transport is added to Request URI. See makeRequest. | |
| static SipMessage * | makeRegister (const NameAddr &to, const Data &transport) |
| Create a Register request with an empty Contact, transport is added to Request URI. See makeRequest. | |
| static SipMessage * | makeSubscribe (const NameAddr &target, const NameAddr &from, const NameAddr &contact) |
| Create a Subscribe request with an overriden Contact. See makeRequest. | |
| static SipMessage * | makeSubscribe (const NameAddr &target, const NameAddr &from) |
| Create a Subscribe request with an empty Contact. See makeRequest. | |
| static SipMessage * | makeMessage (const NameAddr &target, const NameAddr &from, const NameAddr &contact) |
| Create a Message request with an overriden Contact. See makeRequest. | |
| static SipMessage * | makeMessage (const NameAddr &target, const NameAddr &from) |
| Create a Message request with an empty Contact. See makeRequest. | |
| static SipMessage * | makePublish (const NameAddr &target, const NameAddr &from, const NameAddr &contact) |
| Create a Publish request with an overriden Contact. See makeRequest. | |
| static SipMessage * | makePublish (const NameAddr &target, const NameAddr &from) |
| Create a Publish request with an empty Contact. See makeRequest. | |
| static SipMessage * | makeFailureAck (const SipMessage &request, const SipMessage &response) |
| This interface should be used by the stack (TransactionState) to create an AckMsg to a failure response. | |
| static Data | computeUniqueBranch () |
| Creates and returns a unique branch parameter. | |
| static Data | computeProxyBranch (const SipMessage &request) |
| static Data | computeCallId () |
| static Data | computeTag (int numBytes) |
| static AuthResult | authenticateRequest (const SipMessage &request, const Data &realm, const Data &password, int expiresDelta=0) |
| static AuthResult | authenticateRequestWithA1 (const SipMessage &request, const Data &realm, const Data &hA1, int expiresDelta=0) |
| static std::pair< AuthResult, Data > | advancedAuthenticateRequest (const SipMessage &request, const Data &realm, const Data &a1, int expiresDelta=0, bool proxyAuthorization=true) |
| static SipMessage * | makeProxyChallenge (const SipMessage &request, const Data &realm, bool useAuth=true, bool stale=false) |
| static SipMessage * | makeWWWChallenge (const SipMessage &request, const Data &realm, bool useAuth=true, bool stale=false) |
| static SipMessage * | makeChallenge (const SipMessage &request, const Data &realm, bool useAuth=true, bool stale=false, bool proxy=false) |
| static Data | qopOption (const Auth &challenge) |
| static void | updateNonceCount (unsigned int &nonceCount, Data &nonceCountString) |
| static bool | algorithmAndQopSupported (const Auth &challenge) |
| static SipMessage & | addAuthorization (SipMessage &request, const SipMessage &challenge, const Data &username, const Data &password, const Data &cnonce, unsigned int &nonceCount) |
| static Auth | makeChallengeResponseAuth (const SipMessage &request, const Data &username, const Data &password, const Auth &challenge, const Data &cnonce, unsigned int &nonceCount, Data &nonceCountString) |
| static void | makeChallengeResponseAuth (const SipMessage &request, const Data &username, const Data &password, const Auth &challenge, const Data &cnonce, const Data &authQop, const Data &nonceCountString, Auth &auth) |
| static Auth | makeChallengeResponseAuthWithA1 (const SipMessage &request, const Data &username, const Data &passwordHashA1, const Auth &challenge, const Data &cnonce, unsigned int &nonceCount, Data &nonceCountString) |
| static void | makeChallengeResponseAuthWithA1 (const SipMessage &request, const Data &username, const Data &passwordHashA1, const Auth &challenge, const Data &cnonce, const Data &authQop, const Data &nonceCountString, Auth &auth) |
| static Data | makeResponseMD5WithA1 (const Data &a1, const Data &method, const Data &digestUri, const Data &nonce, const Data &qop=Data::Empty, const Data &cnonce=Data::Empty, const Data &cnonceCount=Data::Empty, const Contents *entityBody=0) |
| static Data | makeResponseMD5 (const Data &username, const Data &password, const Data &realm, const Data &method, const Data &digestUri, const Data &nonce, const Data &qop=Data::Empty, const Data &cnonce=Data::Empty, const Data &cnonceCount=Data::Empty, const Contents *entityBody=0) |
| static void | setNonceHelper (NonceHelper *nonceHelper) |
| Note: Helper assumes control of NonceHelper object and will delete when global scope is cleaned up. | |
| static NonceHelper * | getNonceHelper () |
| static Data | makeNonce (const SipMessage &request, const Data ×tamp) |
| static Uri | makeUri (const Data &aor, const Data &scheme=Symbols::DefaultSipScheme) |
| static void | processStrictRoute (SipMessage &request) |
| static int | getPortForReply (SipMessage &request) |
| static void | massageRoute (const SipMessage &request, NameAddr &route) |
| static Uri | fromAor (const Data &aor, const Data &scheme=Symbols::DefaultSipScheme) |
| static bool | validateMessage (const SipMessage &message, resip::Data *reason=0) |
| static Data | gruuUserPart (const Data &instanceId, const Data &aor, const Data &key) |
| static std::pair< Data, Data > | fromGruuUserPart (const Data &gruuUserPart, const Data &key) |
| static ContentsSecAttrs | extractFromPkcs7 (const SipMessage &message, Security &security) |
| static FailureMessageEffect | determineFailureMessageEffect (const SipMessage &response) |
| static std::auto_ptr< SdpContents > | getSdp (Contents *tree) |
| static bool | isClientBehindNAT (const SipMessage &request, bool privateToPublicOnly=true) |
| Looks at SIP headers and message source for a mismatch to make an assumption that the sender is behind a NAT device. | |
| static Tuple | getClientPublicAddress (const SipMessage &request) |
| Look at Via headers, and find the first public IP address closest to the sending client. | |
Static Public Attributes | |
| static const int | tagSize = 4 |
| bytes in to-tag& from-tag, should prob. live somewhere else | |
Static Private Attributes | |
| static NonceHelperPtr | mNonceHelperPtr |
An aggregation of useful static functions.
These are mostly involved with
Definition at line 43 of file Helper.hxx.
Definition at line 397 of file Helper.hxx.
{Failed = 1, Authenticated, Expired, BadlyFormed};
| DialogTermination | |
| TransactionTermination | |
| UsageTermination | |
| RetryAfter | |
| OptionalRetryAfter | |
| ApplicationDependant |
Definition at line 540 of file Helper.hxx.
| static T resip::Helper::aBitSmallerThan | ( | T | secs | ) | [inline, static] |
Used by Registration, Publication and Subscription refreshes, to calculate the time at which a refresh should be performed (which is some time, that is a bit smaller than the Expiration interval).
The recommended calculation from the RFC's is the minimnum of the Exipiration interval less 5 seconds and nine tenths of the exipiration interval.
Definition at line 59 of file Helper.hxx.
References resip::resipMax(), and resip::resipMin().
Referenced by main().

| SipMessage & Helper::addAuthorization | ( | SipMessage & | request, |
| const SipMessage & | challenge, | ||
| const Data & | username, | ||
| const Data & | password, | ||
| const Data & | cnonce, | ||
| unsigned int & | nonceCount | ||
| ) | [static] |
Definition at line 1565 of file Helper.cxx.
References resip::ParserContainer< T >::begin(), resip::Data::Empty, resip::ParserContainer< T >::end(), resip::SipMessage::exists(), resip::SipMessage::header(), and resip::SipMessage::isResponse().
Referenced by resip::TuIM::processRegisterResponse().
{
Data nonceCountString = Data::Empty;
assert(challenge.isResponse());
assert(challenge.header(h_StatusLine).responseCode() == 401 ||
challenge.header(h_StatusLine).responseCode() == 407);
if (challenge.exists(h_ProxyAuthenticates))
{
const ParserContainer<Auth>& auths = challenge.header(h_ProxyAuthenticates);
for (ParserContainer<Auth>::const_iterator i = auths.begin();
i != auths.end(); i++)
{
request.header(h_ProxyAuthorizations).push_back(makeChallengeResponseAuth(request, username, password, *i,
cnonce, nonceCount, nonceCountString));
}
}
if (challenge.exists(h_WWWAuthenticates))
{
const ParserContainer<Auth>& auths = challenge.header(h_WWWAuthenticates);
for (ParserContainer<Auth>::const_iterator i = auths.begin();
i != auths.end(); i++)
{
request.header(h_Authorizations).push_back(makeChallengeResponseAuth(request, username, password, *i,
cnonce, nonceCount, nonceCountString));
}
}
return request;
}

| std::pair< Helper::AuthResult, Data > Helper::advancedAuthenticateRequest | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| const Data & | a1, | ||
| int | expiresDelta = 0, |
||
| bool | proxyAuthorization = true |
||
| ) | [static] |
Definition at line 767 of file Helper.cxx.
References resip::Symbols::auth, resip::Symbols::authInt, resip::ParserContainer< T >::begin(), DebugLog, digest, resip::ParserContainer< T >::end(), resip::SipMessage::exists(), resip::SipMessage::getContents(), resip::NonceHelper::Nonce::getCreationTime(), resip::RequestLine::getMethod(), resip::Timer::getTimeSecs(), resip::SipMessage::header(), InfoLog, and resip::isEqualNoCase().
{
Data username;
DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta);
//DebugLog(<< request);
const ParserContainer<Auth>* auths = 0;
if(proxyAuthorization)
{
if(request.exists(h_ProxyAuthorizations))
{
auths = &request.header(h_ProxyAuthorizations);
}
}
else
{
if(request.exists(h_Authorizations))
{
auths = &request.header(h_Authorizations);
}
}
if (auths)
{
for (ParserContainer<Auth>::const_iterator i = auths->begin(); i != auths->end(); i++)
{
if (i->exists(p_realm) &&
i->exists(p_nonce) &&
i->exists(p_response) &&
i->param(p_realm) == realm)
{
if(!isEqualNoCase(i->scheme(),digest))
{
DebugLog(<< "Scheme must be Digest");
continue;
}
/* ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size());
if (!pb.eof() && !isdigit(*pb.position()))
{
DebugLog(<< "Invalid nonce; expected timestamp.");
return make_pair(BadlyFormed,username);
}
const char* anchor = pb.position();
pb.skipToChar(Symbols::COLON[0]);
if (pb.eof())
{
DebugLog(<< "Invalid nonce; expected timestamp terminator.");
return make_pair(BadlyFormed,username);
}
Data then;
pb.data(then, anchor);
if (expiresDelta > 0)
{
unsigned int now = (unsigned int)(Timer::getTimeMs()/1000);
if ((unsigned int)then.convertUInt64() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return make_pair(Expired,username);
}
} */
NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
if(x_nonce.getCreationTime() == 0)
return make_pair(BadlyFormed,username);
if (expiresDelta > 0)
{
UInt64 now = Timer::getTimeSecs();
if (x_nonce.getCreationTime() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return make_pair(Expired,username);
}
}
Data then(x_nonce.getCreationTime());
if (i->param(p_nonce) != makeNonce(request, then))
{
InfoLog(<< "Not my nonce. expected=" << makeNonce(request, then)
<< " received=" << i->param(p_nonce)
<< " then=" << then);
return make_pair(BadlyFormed,username);
}
if (i->exists(p_qop))
{
if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt)
{
if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc))
{
if (i->param(p_response) == makeResponseMD5WithA1(a1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce),
i->param(p_qop),
i->param(p_cnonce),
i->param(p_nc),
request.getContents()))
{
if(i->exists(p_username))
{
username = i->param(p_username);
}
return make_pair(Authenticated,username);
}
else
{
return make_pair(Failed,username);
}
}
}
else
{
InfoLog (<< "Unsupported qop=" << i->param(p_qop));
return make_pair(Failed,username);
}
}
else if(i->exists(p_uri))
{
if (i->param(p_response) == makeResponseMD5WithA1(a1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce)))
{
if(i->exists(p_username))
{
username = i->param(p_username);
}
return make_pair(Authenticated,username);
}
else
{
return make_pair(Failed,username);
}
}
}
else
{
return make_pair(BadlyFormed,username);
}
}
return make_pair(BadlyFormed,username);
}
DebugLog (<< "No authentication headers. Failing request.");
return make_pair(Failed,username);
}

| bool Helper::algorithmAndQopSupported | ( | const Auth & | challenge | ) | [static] |
Definition at line 1551 of file Helper.cxx.
References resip::Symbols::auth, resip::Symbols::authInt, resip::Auth::exists(), resip::isEqualNoCase(), and resip::ParserCategory::param().
{
if ( !(challenge.exists(p_nonce) && challenge.exists(p_realm)))
{
return false;
}
return ((!challenge.exists(p_algorithm)
|| isEqualNoCase(challenge.param(p_algorithm), "MD5"))
&& (!challenge.exists(p_qop)
|| isEqualNoCase(challenge.param(p_qop), Symbols::auth)
|| isEqualNoCase(challenge.param(p_qop), Symbols::authInt)));
}

| Helper::AuthResult Helper::authenticateRequest | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| const Data & | password, | ||
| int | expiresDelta = 0 |
||
| ) | [static] |
Definition at line 922 of file Helper.cxx.
References resip::ParserContainerBase::append(), resip::Symbols::auth, resip::Symbols::authInt, resip::ParserContainer< T >::begin(), DebugLog, digest, resip::ParserContainerBase::empty(), resip::ParserContainer< T >::end(), resip::SipMessage::exists(), resip::SipMessage::getContents(), resip::NonceHelper::Nonce::getCreationTime(), resip::RequestLine::getMethod(), resip::Timer::getTimeSecs(), resip::SipMessage::header(), InfoLog, and resip::isEqualNoCase().
{
DebugLog(<< "Authenticating: realm=" << realm << " expires=" << expiresDelta);
//DebugLog(<< request);
// !bwc! Somewhat inefficient. Maybe optimize later.
ParserContainer<Auth> auths;
if(request.exists(h_ProxyAuthorizations))
{
auths.append(request.header(h_ProxyAuthorizations));
}
if(request.exists(h_Authorizations))
{
auths.append(request.header(h_Authorizations));
}
if(auths.empty())
{
DebugLog (<< "No authentication headers. Failing request.");
return Failed;
}
// ?bwc? Why is const_iterator& operator=(const iterator& rhs)
// not working properly?
//ParserContainer<Auth>::const_iterator i = auths.begin();
ParserContainer<Auth>::iterator i = auths.begin();
for (; i != auths.end(); i++)
{
if (i->exists(p_realm) &&
i->exists(p_nonce) &&
i->exists(p_response) &&
i->param(p_realm) == realm)
{
if(!isEqualNoCase(i->scheme(),digest))
{
DebugLog(<< "Scheme must be Digest");
continue;
}
/*
ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size());
if (!pb.eof() && !isdigit(*pb.position()))
{
DebugLog(<< "Invalid nonce; expected timestamp.");
return BadlyFormed;
}
const char* anchor = pb.position();
pb.skipToChar(Symbols::COLON[0]);
if (pb.eof())
{
DebugLog(<< "Invalid nonce; expected timestamp terminator.");
return BadlyFormed;
}
Data then;
pb.data(then, anchor);
*/
NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
if(x_nonce.getCreationTime() == 0)
return BadlyFormed;
if (expiresDelta > 0)
{
UInt64 now = Timer::getTimeSecs();
if (x_nonce.getCreationTime() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return Expired;
}
}
Data then(x_nonce.getCreationTime());
if (i->param(p_nonce) != makeNonce(request, then))
{
InfoLog(<< "Not my nonce.");
return Failed;
}
InfoLog (<< " username=" << (i->param(p_username))
<< " password=" << password
<< " realm=" << realm
<< " method=" << getMethodName(request.header(h_RequestLine).getMethod())
<< " uri=" << i->param(p_uri)
<< " nonce=" << i->param(p_nonce));
if (i->exists(p_qop))
{
if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt)
{
if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc))
{
if (i->param(p_response) == makeResponseMD5(i->param(p_username),
password,
realm,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce),
i->param(p_qop),
i->param(p_cnonce),
i->param(p_nc)),
request.getContents())
{
return Authenticated;
}
else
{
return Failed;
}
}
}
else
{
InfoLog (<< "Unsupported qop=" << i->param(p_qop));
return Failed;
}
}
else if(i->exists(p_uri))
{
if (i->param(p_response) == makeResponseMD5(i->param(p_username),
password,
realm,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce)))
{
return Authenticated;
}
else
{
return Failed;
}
}
}
else
{
return BadlyFormed;
}
}
return BadlyFormed;
}

| Helper::AuthResult Helper::authenticateRequestWithA1 | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| const Data & | hA1, | ||
| int | expiresDelta = 0 |
||
| ) | [static] |
Definition at line 1078 of file Helper.cxx.
References resip::ParserContainerBase::append(), resip::Symbols::auth, resip::Symbols::authInt, resip::ParserContainer< T >::begin(), DebugLog, digest, resip::ParserContainerBase::empty(), resip::ParserContainer< T >::end(), resip::SipMessage::exists(), resip::SipMessage::getContents(), resip::NonceHelper::Nonce::getCreationTime(), resip::RequestLine::getMethod(), resip::Timer::getTimeSecs(), resip::SipMessage::header(), InfoLog, and resip::isEqualNoCase().
{
DebugLog(<< "Authenticating with HA1: realm=" << realm << " expires=" << expiresDelta);
//DebugLog(<< request);
// !bwc! Somewhat inefficient. Maybe optimize later.
ParserContainer<Auth> auths;
if(request.exists(h_ProxyAuthorizations))
{
auths.append(request.header(h_ProxyAuthorizations));
}
if(request.exists(h_Authorizations))
{
auths.append(request.header(h_Authorizations));
}
if(auths.empty())
{
DebugLog (<< "No authentication headers. Failing request.");
return Failed;
}
// ?bwc? Why is const_iterator& operator=(const iterator& rhs)
// not working properly?
//ParserContainer<Auth>::const_iterator i = auths.begin();
ParserContainer<Auth>::iterator i = auths.begin();
for (;i != auths.end(); i++)
{
if (i->exists(p_realm) &&
i->exists(p_nonce) &&
i->exists(p_response) &&
i->param(p_realm) == realm)
{
if(!isEqualNoCase(i->scheme(),digest))
{
DebugLog(<< "Scheme must be Digest");
continue;
}
/*
ParseBuffer pb(i->param(p_nonce).data(), i->param(p_nonce).size());
if (!pb.eof() && !isdigit(*pb.position()))
{
DebugLog(<< "Invalid nonce; expected timestamp.");
return BadlyFormed;
}
const char* anchor = pb.position();
pb.skipToChar(Symbols::COLON[0]);
if (pb.eof())
{
DebugLog(<< "Invalid nonce; expected timestamp terminator.");
return BadlyFormed;
}
Data then;
pb.data(then, anchor);
*/
NonceHelper::Nonce x_nonce = getNonceHelper()->parseNonce(i->param(p_nonce));
if(x_nonce.getCreationTime() == 0)
return BadlyFormed;
if (expiresDelta > 0)
{
UInt64 now = Timer::getTimeSecs();
if (x_nonce.getCreationTime() + expiresDelta < now)
{
DebugLog(<< "Nonce has expired.");
return Expired;
}
}
Data then(x_nonce.getCreationTime());
if (i->param(p_nonce) != makeNonce(request, then))
{
InfoLog(<< "Not my nonce.");
return Failed;
}
InfoLog (<< " username=" << (i->param(p_username))
<< " H(A1)=" << hA1
<< " realm=" << realm
<< " method=" << getMethodName(request.header(h_RequestLine).getMethod())
<< " uri=" << i->param(p_uri)
<< " nonce=" << i->param(p_nonce));
if (i->exists(p_qop))
{
if (i->param(p_qop) == Symbols::auth || i->param(p_qop) == Symbols::authInt)
{
if(i->exists(p_uri) && i->exists(p_cnonce) && i->exists(p_nc))
{
if (i->param(p_response) == makeResponseMD5WithA1(hA1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce),
i->param(p_qop),
i->param(p_cnonce),
i->param(p_nc),
request.getContents()))
{
return Authenticated;
}
else
{
return Failed;
}
}
}
else
{
InfoLog (<< "Unsupported qop=" << i->param(p_qop));
return Failed;
}
}
else if(i->exists(p_uri))
{
if (i->param(p_response) == makeResponseMD5WithA1(hA1,
getMethodName(request.header(h_RequestLine).getMethod()),
i->param(p_uri),
i->param(p_nonce)))
{
return Authenticated;
}
else
{
return Failed;
}
}
}
else
{
return BadlyFormed;
}
}
return BadlyFormed;
}

| Data Helper::computeCallId | ( | ) | [static] |
Definition at line 650 of file Helper.cxx.
References resip::Data::append(), resip::Data::BASE64, resip::Random::getRandomHex(), localhostname, and resip::Data::md5().
Referenced by main(), makeMessage(), makePublish(), makeRegister(), makeRequest(), and makeSubscribe().
{
Data hostAndSalt(localhostname + Random::getRandomHex(16));
#ifndef USE_SSL // .bwc. None of this is neccessary if we're using openssl
#if defined(__linux__) || defined(__APPLE__)
pid_t pid = getpid();
hostAndSalt.append((char*)&pid,sizeof(pid));
#endif
#ifdef __APPLE__
pthread_t thread = pthread_self();
hostAndSalt.append((char*)&thread,sizeof(thread));
#endif
#ifdef WIN32
DWORD proccessId = ::GetCurrentProcessId();
DWORD threadId = ::GetCurrentThreadId();
hostAndSalt.append((char*)&proccessId,sizeof(proccessId));
hostAndSalt.append((char*)&threadId,sizeof(threadId));
#endif
#endif // of USE_SSL
return hostAndSalt.md5(Data::BASE64);
}

| static Data resip::Helper::computeProxyBranch | ( | const SipMessage & | request | ) | [static] |
| Data Helper::computeTag | ( | int | numBytes | ) | [static] |
Definition at line 673 of file Helper.cxx.
References resip::Random::getRandomHex().
Referenced by makeMessage(), makePublish(), makeRegister(), makeRequest(), resip::DeprecatedDialog::makeResponse(), makeResponse(), makeSubscribe(), and Server::thread().
{
return Random::getRandomHex(numBytes);
}

| Data Helper::computeUniqueBranch | ( | ) | [static] |
Creates and returns a unique branch parameter.
Generated branch will contain the RFC3261 magic cookie + 4 randome hex characters + "C1" + 2 random hex characters.
Definition at line 637 of file Helper.cxx.
References cookie, resip::Random::getRandomHex(), and resip::Data::Preallocate.
{
Data result(16, Data::Preallocate);
result += cookie;
result += Random::getRandomHex(4);
result += "C1";
result += Random::getRandomHex(2);
return result;
}

| Helper::FailureMessageEffect Helper::determineFailureMessageEffect | ( | const SipMessage & | response | ) | [static] |
Definition at line 1996 of file Helper.cxx.
References ApplicationDependant, DialogTermination, resip::SipMessage::exists(), resip::SipMessage::header(), resip::SipMessage::isResponse(), OptionalRetryAfter, RetryAfter, TransactionTermination, and UsageTermination.
{
assert(response.isResponse());
int code = response.header(h_StatusLine).statusCode();
assert(code >= 400);
switch(code)
{
case 404:
case 410:
case 416:
case 480: // but maybe not, still not quite decided:
case 481:
case 482: // but maybe not, still not quite decided:
case 484:
case 485:
case 502:
case 604:
return DialogTermination;
case 403:
case 489: //only for only subscription
case 408: //again, maybe not. This seems best.
return UsageTermination;
case 400:
case 401:
case 402:
case 405: //doesn't agree w/ -00 of dialogusage
case 406:
case 412:
case 413:
case 414:
case 415:
case 420:
case 421:
case 423:
case 429: // but if this the refer creating the Subscription, no sub will be created.
case 486:
case 487:
case 488:
case 491:
case 493:
case 494:
case 500:
case 505:
case 513:
case 603:
case 606:
return TransactionTermination;
case 483: // who knows, gravefully terminate or just destroy dialog
case 501:
return ApplicationDependant;
default:
if (code < 600)
{
if (response.exists(h_RetryAfter))
{
return RetryAfter;
}
else
{
return OptionalRetryAfter;
}
}
else
{
if (response.exists(h_RetryAfter))
{
return RetryAfter;
}
else
{
return ApplicationDependant;
}
}
}
}

| Helper::ContentsSecAttrs Helper::extractFromPkcs7 | ( | const SipMessage & | message, |
| Security & | security | ||
| ) | [static] |
Definition at line 1969 of file Helper.cxx.
References extractFromPkcs7Recurse(), fromAor(), resip::Uri::getAor(), resip::SipMessage::getContents(), resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::SecurityAttributes::setIdentity(), and resip::RequestLine::uri().
{
SecurityAttributes* attr = new SecurityAttributes;
// .dlb. currently flattening SecurityAttributes?
//attr->setIdentity(message.getIdentity());
attr->setIdentity(message.header(h_From).uri().getAor());
Contents *b = message.getContents();
if (b)
{
Data fromAor(message.header(h_From).uri().getAor());
Data toAor(message.header(h_To).uri().getAor());
if (message.isRequest())
{
b = extractFromPkcs7Recurse(b, fromAor, toAor, attr, security);
}
else // its a response
{
b = extractFromPkcs7Recurse(b, toAor, fromAor, attr, security);
}
}
std::auto_ptr<Contents> c(b);
std::auto_ptr<SecurityAttributes> a(attr);
return ContentsSecAttrs(c, a);
}

| Uri Helper::fromAor | ( | const Data & | aor, |
| const Data & | scheme = Symbols::DefaultSipScheme |
||
| ) | [static] |
Definition at line 1699 of file Helper.cxx.
Referenced by extractFromPkcs7().
{
return makeUri(aor, scheme);
}
| static std::pair<Data,Data> resip::Helper::fromGruuUserPart | ( | const Data & | gruuUserPart, |
| const Data & | key | ||
| ) | [static] |
| Tuple Helper::getClientPublicAddress | ( | const SipMessage & | request | ) | [static] |
Look at Via headers, and find the first public IP address closest to the sending client.
| request | Request message that we use for checking. |
Definition at line 2210 of file Helper.cxx.
References resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::Tuple::setPort(), resip::Tuple::toTransport(), and resip::UNKNOWN_TRANSPORT.
{
assert(request.isRequest());
assert(!request.header(h_Vias).empty());
// Iterate through Via's starting at the bottom (closest to the client). Return the first
// public address found from received parameter if present, or Via host.
Vias::const_iterator it = request.header(h_Vias).end();
while(true)
{
it--;
if(it->exists(p_received))
{
// Check IP from received parameter
Tuple address(it->param(p_received), 0, UNKNOWN_TRANSPORT);
if(!address.isPrivateAddress())
{
address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort());
address.setType(Tuple::toTransport(it->transport()));
return address;
}
}
// Check IP from Via sentHost
Tuple address(it->sentHost(), 0, UNKNOWN_TRANSPORT);
if(!address.isPrivateAddress())
{
address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort());
address.setType(Tuple::toTransport(it->transport()));
return address;
}
if(it == request.header(h_Vias).begin()) break;
}
return Tuple();
}

| NonceHelper * Helper::getNonceHelper | ( | ) | [static] |
Definition at line 685 of file Helper.cxx.
{
if (mNonceHelperPtr.mNonceHelper == 0)
{
mNonceHelperPtr.mNonceHelper = new BasicNonceHelper();
}
return mNonceHelperPtr.mNonceHelper;
}
| int Helper::getPortForReply | ( | SipMessage & | request | ) | [static] |
Definition at line 1656 of file Helper.cxx.
References resip::SipMessage::const_header(), resip::Symbols::DefaultSipPort, resip::Symbols::DefaultSipsPort, resip::DTLS, resip::Tuple::getPort(), resip::SipMessage::getSource(), resip::SipMessage::isRequest(), resip::Symbols::TCP, resip::TLS, and resip::Symbols::TLS.
Referenced by resip::TransactionState::processSipMessageAsNew().
{
assert(request.isRequest());
int port = 0;
if(request.const_header(h_Vias).front().transport() == Symbols::TCP ||
request.const_header(h_Vias).front().transport() == Symbols::TLS)
{
// 18.2.2 - bullet 1 and 2
port = request.getSource().getPort();
if(port == 0) // .slg. not sure if it makes sense for sourcePort to be 0
{
port = request.const_header(h_Vias).front().sentPort();
}
}
else // unreliable transport 18.2.2 bullets 3 and 4
{
if (request.const_header(h_Vias).front().exists(p_rport))
{
port = request.getSource().getPort();
}
else
{
port = request.const_header(h_Vias).front().sentPort();
}
}
// If we haven't got a valid port yet, then use the default
if (port <= 0 || port > 65535)
{
if(request.const_header(h_Vias).front().transport() == Symbols::TLS ||
request.const_header(h_Vias).front().transport() == Symbols::DTLS)
{
port = Symbols::DefaultSipsPort;
}
else
{
port = Symbols::DefaultSipPort;
}
}
return port;
}

| void Helper::getResponseCodeReason | ( | int | responseCode, |
| Data & | reason | ||
| ) | [static] |
Returns the default reason string for a particular response code.
| responseCode | Response code to get reason for |
| reason | Data where the reason string associated with the responseCode will be set. |
Definition at line 509 of file Helper.cxx.
{
switch (responseCode)
{
case 100: reason = "Trying"; break;
case 180: reason = "Ringing"; break;
case 181: reason = "Call Is Being Forwarded"; break;
case 182: reason = "Queued"; break;
case 183: reason = "Session Progress"; break;
case 200: reason = "OK"; break;
case 202: reason = "Accepted"; break;
case 300: reason = "Multiple Choices"; break;
case 301: reason = "Moved Permanently"; break;
case 302: reason = "Moved Temporarily"; break;
case 305: reason = "Use Proxy"; break;
case 380: reason = "Alternative Service"; break;
case 400: reason = "Bad Request"; break;
case 401: reason = "Unauthorized"; break;
case 402: reason = "Payment Required"; break;
case 403: reason = "Forbidden"; break;
case 404: reason = "Not Found"; break;
case 405: reason = "Method Not Allowed"; break;
case 406: reason = "Not Acceptable"; break;
case 407: reason = "Proxy Authentication Required"; break;
case 408: reason = "Request Timeout"; break;
case 410: reason = "Gone"; break;
case 412: reason = "Precondition Failed"; break;
case 413: reason = "Request Entity Too Large"; break;
case 414: reason = "Request-URI Too Long"; break;
case 415: reason = "Unsupported Media Type"; break;
case 416: reason = "Unsupported URI Scheme"; break;
case 420: reason = "Bad Extension"; break;
case 421: reason = "Extension Required"; break;
case 422: reason = "Session Interval Too Small"; break;
case 423: reason = "Interval Too Brief"; break;
case 430: reason = "Flow failed"; break;
case 439: reason = "First Hop Lacks Outbound Support"; break;
case 480: reason = "Temporarily Unavailable"; break;
case 481: reason = "Call/Transaction Does Not Exist"; break;
case 482: reason = "Loop Detected"; break;
case 483: reason = "Too Many Hops"; break;
case 484: reason = "Address Incomplete"; break;
case 485: reason = "Ambiguous"; break;
case 486: reason = "Busy Here"; break;
case 487: reason = "Request Terminated"; break;
case 488: reason = "Not Acceptable Here"; break;
case 489: reason = "Event Package Not Supported"; break;
case 491: reason = "Request Pending"; break;
case 493: reason = "Undecipherable"; break;
case 500: reason = "Server Internal Error"; break;
case 501: reason = "Not Implemented"; break;
case 502: reason = "Bad Gateway"; break;
case 503: reason = "Service Unavailable"; break;
case 504: reason = "Server Time-out"; break;
case 505: reason = "Version Not Supported"; break;
case 513: reason = "Message Too Large"; break;
case 600: reason = "Busy Everywhere"; break;
case 603: reason = "Decline"; break;
case 604: reason = "Does Not Exist Anywhere"; break;
case 606: reason = "Not Acceptable"; break;
}
}
| auto_ptr< SdpContents > Helper::getSdp | ( | Contents * | tree | ) | [static] |
Definition at line 2162 of file Helper.cxx.
References resip::SdpContents::clone(), DebugLog, emptysdp, and getSdpRecurse().
{
if (tree)
{
SdpContents* sdp = getSdpRecurse(tree);
if (sdp)
{
DebugLog(<< "Got sdp" << endl);
return auto_ptr<SdpContents>(static_cast<SdpContents*>(sdp->clone()));
}
}
//DebugLog(<< "No sdp" << endl);
return emptysdp;
}

| static Data resip::Helper::gruuUserPart | ( | const Data & | instanceId, |
| const Data & | aor, | ||
| const Data & | key | ||
| ) | [static] |
| unsigned int Helper::hex2integer | ( | const char * | _s | ) | [static] |
Converts a character string containing a hexidecimal value into an unsigned int.
Note: Parsing stops after the first non-hex character, or after 8 characters have been processed.
| _s | A pointer to the character buffer to convert. |
Definition at line 86 of file Helper.cxx.
Referenced by resip::SdpContents::Session::Medium::parse(), and resip::SERNonceHelper::parseNonce().
{
unsigned int i, res = 0;
for(i = 0; i < 8; i++)
{
if ((_s[i] >= '0') && (_s[i] <= '9'))
{
res *= 16;
res += _s[i] - '0';
}
else if ((_s[i] >= 'a') && (_s[i] <= 'f'))
{
res *= 16;
res += _s[i] - 'a' + 10;
}
else if ((_s[i] >= 'A') && (_s[i] <= 'F'))
{
res *= 16;
res += _s[i] - 'A' + 10;
}
else
{
return res;
}
}
return res;
}
| void Helper::integer2hex | ( | char * | _d, |
| unsigned int | _s, | ||
| bool | _l = true |
||
| ) | [static] |
Converts an interger in a character string containing the hexidecimal representation of the integer.
Note: The string buffer provided should be at least 8 characters long. This function will NOT NULL terminate the string.
| _d | A pointer to the character buffer to write the hex string |
| _s | The integer value to convert. |
| _l | Boolean flag to include leading 0 zeros or not. |
Definition at line 46 of file Helper.cxx.
Referenced by resip::SERNonceHelper::makeNonce(), and resip::SdpContents::Session::Medium::parse().
{
int i;
unsigned char j;
int k = 0;
char* s;
_s = htonl(_s);
s = (char*)&_s;
for (i = 0; i < 4; i++)
{
j = (s[i] >> 4) & 0xf;
if (j <= 9)
{
if(_l || j != 0 || k != 0)
{
_d[k++] = (j + '0');
}
}
else
{
_d[k++] = (j + 'a' - 10);
}
j = s[i] & 0xf;
if (j <= 9)
{
if(_l || j != 0 || k != 0)
{
_d[k++] = (j + '0');
}
}
else
{
_d[k++] = (j + 'a' - 10);
}
}
}
| bool Helper::isClientBehindNAT | ( | const SipMessage & | request, |
| bool | privateToPublicOnly = true |
||
| ) | [static] |
Looks at SIP headers and message source for a mismatch to make an assumption that the sender is behind a NAT device.
| request | Request message that we use for checking. |
If enabled then we ensure that the via is private address and that the source was a public address. This allows us to ignore cases of private-private NAT'ing or false detections, when a server behind a load balancer is sending us requests and using the load balancer address in the Via, instead of the real of the adapter.
Definition at line 2180 of file Helper.cxx.
References resip::SipMessage::header(), resip::SipMessage::isRequest(), and resip::UNKNOWN_TRANSPORT.
{
assert(request.isRequest());
assert(!request.header(h_Vias).empty());
// If received parameter is on top Via, then the source of the message doesn't match
// the address provided in the via. Assume this is because the sender is behind a NAT.
// The assumption here is that this SipStack instance is the first hop in a public SIP server
// architecture, and that clients are directly connected to this instance.
if(request.header(h_Vias).front().exists(p_received))
{
if(privateToPublicOnly)
{
if(Tuple(request.header(h_Vias).front().sentHost(), 0, UNKNOWN_TRANSPORT).isPrivateAddress() &&
!Tuple(request.header(h_Vias).front().param(p_received), 0, UNKNOWN_TRANSPORT).isPrivateAddress())
{
return true;
}
else
{
return false;
}
}
return true;
}
return false;
}

| int Helper::jitterValue | ( | int | input, |
| int | lowerPercentage, | ||
| int | upperPercentage, | ||
| int | minimum = 0 |
||
| ) | [static] |
Used to jitter the expires in a SUBSCRIBE or REGISTER expires header.
| input | Value to jitter |
| lowerPercentage | The lower range of the random percentage by which to jitter the value by. |
| upperPercentage | The upper range of the random percentage by which to jitter the value by. Must be greater than or equal to lowerPercentage |
| minimum | Only jitter the input if greater than minimum |
Definition at line 316 of file Helper.cxx.
References resip::Random::getRandom(), and input.
{
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::make405 | ( | const SipMessage & | request, |
| const int * | allowedMethods = 0, |
||
| int | nMethods = -1 |
||
| ) | [static] |
Make a 405 response to a provided request.
Allows header is added with specified methods, or with all methods the stack knows about. Caller owns the returned pointer and is responsible for deleting it.
| request | SipMessage request from which to generate the response |
| allowedMethods | Array of integers representing a list of Method Types to add to the generated Allows header. See MethodTypes.hxx. |
| nMethods | Number of methods specified in the allowedMethods integer array. Specify -1 to have this method fill in the Allows header automatically with each method supported by the stack. |
Definition at line 1229 of file Helper.cxx.
References resip::SipMessage::header(), len, makeResponse(), and resip::Token::value().
Referenced by resip::TuIM::processRequest().
{
SipMessage* resp = Helper::makeResponse(request, 405);
if (len < 0)
{
int upperBound = static_cast<int>(MAX_METHODS);
// The UNKNOWN method name is the first in the enum
for (int i = 1 ; i < upperBound; i ++)
{
int last = 0;
// ENUMS must be contiguous in order for this to work.
assert( i - last <= 1);
Token t;
t.value() = getMethodName(static_cast<resip::MethodTypes>(i));
resp->header(h_Allows).push_back(t);
last = i;
}
}
else
{
// use user's list
for ( int i = 0 ; i < len ; i++)
{
Token t;
t.value() = getMethodName(static_cast<resip::MethodTypes>(allowedMethods[i]));
resp->header(h_Allows).push_back(t);
}
}
return resp;
}

| SipMessage * Helper::makeCancel | ( | const SipMessage & | request | ) | [static] |
Make a new Cancel request for the specified request.
Caller owns the returned pointer and is responsible for deleting it.
| request | Request for which the Cancel will apply. ie. Invite request. |
Definition at line 573 of file Helper.cxx.
References resip::SipMessage::exists(), resip::RequestLine::getMethod(), resip::RequestLine::getSipVersion(), resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::RequestLine::method(), and resip::RequestLine::uri().
Referenced by resip::TransactionState::processClientInvite().
{
assert(request.isRequest());
assert(request.header(h_RequestLine).getMethod() == INVITE);
std::auto_ptr<SipMessage> cancel(new SipMessage);
RequestLine rLine(CANCEL, request.header(h_RequestLine).getSipVersion());
rLine.uri() = request.header(h_RequestLine).uri();
cancel->header(h_RequestLine) = rLine;
cancel->header(h_MaxForwards).value() = 70;
cancel->header(h_To) = request.header(h_To);
cancel->header(h_From) = request.header(h_From);
cancel->header(h_CallId) = request.header(h_CallId);
if (request.exists(h_ProxyAuthorizations))
{
cancel->header(h_ProxyAuthorizations) = request.header(h_ProxyAuthorizations);
}
if (request.exists(h_Authorizations))
{
cancel->header(h_Authorizations) = request.header(h_Authorizations);
}
if (request.exists(h_Routes))
{
cancel->header(h_Routes) = request.header(h_Routes);
}
cancel->header(h_CSeq) = request.header(h_CSeq);
cancel->header(h_CSeq).method() = CANCEL;
cancel->header(h_Vias).push_back(request.header(h_Vias).front());
return cancel.release();
}

| SipMessage * Helper::makeChallenge | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| bool | useAuth = true, |
||
| bool | stale = false, |
||
| bool | proxy = false |
||
| ) | [static] |
Definition at line 1279 of file Helper.cxx.
References resip::Symbols::Digest, resip::Timer::getTimeSecs(), resip::SipMessage::header(), makeResponse(), resip::ParserCategory::param(), and resip::Auth::scheme().
{
Auth auth;
auth.scheme() = Symbols::Digest;
Data timestamp(Timer::getTimeSecs());
auth.param(p_nonce) = makeNonce(request, timestamp);
auth.param(p_algorithm) = "MD5";
auth.param(p_realm) = realm;
if (useAuth)
{
auth.param(p_qopOptions) = "auth,auth-int";
}
if (stale)
{
auth.param(p_stale) = "true";
}
SipMessage *response;
if(proxy)
{
response = Helper::makeResponse(request, 407);
response->header(h_ProxyAuthenticates).push_back(auth);
}
else
{
response = Helper::makeResponse(request, 401);
response->header(h_WWWAuthenticates).push_back(auth);
}
return response;
}

| Auth Helper::makeChallengeResponseAuth | ( | const SipMessage & | request, |
| const Data & | username, | ||
| const Data & | password, | ||
| const Auth & | challenge, | ||
| const Data & | cnonce, | ||
| unsigned int & | nonceCount, | ||
| Data & | nonceCountString | ||
| ) | [static] |
Definition at line 1336 of file Helper.cxx.
References resip::Data::empty().
{
Auth auth;
Data authQop = qopOption(challenge);
if(!authQop.empty())
{
updateNonceCount(nonceCount, nonceCountString);
}
makeChallengeResponseAuth(request, username, password, challenge, cnonce, authQop, nonceCountString, auth);
return auth;
}

| void Helper::makeChallengeResponseAuth | ( | const SipMessage & | request, |
| const Data & | username, | ||
| const Data & | password, | ||
| const Auth & | challenge, | ||
| const Data & | cnonce, | ||
| const Data & | authQop, | ||
| const Data & | nonceCountString, | ||
| Auth & | auth | ||
| ) | [static] |
Definition at line 1355 of file Helper.cxx.
References resip::Symbols::Digest, resip::Data::empty(), resip::Auth::exists(), resip::SipMessage::getContents(), resip::RequestLine::getMethod(), resip::SipMessage::header(), makeResponseMD5(), resip::ParserCategory::param(), resip::Auth::scheme(), resip::Data::size(), and resip::RequestLine::uri().
{
auth.scheme() = Symbols::Digest;
auth.param(p_username) = username;
assert(challenge.exists(p_realm));
auth.param(p_realm) = challenge.param(p_realm);
assert(challenge.exists(p_nonce));
auth.param(p_nonce) = challenge.param(p_nonce);
Data digestUri;
{
DataStream s(digestUri);
//s << request.header(h_RequestLine).uri().host(); // wrong
s << request.header(h_RequestLine).uri(); // right
}
auth.param(p_uri) = digestUri;
if (!authQop.empty())
{
auth.param(p_response) = Helper::makeResponseMD5(username,
password,
challenge.param(p_realm),
getMethodName(request.header(h_RequestLine).getMethod()),
digestUri,
challenge.param(p_nonce),
authQop,
cnonce,
nonceCountString,
request.getContents());
auth.param(p_cnonce) = cnonce;
auth.param(p_nc) = nonceCountString;
auth.param(p_qop) = authQop;
}
else
{
assert(challenge.exists(p_realm));
auth.param(p_response) = Helper::makeResponseMD5(username,
password,
challenge.param(p_realm),
getMethodName(request.header(h_RequestLine).getMethod()),
digestUri,
challenge.param(p_nonce));
}
if (challenge.exists(p_algorithm))
{
auth.param(p_algorithm) = challenge.param(p_algorithm);
}
else
{
auth.param(p_algorithm) = "MD5";
}
if (challenge.exists(p_opaque) && challenge.param(p_opaque).size() > 0)
{
auth.param(p_opaque) = challenge.param(p_opaque);
}
}

| Auth Helper::makeChallengeResponseAuthWithA1 | ( | const SipMessage & | request, |
| const Data & | username, | ||
| const Data & | passwordHashA1, | ||
| const Auth & | challenge, | ||
| const Data & | cnonce, | ||
| unsigned int & | nonceCount, | ||
| Data & | nonceCountString | ||
| ) | [static] |
Definition at line 1468 of file Helper.cxx.
References resip::Data::empty().
{
Auth auth;
Data authQop = qopOption(challenge);
if(!authQop.empty())
{
updateNonceCount(nonceCount, nonceCountString);
}
makeChallengeResponseAuthWithA1(request, username, passwordHashA1, challenge, cnonce, authQop, nonceCountString, auth);
return auth;
}

| void Helper::makeChallengeResponseAuthWithA1 | ( | const SipMessage & | request, |
| const Data & | username, | ||
| const Data & | passwordHashA1, | ||
| const Auth & | challenge, | ||
| const Data & | cnonce, | ||
| const Data & | authQop, | ||
| const Data & | nonceCountString, | ||
| Auth & | auth | ||
| ) | [static] |
Definition at line 1487 of file Helper.cxx.
References resip::SipMessage::const_header(), resip::Symbols::Digest, resip::Data::empty(), resip::Auth::exists(), resip::SipMessage::getContents(), resip::RequestLine::getMethod(), resip::SipMessage::header(), makeResponseMD5WithA1(), resip::ParserCategory::param(), resip::Auth::scheme(), resip::Data::size(), and resip::RequestLine::uri().
{
auth.scheme() = Symbols::Digest;
auth.param(p_username) = username;
assert(challenge.exists(p_realm));
auth.param(p_realm) = challenge.param(p_realm);
assert(challenge.exists(p_nonce));
auth.param(p_nonce) = challenge.param(p_nonce);
Data digestUri;
{
DataStream s(digestUri);
//s << request.const_header(h_RequestLine).uri().host(); // wrong
s << request.const_header(h_RequestLine).uri(); // right
}
auth.param(p_uri) = digestUri;
if (!authQop.empty())
{
auth.param(p_response) = Helper::makeResponseMD5WithA1(passwordHashA1,
getMethodName(request.header(h_RequestLine).getMethod()),
digestUri,
challenge.param(p_nonce),
authQop,
cnonce,
nonceCountString,
request.getContents());
auth.param(p_cnonce) = cnonce;
auth.param(p_nc) = nonceCountString;
auth.param(p_qop) = authQop;
}
else
{
assert(challenge.exists(p_realm));
auth.param(p_response) = Helper::makeResponseMD5WithA1(passwordHashA1,
getMethodName(request.header(h_RequestLine).getMethod()),
digestUri,
challenge.param(p_nonce));
}
if (challenge.exists(p_algorithm))
{
auth.param(p_algorithm) = challenge.param(p_algorithm);
}
else
{
auth.param(p_algorithm) = "MD5";
}
if (challenge.exists(p_opaque) && challenge.param(p_opaque).size() > 0)
{
auth.param(p_opaque) = challenge.param(p_opaque);
}
}

| SipMessage * Helper::makeFailureAck | ( | const SipMessage & | request, |
| const SipMessage & | response | ||
| ) | [static] |
This interface should be used by the stack (TransactionState) to create an AckMsg to a failure response.
See RFC3261 section 17.1.1.3. Caller owns the returned pointer and is responsible for deleting it.
| request | Request that this ACK applies to. |
| response | Response that we are ACKing - required so that we can get the To tag into the generated ACK. |
Definition at line 609 of file Helper.cxx.
References resip::SipMessage::exists(), resip::RequestLine::getMethod(), resip::RequestLine::getSipVersion(), resip::SipMessage::header(), resip::RequestLine::method(), and resip::RequestLine::uri().
Referenced by resip::TransactionState::processClientInvite().
{
assert (request.header(h_Vias).size() >= 1);
assert (request.header(h_RequestLine).getMethod() == INVITE);
std::auto_ptr<SipMessage> ack(new SipMessage);
RequestLine rLine(ACK, request.header(h_RequestLine).getSipVersion());
rLine.uri() = request.header(h_RequestLine).uri();
ack->header(h_RequestLine) = rLine;
ack->header(h_MaxForwards).value() = 70;
ack->header(h_CallId) = request.header(h_CallId);
ack->header(h_From) = request.header(h_From);
ack->header(h_To) = response.header(h_To); // to get to-tag
ack->header(h_Vias).push_back(request.header(h_Vias).front());
ack->header(h_CSeq) = request.header(h_CSeq);
ack->header(h_CSeq).method() = ACK;
if (request.exists(h_Routes))
{
ack->header(h_Routes) = request.header(h_Routes);
}
return ack.release();
}

| SipMessage * Helper::makeInvite | ( | const NameAddr & | target, |
| const NameAddr & | from | ||
| ) | [static] |
Make an invite request - Empty Contact and Via is added and will be populated by the stack when sent.
| target | Ends up in the RequestURI and To header |
| from | Ends up in the From header |
Definition at line 335 of file Helper.cxx.
References makeRequest().
Referenced by Client::Client(), main(), Client::process(), and Client::thread().
{
return Helper::makeRequest(target, from, INVITE);
}

| SipMessage * Helper::makeInvite | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Make an invite request using a overridden contact header - Empty Via is added and will be populated by the stack when sent.
| target | Ends up in the RequestURI and To header |
| from | Ends up in the From header |
| contact | Ends up in the Contact header. Stack will not change this when sent. |
Definition at line 341 of file Helper.cxx.
References makeRequest().
{
return Helper::makeRequest(target, from, contact, INVITE);
}

| SipMessage * Helper::makeMessage | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Create a Message request with an overriden Contact. See makeRequest.
Definition at line 262 of file Helper.cxx.
References computeCallId(), computeTag(), resip::RequestLine::method(), resip::ParserCategory::param(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
Referenced by resip::DeprecatedDialog::makeInitialMessage().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makeMessage | ( | const NameAddr & | target, |
| const NameAddr & | from | ||
| ) | [static] |
Create a Message request with an empty Contact. See makeRequest.
Definition at line 255 of file Helper.cxx.
{
NameAddr contact;
return makeMessage(target, from, contact);
}
| Data Helper::makeNonce | ( | const SipMessage & | request, |
| const Data & | timestamp | ||
| ) | [static] |
Definition at line 696 of file Helper.cxx.
{
return getNonceHelper()->makeNonce(request, timestamp);
}
| SipMessage * Helper::makeProxyChallenge | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| bool | useAuth = true, |
||
| bool | stale = false |
||
| ) | [static] |
Definition at line 1267 of file Helper.cxx.
{
return makeChallenge(request,realm,useAuth,stale,true);
}
| SipMessage * Helper::makePublish | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Create a Publish request with an overriden Contact. See makeRequest.
Definition at line 232 of file Helper.cxx.
References computeCallId(), computeTag(), resip::RequestLine::method(), resip::ParserCategory::param(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makePublish | ( | const NameAddr & | target, |
| const NameAddr & | from | ||
| ) | [static] |
Create a Publish request with an empty Contact. See makeRequest.
Definition at line 225 of file Helper.cxx.
{
NameAddr contact;
return makePublish(target, from, contact);
}
| void Helper::makeRawResponse | ( | Data & | rawBuffer, |
| const SipMessage & | request, | ||
| int | responseCode, | ||
| const Data & | additionalHeaders = Data::Empty, |
||
| const Data & | body = Data::Empty |
||
| ) | [static] |
Definition at line 485 of file Helper.cxx.
References resip::SipMessage::encodeSingleHeader(), resip::Data::reserve(), and resip::Data::size().
Referenced by resip::Transport::make100(), and resip::Transport::make503().
{
raw.reserve(256);
{
DataStream encodeStream(raw);
encodeStream << "SIP/2.0 " << responseCode << " ";
Data reason;
getResponseCodeReason(responseCode, reason);
encodeStream << reason;
msg.encodeSingleHeader(Headers::Via,encodeStream);
msg.encodeSingleHeader(Headers::To,encodeStream);
msg.encodeSingleHeader(Headers::From,encodeStream);
msg.encodeSingleHeader(Headers::CallID,encodeStream);
msg.encodeSingleHeader(Headers::CSeq,encodeStream);
encodeStream << additionalHeaders;
encodeStream << "Content-Length: " << body.size() << "\r\n\r\n";
}
}

| SipMessage * Helper::makeRegister | ( | const NameAddr & | to, |
| const NameAddr & | from, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Create a Register request with an overriden Contact. See makeRequest.
Definition at line 154 of file Helper.cxx.
References computeCallId(), computeTag(), resip::Uri::exists(), resip::Uri::host(), resip::RequestLine::method(), resip::ParserCategory::param(), resip::Uri::port(), resip::Uri::scheme(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
Referenced by doit(), and main().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makeRegister | ( | const NameAddr & | to, |
| const NameAddr & | from | ||
| ) | [static] |
Create a Register request with an empty Contact. See makeRequest.
Definition at line 147 of file Helper.cxx.
{
NameAddr contact;
return makeRegister(to, from, contact);
}
| SipMessage * Helper::makeRegister | ( | const NameAddr & | to, |
| const Data & | transport, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Create a Register request with an overriden Contact, transport is added to Request URI. See makeRequest.
Definition at line 193 of file Helper.cxx.
References computeCallId(), computeTag(), resip::Data::empty(), resip::Uri::host(), resip::RequestLine::method(), resip::ParserCategory::param(), resip::Uri::port(), resip::Uri::scheme(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makeRegister | ( | const NameAddr & | to, |
| const Data & | transport | ||
| ) | [static] |
Create a Register request with an empty Contact, transport is added to Request URI. See makeRequest.
Definition at line 185 of file Helper.cxx.
{
NameAddr contact;
return makeRegister(to, transport, contact);
}
| SipMessage * Helper::makeRequest | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| const NameAddr & | contact, | ||
| MethodTypes | method | ||
| ) | [static] |
Make a new request with a overridden Contact.
To, maxforward=70, requestline created, cseq method set, cseq sequence is 1, from and from tag set, contact set, CallId created. Caller owns the returned pointer and is responsible for deleting it.
| target | Ends up in the RequestURI and To header |
| from | Ends up in the From header |
| contact | Ends up in the Contact header. Stack will not change this when sent. |
| method | Type of request to create. Methos is used in the Request Line and the CSeq. |
Definition at line 117 of file Helper.cxx.
References computeCallId(), computeTag(), resip::RequestLine::method(), resip::ParserCategory::param(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
Referenced by main(), and makeInvite().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makeRequest | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| MethodTypes | method | ||
| ) | [static] |
Make a new request.
To, maxforward=70, requestline created, cseq method set, cseq sequence is 1, from and from tag set, CallId created. Caller owns the returned pointer and is responsible for deleting it.
| target | Ends up in the RequestURI and To header |
| from | Ends up in the From header |
| method | Type of request to create. Methos is used in the Request Line and the CSeq. |
Definition at line 140 of file Helper.cxx.
{
NameAddr contact;
return makeRequest(target, from, contact, method);
}
| void Helper::makeResponse | ( | SipMessage & | response, |
| const SipMessage & | request, | ||
| int | responseCode, | ||
| const Data & | reason = Data::Empty, |
||
| const Data & | hostname = Data::Empty, |
||
| const Data & | warning = Data::Empty |
||
| ) | [static] |
Make a response to a provided request.
Adds a To tag, Contact and Record-Route headers appropriately.
| response | SipMessage populated with the appropriate response |
| request | SipMessage request from which to generate the response |
| responseCode | Response code to use on status line. |
| reason | Optional reason string to use on status line. If not provided then a default reason string will be added for well defined response codes. |
| hostname | Optional hostname to use in Warning header. Only used if warning is also provided. |
| warning | Optional warning text. If present a Warning header is added and hostname is used in warning header. |
Definition at line 366 of file Helper.cxx.
References resip::Message::brief(), resip::WarningCategory::code(), computeTag(), resip::SipMessage::const_header(), DebugLog, resip::Data::empty(), resip::SipMessage::exists(), resip::SipMessage::getRFC2543TransactionId(), resip::SipMessage::header(), resip::WarningCategory::hostname(), resip::SipMessage::isExternal(), resip::LazyParser::isWellFormed(), resip::RequestLine::method(), resip::SipMessage::setFromExternal(), resip::SipMessage::setFromTU(), resip::SipMessage::setRFC2543TransactionId(), resip::Data::size(), tagSize, and resip::WarningCategory::text().
Referenced by doit(), resip::TransactionState::handleBadRequest(), main(), resip::TransactionState::make100(), make405(), makeChallenge(), resip::Transport::makeFailedResponse(), resip::TransactionState::processClientInvite(), resip::TransactionState::processClientNonInvite(), resip::TuIM::processMessageRequest(), resip::TransactionState::processNoDnsResults(), resip::TuIM::processNotifyRequest(), resip::TuIM::processRegisterRequest(), resip::TransactionState::processServerInvite(), resip::TransactionState::processServerNonInvite(), resip::TransactionState::processSipMessageAsNew(), resip::TransactionState::processTransportFailure(), resip::TransactionController::send(), resip::TransactionState::sendToTU(), and Server::thread().
{
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() = 399;
warn.hostname() = hostname;
warn.text() = warning;
response.header(h_Warnings).push_back(warn);
}
if(responseCode > 100 &&
response.const_header(h_To).isWellFormed() &&
!response.const_header(h_To).exists(p_tag))
{
// Only generate a To: tag if one doesn't exist. Think Re-INVITE.
// No totag for failure responses or 100s
// ?bwc? Should we be generating to-tags for failure responses or not?
// The comments say no, but the code says yes. Which is it?
response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize);
}
// .bwc. This will only throw if the topmost Via is malformed, and that
// should have been caught at the transport level.
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.const_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());
}
}

| void Helper::makeResponse | ( | SipMessage & | response, |
| const SipMessage & | request, | ||
| int | responseCode, | ||
| const NameAddr & | myContact, | ||
| const Data & | reason = Data::Empty, |
||
| const Data & | hostname = Data::Empty, |
||
| const Data & | warning = Data::Empty |
||
| ) | [static] |
Make a response to a provided request with an overridden Contact.
Adds a To tag, Contact and Record-Route headers appropriately.
| response | SipMessage populated with the appropriate response |
| request | SipMessage request from which to generate the response |
| responseCode | Response code to use on status line. |
| myContact | Contact header to add to response. |
| reason | Optional reason string to use on status line. If not provided then a default reason string will be added for well defined response codes. |
| hostname | Optional hostname to use in Warning header. Only used if warning is also provided. |
| warning | Optional warning text. If present a Warning header is added and hostname is used in warning header. |
Definition at line 348 of file Helper.cxx.
References resip::LazyParser::clear(), and resip::SipMessage::header().
{
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);
}

| SipMessage * Helper::makeResponse | ( | const SipMessage & | request, |
| int | responseCode, | ||
| const Data & | reason = Data::Empty, |
||
| const Data & | hostname = Data::Empty, |
||
| const Data & | warning = Data::Empty |
||
| ) | [static] |
Make a new response to a provided request.
Adds a To tag, Contact and Record-Route headers appropriately. Caller owns the returned pointer and is responsible for deleting it.
| request | SipMessage request from which to generate the response |
| responseCode | Response code to use on status line. |
| reason | Optional reason string to use on status line. If not provided then a default reason string will be added for well defined response codes. |
| hostname | Optional hostname to use in Warning header. Only used if warning is also provided. |
| warning | Optional warning text. If present a Warning header is added and hostname is used in warning header |
Definition at line 470 of file Helper.cxx.
{
// .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);
return response.release();
}
| SipMessage * Helper::makeResponse | ( | const SipMessage & | request, |
| int | responseCode, | ||
| const NameAddr & | myContact, | ||
| const Data & | reason = Data::Empty, |
||
| const Data & | hostname = Data::Empty, |
||
| const Data & | warning = Data::Empty |
||
| ) | [static] |
Make a new response to a provided request with an overridden Contact.
Adds a To tag, Contact and Record-Route headers appropriately. Caller owns the returned pointer and is responsible for deleting it.
| request | SipMessage request from which to generate the response |
| responseCode | Response code to use on status line. |
| myContact | Contact header to add to response. |
| reason | Optional reason string to use on status line. If not provided then a default reason string will be added for well defined response codes. |
| hostname | Optional hostname to use in Warning header. Only used if warning is also provided. |
| warning | Optional warning text. If present a Warning header is added and hostname is used in warning header. |
Definition at line 447 of file Helper.cxx.
{
// .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();
}
| Data Helper::makeResponseMD5 | ( | const Data & | username, |
| const Data & | password, | ||
| const Data & | realm, | ||
| const Data & | method, | ||
| const Data & | digestUri, | ||
| const Data & | nonce, | ||
| const Data & | qop = Data::Empty, |
||
| const Data & | cnonce = Data::Empty, |
||
| const Data & | cnonceCount = Data::Empty, |
||
| const Contents * | entityBody = 0 |
||
| ) | [static] |
Definition at line 749 of file Helper.cxx.
References resip::Symbols::COLON, and resip::MD5Stream::getHex().
Referenced by makeChallengeResponseAuth().
{
MD5Stream a1;
a1 << username
<< Symbols::COLON
<< realm
<< Symbols::COLON
<< password;
return makeResponseMD5WithA1(a1.getHex(), method, digestUri, nonce, qop,
cnonce, cnonceCount, entity);
}

| Data Helper::makeResponseMD5WithA1 | ( | const Data & | a1, |
| const Data & | method, | ||
| const Data & | digestUri, | ||
| const Data & | nonce, | ||
| const Data & | qop = Data::Empty, |
||
| const Data & | cnonce = Data::Empty, |
||
| const Data & | cnonceCount = Data::Empty, |
||
| const Contents * | entityBody = 0 |
||
| ) | [static] |
Definition at line 703 of file Helper.cxx.
References resip::Symbols::authInt, resip::Symbols::COLON, resip::Data::empty(), resip::MD5Stream::getHex(), and noBody.
Referenced by makeChallengeResponseAuthWithA1().
{
MD5Stream a2;
a2 << method
<< Symbols::COLON
<< digestUri;
if (qop == Symbols::authInt)
{
if (entityBody)
{
MD5Stream eStream;
eStream << *entityBody;
a2 << Symbols::COLON << eStream.getHex();
}
else
{
a2 << Symbols::COLON << noBody;
}
}
MD5Stream r;
r << a1
<< Symbols::COLON
<< nonce
<< Symbols::COLON;
if (!qop.empty())
{
r << cnonceCount
<< Symbols::COLON
<< cnonce
<< Symbols::COLON
<< qop
<< Symbols::COLON;
}
r << a2.getHex();
return r.getHex();
}

| SipMessage * Helper::makeSubscribe | ( | const NameAddr & | target, |
| const NameAddr & | from, | ||
| const NameAddr & | contact | ||
| ) | [static] |
Create a Subscribe request with an overriden Contact. See makeRequest.
Definition at line 293 of file Helper.cxx.
References computeCallId(), computeTag(), resip::RequestLine::method(), resip::ParserCategory::param(), tagSize, resip::RequestLine::uri(), and resip::NameAddr::uri().
{
std::auto_ptr<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.release();
}

| SipMessage * Helper::makeSubscribe | ( | const NameAddr & | target, |
| const NameAddr & | from | ||
| ) | [static] |
Create a Subscribe request with an empty Contact. See makeRequest.
Definition at line 286 of file Helper.cxx.
{
NameAddr contact;
return makeSubscribe(target, from, contact);
}
| Uri Helper::makeUri | ( | const Data & | aor, |
| const Data & | scheme = Symbols::DefaultSipScheme |
||
| ) | [static] |
Definition at line 1602 of file Helper.cxx.
References resip::Symbols::COLON, resip::Data::Preallocate, resip::Data::prefix(), and resip::Data::size().
{
assert(!aor.prefix("sip:"));
assert(!aor.prefix("sips:"));
Data tmp(aor.size() + scheme.size() + 1, Data::Preallocate);
tmp += scheme;
tmp += Symbols::COLON;
tmp += aor;
Uri uri(tmp);
return uri;
}

| SipMessage * Helper::makeWWWChallenge | ( | const SipMessage & | request, |
| const Data & | realm, | ||
| bool | useAuth = true, |
||
| bool | stale = false |
||
| ) | [static] |
Definition at line 1273 of file Helper.cxx.
{
return makeChallenge(request,realm,useAuth,stale,false);
}
| void Helper::massageRoute | ( | const SipMessage & | request, |
| NameAddr & | route | ||
| ) | [static] |
Definition at line 1634 of file Helper.cxx.
References resip::SipMessage::empty(), resip::SipMessage::header(), resip::SipMessage::isRequest(), resip::LazyParser::isWellFormed(), resip::ParserCategory::param(), resip::Uri::scheme(), resip::RequestLine::uri(), and resip::NameAddr::uri().
{
assert(request.isRequest());
// .bwc. Let's not record-route with a tel uri or something, shall we?
// If the topmost route header is malformed, we can get along without.
if (!request.empty(h_Routes) &&
request.header(h_Routes).front().isWellFormed() &&
(request.header(h_Routes).front().uri().scheme() == "sip" ||
request.header(h_Routes).front().uri().scheme() == "sips" ))
{
rt.uri().scheme() = request.header(h_Routes).front().uri().scheme();
}
else if(request.header(h_RequestLine).uri().scheme() == "sip" ||
request.header(h_RequestLine).uri().scheme() == "sips")
{
rt.uri().scheme() = request.header(h_RequestLine).uri().scheme();
}
rt.uri().param(p_lr);
}

| void Helper::processStrictRoute | ( | SipMessage & | request | ) | [static] |
Definition at line 1616 of file Helper.cxx.
References resip::SipMessage::const_header(), resip::Uri::exists(), resip::SipMessage::exists(), resip::SipMessage::hasForceTarget(), resip::SipMessage::header(), resip::SipMessage::setForceTarget(), and resip::RequestLine::uri().
Referenced by resip::DeprecatedDialog::makeRequestInternal(), and resip::DeprecatedDialog::updateRequest().
{
if (request.exists(h_Routes) &&
!request.const_header(h_Routes).empty() &&
!request.const_header(h_Routes).front().uri().exists(p_lr))
{
// The next hop is a strict router. Move the next hop into the
// Request-URI and move the ultimate destination to the end of the
// route list. Force the message target to be the next hop router.
request.header(h_Routes).push_back(NameAddr(request.const_header(h_RequestLine).uri()));
request.header(h_RequestLine).uri() = request.const_header(h_Routes).front().uri();
request.header(h_Routes).pop_front(); // !jf!
assert(!request.hasForceTarget());
request.setForceTarget(request.const_header(h_RequestLine).uri());
}
}

Definition at line 1428 of file Helper.cxx.
References resip::Symbols::COMMA, resip::Data::data(), resip::Data::empty(), resip::Data::Empty, resip::Auth::exists(), resip::ParserCategory::param(), preferredTokens, pTokenSize, resip::Data::size(), and resip::ParseBuffer::skipWhitespace().
{
bool found = false;
size_t index = pTokenSize;
if (challenge.exists(p_qopOptions) && !challenge.param(p_qopOptions).empty())
{
ParseBuffer pb(challenge.param(p_qopOptions).data(), challenge.param(p_qopOptions).size());
do
{
const char* anchor = pb.skipWhitespace();
pb.skipToChar(Symbols::COMMA[0]);
Data q;
pb.data(q, anchor);
if (!pb.eof())
pb.skipChar();
for (size_t i=0; i < pTokenSize; i++)
{
if (q == preferredTokens[i])
{
// found a preferred token; is it higher priority?
if (i < index)
{
found = true;
index = i;
}
}
}
}
while(!pb.eof());
}
if (found)
return preferredTokens[index];
return Data::Empty;
}

| void Helper::setNonceHelper | ( | NonceHelper * | nonceHelper | ) | [static] |
Note: Helper assumes control of NonceHelper object and will delete when global scope is cleaned up.
Definition at line 679 of file Helper.cxx.
{
mNonceHelperPtr.mNonceHelper = nonceHelper;
}
| void Helper::updateNonceCount | ( | unsigned int & | nonceCount, |
| Data & | nonceCountString | ||
| ) | [static] |
Definition at line 1310 of file Helper.cxx.
References DebugLog, and resip::Data::empty().
{
if (!nonceCountString.empty())
{
return;
}
nonceCount++;
{
//DataStream s(nonceCountString);
//s << std::setw(8) << std::setfill('0') << std::hex << nonceCount;
char buf[128];
*buf = 0;
#if (defined(_MSC_VER) && _MSC_VER >= 1400)
sprintf_s(buf,128,"%08x",nonceCount);
#else
sprintf(buf,"%08x",nonceCount);
#endif
nonceCountString = buf;
}
DebugLog(<< "nonceCount is now: [" << nonceCountString << "]");
}

| bool Helper::validateMessage | ( | const SipMessage & | message, |
| resip::Data * | reason = 0 |
||
| ) | [static] |
Definition at line 1705 of file Helper.cxx.
References DebugLog, resip::SipMessage::empty(), resip::SipMessage::header(), InfoLog, resip::SipMessage::isRequest(), resip::LazyParser::isWellFormed(), and resip::RequestLine::method().
Referenced by resip::Transport::basicCheck().
{
if (message.empty(h_To) ||
message.empty(h_From) ||
message.empty(h_CSeq) ||
message.empty(h_CallId) ||
message.empty(h_Vias) ||
message.empty(h_Vias))
{
InfoLog(<< "Missing mandatory header fields (To, From, CSeq, Call-Id or Via)");
DebugLog(<< message);
if(reason) *reason="Missing mandatory header field";
return false;
}
else
{
if(!message.header(h_CSeq).isWellFormed())
{
InfoLog(<<"Malformed CSeq header");
if(reason) *reason="Malformed CSeq header";
return false;
}
if(!message.header(h_Vias).front().isWellFormed())
{
InfoLog(<<"Malformed topmost Via header");
if(reason) *reason="Malformed topmost Via header";
return false;
}
if (message.isRequest())
{
if(!message.header(h_RequestLine).isWellFormed())
{
InfoLog(<< "Illegal request line");
if(reason) *reason="Malformed Request Line";
return false;
}
if(message.header(h_RequestLine).method()!=message.header(h_CSeq).method())
{
InfoLog(<< "Method mismatch btw Request Line and CSeq");
if(reason) *reason="Method mismatch btw Request Line and CSeq";
return false;
}
}
else
{
if(!message.header(h_StatusLine).isWellFormed())
{
InfoLog(<< "Malformed status line");
if(reason) *reason="Malformed status line";
return false;
}
}
return true;
}
}

Helper::NonceHelperPtr Helper::mNonceHelperPtr [static, private] |
Definition at line 581 of file Helper.hxx.
const int Helper::tagSize = 4 [static] |
bytes in to-tag& from-tag, should prob. live somewhere else
Definition at line 48 of file Helper.hxx.
Referenced by makeMessage(), makePublish(), makeRegister(), makeRequest(), resip::DeprecatedDialog::makeResponse(), makeResponse(), and makeSubscribe().
1.7.5.1