1#if defined(HAVE_CONFIG_H)
7#if defined(HAVE_SYS_SOCKIO_H)
28#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
33 mSipMessageLoggingHandlers.clear();
37 mSipMessageLoggingHandlers.push_back(handler);
46 mSipMessageLoggingHandlers.push_back(handler);
53 mSipMessageLoggingHandlers = handlers;
59 mSipMessageLoggingHandlers.clear();
65 return mSipMessageLoggingHandlers;
98 const Data& tlsDomain,
101 unsigned transportFlags,
105 mCongestionManager(nullptr),
106 mStateMachineFifo(rxFifo,8),
107 mShuttingDown(false),
108 mTlsDomain(tlsDomain),
109 mSocketFunc(socketFunc),
110 mCompression(compression),
111 mTransportFlags(transportFlags)
151 const int wanted =
mDscp.load();
168Transport::reportDscp(
int wanted)
const
184 ErrLog(<< *
this <<
" cannot read the signaling DSCP class back from its listener");
190 if ((carried >> 2) != wanted)
192 ErrLog(<< *
this <<
" asked for signaling DSCP " << wanted
193 <<
" but its listener carries " << (carried >> 2)
194 <<
" (ToS byte " << carried <<
")");
198 InfoLog(<< *
this <<
" signaling DSCP " << (carried >> 2)
199 <<
" (ToS byte " << carried <<
")");
222 ds <<
"No data ready to read: " <<
strError(e);
225 ds <<
"The call was interrupted by a signal before any data was read: " <<
strError(e);
231 ds <<
"fd is not a valid file descriptor or is not open for reading: " <<
strError(e);
234 ds <<
"fd is attached to an object which is unsuitable for reading: " <<
strError(e);
237 ds <<
"buf is outside your accessible address space: " <<
strError(e);
242 ds <<
"The network subsystem has failed.";
245 ds <<
"The buf or from parameters are not part of the user address space, "
246 "or the fromlen parameter is too small to accommodate the peer address.";
249 ds <<
"The (blocking) call was canceled through WSACancelBlockingCall.";
252 ds <<
"A blocking Windows Sockets 1.1 call is in progress, or the "
253 "service provider is still processing a callback function.";
256 ds <<
"The socket has not been bound with bind, or an unknown flag was specified, "
257 "or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, "
258 "or (for byte stream-style sockets only) len was zero or negative.";
261 ds <<
"The socket is connected. This function is not permitted with a connected socket, "
262 "whether the socket is connection-oriented or connectionless.";
265 ds <<
"The connection has been broken due to the keep-alive activity "
266 "detecting a failure while the operation was in progress.";
269 ds <<
"The descriptor is not a socket.";
272 ds <<
" MSG_OOB was specified, but the socket is not stream-style such as type "
273 "SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, "
274 "or the socket is unidirectional and supports only send operations.";
277 ds <<
"The socket has been shut down; it is not possible to recvfrom on a socket after "
278 "shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.";
281 ds <<
"The message was too large to fit into the specified buffer and was truncated.";
284 ds <<
"The connection has been dropped, because of a network failure or because the "
285 "system on the other end went down without notice.";
288 ds <<
"Connection reset.";
291 ds <<
"Would block.";
293 case WSAEHOSTUNREACH:
294 ds <<
"A socket operation was attempted to an unreachable host.";
297 ds <<
"Either the application has not called WSAStartup or WSAStartup failed. "
298 "The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks),"
299 "or WSACleanup has been called too many times.";
302 ds <<
"An attempt was made to access a socket in a way forbidden by its access permissions.";
305 ds <<
"An operation on a socket could not be performed because the system lacked sufficient "
306 "buffer space or because a queue was full.";
309 ds <<
"A request to send or receive data was disallowed because the socket is not connected "
310 "and (when sending on a datagram socket using sendto) no address was supplied.";
312 case WSAECONNABORTED:
313 ds <<
"An established connection was aborted by the software in your host computer, possibly "
314 "due to a data transmission time-out or protocol error.";
316 case WSAEADDRNOTAVAIL:
317 ds <<
"The requested address is not valid in its context. This normally results from an attempt to "
318 "bind to an address that is not valid for the local computer.";
320 case WSAEAFNOSUPPORT:
321 ds <<
"An address incompatible with the requested protocol was used.";
323 case WSAEDESTADDRREQ:
324 ds <<
"A required address was omitted from an operation on a socket.";
327 ds <<
"A socket operation was attempted to an unreachable network.";
332 ds <<
"Some other error (" << e <<
"): " <<
strError(e);
369std::unique_ptr<SendData>
373 std::unique_ptr<SendData> data(
new SendData(dest, d, tid, sigcompId));
380 const char * warning)
388 warning ? warning :
"Original request had no Vias"));
395 errMsg->encode(encodeStream);
396 encodeStream.flush();
399 InfoLog(<<
"Sending response directly to " << dest <<
" : " << errMsg->brief() );
402 Data remoteSigcompId;
407std::unique_ptr<SendData>
410 std::unique_ptr<SendData> result;
429 Data remoteSigcompId;
434 static const Data retryAfterHeader(
"Retry-After: ");
435 Data value(retryAfter);
441std::unique_ptr<SendData>
444 std::unique_ptr<SendData> result;
463 Data remoteSigcompId;
482 if(topVia.
exists(p_comp) && topVia.
param(p_comp) ==
"sigcomp")
484 if (topVia.
exists(p_sigcompId))
486 remoteSigcompId = topVia.
param(p_sigcompId);
495 remoteSigcompId = topVia.
sentHost();
516 if(message->
const_header(h_Vias).front().sentHost() != received)
518 message->
header(h_Vias).front().param(p_received) = received;
521 if (message->
const_header(h_Vias).front().exists(p_rport))
523 message->
header(h_Vias).front().param(p_rport).port() = tuple.
getPort();
527 StackLog (<< endl << endl << *message);
540 InfoLog(<<
"Message Failed basicCheck :" << msg.
brief());
551 InfoLog (<<
"Server has been shutdown, reject message with 503");
560 InfoLog (<<
"Cannot make failure response to badly constructed message: " << e);
571 if (dscp < -1 || dscp > 63)
573 ErrLog(<< *
this <<
" refusing DSCP class " << dscp <<
", outside -1..63");
577 if (
mDscp.exchange(dscp) != dscp)
652 strm <<
"Transport: " << rhs.
mTuple;
654 if (!rhs.mTlsDomain.
empty()) strm <<
" (tlsdomain=" << rhs.mTlsDomain <<
")";
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
#define WSANOTINITIALISED
The abstract base-class for all exceptions thrown by resip code.
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.
const char * c_str() const
Returns a null-terminated string representing.
bool empty() const noexcept
Checks whether the Data is empty.
Data & clear()
Clears the contents of this Data.
A templated, threadsafe message-queue class.
static bool validateMessage(const SipMessage &message, resip::Data *reason=0)
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 void makeRawResponse(Data &rawBuffer, const SipMessage &request, int responseCode, const Data &additionalHeaders=Data::Empty, const Data &body=Data::Empty)
virtual Brief brief() const
return a facet for brief encoding of message
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
const Tuple & getReceivedTransportTuple() const
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool isResponse() const
Returns true if message is a response, false otherwise.
const RequestLine & const_header(const RequestLineType &l) const
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
const Tuple & getSource() const
Returns the source tuple that the message was received from only makes sense for messages received fr...
bool isExternal() const
Check if SipMessage is to be treated as it came off the wire.
resip::MethodTypes method() const
returns the method type of the message
This message is used to indicate to the transaction state that a TCP based transport is trying to TCP...
This message is used to indicate that the TransportSelector has sent a sip message using either relia...
Exception(const Data &msg, const Data &file, int line)
The base class for Transport classes.
void drainDscpRefresh()
Serves a pending refresh and a pending report.
virtual bool hasSpecificContact() const
std::unique_ptr< SendData > make503(SipMessage &msg, uint16_t retryAfter)
void setSipMessageLoggingHandlers(const SipMessageLoggingHandlerList &handlers)
void makeFailedResponse(const SipMessage &msg, int responseCode=400, const char *warning=nullptr)
void unsetSipMessageLoggingHandler() noexcept
IpVersion ipVersion() const
std::atomic< bool > mWasMarkRequested
Whether this transport has asked a socket to carry a class that a clear would have to undo.
AfterSocketCreationFuncPtr mSocketFunc
int effectiveDscp() const
The class to write to a socket right now, or -1 to leave it alone.
const TransportType transport() const
CongestionManager * mCongestionManager
virtual void pushRxMsgUp(SipMessage *msg)
std::unique_ptr< SendData > make100(SipMessage &msg)
Transport(Fifo< TransactionMessage > &rxFifo, const GenericIPAddress &address, const Data &tlsDomain=Data::Empty, AfterSocketCreationFuncPtr socketFunc=nullptr, Compression &compression=Compression::Disabled)
std::atomic< bool > mDscpReportPending
Set by every setDscp() call, cleared by the owning thread's report, so a reload that changed nothing ...
static void stampReceived(SipMessage *request)
static Data errorToString(int e)
SipMessageLoggingHandlerList getSipMessageLoggingHandlers() const noexcept
void fail(const Data &tid, TransportFailure::FailureReason reason=TransportFailure::Failure, int subCode=0)
Posts a TransportFailure to the TransactionMessage Fifo.
Compression & mCompression
std::atomic< int > mDscp
the class to write, -1 for "do not mark"
bool operator==(const Transport &rhs) const
void callSocketFunc(Socket sock) const
bool basicCheck(const SipMessage &msg)
Perform basic sanity checks on message.
const sockaddr & boundInterface() const
virtual void invokeAfterSocketCreationFunc() const =0
void setSipMessageLoggingHandler(std::shared_ptr< SipMessageLoggingHandler > handler)
const Data & tlsDomain() const
bool setDscp(int dscp)
Sets the DSCP class this transport puts on its sockets, and returns whether it was accepted.
void applyDscpToOwnSockets()
Re-runs the per-socket set-up on every socket this transport holds – the listener,...
std::atomic< bool > mDscpRefreshPending
Set by setDscp() when the value changes, cleared by the owning thread's refresh.
void setRemoteSigcompId(SipMessage &msg, Data &id)
void applySocketOptions(Socket sock) const
The one place a socket of this transport is configured.
static void error(int e)
Generates a generic log for the platform specific socket error number.
ProducerFifoBuffer< TransactionMessage > mStateMachineFifo
void keepAlivePong(const Tuple &flow)
std::vector< std::shared_ptr< SipMessageLoggingHandler > > SipMessageLoggingHandlerList
std::unique_ptr< SendData > makeSendData(const Tuple &tuple, const Data &data, const Data &tid, const Data &sigcompId=Data::Empty)
void flowTerminated(const Tuple &flow, TransportFailure::FailureReason failureReason, int failureSubCode, const Data &failureString, const std::list< Data > additionalFailureStrings)
Posts a ConnectionTerminated message to TransactionMessage Fifo.
void addSipMessageLoggingHandler(std::shared_ptr< SipMessageLoggingHandler > handler)
virtual void send(std::unique_ptr< SendData > data)=0
virtual Socket getListenerSocket() const
The transport's own listening or bound socket, or INVALID_SOCKET for a transport that holds none.
void setTcpConnectState(const Data &tid, TcpConnectState::State state)
Posts a TcpConnectState to the TransactionMessage Fifo.
Represents a network address.
static Data inet_ntop(const Tuple &tuple)
Converts the binary socket address to presentation format, via the DnsUtil::inet_ntop() method.
Represents the "via-parm" element in the RFC 3261 grammar.
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;
void(* AfterSocketCreationFuncPtr)(Socket s, int transportType, const char *file, int line)
int setSocketDscp(Socket fd, int dscp, IpVersion version)
Sets the DSCP class of {fd}, in the IPv4 ToS byte or the IPv6 traffic class, and reads it back.
std::string strError(int err)
int getSocketTos(Socket fd, IpVersion version)
Reads the IPv4 ToS byte, or the IPv6 traffic class, of {fd}.
IpVersion
An enumeration of IP versions.
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
Represents an IP-address and port (V4 or V6).