reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Proxy.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
6#include "repro/Proxy.hxx"
8#include "repro/UserStore.hxx"
10
16#include "rutil/Random.hxx"
17#include "rutil/Lock.hxx"
18#include "rutil/Logger.hxx"
19#include "rutil/Inserter.hxx"
21
22#include <utility>
23
24#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
25
26using namespace resip;
27using namespace repro;
28using namespace std;
29
30// Initialize statics
32
33// Use Static fn with static local object to ensure KeyValueStoreKeyAllocator is created before
34// static calls to allocate new keys in the monkey classes
40
46
52
57
62
67
70 ProcessorChain& requestP, // monkeys
71 ProcessorChain& responseP, // lemurs
72 ProcessorChain& targetP) // baboons
73{
74 return new RequestContext(proxy, requestP, responseP, targetP);
75}
76
78 ProxyConfig& config,
79 ProcessorChain& requestP,
80 ProcessorChain& responseP,
81 ProcessorChain& targetP)
82 : TransactionUser(TransactionUser::RegisterForTransactionTermination),
83 mStack(stack),
84 mConfig(config),
85 mRecordRoute(config.getConfigUri("RecordRouteUri", Uri())),
86 mRecordRouteForced(config.getConfigBool("ForceRecordRouting", false)),
87 mPAssertedIdentityProcessing(config.getConfigBool("EnablePAssertedIdentityProcessing", false)),
88 mNeverStripProxyAuthorizationHeaders(config.getConfigBool("NeverStripProxyAuthorizationHeaders", false)),
89#ifdef PACKAGE_VERSION
90 mServerText(config.getConfigData("ServerText", "repro " PACKAGE_VERSION)),
91#else
92 mServerText(config.getConfigData("ServerText", "")),
93#endif
94 mTimerC(config.getConfigInt("TimerC", 180)),
95 mKeyValueStore(*Proxy::getGlobalKeyValueStoreKeyAllocator()),
96 mRequestProcessorChain(requestP),
97 mResponseProcessorChain(responseP),
98 mTargetProcessorChain(targetP),
99 mUserStore(config.getDataStore()->mUserStore),
100 mOptionsHandler(0),
101 mRequestContextFactory(new RequestContextFactory),
102 mSessionAccountingEnabled(config.getConfigBool("SessionAccountingEnabled", false)),
103 mRegistrationAccountingEnabled(config.getConfigBool("RegistrationAccountingEnabled", false)),
104 mAccountingCollector(0)
105{
106 FlowTokenSalt = Random::getCryptoRandom(20); // 20-octet Crypto Random Key for Salting Flow Token HMACs
107
108 mFifo.setDescription("Proxy::mFifo");
109
111 {
112 addSupportedOption("outbound");
113 }
114
115 // Create Accounting Collector if enabled
117 {
119 }
120}
121
123{
124 shutdown();
125 join();
127 InfoLog (<< "Proxy::thread shutdown with " << mServerRequestContexts.size() << " ServerRequestContexts and " << mClientRequestContexts.size() << " ClientRequestContexts.");
128}
129
130void
132{
133 mOptionsHandler = handler;
134}
135
136void
137Proxy::setRequestContextFactory(std::unique_ptr<RequestContextFactory> requestContextFactory) noexcept
138{
139 mRequestContextFactory = std::move(requestContextFactory);
140}
141
142bool
144{
145 return false;
146}
147
150{
151 return mUserStore;
152}
153
154void
156{
157 InfoLog (<< "Proxy::thread start");
158
159 while (!isShutdown())
160 {
161 Message* msg=0;
162 //DebugLog (<< "TransactionUser::postToTransactionUser " << " &=" << &mFifo << " size=" << mFifo.size());
163
164 try
165 {
166 if ((msg = mFifo.getNext(100)) != 0)
167 {
168 DebugLog (<< "Got: " << *msg);
169
170 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
171 ApplicationMessage* app = dynamic_cast<ApplicationMessage*>(msg);
172 TransactionTerminated* term = dynamic_cast<TransactionTerminated*>(msg);
173
174 if (sip)
175 {
176 Data tid(sip->getTransactionId());
177 tid.lowercase();
178 if (sip->isRequest())
179 {
180 // Verify that the request has all the mandatory headers
181 // (To, From, Call-ID, CSeq) Via is already checked by stack.
182 // See RFC 3261 Section 16.3 Step 1
183 if (!sip->exists(h_To) ||
184 !sip->exists(h_From) ||
185 !sip->exists(h_CallID) ||
186 !sip->exists(h_CSeq) )
187 {
188 // skip this message and move on to the next one
189 delete sip;
190 continue;
191 }
192
193 // The TU selector already checks the URI scheme for us (Sect 16.3, Step 2)
194 if(sip->method()==OPTIONS &&
196 {
198 {
199 std::unique_ptr<SipMessage> resp(new SipMessage);
200 Helper::makeResponse(*resp,*sip,200);
201 if(mOptionsHandler->onOptionsRequest(*sip, *resp))
202 {
203 mStack.send(*resp,this);
204 delete sip;
205 continue;
206 }
207 }
208 else if(sip->header(h_RequestLine).uri().user().empty())
209 {
210 std::unique_ptr<SipMessage> resp(new SipMessage);
211 Helper::makeResponse(*resp,*sip,200);
212
214 {
215 resp->header(h_Supporteds).push_back(Token(Symbols::Outbound));
216 }
217 mStack.send(*resp,this);
218 delete sip;
219 continue;
220 }
221 }
222
223 // check the MaxForwards isn't too low
224 if (!sip->exists(h_MaxForwards))
225 {
226 // .bwc. Add Max-Forwards header if not found.
227 sip->header(h_MaxForwards).value()=20;
228 }
229
230 if(!sip->header(h_MaxForwards).isWellFormed())
231 {
232 //Malformed Max-Forwards! (Maybe we can be lenient and set
233 // it to 70...)
234 std::unique_ptr<SipMessage> response(Helper::makeResponse(*sip,400));
235 response->header(h_StatusLine).reason()="Malformed Max-Forwards";
236 mStack.send(*response,this);
237 delete sip;
238 continue;
239 }
240
241 // .bwc. Unacceptable values for Max-Forwards
242 // !bwc! TODO make this ceiling configurable
243 if(sip->header(h_MaxForwards).value() > 255)
244 {
245 sip->header(h_MaxForwards).value() = 20;
246 }
247 else if(sip->header(h_MaxForwards).value() <= 0)
248 {
249 if (sip->header(h_RequestLine).method() != OPTIONS)
250 {
251 std::unique_ptr<SipMessage> response(Helper::makeResponse(*sip, 483));
252 mStack.send(*response, this);
253 }
254 else // If the request is an OPTIONS, send an appropriate response
255 {
256 std::unique_ptr<SipMessage> response(Helper::makeResponse(*sip, 200));
257 mStack.send(*response, this);
258 }
259 // in either case get rid of the request and process the next one
260 delete sip;
261 continue;
262 }
263
264 if(!sip->empty(h_ProxyRequires))
265 {
266 std::unique_ptr<SipMessage> response;
267
268 for(Tokens::iterator i=sip->header(h_ProxyRequires).begin();
269 i!=sip->header(h_ProxyRequires).end();
270 ++i)
271 {
272 if(!i->isWellFormed() ||
273 !mSupportedOptions.count(i->value()) )
274 {
275 if(!response)
276 {
277 response.reset(Helper::makeResponse(*sip, 420, "Bad extension"));
278 }
279 response->header(h_Unsupporteds).push_back(*i);
280 }
281 }
282
283 if(response)
284 {
285 mStack.send(*response, this);
286 delete sip;
287 continue;
288 }
289 }
290
291
292 if (sip->method() == CANCEL)
293 {
294 RequestContextMap::iterator i = mServerRequestContexts.find(tid);
295
296 if(i == mServerRequestContexts.end())
297 {
298 SipMessage response;
299 Helper::makeResponse(response,*sip,481);
300 mStack.send(response,this);
301 delete sip;
302 }
303 else
304 {
305 try
306 {
307 i->second->process(std::unique_ptr<resip::SipMessage>(sip));
308 }
309 catch(resip::BaseException& e)
310 {
311 // .bwc. Some sort of unhandled error in process.
312 // This is very bad; we cannot form a response
313 // at this point because we do not know
314 // whether the original request still exists.
315 ErrLog(<<"Uncaught exception in process on a CANCEL "
316 "request: " << e);
318 }
319 }
320 }
321 else if (sip->method() == ACK)
322 {
323 // .bwc. This is going to be treated as a new transaction.
324 // The stack is maintaining no state whatsoever for this.
325 // We should treat this exactly like a new transaction.
326 if(sip->mIsBadAck200)
327 {
328 static Data ack("ack");
329 tid+=ack;
330 }
331
332 RequestContext* context=0;
333 RequestContextMap::iterator i = mServerRequestContexts.find(tid);
334
335 // .bwc. This might be an ACK/200, or a stray ACK/failure
336 if(i == mServerRequestContexts.end())
337 {
338 context = mRequestContextFactory->createRequestContext(*this,
342 mServerRequestContexts[tid] = context;
343 }
344 else // .bwc. ACK/failure
345 {
346 context = i->second;
347 }
348
349 // The stack will send TransactionTerminated messages for
350 // client and server transaction which will clean up this
351 // RequestContext
352 try
353 {
354 context->process(std::unique_ptr<resip::SipMessage>(sip));
355 }
356 catch(resip::BaseException& e)
357 {
358 // .bwc. Some sort of unhandled error in process.
359 ErrLog(<<"Uncaught exception in process on an ACK "
360 "request: " << e);
361 }
362 }
363 else
364 {
365 // This is a new request, so create a Request Context for it
366 InfoLog (<< "New RequestContext tid=" << tid << " : " << sip->brief());
367
368
369 if(mServerRequestContexts.count(tid) == 0)
370 {
371 RequestContext* context = mRequestContextFactory->createRequestContext(*this,
375 InfoLog (<< "Inserting new RequestContext tid=" << tid
376 << " -> " << *context);
377 mServerRequestContexts[tid] = context;
378 //DebugLog (<< "RequestContexts: " << InserterP(mServerRequestContexts)); For a busy proxy - this generates a HUGE log statement!
379 try
380 {
381 context->process(std::unique_ptr<resip::SipMessage>(sip));
382 }
383 catch(resip::BaseException& e)
384 {
385 // .bwc. Some sort of unhandled error in process.
386 // This is very bad; we cannot form a response
387 // at this point because we do not know
388 // whether the original request still exists.
389 ErrLog(<<"Uncaught exception in process on a new "
390 "request: " << e);
392 }
393 }
394 else
395 {
396 InfoLog(<<"Got a new non-ACK request "
397 "with an already existing transaction ID. This can "
398 "happen if a new request collides with a previously "
399 "received ACK/200.");
400 SipMessage response;
401 Helper::makeResponse(response,*sip,400,"Transaction-id "
402 "collision");
403 mStack.send(response,this);
404 delete sip;
405 }
406 }
407 }
408 else if (sip->isResponse())
409 {
410 InfoLog (<< "Looking up RequestContext tid=" << tid);
411
412 // TODO is there a problem with a stray 200?
413 RequestContextMap::iterator i = mClientRequestContexts.find(tid);
414 if (i != mClientRequestContexts.end())
415 {
416 try
417 {
418 i->second->process(std::unique_ptr<resip::SipMessage>(sip));
419 }
420 catch(resip::BaseException& e)
421 {
422 // .bwc. Some sort of unhandled error in process.
423 ErrLog(<<"Uncaught exception in process on a response: " << e);
424 }
425 }
426 else
427 {
428 // throw away stray responses
429 InfoLog (<< "Unmatched response (stray?) : " << endl << *msg);
430 delete sip;
431 }
432 }
433 }
434 else if (app)
435 {
436 Data tid(app->getTransactionId());
437 tid.lowercase();
438 DebugLog(<< "Trying to dispatch : " << *app );
439 RequestContextMap::iterator i = mServerRequestContexts.find(tid);
440 // the underlying RequestContext may not exist
441 if (i != mServerRequestContexts.end())
442 {
443 DebugLog(<< "Sending " << *app << " to " << *(i->second));
444 // This goes in as a Message and not an ApplicationMessage
445 // so that we have one peice of code doing dispatch to Monkeys
446 // (the intent is that Monkeys may eventually handle non-SIP
447 // application messages).
448 bool eraseThisTid = (dynamic_cast<Ack200DoneMessage*>(app)!=0);
449 try
450 {
451 i->second->process(std::unique_ptr<resip::ApplicationMessage>(app));
452 }
453 catch(resip::BaseException& e)
454 {
455 ErrLog(<<"Uncaught exception in process: " << e);
456 }
457
458 if (eraseThisTid)
459 {
460 mServerRequestContexts.erase(i);
461 }
462 }
463 else
464 {
465 RequestContextMap::iterator i = mClientRequestContexts.find(tid);
466 if (i != mClientRequestContexts.end())
467 {
468 DebugLog(<< "Sending " << *app << " to " << *(i->second));
469 try
470 {
471 i->second->process(std::unique_ptr<resip::ApplicationMessage>(app));
472 }
473 catch (resip::BaseException &e)
474 {
475 ErrLog(<< "Uncaught exception in process: " << e);
476 }
477 }
478 else
479 {
480 InfoLog(<< "No matching request context...ignoring " << *app);
481 delete app;
482 }
483 }
484 }
485 else if (term)
486 {
487 Data tid(term->getTransactionId());
488 tid.lowercase();
489 if (term->isClientTransaction())
490 {
491 RequestContextMap::iterator i = mClientRequestContexts.find(tid);
492 if (i != mClientRequestContexts.end())
493 {
494 try
495 {
496 i->second->process(*term);
497 }
498 catch(resip::BaseException& e)
499 {
500 ErrLog(<<"Uncaught exception in process: " << e);
501 }
502 mClientRequestContexts.erase(i);
503 }
504 else
505 {
506 InfoLog (<< "No matching request context...ignoring " << *term);
507 }
508 }
509 else
510 {
511 RequestContextMap::iterator i = mServerRequestContexts.find(tid);
512 if (i != mServerRequestContexts.end())
513 {
514 try
515 {
516 i->second->process(*term);
517 }
518 catch(resip::BaseException& e)
519 {
520 ErrLog(<<"Uncaught exception in process: " << e);
521 }
522 mServerRequestContexts.erase(i);
523 }
524 else
525 {
526 InfoLog (<< "No matching request context...ignoring " << *term);
527 }
528 }
529 delete term;
530 }
531 else
532 {
534 }
535 }
536 }
537 catch (BaseException& e)
538 {
539 ErrLog (<< "Caught: " << e);
540 }
541 catch (...)
542 {
543 ErrLog (<< "Caught unknown exception");
544 }
545 }
546 InfoLog (<< "Proxy::thread exit");
547}
548
549void
551{
552 ErrLog(<< "Unknown/unprocessed message passed to proxy fifo (this will leak): " << *msg);
553 resip_assert(false);
554}
555
556void
558{
559 mStack.send(msg, this);
560}
561
562void
564{
565 if(mClientRequestContexts.count(transactionId) == 0)
566 {
567 InfoLog (<< "add client transaction tid=" << transactionId << " " << rc);
568 mClientRequestContexts[transactionId] = rc;
569 }
570 else
571 {
572 ErrLog(<< "Received a client request context whose transaction id matches that of an existing request context. Ignoring.");
573 }
574}
575
576void
577Proxy::postTimerC(std::unique_ptr<TimerCMessage> tc)
578{
579 if(mTimerC > 0)
580 {
581 InfoLog(<<"Posting timer C");
582 mStack.post(*tc,mTimerC,this);
583 }
584}
585
586void
587Proxy::postMS(std::unique_ptr<resip::ApplicationMessage> msg, int msec)
588{
589 mStack.postMS(*msg,msec,this);
590}
591
592const Data&
594{
595 static Data n("Proxy");
596 return n;
597}
598
599bool
600Proxy::isMyUri(const Uri& uri) const
601{
602 bool ret = mStack.isMyDomain(uri.host(), uri.port());
603 if(!ret)
604 {
605 ret = isMyDomain(uri.host());
606 if(ret)
607 {
608 // check if we are listening on the specified port
609 // .slg. this is not perfect, but it will allow us to operate in most environments
610 // where the repro proxy and a UA are running on the same machine.
611 // Note: There is a scenario that we cannot correctly handle - when a UA and
612 // repro are running on the same machine, and they are using the same port but on
613 // different transports types or interfaces. In this case we cannot tell, by looking
614 // at a requestUri or From header if the uri is ours or the UA's, and things will break.
615 if(uri.port() != 0)
616 {
617 ret = mStack.isMyPort(uri.port());
618 }
619 }
620 if (!ret)
621 {
622 ret = isUriTransportRecordRoute(uri);
623 }
624 }
625 DebugLog( << "Proxy::isMyUri " << uri << " " << ret);
626 return ret;
627}
628
629void
630Proxy::addTransportRecordRoute(unsigned int transportKey, const resip::NameAddr& recordRoute)
631{
633 mTransportRecordRoutes[transportKey] = recordRoute;
634}
635
636void Proxy::removeTransportRecordRoute(unsigned int transportKey)
637{
639 mTransportRecordRoutes.erase(transportKey);
640}
641
642bool
644{
646 for (const auto& pair : mTransportRecordRoutes)
647 {
648 if (pair.second.uri().host() == uri.host() &&
649 pair.second.uri().port() == uri.port())
650 {
651 if (pair.second.uri().exists(p_transport) && uri.exists(p_transport))
652 {
653 //InfoLog(<< "Proxy::isUriTransportRecordRoute: recordRoute(with transport)=" << pair.second.uri() << ", uri=" << uri);
654 return pair.second.uri().param(p_transport) == uri.param(p_transport);
655 }
656 //InfoLog(<< "Proxy::isUriTransportRecordRoute: recordRoute=" << pair.second.uri() << ", uri=" << uri);
657 return true;
658 }
659 }
660 return false;
661}
662
663const resip::NameAddr&
664Proxy::getRecordRoute(unsigned int transportKey, bool* transportSpecific) const
665{
667 TransportRecordRouteMap::const_iterator it = mTransportRecordRoutes.find(transportKey);
668 if(it != mTransportRecordRoutes.end())
669 {
670 if(transportSpecific)
671 {
672 *transportSpecific = true;
673 }
674 // Transport specific record-route found
675 return it->second;
676 }
677 if (transportSpecific)
678 {
679 *transportSpecific = false;
680 }
681 return mRecordRoute;
682}
683
684bool
689
690void
692{
693 mSupportedOptions.insert(option);
694}
695
696void
698{
699 mSupportedOptions.erase(option);
700}
701
702void
704{
706 {
708 mAccountingCollector->doSessionAccounting(sip, received, context);
709 }
710}
711
712void
721
722
723/* ====================================================================
724 * The Vovida Software License, Version 1.0
725 *
726 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
727 *
728 * Redistribution and use in source and binary forms, with or without
729 * modification, are permitted provided that the following conditions
730 * are met:
731 *
732 * 1. Redistributions of source code must retain the above copyright
733 * notice, this list of conditions and the following disclaimer.
734 *
735 * 2. Redistributions in binary form must reproduce the above copyright
736 * notice, this list of conditions and the following disclaimer in
737 * the documentation and/or other materials provided with the
738 * distribution.
739 *
740 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
741 * and "Vovida Open Communication Application Library (VOCAL)" must
742 * not be used to endorse or promote products derived from this
743 * software without prior written permission. For written
744 * permission, please contact vocal@vovida.org.
745 *
746 * 4. Products derived from this software may not be called "VOCAL", nor
747 * may "VOCAL" appear in their name, without prior written
748 * permission of Vovida Networks, Inc.
749 *
750 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
751 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
752 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
753 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
754 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
755 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
756 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
757 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
758 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
759 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
760 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
761 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
762 * DAMAGE.
763 *
764 * ====================================================================
765 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
virtual void doSessionAccounting(const resip::SipMessage &sip, bool received, RequestContext &context)
virtual void doRegistrationAccounting(RegistrationEvent regevent, const resip::SipMessage &sip)
virtual bool onOptionsRequest(const resip::SipMessage &request, resip::SipMessage &response)=0
virtual bool isMyUri(const resip::Uri &uri) const
Definition Proxy.cxx:600
const resip::NameAddr & getRecordRoute(unsigned int transportKey, bool *transportSpecific=0) const
Definition Proxy.cxx:664
virtual bool isShutDown() const
Definition Proxy.cxx:143
bool mRegistrationAccountingEnabled
Definition Proxy.hxx:154
virtual ~Proxy()
Definition Proxy.cxx:122
void doSessionAccounting(const resip::SipMessage &sip, bool received, RequestContext &context)
Definition Proxy.cxx:703
void addSupportedOption(const resip::Data &option)
Definition Proxy.cxx:691
void removeSupportedOption(const resip::Data &option)
Definition Proxy.cxx:697
virtual const resip::Data & name() const
Return the name of this TransactionUser.
Definition Proxy.cxx:593
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getRequestKeyValueStoreKeyAllocator()
Definition Proxy.cxx:41
ProcessorChain & mResponseProcessorChain
Definition Proxy.hxx:132
void removeTransportRecordRoute(unsigned int transportKey)
Definition Proxy.cxx:636
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getGlobalKeyValueStoreKeyAllocator()
Definition Proxy.cxx:35
UserStore & getUserStore() noexcept
Definition Proxy.cxx:149
TransportRecordRouteMap mTransportRecordRoutes
Definition Proxy.hxx:120
std::unique_ptr< RequestContextFactory > mRequestContextFactory
Definition Proxy.hxx:151
static resip::Data FlowTokenSalt
Definition Proxy.hxx:61
OptionsHandler * mOptionsHandler
Definition Proxy.hxx:150
resip::NameAddr mRecordRoute
Definition Proxy.hxx:118
void doRegistrationAccounting(repro::AccountingCollector::RegistrationEvent regEvent, const resip::SipMessage &sip)
Definition Proxy.cxx:713
static resip::KeyValueStore::Key allocateRequestKeyValueStoreKey()
Definition Proxy.cxx:58
void addTransportRecordRoute(unsigned int transportKey, const resip::NameAddr &recordRoute)
Definition Proxy.cxx:630
ProcessorChain & mRequestProcessorChain
Definition Proxy.hxx:131
bool compressionEnabled() const
Definition Proxy.cxx:685
static resip::KeyValueStore::Key allocateGlobalKeyValueStoreKey()
Definition Proxy.cxx:53
ProcessorChain & mTargetProcessorChain
Definition Proxy.hxx:133
bool isUriTransportRecordRoute(const resip::Uri &uri) const
Definition Proxy.cxx:643
bool mSessionAccountingEnabled
Definition Proxy.hxx:153
void setOptionsHandler(OptionsHandler *handler) noexcept
Definition Proxy.cxx:131
void setRequestContextFactory(std::unique_ptr< RequestContextFactory > requestContextFactory) noexcept
Definition Proxy.cxx:137
void postTimerC(std::unique_ptr< TimerCMessage > tc)
Definition Proxy.cxx:577
std::set< resip::Data > mSupportedOptions
Definition Proxy.hxx:149
resip::Mutex mTransportRecordRouteMutex
Definition Proxy.hxx:121
void postMS(std::unique_ptr< resip::ApplicationMessage > msg, int msec)
Definition Proxy.cxx:587
void send(const resip::SipMessage &msg)
Definition Proxy.cxx:557
AccountingCollector * mAccountingCollector
Definition Proxy.hxx:155
virtual void thread()
Definition Proxy.cxx:155
UserStore & mUserStore
Definition Proxy.hxx:148
RequestContextMap mServerRequestContexts
Definition Proxy.hxx:146
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getTargetKeyValueStoreKeyAllocator()
Definition Proxy.cxx:47
resip::SipStack & mStack
Definition Proxy.hxx:116
RequestContextMap mClientRequestContexts
Definition Proxy.hxx:145
static resip::KeyValueStore::Key allocateTargetKeyValueStoreKey()
Definition Proxy.cxx:63
void addClientTransaction(const resip::Data &transactionId, RequestContext *rc)
Definition Proxy.cxx:563
virtual void processUnknownMessage(resip::Message *msg)
Definition Proxy.cxx:550
virtual RequestContext * createRequestContext(Proxy &proxy, ProcessorChain &requestP, ProcessorChain &responseP, ProcessorChain &targetP)
Definition Proxy.cxx:69
virtual void process(resip::TransactionTerminated &msg)
A base-class for messages used by applications.
virtual const Data & getTransactionId() const
The abstract base-class for all exceptions thrown by resip code.
Algorithm getAlgorithm() const
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
Data & lowercase()
Converts this Data to lowercase.
Definition Data.cxx:1635
size_type find(const Data &match, size_type start=0) const
Finds a specified sequence of bytes in this Data.
Definition Data.cxx:1947
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
static bool getOutboundSupported()
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
The base-class used for message-passing.
Definition Message.hxx:21
virtual Brief brief() const
return a facet for brief encoding of message
Definition Message.cxx:16
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
static int getCryptoRandom()
Definition Random.cxx:330
const Uri & uri() const
MethodTypes & method()
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
bool empty(const HeaderBase &headerType) const
Returns true if the header field is present and non-empty, false otherwise.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
virtual const Data & getTransactionId() const
Returns the transaction id from the branch or if 2543, the computed hash.
bool isResponse() const
Returns true if message is a response, false otherwise.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
resip::MethodTypes method() const
returns the method type of the message
This is the primary point of interaction between the app-layer and the stack.
Definition SipStack.hxx:160
bool isMyPort(int port) const
Returns true if port is handled by this stack.
Definition SipStack.cxx:847
void send(const SipMessage &msg, TransactionUser *tu=0)
allows a TU to send a message
Definition SipStack.cxx:867
bool isMyDomain(const Data &domain, int port) const
Returns true if domain is handled by this stack.
Definition SipStack.cxx:837
void abandonServerTransaction(const Data &tid)
Tells the stack that the TU has abandoned a server transaction.
void post(std::unique_ptr< ApplicationMessage > message, unsigned int secondsLater, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in seconds.
void postMS(std::unique_ptr< ApplicationMessage > message, unsigned int ms, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in milli-seconds.
static const char * Outbound
Definition Symbols.hxx:114
virtual void shutdown()
Definition ThreadIf.cxx:190
bool isShutdown() const
Definition ThreadIf.cxx:212
Represents the "token" element in the RFC 3261 grammar.
Definition Token.hxx:18
virtual const Data & getTransactionId() const
The base-class for an RFC 3261 Transaction User.
TimeLimitFifo< Message > mFifo
This TransactionUser's fifo.
bool isMyDomain(const Data &domain) const
Returns true iff domain matches one of the domains that this TransactionUser is responsible for.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
int & port()
Definition Uri.hxx:145
bool exists(const Param< Uri > &paramType) const
Definition Uri.cxx:1701
Data & user()
Definition Uri.hxx:42
Data & host()
Definition Uri.hxx:40
const Data & param(const ExtensionParameter &param) const
Const accessor for non-natively-supported parameter types.
Compression & getCompression()
Accessor for the Compression object the stack is using.
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
Definition Headers.cxx:348
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
Definition Lock.hxx:28
RequestLineType h_RequestLine
Definition Headers.cxx:347