📄 dtlstransport.cxx
字号:
} // no pp error int used = unprocessedCharPtr - (char *)pt ; if ( used < len ) { // body is present .. add it up. // NB. The Sip Message uses an overlay (again) // for the body. It ALSO expects that the body // will be contiguous (of course). // it doesn't need a new buffer in UDP b/c there // will only be one datagram per buffer. (1:1 strict) message->setBody( (char *)pt + used, len - used ) ; //DebugLog(<<"added " << len-used << " byte body"); } if ( ! basicCheck( *message ) ) { delete message ; // cannot use it, so, punt on it... // basicCheck queued any response required message = 0 ; return ; } stampReceived( message) ;#ifdef USE_SIGCOMP if (mCompression.isEnabled() && sc) { const Via &via = message->header(h_Vias).front(); if (message->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()); } }#endif mStateMachineFifo.add( message ) ;}void DtlsTransport::_write( FdSet& fdset ){ SSL *ssl ; BIO *wBio ; int retry = 0 ; SendData *sendData ; if ( mSendData != NULL ) sendData = mSendData ; else sendData = mTxFifo.getNext() ; //DebugLog (<< "Sent: " << sendData->data); //DebugLog (<< "Sending message on udp."); assert( &(*sendData) ); assert( sendData->destination.getPort() != 0 ); sockaddr peer = sendData->destination.getSockaddr(); ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ; /* If we don't have a binding, then we're a client */ if ( ssl == NULL ) { ssl = SSL_new( mClientCtx ) ; assert( ssl ) ; SSL_set_connect_state( ssl ) ; wBio = BIO_new_dgram( mFd, BIO_NOCLOSE ) ; assert( wBio ) ; BIO_dgram_set_peer( wBio, &peer) ; /* the real rbio will be set by _read */ SSL_set_bio( ssl, mDummyBio, wBio ) ; /* we should be ready to take this out if the * connection fails later */ mDtlsConnections [ *((struct sockaddr_in *)&peer) ] = ssl ; } int expected; int count;#ifdef USE_SIGCOMP // If message needs to be compressed, compress it here. if (mSigcompStack && sendData->sigcompId.size() > 0 && !sendData->isAlreadyCompressed ) { osc::SigcompMessage *sm = mSigcompStack->compressMessage (sendData->data.data(), sendData->data.size(), sendData->sigcompId.data(), sendData->sigcompId.size(), isReliable()); DebugLog (<< "Compressed message from " << sendData->data.size() << " bytes to " << sm->getDatagramLength() << " bytes"); expected = sm->getDatagramLength(); count = SSL_Write(ssl, sm->getDatagramMessage(), sm->getDatagramLength()); delete sm; } else#endif { expected = sendData->data.size(); count = SSL_write(ssl, sendData->data.data(), sendData->data.size()); } /* * all reads go through _read, so the most likely result during a handshake * will be SSL_ERROR_WANT_READ */ if ( count <= 0 ) { /* cache unqueued data */ mSendData = sendData ; int err = SSL_get_error( ssl, count ) ; switch( err ) { case SSL_ERROR_NONE: break; case SSL_ERROR_SSL: break; case SSL_ERROR_WANT_READ: retry = 1 ; break; case SSL_ERROR_WANT_WRITE: retry = 1 ; fdset.setWrite(mFd); break; case SSL_ERROR_SYSCALL: { int e = getErrno(); error(e); InfoLog (<< "Failed (" << e << ") sending to " << sendData->destination); fail(sendData->transactionId); break; } case SSL_ERROR_ZERO_RETURN: _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ; break ; case SSL_ERROR_WANT_CONNECT: break; case SSL_ERROR_WANT_ACCEPT: break; default: break ; } } else { mSendData = NULL ; } /* * ngm: is sendData deleted by a higher layer? Seems to be the case after * checking with UdpTransport */ if ( ! retry && count != int(sendData->data.size()) ) { ErrLog (<< "UDPTransport - send buffer full" ); fail(sendData->transactionId); }}voidDtlsTransport::_doHandshake( void ){ DtlsMessage *msg = mHandshakePending.getNext() ; SSL *ssl = msg->getSsl() ; delete msg ; int ret = SSL_do_handshake( ssl ) ; switch( ret ) { case SSL_ERROR_NONE: break; case SSL_ERROR_SSL: break; case SSL_ERROR_WANT_READ: break; case SSL_ERROR_WANT_WRITE: break; case SSL_ERROR_SYSCALL: break; case SSL_ERROR_ZERO_RETURN: break; case SSL_ERROR_WANT_CONNECT: break; case SSL_ERROR_WANT_ACCEPT: break; default: break ; }}void DtlsTransport::process(FdSet& fdset){ // pull buffers to send out of TxFifo // receive datagrams from fd // preparse and stuff into RxFifo mTimer.process() ; while ( mHandshakePending.messageAvailable() ) _doHandshake() ; if ( ( mSendData != NULL || mTxFifo.messageAvailable() ) && fdset.readyToWrite( mFd ) ) _write( fdset ) ; // !jf! this may have to change - when we read a message that is too big if ( fdset.readyToRead(mFd) ) _read( fdset ) ;}void DtlsTransport::buildFdSet( FdSet& fdset ){ fdset.setRead(mFd); if ( mSendData != NULL || mTxFifo.messageAvailable() ) { fdset.setWrite(mFd); }}voidDtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ){ /* * SSL_free decrements the ref-count for mDummyBio by 1, so * add 1 to the ref-count to make sure it does not get free'd */ CRYPTO_add( &mDummyBio->references, 1, CRYPTO_LOCK_BIO ) ; SSL_free( ssl ) ; mDtlsConnections.erase( peer ) ;}voidDtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl ){ fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ; fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ;}voidDtlsTransport::_printSock( const struct sockaddr_in *sock ){ fprintf( stderr, "addr = %s\t port = %d\n", inet_ntoa( sock->sin_addr ), ntohs( sock->sin_port ) ) ;}#endif /* USE_DTLS *//* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * 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 + -