📄 connectionbase.cxx
字号:
bytesRead = overHang;
goto start;
}
}
}
break;
}
case PartialBody:
{
size_t contentLength = 0;
try
{
contentLength = mMessage->header(h_ContentLength).value();
}
catch(resip::ParseBuffer::Exception& e)
{
WarningLog(<<"Malformed Content-Length in connection-based transport"
". Not much we can do to fix this. " << e);
// !bwc! Bad Content-Length. We are hosed.
delete [] mBuffer;
mBuffer = 0;
delete mMessage;
mMessage = 0;
//.jacob. Shouldn't the state also be set here?
delete this;
return;
}
mBufferPos += bytesRead;
if (mBufferPos == contentLength)
{
mMessage->addBuffer(mBuffer);
mMessage->setBody(mBuffer, contentLength);
if (!transport()->basicCheck(*mMessage))
{
delete mMessage;
mMessage = 0;
}
else
{
DebugLog(<< "##ConnectionBase: " << *this << " received: " << *mMessage);
Transport::stampReceived(mMessage);
fifo.add(mMessage);
mMessage = 0;
}
mConnState = NewMessage;
mBuffer = 0;
}
break;
}
default:
assert(0);
}
}
#ifdef USE_SIGCOMP
void
ConnectionBase::decompressNewBytes(int bytesRead,
Fifo<TransactionMessage>& fifo)
{
mConnState = SigComp;
if (!mSigcompFramer)
{
mSigcompFramer = new osc::TcpStream();
}
mSigcompFramer->addData(mBuffer, bytesRead);
size_t bytesUncompressed;
osc::StateChanges *sc = 0;
char *uncompressed = new char[65536];
while ((bytesUncompressed = mSigcompStack->uncompressMessage(
*mSigcompFramer, uncompressed, 65536, sc)) > 0)
{
DebugLog (<< "Uncompressed Connection-oriented message");
mMessage = new SipMessage(mWho.transport);
mMessage->setSource(mWho);
mMessage->setTlsDomain(mWho.transport->tlsDomain());
char *sipBuffer = new char[bytesUncompressed];
memmove(sipBuffer, uncompressed, bytesUncompressed);
mMessage->addBuffer(sipBuffer);
mMsgHeaderScanner.prepareForMessage(mMessage);
char *unprocessedCharPtr;
if (mMsgHeaderScanner.scanChunk(sipBuffer,
bytesUncompressed,
&unprocessedCharPtr) !=
MsgHeaderScanner::scrEnd)
{
StackLog(<<"Scanner rejecting compressed message as unparsable");
StackLog(<< Data(sipBuffer, bytesUncompressed));
delete mMessage;
mMessage=0;
}
unsigned int used = unprocessedCharPtr - sipBuffer;
if (mMessage && (used < bytesUncompressed))
{
mMessage->setBody(sipBuffer+used, bytesUncompressed-used);
}
if (mMessage && !transport()->basicCheck(*mMessage))
{
delete mMessage;
mMessage = 0;
}
if (mMessage)
{
Transport::stampReceived(mMessage);
// If the message made it this far, we should let it store
// SigComp state: extract the compartment ID.
const Via &via = mMessage->header(h_Vias).front();
if (mMessage->isRequest())
{
// For requests, the compartment ID is read out of the
// top via header field; if not present, we use the
// TCP connection for identification purposes.
if (via.exists(p_sigcompId))
{
Data compId = via.param(p_sigcompId);
mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size());
}
else
{
mSigcompStack->provideCompartmentId(sc, this, sizeof(this));
}
}
else
{
// For responses, the compartment ID is supposed to be
// the same as the compartment ID of the request. We
// *could* dig down into the transaction layer to try to
// figure this out, but that's a royal pain, and a rather
// severe layer violation. In practice, we're going to ferret
// the ID out of the the Via header field, which is where we
// squirreled it away when we sent this request in the first place.
Data compId = via.param(p_branch).getSigcompCompartment();
mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size());
}
fifo.add(mMessage);
mMessage = 0;
sc = 0;
}
else
{
delete sc;
sc = 0;
}
}
delete uncompressed;
// If there was a decompression failure, let the other side know.
osc::SigcompMessage *nack = mSigcompStack->getNack();
if (nack)
{
if (mSendingTransmissionFormat == Compressed)
{
mOutstandingSends.push_back(new SendData(
who(),
Data(nack->getStreamMessage(), nack->getStreamLength()),
Data::Empty,
Data::Empty,
true));
}
else
{
delete nack;
}
}
}
#endif
std::pair<char*, size_t>
ConnectionBase::getWriteBuffer()
{
if (mConnState == NewMessage)
{
if (mBuffer)
{
delete [] mBuffer;
}
DebugLog (<< "Creating buffer for " << *this);
mBuffer = MsgHeaderScanner::allocateBuffer(ConnectionBase::ChunkSize);
mBufferSize = ConnectionBase::ChunkSize;
mBufferPos = 0;
}
return std::make_pair(mBuffer + mBufferPos, mBufferSize - mBufferPos);
}
char*
ConnectionBase::getWriteBufferForExtraBytes(int extraBytes)
{
char* buffer = MsgHeaderScanner::allocateBuffer(mBufferSize + extraBytes);
memcpy(buffer, mBuffer, mBufferSize);
delete [] mBuffer;
mBuffer = buffer;
buffer += mBufferSize;
mBufferSize += extraBytes;
return buffer;
}
void
ConnectionBase::setBuffer(char* bytes, int count)
{
mBuffer = bytes;
mBufferPos = 0;
mBufferSize = count;
}
Transport*
ConnectionBase::transport()
{
assert(this);
return mWho.transport;
}
std::ostream&
resip::operator<<(std::ostream& strm,
const resip::ConnectionBase& c)
{
strm << "CONN_BASE: " << &c << " " << c.mWho;
return strm;
}
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -