|
reSIProcate/repro
9694
|
#include <LocationServer.hxx>


Public Member Functions | |
| LocationServer (ProxyConfig &config, resip::RegistrationPersistenceManager &store, Dispatcher *userInfoDispatcher) | |
| virtual | ~LocationServer () |
| virtual processor_action_t | process (RequestContext &) |
Private Attributes | |
| resip::RegistrationPersistenceManager & | mStore |
| Dispatcher * | mUserInfoDispatcher |
Definition at line 11 of file LocationServer.hxx.
| repro::LocationServer::LocationServer | ( | ProxyConfig & | config, |
| resip::RegistrationPersistenceManager & | store, | ||
| Dispatcher * | userInfoDispatcher | ||
| ) | [inline] |
Definition at line 14 of file LocationServer.hxx.
:
Processor("LocationServer"),
mStore(store),
mUserInfoDispatcher(userInfoDispatcher)
{};
| virtual repro::LocationServer::~LocationServer | ( | ) | [inline, virtual] |
Definition at line 22 of file LocationServer.hxx.
{};
| Processor::processor_action_t LocationServer::process | ( | RequestContext & | context | ) | [virtual] |
RjS! This doesn't look exception safe - need guards
Implements repro::Processor.
Definition at line 30 of file LocationServer.cxx.
{
DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context);
// UserInfoMessage is used to look for existence of user if we cannot find
// them in the Regisration Database. This code handles the asynchronous
// lookup.
UserInfoMessage *userInfo = dynamic_cast<UserInfoMessage*>(context.getCurrentEvent());
if(userInfo && userInfo->getOriginatorAddress() == getAddress()) // Ensure we generated the UserInfo - it could be from the Digest Authenticator
{
// If A1 is empty, then user does not exist - return 404
if(userInfo->A1().empty())
{
resip::SipMessage response;
Helper::makeResponse(response, context.getOriginalRequest(), 404);
context.sendResponse(response);
return Processor::SkipThisChain;
}
else
{
// User exists, but is just not registered - continue processing
return Processor::Continue;
}
}
resip::Uri inputUri = context.getOriginalRequest().header(h_RequestLine).uri().getAorAsUri(context.getOriginalRequest().getSource().getType());
//!RjS! This doesn't look exception safe - need guards
mStore.lockRecord(inputUri);
resip::ContactList contacts;
mStore.getContacts(inputUri,contacts);
if(contacts.size() > 0)
{
TargetPtrList batch;
std::map<resip::Data,resip::ContactList> outboundBatch;
UInt64 now = Timer::getTimeSecs();
for(resip::ContactList::iterator i = contacts.begin(); i != contacts.end(); ++i)
{
resip::ContactInstanceRecord contact = *i;
if (contact.mRegExpires > now)
{
InfoLog (<< *this << " adding target " << contact.mContact <<
" with tuple " << contact.mReceivedFrom);
if(contact.mInstance.empty() || contact.mRegId==0)
{
QValueTarget* target = new QValueTarget(contact);
batch.push_back(target);
}
else
{
outboundBatch[contact.mInstance].push_back(contact);
}
}
else
{
// remove expired contact
mStore.removeContact(inputUri, contact);
}
}
mStore.unlockRecord(inputUri);
std::map<resip::Data,resip::ContactList>::iterator o;
for(o=outboundBatch.begin(); o!=outboundBatch.end(); ++o)
{
o->second.sort(OutboundTarget::instanceCompare); // Orders records by lastUpdate time
OutboundTarget* ot = new OutboundTarget(o->first, o->second);
batch.push_back(ot);
}
if(!batch.empty())
{
// Note: some elements of list are already in a sorted order (see outbound bactch sorting
// above), however list::sort is stable, so it's safe to sort twice, as relative order
// of equal elements is preserved
#ifdef __SUNPRO_CC
sort(batch.begin(), batch.end(), Target::priorityMetricCompare);
#else
batch.sort(Target::priorityMetricCompare);
#endif
context.getResponseContext().addTargetBatch(batch, false /* high priority */);
//ResponseContext should be consuming the vector
assert(batch.empty());
}
}
else
{
mStore.unlockRecord(inputUri);
if(mUserInfoDispatcher)
{
// User does not have an active registration - check if they even exist or not
// so we know if should send a 404 vs a 480.
// Since users are not kept in memory we need to go to the database asynchrounously
// to look for existance. We will use the existing mechanism in place for asynhcronous
// authentication lookups in order to check for existance - we don't need the returned
// A1 hash, but the efficiency of this request is more than adequate for this purpose.
// Currently repro authentication treats authentication realm the same as users aor domain,
// if this changes in the future we may need to add a different mechanism to check for
// existance.
// Note: repro authentication must be enabled in order for mUserInfoDispatcher to be
// defined and for 404 responses to work
UserInfoMessage* async = new UserInfoMessage(*this, context.getTransactionId(), &(context.getProxy()));
async->user() = inputUri.user();
async->realm() = inputUri.host();
async->domain() = inputUri.host();
std::auto_ptr<ApplicationMessage> app(async);
mUserInfoDispatcher->post(app);
return WaitingForEvent;
}
}
return Processor::Continue;
}
Definition at line 27 of file LocationServer.hxx.
Definition at line 28 of file LocationServer.hxx.
1.7.5.1