1#if defined(HAVE_CONFIG_H)
11#include <sys/socket.h>
45#include <osc/SigcompMessage.h>
60#define gai_strerror strerror
68#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
87 return mTuple < rhs.
mTuple;
93 mDns(dnsStub, useDnsVip),
96 mCompression(compression),
100 mInterruptorHandle(0)
102 memset(&mUnspecified.
v4Address, 0,
sizeof(sockaddr_in));
103 mUnspecified.
v4Address.sin_family = AF_UNSPEC;
106 memset(&mUnspecified6.v6Address, 0,
sizeof(sockaddr_in6));
107 mUnspecified6.v6Address.sin6_family = AF_UNSPEC;
113 DebugLog (<<
"Compression enabled for Transport Selector");
119 DebugLog (<<
"Compression disabled for Transport Selector");
122 DebugLog (<<
"No compression library available");
128 mExactTransports.clear();
129 mAnyInterfaceTransports.clear();
130 mAnyPortTransports.clear();
131 mAnyPortAnyInterfaceTransports.clear();
132 mTlsTransports.clear();
133 mSharedProcessTransports.clear();
134 mHasOwnProcessTransports.clear();
135 mTypeToTransportMap.clear();
136 for(TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++)
141 delete mSigcompStack;
144 for(HashMap<Data, Socket>::iterator socketIterator = mSockets.begin();
145 socketIterator != mSockets.end(); socketIterator++)
150 DebugLog(<<
"Closing TransportSelector::mSocket[" << socketIterator->first <<
"]");
154 for(HashMap<Data, Socket>::iterator socketIterator = mSocket6s.begin();
155 socketIterator != mSocket6s.end(); socketIterator++)
160 DebugLog(<<
"Closing TransportSelector::mSocket6[" << socketIterator->first <<
"]");
170 for(TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++)
172 it->second->shutdown();
179 for(TransportKeyMap::const_iterator it = mTransports.begin(); it != mTransports.end(); it++)
181 if (!it->second->isFinished())
192 Transport* transport = autoTransport.release();
241 if(mExactTransports.find(tuple) == mExactTransports.end() &&
242 mAnyInterfaceTransports.find(tuple) == mAnyInterfaceTransports.end())
244 DebugLog (<<
"Adding transport: " << tuple);
253 mAnyInterfaceTransports[tuple] = transport;
254 mAnyPortAnyInterfaceTransports[tuple] = transport;
258 mExactTransports[tuple] = transport;
259 mAnyPortTransports[tuple] = transport;
264 WarningLog (<<
"Can't add transport, overlapping properties with existing transport: " << tuple);
272 if(mTlsTransports.find(key) == mTlsTransports.end())
274 mTlsTransports[key] = transport;
278 WarningLog (<<
"Can't add transport, overlapping properties with existing transport: "
279 << tuple <<
" (domain=" << transport->
tlsDomain() <<
")");
295 mTransportsToAddRemove.add(transport);
303 mSharedProcessTransports.push_back(transport);
308 mHasOwnProcessTransports.push_back(transport);
309 mHasOwnProcessTransports.back()->startOwnProcessing();
312 mTypeToTransportMap.insert(TypeToTransportMap::value_type(tuple,transport));
314 mTransports[transport->
getKey()] = transport;
316 InfoLog(<<
"TransportSelector::addTransport: added transport for tuple=" << tuple <<
", key=" << transport->
getKey());
327 TransportKeyMap::iterator it = mTransports.find(transportKey);
328 if(it != mTransports.end())
330 transportToRemove = it->second;
331 mTransports.erase(it);
335 if(transportToRemove)
343 mExactTransports.erase(transportToRemove->
getTuple());
344 mAnyInterfaceTransports.erase(transportToRemove->
getTuple());
348 rebuildAnyPortTransportMaps();
353 mTlsTransports.erase(tlsKey);
358 for (TypeToTransportMap::iterator itTypeToTransport = mTypeToTransportMap.begin(); itTypeToTransport != mTypeToTransportMap.end(); itTypeToTransport++)
360 if (itTypeToTransport->second->getKey() == transportKey)
362 mTypeToTransportMap.erase(itTypeToTransport);
375 mTransportsToAddRemove.add(transportToRemove);
380 for(TransportList::iterator it = mHasOwnProcessTransports.begin(); it != mHasOwnProcessTransports.end(); it++)
382 if((*it)->getKey() == transportKey)
384 mHasOwnProcessTransports.erase(it);
390 delete transportToRemove;
396TransportSelector::rebuildAnyPortTransportMaps()
404 mAnyPortTransports.clear();
405 mAnyPortAnyInterfaceTransports.clear();
407 for (TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++)
409 if (!
isSecure(it->second->transport()))
414 if (it->second->interfaceName().empty() ||
415 it->second->getTuple().isAnyInterface() ||
416 it->second->hasSpecificContact())
418 mAnyPortAnyInterfaceTransports[it->second->getTuple()] = it->second;
422 mAnyPortTransports[it->second->getTuple()] = it->second;
431 if(mPollGrp && mInterruptorHandle)
435 mInterruptorHandle=0;
440 if(mPollGrp && mSelectInterruptor.get())
442 mInterruptorHandle = mPollGrp->
addPollItem(mSelectInterruptor->getReadSocket(),
FPEM_Read, mSelectInterruptor.get());
445 for(TransportList::iterator t=mSharedProcessTransports.begin(); t!=mSharedProcessTransports.end(); ++t)
447 (*t)->setPollGrp(mPollGrp);
454 if(!mSelectInterruptor.get())
459 mInterruptorHandle = mPollGrp->
addPollItem(mSelectInterruptor->getReadSocket(),
FPEM_Read, mSelectInterruptor.get());
467 for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++)
469 (*it)->buildFdSet(fdset);
471 if(mSelectInterruptor.get())
473 mSelectInterruptor->buildFdSet(fdset);
480 checkTransportAddRemoveQueue();
482 for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++)
486 (*it)->process(fdset);
490 ErrLog (<<
"Exception thrown from Transport::process: " << e);
494 if(mSelectInterruptor.get())
496 mSelectInterruptor->process(fdset);
504 checkTransportAddRemoveQueue();
506 for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++)
514 ErrLog (<<
"Exception thrown from Transport::process: " << e);
520TransportSelector::checkTransportAddRemoveQueue()
525 Transport* t(mTransportsToAddRemove.getNext(-1));
528 if(!t->isShuttingDown())
531 mSharedProcessTransports.push_back(t);
536 for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++)
538 if((*it)->getKey() == t->getKey())
540 mSharedProcessTransports.erase(it);
549 t = mTransportsToAddRemove.getNext(-1);
556 for(TransportList::iterator it = mHasOwnProcessTransports.begin(); it != mHasOwnProcessTransports.end(); it++)
564 ErrLog (<<
"Exception thrown from Transport::process: " << e);
568 if(mSelectInterruptor.get() )
570 mSelectInterruptor->handleProcessNotification();
577 for(TransportList::const_iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++)
579 if ((*it)->hasDataToSend())
630 ErrLog(<<
"unimplemented response dns");
642 static const bool unknown_transport =
false;
659 return unknown_transport;
673 char hostname[256] =
"";
674 if(gethostname(hostname,
sizeof(hostname)) != 0)
678 InfoLog(<<
"Can't query local hostname : [" << e <<
"] " <<
strError(e) );
681 InfoLog(<<
"Local hostname is [" << hostname <<
"]");
687 memset(&hint, 0,
sizeof(hint));
688 hint.ai_family = is_v4 ? PF_INET : PF_INET6;
689 hint.ai_flags = AI_PASSIVE;
690 hint.ai_socktype = is_dgram ? SOCK_DGRAM : SOCK_STREAM;
693 int ret = getaddrinfo(
702 InfoLog(<<
"Can't resolve " << hostname <<
"'s address : [" << ret <<
"] " << gai_strerror(ret) );
710 Tuple source(*(results->ai_addr), type);
711 InfoLog(<<
"Local address is " << source);
712 addrinfo* ai = results->ai_next;
713 for(; ai; ai = ai->ai_next)
715 Tuple addr(*(ai->ai_addr), type);
716 InfoLog(<<
"Additional address " << addr);
718 freeaddrinfo(results);
745 Data::Empty, target.getNetNs());
746 DebugLog(<<
"TransportSelector::findTransportByVia: source: " << source);
750 WarningLog(<<
"Sending request with incomplete Via header and FlowKey."
751 <<
" This code no smart enough to pick the correct Transport."
779TransportSelector::determineSourceInterface(
SipMessage* msg,
const Tuple& target)
const
783 const Via& via = msg->
header(h_Vias).front();
789 Tuple source(target);
790#if defined(WIN32) && !defined(NO_IPHLPAPI)
796 catch (WinCompat::Exception& ex)
798 ErrLog (<<
"Can't find source interface to use: " << ex);
818 if (mSockets.find(netNs) == mSockets.end() || mSockets[netNs] ==
INVALID_SOCKET)
825 tmp = mSockets[netNs];
830 if (mSocket6s.find(netNs) == mSocket6s.end() || mSocket6s[netNs] ==
INVALID_SOCKET)
837 tmp = mSocket6s[netNs];
850 InfoLog(<<
"Unable to route to " << target <<
" : [" << e <<
"] " <<
strError(e) );
854 socklen_t len = source.
length();
860 InfoLog(<<
"Can't determine name of socket " << target <<
" : " <<
strError(e) );
868 long src = (
reinterpret_cast<const sockaddr_in*
>(&source.
getSockaddr())->sin_addr.s_addr);
869 if(src == INADDR_ANY)
871 InfoLog(<<
"Connected UDP failed to determine source address, use first address instaed.");
878#if defined(USE_IPV6) && !defined(WIN32)
890 ret = connect(mSockets[netNs],
891 (
struct sockaddr*)&mUnspecified.
v4Address,
897 ret = connect(mSocket6s[netNs],
898 (
struct sockaddr*)&mUnspecified6.v6Address,
899 sizeof(mUnspecified6.v6Address));
912 if (!(e ==EAFNOSUPPORT || e == EADDRNOTAVAIL))
936 DebugLog (<<
"Looked up source for destination: " << target
939 <<
" sent-port=" << via.
sentPort());
999 Data remoteSigcompId;
1006 transport = findTransportByVia(msg, target, source);
1012 DebugLog(<<
"Found (request) " << *transport <<
" by target=" << target);
1017 DebugLog(<<
"Found (request) " << *transport <<
" by via, source=" << source <<
" for target=" << target);
1034 Tuple temp = determineSourceInterface(msg,target);
1054 source = determineSourceInterface(msg, target);
1060 DebugLog(<<
"Found (request) " << *transport <<
" by source=" << source <<
" for target=" << target);
1075 Via& topVia(msg->
header(h_Vias).front());
1095 if (!topVia.
exists(p_comp))
1097 topVia.
param(p_comp) =
"sigcomp";
1099 if (!topVia.
exists(p_sigcompId))
1112 if(msg->
exists(h_Routes) &&
1122 if (destination.
exists(p_comp) &&
1123 destination.
param(p_comp) ==
"sigcomp")
1125 if (destination.
exists(p_sigcompId))
1127 remoteSigcompId = destination.
param(p_sigcompId);
1131 remoteSigcompId = destination.
host();
1137 topVia.
param(p_branch).setSigcompCompartment(remoteSigcompId);
1152 DebugLog(<<
"Found (response) " << *transport <<
" by target=" << target);
1158 Tuple temp = source;
1159 source = determineSourceInterface(msg,target);
1174 Via& topVia(msg->
header(h_Vias).front());
1176 if(topVia.
exists(p_comp) && topVia.
param(p_comp) ==
"sigcomp")
1178 if (topVia.
exists(p_sigcompId))
1180 remoteSigcompId = topVia.
param(p_sigcompId);
1188 remoteSigcompId = topVia.
sentHost();
1210 if (msg->
exists(h_Contacts) && msg->
header(h_Contacts).size()==1)
1212 for (NameAddrs::iterator i=msg->
header(h_Contacts).begin(); i != msg->
header(h_Contacts).end(); i++)
1237 contact.
uri().
param(p_comp) =
"sigcomp";
1239 if (!contact.
exists(p_Instance) &&
1248 if (c_contact.
uri().
exists(p_addTransport))
1263 if (msg->
exists(h_ReferredBy)
1280 if (msg->
exists(h_RecordRoutes)
1288 rr.
uri().
host() = sourceAddress;
1302 rr.
uri().
param(p_comp) =
"sigcomp";
1319 msg->
header(h_Date) = now;
1328 InfoLog (<<
"Couldn't add identity header: " << e);
1330 if (msg->
exists(h_IdentityInfo))
1332 msg->
remove(h_IdentityInfo);
1345 handler->outboundMessage(source, target, *msg);
1348 std::unique_ptr<SendData> send(
new SendData(target,
1353 send->data.reserve(mAvgBufferSize + mAvgBufferSize/4);
1362 mAvgBufferSize = (255*mAvgBufferSize + (int)send->data.size()+128)/256;
1365 DebugLog (<<
"Transmitting to " << target
1367 <<
" via " << source
1368 << std::endl << std::endl << send->data.escaped()
1369 <<
"sigcomp id=" << remoteSigcompId);
1376 transport->
send(std::move(send));
1431 transport->
send(std::unique_ptr<SendData>(data.
clone()));
1446 t->
send(std::unique_ptr<SendData>(close));
1453 unsigned int sum = 0;
1454 for(TransportKeyMap::const_iterator it = mTransports.begin(); it != mTransports.end(); it++)
1456 sum += it->second->getFifoSize();
1485 for (TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++)
1489 it->second->invokeAfterSocketCreationFunc();
1504 TransportKeyMap::iterator it = mTransports.find(target.
mTransportKey);
1505 if(it != mTransports.end())
1512 std::pair<TypeToTransportMap::iterator, TypeToTransportMap::iterator> range(mTypeToTransportMap.equal_range(target));
1514 if(range.first != range.second)
1516 TypeToTransportMap::iterator i=range.first;
1520 return range.first->second;
1534TransportSelector::findLoopbackTransportBySource(
bool ignorePort,
Tuple& search)
const
1542 ExactTupleMap::const_iterator i;
1543 for (i=mExactTransports.begin();i != mExactTransports.end();i++)
1545 DebugLog(<<
"search: " << search <<
" elem: " << i->first);
1546 if(i->first.ipVersion()==
V4)
1549 if(i->first.isEqualWithMask(search,8,ignorePort))
1552 if(i->first.getNetNs() == search.
getNetNs())
1561 else if(i->first.ipVersion()==
V6)
1578 DebugLog(<<
"findTransportBySource(" << search <<
")");
1589 bool ignorePort = (search.
getPort() == 0);
1590 DebugLog(<<
"should port be ignored: " << ignorePort);
1596 ExactTupleMap::const_iterator i = mExactTransports.find(search);
1597 if (i != mExactTransports.end())
1599 DebugLog(<<
"findTransport (exact) => " << *(i->second));
1607 Transport *trans = findLoopbackTransportBySource(
false, search);
1610 DebugLog(<<
"findLoopbackTransportBySource(" << search <<
")");
1617 AnyInterfaceTupleMap::const_iterator i = mAnyInterfaceTransports.find(search);
1618 if (i != mAnyInterfaceTransports.end())
1620 DebugLog(<<
"findTransport (any interface) => " << *(i->second));
1629 AnyPortTupleMap::const_iterator i = mAnyPortTransports.find(search);
1630 if (i != mAnyPortTransports.end())
1632 DebugLog(<<
"findTransport (any port, specific interface) => " << *(i->second) <<
" key: " << (i->first) <<
" search: " << search);
1640 Transport *trans = findLoopbackTransportBySource(
true, search);
1650 AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.find(search);
1651 if (i != mAnyPortAnyInterfaceTransports.end())
1653 DebugLog(<<
"findTransport (any port, any interface) => " << *(i->second));
1659 DebugLog (<<
"Exact interface / Specific port: " <<
Inserter(mExactTransports));
1660 DebugLog (<<
"Any interface / Specific port: " <<
Inserter(mAnyInterfaceTransports));
1661 DebugLog (<<
"Exact interface / Any port: " <<
Inserter(mAnyPortTransports));
1662 DebugLog (<<
"Any interface / Any port: " <<
Inserter(mAnyPortAnyInterfaceTransports));
1664 WarningLog(<<
"Can't find matching transport " << search);
1669TransportSelector::findTlsTransport(
const Data& domainname,
const Tuple& search)
const
1677 TlsTransportKey searchKey(domainname, search);
1678 const auto& i = mTlsTransports.find(searchKey);
1680 if (i != mTlsTransports.end())
1682 DebugLog(<<
"findTlsTransport: numSecureTransports=" << mTlsTransports.size() <<
", search=" << searchKey <<
" (exact match) => " << *(i->second));
1687 for (
const auto& tlsTransport : mTlsTransports)
1689 const TlsTransportKey& key = tlsTransport.first;
1692 if (key.mTuple.getType() != search.
getType() || key.mTuple.ipVersion() != search.
ipVersion())
1698 if ((search.
getPort() != 0) && (key.mTuple.getPort() != search.
getPort()))
1705 !search.
isEqual(key.mTuple,
true ))
1711 if (!domainname.
empty() && !key.mTuple.getTargetDomain().empty() &&
1712 domainname != key.mTuple.getTargetDomain())
1717 DebugLog(<<
"findTlsTransport: numSecureTransports=" << mTlsTransports.size() <<
", search=" << searchKey <<
" (relaxed match) => " << *tlsTransport.second);
1719 return tlsTransport.second;
1722 DebugLog(<<
"findTlsTransport: No TLS transport found, numSecureTransports=" << mTlsTransports.size() <<
", search=" << searchKey);
1746 ostrm << tlsTransportKey.
mTuple;
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
bool isDgramTransport(TransportType type)
The abstract base-class for all exceptions thrown by resip code.
Data computeIdentity(const Data &signerDomain, const Data &in) const
void addCompressorsToStack(osc::Stack *)
const Data & getSigcompId()
osc::StateHandler & getStateHandler()
An iostream that operates on an existing Data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
Represents the "SIP-date" element in the RFC 3261 grammar.
void addTransportType(TransportType type, IpVersion version)
void lookup(DnsResult *res, const Uri &uri)
TupleMarkManager & getMarkManager()
void removeTransportType(TransportType type, IpVersion version)
DnsResult * createDnsResult(DnsHandler *handler=0)
virtual FdPollItemHandle addPollItem(Socket sock, FdPollEventMask newMask, FdPollItemIf *item)=0
virtual void delPollItem(FdPollItemHandle handle)=0
Object-oriented wrapper for your platform's file-descriptor set.
A templated, threadsafe message-queue class.
static Socket socket(TransportType type, IpVersion ipVer)
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
bool exists(const Param< NameAddr > ¶mType) const
Used to 'artificially' interrupt a select call.
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
bool hasForceTarget() const
void callOutboundDecorators(const Tuple &src, const Tuple &dest, const Data &sigcompId)
void setForceTarget(const Uri &uri)
deal with a notion of an "out-of-band" forced target for SIP routing
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.
const RequestLine & const_header(const RequestLineType &l) const
const Uri & getForceTarget() const
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
void remove(const HeaderBase &headerType)
Prevents a header field from being present when the message is prepared for sending to a transport.
void rollbackOutboundDecorators()
const Data & getTlsDomain() const
Data getCanonicalIdentityString() const
virtual EncodeStream & encode(EncodeStream &str) const
Generate a string from the SipMessage object.
This message is used to indicate that the TransportSelector has sent a sip message using either relia...
bool operator<(const TlsTransportKey &rhs) const
void registerMarkListener(MarkListener *listener)
unsigned int sumTransportFifoSizes() const
static Tuple getFirstInterface(bool is_v4, TransportType type)
Transport * findTransportBySource(Tuple &src, const SipMessage *msg) const
void closeConnection(const Tuple &peer)
void poke()
Causes transport process loops to be interrupted if there is stuff in their transmit fifos.
void createSelectInterruptor()
Called when the TransportSelector will be running in a different.
TransportSelector(Fifo< TransactionMessage > &fifo, Security *security, DnsStub &dnsStub, Compression &compression, bool useDnsVip)
void buildFdSet(FdSet &fdset)
Builds an FdSet comprised of all FDs from all suitable Transports.
Transport * findTransportByDest(const Tuple &dest)
bool isFinished() const
Returns true if all Transports have their buffers cleared, false otherwise.
unsigned int getTimeTillNextProcessMS()
void removeTransport(unsigned int transportKey)
bool hasDataToSend() const
void addTransport(std::unique_ptr< Transport > transport, bool isStackRunning)
Add/Remove a transport.
DnsResult * createDnsResult(DnsHandler *handler)
DNS Resolution.
void setPollGrp(FdPollGrp *pollGrp)
Configure a PollGrp to use (instead of buildFdSet/process) Must be called before adding any transport...
TransmitState
transmit results in msg->resolve() being called to either kick off dns resolution or to pick the next...
void enableFlowTimer(const resip::Tuple &flow)
void shutdown()
Shuts down all transports.
void unregisterMarkListener(MarkListener *listener)
void terminateFlow(const resip::Tuple &flow)
TransmitState transmit(SipMessage *msg, Tuple &target, SendData *sendData=0)
void invokeAfterSocketCreationFunc(TransportType type)
void dnsResolve(DnsResult *result, SipMessage *msg)
virtual ~TransportSelector()
void retransmit(const SendData &msg)
Resend to the same transport as last time.
General exception class for Transport.
The base class for Transport classes.
const Tuple & getTuple() const
virtual bool hasSpecificContact() const
IpVersion ipVersion() const
const TransportType transport() const
virtual void shutdown()
This starts shutting-down procedures for this Transport.
unsigned int getKey() const
SipMessageLoggingHandlerList getSipMessageLoggingHandlers() const noexcept
const Data & interfaceName() const
const Data & netNs() const
virtual void setPollGrp(FdPollGrp *grp)=0
const Data & tlsDomain() const
virtual bool shareStackProcessAndSelect() const =0
Returns true if this Transport should be included in the FdSet processing loop, false if the Transpor...
static void error(int e)
Generates a generic log for the platform specific socket error number.
virtual void send(std::unique_ptr< SendData > data)=0
void registerMarkListener(MarkListener *)
void unregisterMarkListener(MarkListener *)
Represents a network address.
IpVersion ipVersion() const
Returns V4 or V6 as appropriate.
sockaddr & getMutableSockaddr()
Retrieve the binary representation of the socket address for this tuple.
void setTargetDomain(const Data &target)
Set the domain name this address tuple intends to represent.
static const Data & toData(TransportType)
Converts the TransportType to a string representation of the transport type, e.g.
const Data & getNetNs() const
Get the netns for this Tuple.
GenericIPAddress toGenericIPAddress() const
bool isAnyInterface() const
TRUE if this address is equal to the "INADDR_ANY" value for this address family.
bool onlyUseExistingConnection
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
static const Data & toDataLower(TransportType type)
bool isEqual(const Tuple &tuple, bool ignorePort=false, bool ignoreTransport=false) const
compares this tuple with the one passed in for family, port and address equality.
TransportType getType() const
static Data inet_ntop(const Tuple &tuple)
Converts the binary socket address to presentation format, via the DnsUtil::inet_ntop() method.
const sockaddr & getSockaddr() const
Retrieve a const binary representation of the socket address for this tuple.
void setSockaddr(const GenericIPAddress &)
Set the internal binary representation of the socket address from the GenericIPAddress.
const Data & getTargetDomain() const
Get the domain name this address tuple intends to represent.
TransportKey mTransportKey
A Transport based on UDP.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
bool exists(const Param< Uri > ¶mType) const
void remove(const Param< Uri > ¶mType)
const Data & param(const ExtensionParameter ¶m) const
Const accessor for non-natively-supported parameter types.
Represents the "via-parm" element in the RFC 3261 grammar.
void remove(const Param< Via > ¶mType)
bool exists(const Param< Via > ¶mType) const
const Data & param(const ExtensionParameter ¶m) const
Const accessor for non-natively-supported parameter types.
dcm! – add UnusedChecking(_enum) below;
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
TransportType toTransportType(const resip::Data &transportName)
bool isSecure(TransportType type)
Returns true if passed in transport type is a secure transport protocol.
int closeSocket(Socket fd)
TransportType
An enumeration of transport protocols.
RequestLineType h_RequestLine
std::string strError(int err)
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
Represents an IP-address and port (V4 or V6).