1
#if defined(HAVE_CONFIG_H)
7
#include "resip/stack/SipMessage.hxx"
8
#include "resip/stack/Helper.hxx"
9
#include "resip/stack/ExtensionParameter.hxx"
10
#include "repro/monkeys/LocationServer.hxx"
11
#include "repro/RequestContext.hxx"
12
#include "repro/UserInfoMessage.hxx"
13
#include "repro/OutboundTarget.hxx"
14
#include "repro/QValueTarget.hxx"
15
#include "repro/Proxy.hxx"
16
#include "resip/stack/SipStack.hxx"
18
#include "rutil/WinLeakCheck.hxx"
21
#include "rutil/Logger.hxx"
22
#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
24
using namespace resip;
25
using namespace repro;
29
Processor::processor_action_t
30
LocationServer::process(RequestContext& context)
32
DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context);
34
// UserInfoMessage is used to look for existence of user if we cannot find
35
// them in the Regisration Database. This code handles the asynchronous
37
UserInfoMessage *userInfo = dynamic_cast<UserInfoMessage*>(context.getCurrentEvent());
38
if(userInfo && userInfo->getOriginatorAddress() == getAddress()) // Ensure we generated the UserInfo - it could be from the Digest Authenticator
40
// If A1 is empty, then user does not exist - return 404
41
if(userInfo->A1().empty())
43
resip::SipMessage response;
44
Helper::makeResponse(response, context.getOriginalRequest(), 404);
45
context.sendResponse(response);
46
return Processor::SkipThisChain;
50
// User exists, but is just not registered - continue processing
51
return Processor::Continue;
55
resip::Uri inputUri = context.getOriginalRequest().header(h_RequestLine).uri().getAorAsUri(context.getOriginalRequest().getSource().getType());
57
//!RjS! This doesn't look exception safe - need guards
58
mStore.lockRecord(inputUri);
60
resip::ContactList contacts;
61
mStore.getContacts(inputUri,contacts);
63
if(contacts.size() > 0)
66
std::map<resip::Data,resip::ContactList> outboundBatch;
67
UInt64 now = Timer::getTimeSecs();
68
for(resip::ContactList::iterator i = contacts.begin(); i != contacts.end(); ++i)
70
resip::ContactInstanceRecord contact = *i;
71
if (contact.mRegExpires > now)
73
InfoLog (<< *this << " adding target " << contact.mContact <<
74
" with tuple " << contact.mReceivedFrom);
75
if(contact.mInstance.empty() || contact.mRegId==0)
77
QValueTarget* target = new QValueTarget(contact);
78
batch.push_back(target);
82
outboundBatch[contact.mInstance].push_back(contact);
87
// remove expired contact
88
mStore.removeContact(inputUri, contact);
92
mStore.unlockRecord(inputUri);
94
std::map<resip::Data,resip::ContactList>::iterator o;
96
for(o=outboundBatch.begin(); o!=outboundBatch.end(); ++o)
98
o->second.sort(OutboundTarget::instanceCompare); // Orders records by lastUpdate time
99
OutboundTarget* ot = new OutboundTarget(o->first, o->second);
105
// Note: some elements of list are already in a sorted order (see outbound bactch sorting
106
// above), however list::sort is stable, so it's safe to sort twice, as relative order
107
// of equal elements is preserved
109
sort(batch.begin(), batch.end(), Target::priorityMetricCompare);
111
batch.sort(Target::priorityMetricCompare);
113
context.getResponseContext().addTargetBatch(batch, false /* high priority */);
114
//ResponseContext should be consuming the vector
115
assert(batch.empty());
120
mStore.unlockRecord(inputUri);
122
if(mUserInfoDispatcher)
124
// User does not have an active registration - check if they even exist or not
125
// so we know if should send a 404 vs a 480.
126
// Since users are not kept in memory we need to go to the database asynchrounously
127
// to look for existance. We will use the existing mechanism in place for asynhcronous
128
// authentication lookups in order to check for existance - we don't need the returned
129
// A1 hash, but the efficiency of this request is more than adequate for this purpose.
130
// Currently repro authentication treats authentication realm the same as users aor domain,
131
// if this changes in the future we may need to add a different mechanism to check for
133
// Note: repro authentication must be enabled in order for mUserInfoDispatcher to be
134
// defined and for 404 responses to work
135
UserInfoMessage* async = new UserInfoMessage(*this, context.getTransactionId(), &(context.getProxy()));
136
async->user() = inputUri.user();
137
async->realm() = inputUri.host();
138
async->domain() = inputUri.host();
139
std::auto_ptr<ApplicationMessage> app(async);
140
mUserInfoDispatcher->post(app);
141
return WaitingForEvent;
145
return Processor::Continue;
149
/* ====================================================================
150
* The Vovida Software License, Version 1.0
152
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
154
* Redistribution and use in source and binary forms, with or without
155
* modification, are permitted provided that the following conditions
158
* 1. Redistributions of source code must retain the above copyright
159
* notice, this list of conditions and the following disclaimer.
161
* 2. Redistributions in binary form must reproduce the above copyright
162
* notice, this list of conditions and the following disclaimer in
163
* the documentation and/or other materials provided with the
166
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
167
* and "Vovida Open Communication Application Library (VOCAL)" must
168
* not be used to endorse or promote products derived from this
169
* software without prior written permission. For written
170
* permission, please contact vocal@vovida.org.
172
* 4. Products derived from this software may not be called "VOCAL", nor
173
* may "VOCAL" appear in their name, without prior written
174
* permission of Vovida Networks, Inc.
176
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
177
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
178
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
179
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
180
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
181
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
182
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
183
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
184
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
185
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
186
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
187
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
190
* ====================================================================
192
* This software consists of voluntary contributions made by Vovida
193
* Networks, Inc. and many individuals on behalf of Vovida Networks,
194
* Inc. For more information on Vovida Networks, Inc., please see
195
* <http://www.vovida.org/>.