1#if defined(HAVE_CONFIG_H)
25#include <osc/SigcompMessage.h>
32#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
38 mFirstWriteAfterConnectedPending(false),
40 mFlowTimerEnabled(false),
45 InfoLog (<<
"Connection::Connection: new connection created to who: " <<
mWho <<
", is server = " << mIsServer);
55 getConnectionManager().addConnection(
this);
63 getConnectionManager().removeConnection(
this);
80Connection::removeFrontOutstandingSend()
88 getConnectionManager().removeFromWritable(
this);
104 getConnectionManager().removeFromWritable(
this);
109 WarningLog(<<
"performWrite invoked while not in write set");
139 removeFrontOutstandingSend();
145 WarningLog(<<
"WebSocket Pong queued on a connection that is not a WebSocket, dropping it");
146 removeFrontOutstandingSend();
189 static const char normalClosure[2] = { 0x03, (char)0xE8 };
203 if(lSize > 0x7D && lSize <= 0xFFFF)
207 else if(lSize > 0xFFFF)
217 uBuffer[0] = (
uint8_t)(0x80 | opcode);
221 uBuffer = &uBuffer[2];
223 else if(lSize <= 0xFFFF)
226 uBuffer[2] = (
uint8_t)((lSize >> 8) & 0xFF);
227 uBuffer[3] = (
uint8_t)(lSize & 0xFF);
228 uBuffer = &uBuffer[4];
233 uBuffer[2] = (
uint8_t)((lSize >> 56) & 0xFF);
234 uBuffer[3] = (
uint8_t)((lSize >> 48) & 0xFF);
235 uBuffer[4] = (
uint8_t)((lSize >> 40) & 0xFF);
236 uBuffer[5] = (
uint8_t)((lSize >> 32) & 0xFF);
237 uBuffer[6] = (
uint8_t)((lSize >> 24) & 0xFF);
238 uBuffer[7] = (
uint8_t)((lSize >> 16) & 0xFF);
239 uBuffer[8] = (
uint8_t)((lSize >> 8) & 0xFF);
240 uBuffer[9] = (
uint8_t)(lSize & 0xFF);
241 uBuffer = &uBuffer[10];
244 memcpy(uBuffer, dataRaw.
data(), dataRaw.
size());
255 osc::SigcompMessage *sm =
259 DebugLog (<<
"Compressed message from "
260 << uncompressed.
size() <<
" bytes to "
261 << sm->getStreamLength() <<
" bytes");
265 Data(sm->getStreamMessage(),
266 sm->getStreamLength()),
300 InfoLog(<<
"Write failed on socket: " << this->
getSocket() <<
", closing connection");
303 else if (nBytes == 0)
319 removeFrontOutstandingSend();
322 DebugLog(<<
"WebSocket Close sent, closing connection: " <<
mWho);
326 return (
int)bytesWritten;
354 getConnectionManager().addToWritable(
this);
360Connection::getConnectionManager()
const
364 return transport->getConnectionManager();
370 strm <<
"CONN: " << &c <<
" " << int(c.
getSocket()) <<
" " << c.
mWho;
378 size_t bytesToRead =
resipMin(writePair.second,
383 int bytesRead =
read(writePair.first, (
int)bytesToRead);
389 getConnectionManager().touch(
this);
424 bool dropConnection =
false;
438 else if(dropConnection)
469 while((bytesRead =
read())>0 && --
max!=0)
471 DebugLog(<<
"Connection::performReads() " <<
" read=" << bytesRead);
476 DebugLog(<<
"Closing connection bytesRead=" << bytesRead);
486 if(!mFlowTimerEnabled)
488 mFlowTimerEnabled =
true;
491 getConnectionManager().moveToFlowTimerLru(
this);
502 DebugLog(<<
"Sending response CRLF (aka pong).");
510 DebugLog(<<
"Received response CRLF (aka pong).");
552 int errNumSize =
sizeof(errNum);
553 if(getsockopt(
mWho.
mFlowKey, SOL_SOCKET, SO_ERROR, (
char *)&errNum, (socklen_t *)&errNumSize) == 0)
555 if (errNum == ETIMEDOUT || errNum == EHOSTUNREACH ||
556 errNum == ECONNREFUSED || errNum == ECONNABORTED)
563 InfoLog(<< failureString <<
"; closing connection");
568 else if (errNum != 0)
570 WarningLog(<<
"checkConnectionTimedout " <<
mWho.
mFlowKey <<
" code: " << errNum <<
"; ignoring - should we error out?");
602 InfoLog(<< failureString <<
"; closing connection");
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
virtual Transport * transport() const
void setFailureReason(TransportFailure::FailureReason failReason, int subCode, const Data &failureString)
Compression & mCompression
TransmissionFormat mSendingTransmissionFormat
bool wsProcessData(int bytesRead)
std::pair< char *, size_t > getWriteBuffer()
bool wsProcessHandshake(int bytesRead, bool &dropConnection)
void decompressNewBytes(int bytesRead)
TransmissionFormat mReceivingTransmissionFormat
osc::Stack * mSigcompStack
std::pair< char *, size_t > getCurrentWriteBuffer()
bool preparseNewBytes(int bytesRead)
std::list< SendData * > mOutstandingSends
Collection of Connection per Transport.
Connection implements, via sockets, ConnectionBase for managed connections.
int performWrite()
send some or all of a queued data; remove from writable if completely written
bool performWrites(unsigned int max=0)
Call performWrite() repeatedly, until either the send queue is exhausted, the write() call fails (pro...
virtual void onWsClose(const Data &payload)
virtual bool checkConnectionTimedout()
virtual bool hasDataToRead()
always true – always add to fdset as read ready
virtual void onWsPing(const Data &payload)
bool mFirstWriteAfterConnectedPending
virtual bool isGood()
has valid connection
virtual bool isWritable()
virtual void onDoubleCRLF()
void enableFlowTimer()
Ensures this connection is in the FlowTimer LRU list in the connection manager.
virtual void invokeAfterSocketCreationFunc() const
void requestWrite(SendData *sendData)
queue data to write and add this to writable list
virtual void onSingleCRLF()
static volatile bool mEnablePostConnectSocketFuncCall
virtual void processPollEvent(FdPollEventMask mask)
Virtual function of FdPollItemIf, called to process io events.
bool performReads(unsigned int max=0)
Call read() repeatedly, until an error occurs (because the fd is not ready to read,...
virtual int write(const char *, const int)
pure virtual, but need concrete Connection for book-ends of lists
void ensureWritable()
ensure that we are on the writeable list if required
virtual bool transportWrite()
int read()
move data from the connection to the buffer; move this to front of least recently used list.
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.
@ Take
The Data instance takes complete ownership of the buffer.
Data & takeBuf(Data &other) noexcept
Take the data from {other}.
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.
static int getOutboundVersion()
The base class for Transport classes.
const TransportType transport() const
static Data errorToString(int e)
void applySocketOptions(Socket sock) const
The one place a socket of this transport is configured.
void keepAlivePong(const Tuple &flow)
void setTcpConnectState(const Data &tid, TcpConnectState::State state)
Posts a TcpConnectState to the TransactionMessage Fifo.
Represents a network address.
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
dcm! – add UnusedChecking(_enum) below;
const _Tp & resipMin(const _Tp &__a, const _Tp &__b)
unsigned short FdPollEventMask
int getSocketError(Socket fd)
bool isWebSocket(TransportType type)
Returns true if passed in transport type is a WebSocket transport protocol.
unsigned long long uint64_t
int closeSocket(Socket fd)
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)