1#if defined(HAVE_CONFIG_H)
24#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
38 return globalAllocator;
44 return requestAllocator;
50 return targetAllocator;
85 mRecordRoute(config.getConfigUri(
"RecordRouteUri",
Uri())),
86 mRecordRouteForced(config.getConfigBool(
"ForceRecordRouting", false)),
87 mPAssertedIdentityProcessing(config.getConfigBool(
"EnablePAssertedIdentityProcessing", false)),
88 mNeverStripProxyAuthorizationHeaders(config.getConfigBool(
"NeverStripProxyAuthorizationHeaders", false)),
90 mServerText(config.getConfigData(
"ServerText",
"repro " PACKAGE_VERSION)),
92 mServerText(config.getConfigData(
"ServerText",
"")),
94 mTimerC(config.getConfigInt(
"TimerC", 180)),
95 mKeyValueStore(*
Proxy::getGlobalKeyValueStoreKeyAllocator()),
96 mRequestProcessorChain(requestP),
97 mResponseProcessorChain(responseP),
98 mTargetProcessorChain(targetP),
99 mUserStore(config.getDataStore()->mUserStore),
102 mSessionAccountingEnabled(config.getConfigBool(
"SessionAccountingEnabled", false)),
103 mRegistrationAccountingEnabled(config.getConfigBool(
"RegistrationAccountingEnabled", false)),
104 mAccountingCollector(0)
108 mFifo.setDescription(
"Proxy::mFifo");
133 mOptionsHandler = handler;
139 mRequestContextFactory = std::move(requestContextFactory);
157 InfoLog (<<
"Proxy::thread start");
166 if ((msg =
mFifo.getNext(100)) != 0)
194 if(sip->
method()==OPTIONS &&
199 std::unique_ptr<SipMessage> resp(
new SipMessage);
210 std::unique_ptr<SipMessage> resp(
new SipMessage);
224 if (!sip->
exists(h_MaxForwards))
227 sip->
header(h_MaxForwards).value()=20;
235 response->header(
h_StatusLine).reason()=
"Malformed Max-Forwards";
243 if(sip->
header(h_MaxForwards).value() > 255)
245 sip->
header(h_MaxForwards).value() = 20;
247 else if(sip->
header(h_MaxForwards).value() <= 0)
264 if(!sip->
empty(h_ProxyRequires))
266 std::unique_ptr<SipMessage> response;
268 for(Tokens::iterator i=sip->
header(h_ProxyRequires).begin();
269 i!=sip->
header(h_ProxyRequires).end();
272 if(!i->isWellFormed() ||
279 response->
header(h_Unsupporteds).push_back(*i);
292 if (sip->
method() == CANCEL)
307 i->second->process(std::unique_ptr<resip::SipMessage>(sip));
315 ErrLog(<<
"Uncaught exception in process on a CANCEL "
321 else if (sip->
method() == ACK)
328 static Data ack(
"ack");
354 context->
process(std::unique_ptr<resip::SipMessage>(sip));
359 ErrLog(<<
"Uncaught exception in process on an ACK "
366 InfoLog (<<
"New RequestContext tid=" << tid <<
" : " << sip->
brief());
375 InfoLog (<<
"Inserting new RequestContext tid=" << tid
376 <<
" -> " << *context);
381 context->
process(std::unique_ptr<resip::SipMessage>(sip));
389 ErrLog(<<
"Uncaught exception in process on a new "
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.");
410 InfoLog (<<
"Looking up RequestContext tid=" << tid);
418 i->second->process(std::unique_ptr<resip::SipMessage>(sip));
423 ErrLog(<<
"Uncaught exception in process on a response: " << e);
429 InfoLog (<<
"Unmatched response (stray?) : " << endl << *msg);
438 DebugLog(<<
"Trying to dispatch : " << *app );
443 DebugLog(<<
"Sending " << *app <<
" to " << *(i->second));
451 i->second->process(std::unique_ptr<resip::ApplicationMessage>(app));
455 ErrLog(<<
"Uncaught exception in process: " << e);
468 DebugLog(<<
"Sending " << *app <<
" to " << *(i->second));
471 i->second->process(std::unique_ptr<resip::ApplicationMessage>(app));
475 ErrLog(<<
"Uncaught exception in process: " << e);
480 InfoLog(<<
"No matching request context...ignoring " << *app);
496 i->second->process(*term);
500 ErrLog(<<
"Uncaught exception in process: " << e);
506 InfoLog (<<
"No matching request context...ignoring " << *term);
516 i->second->process(*term);
520 ErrLog(<<
"Uncaught exception in process: " << e);
526 InfoLog (<<
"No matching request context...ignoring " << *term);
539 ErrLog (<<
"Caught: " << e);
543 ErrLog (<<
"Caught unknown exception");
546 InfoLog (<<
"Proxy::thread exit");
552 ErrLog(<<
"Unknown/unprocessed message passed to proxy fifo (this will leak): " << *msg);
567 InfoLog (<<
"add client transaction tid=" << transactionId <<
" " << rc);
572 ErrLog(<<
"Received a client request context whose transaction id matches that of an existing request context. Ignoring.");
595 static Data n(
"Proxy");
625 DebugLog( <<
"Proxy::isMyUri " << uri <<
" " << ret);
648 if (pair.second.uri().host() == uri.
host() &&
649 pair.second.uri().port() == uri.
port())
651 if (pair.second.uri().exists(p_transport) && uri.
exists(p_transport))
654 return pair.second.uri().param(p_transport) == uri.
param(p_transport);
670 if(transportSpecific)
672 *transportSpecific =
true;
677 if (transportSpecific)
679 *transportSpecific =
false;
#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
const resip::NameAddr & getRecordRoute(unsigned int transportKey, bool *transportSpecific=0) const
virtual bool isShutDown() const
bool mRegistrationAccountingEnabled
void doSessionAccounting(const resip::SipMessage &sip, bool received, RequestContext &context)
void addSupportedOption(const resip::Data &option)
void removeSupportedOption(const resip::Data &option)
virtual const resip::Data & name() const
Return the name of this TransactionUser.
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getRequestKeyValueStoreKeyAllocator()
ProcessorChain & mResponseProcessorChain
void removeTransportRecordRoute(unsigned int transportKey)
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getGlobalKeyValueStoreKeyAllocator()
UserStore & getUserStore() noexcept
TransportRecordRouteMap mTransportRecordRoutes
std::unique_ptr< RequestContextFactory > mRequestContextFactory
static resip::Data FlowTokenSalt
OptionsHandler * mOptionsHandler
resip::NameAddr mRecordRoute
void doRegistrationAccounting(repro::AccountingCollector::RegistrationEvent regEvent, const resip::SipMessage &sip)
static resip::KeyValueStore::Key allocateRequestKeyValueStoreKey()
void addTransportRecordRoute(unsigned int transportKey, const resip::NameAddr &recordRoute)
ProcessorChain & mRequestProcessorChain
bool compressionEnabled() const
static resip::KeyValueStore::Key allocateGlobalKeyValueStoreKey()
ProcessorChain & mTargetProcessorChain
bool isUriTransportRecordRoute(const resip::Uri &uri) const
bool mSessionAccountingEnabled
void setOptionsHandler(OptionsHandler *handler) noexcept
void setRequestContextFactory(std::unique_ptr< RequestContextFactory > requestContextFactory) noexcept
void postTimerC(std::unique_ptr< TimerCMessage > tc)
std::set< resip::Data > mSupportedOptions
resip::Mutex mTransportRecordRouteMutex
void postMS(std::unique_ptr< resip::ApplicationMessage > msg, int msec)
void send(const resip::SipMessage &msg)
AccountingCollector * mAccountingCollector
RequestContextMap mServerRequestContexts
static resip::KeyValueStore::KeyValueStoreKeyAllocator * getTargetKeyValueStoreKeyAllocator()
RequestContextMap mClientRequestContexts
static resip::KeyValueStore::Key allocateTargetKeyValueStoreKey()
void addClientTransaction(const resip::Data &transactionId, RequestContext *rc)
virtual void processUnknownMessage(resip::Message *msg)
virtual RequestContext * createRequestContext(Proxy &proxy, ProcessorChain &requestP, ProcessorChain &responseP, ProcessorChain &targetP)
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.
bool empty() const noexcept
Checks whether the Data is empty.
Data & lowercase()
Converts this Data to lowercase.
size_type find(const Data &match, size_type start=0) const
Finds a specified sequence of bytes in this Data.
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.
static bool getOutboundSupported()
KeyValueStore::Key allocateNewKey()
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
The base-class used for message-passing.
virtual Brief brief() const
return a facet for brief encoding of message
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
static int getCryptoRandom()
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.
bool isMyPort(int port) const
Returns true if port is handled by this stack.
void send(const SipMessage &msg, TransactionUser *tu=0)
allows a TU to send a message
bool isMyDomain(const Data &domain, int port) const
Returns true if domain is handled by this stack.
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
Represents the "token" element in the RFC 3261 grammar.
virtual bool isClientTransaction() const
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.
bool exists(const Param< Uri > ¶mType) const
const Data & param(const ExtensionParameter ¶m) 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
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
RequestLineType h_RequestLine