reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
LocationServer.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#include <algorithm>
6
15#include "repro/Proxy.hxx"
17
19
20
21#include "rutil/Logger.hxx"
22#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
23
24using namespace resip;
25using namespace repro;
26using namespace std;
27
28
31{
32 DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << context);
33
34 // UserInfoMessage is used to look for existence of user if we cannot find
35 // them in the Registration Database. This code handles the asynchronous
36 // lookup.
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
39 {
40 // If A1 is empty, then user does not exist - return 404
41 if(userInfo->A1().empty())
42 {
43 resip::SipMessage response;
44 Helper::makeResponse(response, context.getOriginalRequest(), 404);
45 context.sendResponse(response);
47 }
48 else
49 {
50 // User exists, but is just not registered - continue processing
52 }
53 }
54
56
58 mStore.lockRecord(inputUri);
59
60 resip::ContactList contacts;
61 mStore.getContacts(inputUri,contacts);
62
63 if(contacts.size() > 0)
64 {
65 TargetPtrList batch;
66 std::map<resip::Data,resip::ContactList> outboundBatch;
68 for(resip::ContactList::iterator i = contacts.begin(); i != contacts.end(); ++i)
69 {
71 if (contact.mRegExpires > now)
72 {
73 InfoLog (<< *this << " adding target " << contact.mContact <<
74 " with tuple " << contact.mReceivedFrom);
75 if(contact.mInstance.empty() || contact.mRegId==0)
76 {
77 QValueTarget* target = new QValueTarget(contact);
78 batch.push_back(target);
79 }
80 else
81 {
82 outboundBatch[contact.mInstance].push_back(contact);
83 }
84 }
85 else
86 {
87 // remove expired contact
88 mStore.removeContact(inputUri, contact);
89 }
90 }
91
92 mStore.unlockRecord(inputUri);
93
94 std::map<resip::Data,resip::ContactList>::iterator o;
95
96 for(o=outboundBatch.begin(); o!=outboundBatch.end(); ++o)
97 {
98 o->second.sort(OutboundTarget::instanceCompare); // Orders records by lastUpdate time
99 OutboundTarget* ot = new OutboundTarget(inputUri.toString(), o->second);
100 batch.push_back(ot);
101 }
102
103 if(!batch.empty())
104 {
105 // Note: some elements of list are already in a sorted order (see outbound batch sorting
106 // above), however list::sort is stable, so it's safe to sort twice, as relative order
107 // of equal elements is preserved
108#ifdef __SUNPRO_CC
109 sort(batch.begin(), batch.end(), Target::priorityMetricCompare);
110#else
112#endif
113 context.getResponseContext().addTargetBatch(batch, false /* high priority */);
114 //ResponseContext should be consuming the vector
115 resip_assert(batch.empty());
116 }
117 }
118 else
119 {
120 mStore.unlockRecord(inputUri);
121
122 // Note: if we already have targets added from the Route processor we will just skip this
123 // as we don't want to return a 404
125 {
126 // User does not have an active registration - check if they even exist or not
127 // so we know if should send a 404 vs a 480.
128 // Since users are not kept in memory we need to go to the database asynchronously
129 // to look for existence. We will use the existing mechanism in place for asynchronous
130 // authentication lookups in order to check for existence - we don't need the returned
131 // A1 hash, but the efficiency of this request is more than adequate for this purpose.
132 // Currently repro authentication treats authentication realm the same as users aor domain,
133 // if this changes in the future we may need to add a different mechanism to check for
134 // existence.
135 // Note: repro authentication must be enabled in order for mUserInfoDispatcher to be
136 // defined and for 404 responses to work
137 UserInfoMessage* async = new UserInfoMessage(*this, context.getTransactionId(), &(context.getProxy()));
138 async->user() = inputUri.user();
139 async->realm() = inputUri.host();
140 async->domain() = inputUri.host();
141 std::unique_ptr<ApplicationMessage> app(async);
143 return WaitingForEvent;
144 }
145 }
146
147 return Processor::Continue;
148}
149
150
151/* ====================================================================
152 * The Vovida Software License, Version 1.0
153 *
154 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
155 *
156 * Redistribution and use in source and binary forms, with or without
157 * modification, are permitted provided that the following conditions
158 * are met:
159 *
160 * 1. Redistributions of source code must retain the above copyright
161 * notice, this list of conditions and the following disclaimer.
162 *
163 * 2. Redistributions in binary form must reproduce the above copyright
164 * notice, this list of conditions and the following disclaimer in
165 * the documentation and/or other materials provided with the
166 * distribution.
167 *
168 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
169 * and "Vovida Open Communication Application Library (VOCAL)" must
170 * not be used to endorse or promote products derived from this
171 * software without prior written permission. For written
172 * permission, please contact vocal@vovida.org.
173 *
174 * 4. Products derived from this software may not be called "VOCAL", nor
175 * may "VOCAL" appear in their name, without prior written
176 * permission of Vovida Networks, Inc.
177 *
178 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
179 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
180 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
181 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
182 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
183 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
184 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
185 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
186 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
187 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
188 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
189 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
190 * DAMAGE.
191 *
192 * ====================================================================
193 *
194 * This software consists of voluntary contributions made by Vovida
195 * Networks, Inc. and many individuals on behalf of Vovida Networks,
196 * Inc. For more information on Vovida Networks, Inc., please see
197 * <http://www.vovida.org/>.
198 *
199 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define resip_assert(x)
This file needs to work for both C and C++ code.
resip::Dispatcher * mUserInfoDispatcher
virtual processor_action_t process(RequestContext &)
resip::RegistrationPersistenceManager & mStore
static bool instanceCompare(const resip::ContactInstanceRecord &lhs, const resip::ContactInstanceRecord &rhs)
std::vector< short > & getOriginatorAddress()
virtual const std::vector< short > & getAddress() const
Definition Processor.cxx:63
resip::SipMessage & getOriginalRequest()
Returns the SipMessage associated with the server transaction.
resip::Message * getCurrentEvent()
Returns the event that we are currently working on.
ResponseContext & getResponseContext()
void sendResponse(resip::SipMessage &response)
resip::Data getTransactionId() const
bool addTargetBatch(TargetPtrList &targets, bool highPriority=false)
Adds a batch of Targets.
static bool priorityMetricCompare(const Target *lhs, const Target *rhs)
Definition Target.hxx:60
const resip::Data & A1() const
const resip::Data & user() const
const resip::Data & domain() const
const resip::Data & realm() const
A single contact record, bound to an Aor during registration.
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
virtual bool post(std::unique_ptr< resip::ApplicationMessage > &work)
Posts a message to this thread bank.
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.
Definition Helper.cxx:412
virtual void unlockRecord(const Uri &aor)=0
virtual void lockRecord(const Uri &aor)=0
virtual void removeContact(const Uri &aor, const ContactInstanceRecord &rec)=0
virtual void getContacts(const Uri &aor, ContactList &container)=0
const Uri & uri() const
Represents a SIP message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
const Tuple & getSource() const
Returns the source tuple that the message was received from only makes sense for messages received fr...
static uint64_t getTimeSecs()
Returns the current clock time in seconds.
Definition Timer.hxx:78
TransportType getType() const
Definition Tuple.hxx:122
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
Data toString() const
Definition Uri.cxx:1678
Data & user()
Definition Uri.hxx:42
Data & host()
Definition Uri.hxx:40
Uri getAorAsUri(TransportType transportTypeToRemoveDefaultPort=UNKNOWN_TRANSPORT) const
Definition Uri.cxx:1103
This Class is used to implement a primitive form of RPC using loose XML formatting.
std::list< Target * > TargetPtrList
Definition Target.hxx:81
dcm! – add UnusedChecking(_enum) below;
RequestLineType h_RequestLine
Definition Headers.cxx:347
std::list< ContactInstanceRecord > ContactList
unsigned __int64 uint64_t
Definition stdint.h:95