~ubuntu-branches/ubuntu/saucy/resiprocate/saucy-proposed

« back to all changes in this revision

Viewing changes to repro/monkeys/LocationServer.cxx

  • Committer: Package Import Robot
  • Author(s): Daniel Pocock
  • Date: 2012-05-17 19:29:59 UTC
  • Revision ID: package-import@ubuntu.com-20120517192959-vv00m77isztdy64q
Tags: upstream-1.8.2
ImportĀ upstreamĀ versionĀ 1.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if defined(HAVE_CONFIG_H)
 
2
#include "config.h"
 
3
#endif
 
4
 
 
5
#include <algorithm>
 
6
 
 
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"
 
17
 
 
18
#include "rutil/WinLeakCheck.hxx"
 
19
 
 
20
 
 
21
#include "rutil/Logger.hxx"
 
22
#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
 
23
 
 
24
using namespace resip;
 
25
using namespace repro;
 
26
using namespace std;
 
27
 
 
28
 
 
29
Processor::processor_action_t
 
30
LocationServer::process(RequestContext& context)
 
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 Regisration 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);
 
46
         return Processor::SkipThisChain;
 
47
      }
 
48
      else
 
49
      {
 
50
         // User exists, but is just not registered - continue processing
 
51
         return Processor::Continue;
 
52
      }
 
53
   }
 
54
 
 
55
   resip::Uri inputUri = context.getOriginalRequest().header(h_RequestLine).uri().getAorAsUri(context.getOriginalRequest().getSource().getType());
 
56
 
 
57
   //!RjS! This doesn't look exception safe - need guards
 
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;
 
67
      UInt64 now = Timer::getTimeSecs();
 
68
      for(resip::ContactList::iterator i  = contacts.begin(); i != contacts.end(); ++i)
 
69
      {
 
70
         resip::ContactInstanceRecord contact = *i;
 
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(o->first, 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 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
 
108
#ifdef __SUNPRO_CC
 
109
         sort(batch.begin(), batch.end(), Target::priorityMetricCompare);
 
110
#else
 
111
         batch.sort(Target::priorityMetricCompare);
 
112
#endif
 
113
         context.getResponseContext().addTargetBatch(batch, false /* high priority */);
 
114
         //ResponseContext should be consuming the vector
 
115
         assert(batch.empty());
 
116
      }
 
117
   }
 
118
   else
 
119
   {
 
120
      mStore.unlockRecord(inputUri);
 
121
 
 
122
      if(mUserInfoDispatcher)
 
123
      {
 
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
 
132
         // existance.
 
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;
 
142
      }
 
143
   }
 
144
 
 
145
   return Processor::Continue;
 
146
}
 
147
 
 
148
 
 
149
/* ====================================================================
 
150
 * The Vovida Software License, Version 1.0 
 
151
 * 
 
152
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
 
153
 * 
 
154
 * Redistribution and use in source and binary forms, with or without
 
155
 * modification, are permitted provided that the following conditions
 
156
 * are met:
 
157
 * 
 
158
 * 1. Redistributions of source code must retain the above copyright
 
159
 *    notice, this list of conditions and the following disclaimer.
 
160
 * 
 
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
 
164
 *    distribution.
 
165
 * 
 
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.
 
171
 *
 
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.
 
175
 * 
 
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
 
188
 * DAMAGE.
 
189
 * 
 
190
 * ====================================================================
 
191
 * 
 
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/>.
 
196
 *
 
197
 */