1#if defined(HAVE_CONFIG_H)
22#include <osc/StateChanges.h>
23#include <osc/SigcompMessage.h>
26#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
35 const Data& pinterface,
38 unsigned transportFlags)
39 :
InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags),
40 mSigcompStack(nullptr),
42 mExternalUnknownDatagramHandler(nullptr),
48 mStunTxIdValid =
false;
55 InfoLog (<<
"Creating UDP transport host=" << pinterface
57 <<
" ipv4=" <<
bool(version==
V4) );
62 DebugLog (<<
"Compression enabled for transport: " << *
this);
68 DebugLog (<<
"Compression disabled for transport: " << *
this);
71 DebugLog (<<
"No compression library available: " << *
this);
73 mTxFifo.setDescription(
"UdpTransport::mTxFifo");
147 if ( !mInWritable && haveMsg )
152 else if ( mInWritable && !haveMsg )
253 std::unique_ptr<SendData> sendData(data);
258 const sockaddr& addr = sendData->destination.getSockaddr();
265 sendData->sigcompId.size() > 0 &&
266 !sendData->isAlreadyEncoded )
269 (sendData->data.data(), sendData->data.size(),
270 sendData->sigcompId.data(), sendData->sigcompId.size(),
273 DebugLog (<<
"Compressed message from "
274 << sendData->data.size() <<
" bytes to "
275 << sm->getDatagramLength() <<
" bytes");
277 expected = sm->getDatagramLength();
280 sm->getDatagramMessage(),
281 sm->getDatagramLength(),
283 &addr, sendData->destination.length());
289 expected = (int)sendData->data.size();
291 sendData->data.data(), (
int)sendData->data.size(),
293 &addr, (
int)sendData->destination.length());
300 InfoLog (<<
"Failed (" << e <<
") sending to " << sendData->destination);
301 fail(sendData->transactionId);
306 if (count != expected)
308 ErrLog (<<
"UDPTransport - send buffer full" );
309 fail(sendData->transactionId);
356 socklen_t slen = sender.
length();
357 int len = recvfrom(
mFd,
366 if ( err != EAGAIN && err != EWOULDBLOCK )
392 StackLog(<<
"Throwing away incoming firewall keep-alive");
409 StackLog(<<
"Dropping unsolicited STUN response from " << sender);
416 if (!mStunServerTuple.
isEqual(sender,
false ,
true ))
418 WarningLog(<<
"Dropping STUN response from unexpected source " << sender
419 <<
" (expected " << mStunServerTuple <<
")");
434 if (memcmp(resp.
msgHdr.
id.
octet, mStunTxId.data(), mStunTxId.size()) != 0)
436 WarningLog(<<
"Dropping STUN response with mismatched transaction id from " << sender);
463 mStunTxIdValid =
false;
474 mStunTxIdValid =
false;
486 bool changePort =
false;
487 bool changeIp =
false;
491 myAddr.
addr = ntohl(bi.sin_addr.s_addr);
492 myAddr.
port = ntohs(bi.sin_port);
495 const sockaddr_in& fi = (
const sockaddr_in&)sender.
getSockaddr();
496 from.
addr = ntohl(fi.sin_addr.s_addr);
497 from.
port = ntohs(fi.sin_port);
522 DebugLog(<<
"Got UDP STUN keepalive. Sending response...");
542 osc::StateChanges *sc = 0;
546 if ((buffer[0] & 0xf8) == 0xf8)
550 InfoLog(<<
"Discarding unexpected SigComp Message");
554 const size_t uncompressedLength =
mSigcompStack->uncompressMessage(buffer, len, mRxUncompressedBuffer.data(), mRxUncompressedBuffer.size(), sc);
556 DebugLog (<<
"Uncompressed message from "
557 << len <<
" bytes to "
558 << uncompressedLength <<
" bytes");
565 Data(nack->getDatagramMessage(),
566 nack->getDatagramLength()),
573 buffer = mRxUncompressedBuffer.data();
574 len = uncompressedLength;
579 memcpy(msgBuffer, buffer, len);
580 msgBuffer[len] =
'\0';
594 message->setSource(sender);
599 message->addBuffer(msgBuffer);
603 char *unprocessedCharPtr;
604 if (mMsgHeaderScanner.
scanChunk(msgBuffer,
606 &unprocessedCharPtr) !=
609 StackLog(<<
"Scanner rejecting datagram as unparsable / fragmented from " << sender);
611 if(mExternalUnknownDatagramHandler)
613 std::unique_ptr<Data> datagram(
new Data(msgBuffer, len));
614 (*mExternalUnknownDatagramHandler)(
this, sender, std::move(datagram));
621 const int used =
static_cast<int>(unprocessedCharPtr - msgBuffer);
632 message->setBody(msgBuffer + used, len - used);
641 && message->isRequest()))
655 send(std::move(tryLater));
673 const Via &via = message->header(h_Vias).front();
674 if (message->isRequest())
679 if (via.
exists(p_sigcompId))
703 Data compId = via.
param(p_branch).getSigcompCompartment();
719 bool changePort=
false;
746 memcpy(mStunTxId.data(), req.
msgHdr.
id.
octet, mStunTxId.size());
747 mStunServerTuple = dest;
748 mStunTxIdValid =
true;
765 mappedAddress = mStunMappedAddress;
773 mExternalUnknownDatagramHandler = handler;
#define RESIP_FIFO_NOWAIT
The getNext() method takes an argument {ms} that normally the number of milliseconds to wait.
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
#define STUN_MAX_MESSAGE_SIZE
#define RESIP_TRANSPORT_FLAG_TXNOW
#define RESIP_TRANSPORT_FLAG_RXALL
#define RESIP_TRANSPORT_FLAG_TXALL
void addCompressorsToStack(osc::Stack *)
osc::StateHandler & getStateHandler()
@ REJECTING_NEW_WORK
Overloaded, should refuse new work.
@ REJECTING_NON_ESSENTIAL
Rejecting all work that is non-essential to the health of the system (ie, if dropping something is li...
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
@ Borrow
The Data instance is borrowing the memory from the passed in buffer.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
Interface functor for external unrecognized datagram handling.
virtual FdPollItemHandle addPollItem(Socket sock, FdPollEventMask newMask, FdPollItemIf *item)=0
virtual void delPollItem(FdPollItemHandle handle)=0
virtual void modPollItem(FdPollItemHandle handle, FdPollEventMask newMask)=0
Object-oriented wrapper for your platform's file-descriptor set.
bool readyToWrite(Socket fd)
bool readyToRead(Socket fd)
A templated, threadsafe message-queue class.
static Socket socket(TransportType type, IpVersion ipVer)
virtual void send(std::unique_ptr< SendData > data)
FdPollItemHandle mPollItemHandle
ConsumerFifoBuffer< SendData > mTxFifoOutBuffer
virtual void setPollGrp(FdPollGrp *grp)
Represents a SIP message.
static const char * CRLFCRLF
void drainDscpRefresh()
Serves a pending refresh and a pending report.
std::unique_ptr< SendData > make503(SipMessage &msg, uint16_t retryAfter)
IpVersion ipVersion() const
const TransportType transport() const
virtual void pushRxMsgUp(SipMessage *msg)
static void stampReceived(SipMessage *request)
uint32_t getExpectedWaitForIncoming() const
void fail(const Data &tid, TransportFailure::FailureReason reason=TransportFailure::Failure, int subCode=0)
Posts a TransportFailure to the TransactionMessage Fifo.
Compression & mCompression
bool basicCheck(const SipMessage &msg)
Perform basic sanity checks on message.
const sockaddr & boundInterface() const
CongestionManager::RejectionBehavior getRejectionBehaviorForIncoming() const
static void error(int e)
Generates a generic log for the platform specific socket error number.
ProducerFifoBuffer< TransactionMessage > mStateMachineFifo
Represents a network address.
sockaddr & getMutableSockaddr()
Retrieve the binary representation of the socket address for this tuple.
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
void setType(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.
const sockaddr & getSockaddr() const
Retrieve a const binary representation of the socket address for this tuple.
UdpTransport(Fifo< TransactionMessage > &fifo, int portNum, IpVersion version, StunSetting stun, const Data &interfaceObj, AfterSocketCreationFuncPtr socketFunc=nullptr, Compression &compression=Compression::Disabled, unsigned transportFlags=0)
void setExternalUnknownDatagramHandler(ExternalUnknownDatagramHandler *handler)
Installs a handler for the unknown datagrams arriving on the udp transport.
virtual bool isReliable() const
virtual void setRcvBufLen(int buflen)
void processRxParse(int len, const Tuple &sender)
Parse the contents of {mRxBuffer} and do something with it.
bool stunSendTest(const Tuple &dest)
Send a STUN Binding Request to dest for public-address discovery.
osc::Stack * mSigcompStack
int processRxRecv(Tuple &sender)
void processTxAll()
Added support for TXNOW and TXALL.
virtual void setPollGrp(FdPollGrp *grp)
static constexpr int MaxMessageSize
virtual void buildFdSet(FdSet &fdset)
Adds the Transport's socket FD to the appropriate read or write sets as applicable.
std::array< char, MaxMessageSize > mRxBuffer
void processRxParseSip(char *buffer, int len, const Tuple &sender)
@ StunResultResponseParseFailed
void processTxOne(SendData *data)
void processRxAll()
Add options RXALL (to try receive all readable data).
virtual void processPollEvent(FdPollEventMask mask)
Called by PollGrp when activity is possible.
StunResult stunResult(Tuple &mappedAddress)
Return the result of the most recent stunSendTest(); on StunResultSuccess, mappedAddress is filled wi...
virtual bool hasDataToSend() const
If we return true, the TransactionController will set the timeout to zero so that process() is called...
unsigned mRxTransactionCnt
virtual void process()
Called after a message is added.
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.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
void(* AfterSocketCreationFuncPtr)(Socket s, int transportType, const char *file, int line)
unsigned short FdPollEventMask
bool stunServerProcessMsg(char *buf, unsigned int bufLen, StunAddress4 &from, StunAddress4 &secondary, StunAddress4 &myAddr, StunAddress4 &altAddr, StunMessage *resp, StunAddress4 *destination, StunAtrString *hmacPassword, bool *changePort, bool *changeIp, bool verbose)
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
void stunBuildReqSimple(StunMessage *msg, const StunAtrString &username, bool changePort, bool changeIp, unsigned int id)
int setSocketRcvBufLen(Socket fd, int buflen)
static const uint32_t StunMagicCookie
bool stunParseMessage(char *buf, unsigned int bufLen, StunMessage &msg, bool verbose)
IpVersion
An enumeration of IP versions.
unsigned int stunEncodeMessage(const StunMessage &msg, char *buf, unsigned int bufLen, const StunAtrString &password, bool verbose)
StunAtrAddress4 xorMappedAddress
StunAtrAddress4 mappedAddress