|
reSIProcate/stack
9694
|
00001 00002 #if defined(HAVE_CONFIG_H) 00003 #include "config.h" 00004 #endif 00005 00006 #ifdef USE_SSL 00007 #ifdef USE_DTLS 00008 00009 #include <memory> 00010 00011 #ifndef RESIP_COMPAT_HXX 00012 #include "rutil/compat.hxx" 00013 #endif 00014 00015 #ifndef RESIP_DATA_HXX 00016 #include "rutil/Data.hxx" 00017 #endif 00018 00019 #ifndef RESIP_DNSUTIL_HXX 00020 #include "rutil/DnsUtil.hxx" 00021 #endif 00022 00023 #ifndef RESIP_SOCKET_HXX 00024 #include "rutil/Socket.hxx" 00025 #endif 00026 00027 #ifndef RESIP_LOGGER_HXX 00028 #include "rutil/Logger.hxx" 00029 #endif 00030 00031 #ifndef RESIP_SIPMESSAGE_HXX 00032 #include "resip/stack/SipMessage.hxx" 00033 #endif 00034 00035 #ifndef RESIP_HELPER_HXX 00036 #include "resip/stack/Helper.hxx" 00037 #endif 00038 00039 #ifndef RESIP_SECURITY_HXX 00040 #include "resip/stack/ssl/Security.hxx" 00041 #endif 00042 00043 #ifndef RESIP_DTLSMESSAGE_HXX 00044 #include "resip/stack/DtlsMessage.hxx" 00045 #endif 00046 00047 #ifndef RESIP_DTLSTRANSPORT_HXX 00048 #include "resip/stack/ssl/DtlsTransport.hxx" 00049 #endif 00050 00051 #include "rutil/WinLeakCheck.hxx" 00052 00053 #include <openssl/e_os2.h> 00054 #include <openssl/evp.h> 00055 #include <openssl/crypto.h> 00056 #include <openssl/err.h> 00057 #include <openssl/pem.h> 00058 #include <openssl/pkcs7.h> 00059 #include <openssl/x509v3.h> 00060 #include <openssl/ssl.h> 00061 00062 #ifdef USE_SIGCOMP 00063 #include <osc/Stack.h> 00064 #include <osc/StateChanges.h> 00065 #include <osc/SigcompMessage.h> 00066 #endif 00067 00068 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT 00069 00070 using namespace std; 00071 using namespace resip; 00072 00073 // .slg. Note that DTLS handshakes were really broken in older versions of OpenSSL 0.9.8 00074 // You should use at least version 0.9.8g for both client and server. 00075 00076 DtlsTransport::DtlsTransport(Fifo<TransactionMessage>& fifo, 00077 int portNum, 00078 IpVersion version, 00079 const Data& interfaceObj, 00080 Security& security, 00081 const Data& sipDomain, 00082 AfterSocketCreationFuncPtr socketFunc, 00083 Compression& compression) 00084 : UdpTransport( fifo, portNum, version, 00085 StunDisabled, interfaceObj, socketFunc, compression ), 00086 mTimer( mHandshakePending ), 00087 mSecurity( &security ), 00088 mDomain(sipDomain) 00089 { 00090 setTlsDomain(sipDomain); 00091 InfoLog ( << "Creating DTLS transport host=" << interfaceObj 00092 << " port=" << mTuple.getPort() 00093 << " ipv4=" << version ) ; 00094 00095 mTxFifo.setDescription("DtlsTransport::mTxFifo"); 00096 00097 mTuple.setType( transport() ); 00098 00099 mClientCtx = mSecurity->createDomainCtx(DTLSv1_client_method(), Data::Empty) ; 00100 mServerCtx = mSecurity->createDomainCtx(DTLSv1_server_method(), sipDomain) ; 00101 assert( mClientCtx ) ; 00102 assert( mServerCtx ) ; 00103 00104 mDummyBio = BIO_new( BIO_s_mem() ) ; 00105 assert( mDummyBio ) ; 00106 00107 mSendData = NULL ; 00108 00109 /* DTLS: partial reads end up discarding unread UDP bytes :-( 00110 * Setting read ahead solves this problem. 00111 * Source of this comment is: apps/s_client.c from OpenSSL source 00112 */ 00113 SSL_CTX_set_read_ahead(mClientCtx, 1); 00114 SSL_CTX_set_read_ahead(mServerCtx, 1); 00115 00116 /* trying to read from this BIO always returns retry */ 00117 BIO_set_mem_eof_return( mDummyBio, -1 ) ; 00118 } 00119 00120 DtlsTransport::~DtlsTransport() 00121 { 00122 DebugLog (<< "Shutting down " << mTuple); 00123 00124 while(mDtlsConnections.begin() != mDtlsConnections.end()) 00125 { 00126 _cleanupConnectionState(mDtlsConnections.begin()->second, mDtlsConnections.begin()->first); 00127 } 00128 SSL_CTX_free(mClientCtx);mClientCtx=0; 00129 SSL_CTX_free(mServerCtx);mServerCtx=0; 00130 00131 BIO_free( mDummyBio) ; 00132 } 00133 00134 void 00135 DtlsTransport::_read( FdSet& fdset ) 00136 { 00137 //should this buffer be allocated on the stack and then copied out, as it 00138 //needs to be deleted every time EWOULDBLOCK is encountered 00139 // .dlb. can we determine the size of the buffer before we allocate? 00140 // something about MSG_PEEK|MSG_TRUNC in Stevens.. 00141 // .dlb. RFC3261 18.1.1 MUST accept 65K datagrams. would have to attempt to 00142 // adjust the UDP buffer as well... 00143 unsigned int bufferLen = UdpTransport::MaxBufferSize + 5 ; 00144 char* buffer = new char[ bufferLen ] ; 00145 unsigned char *pt = new unsigned char[ bufferLen ] ; 00146 00147 SSL *ssl ; 00148 BIO *rbio ; 00149 BIO *wbio ; 00150 00151 // !jf! how do we tell if it discarded bytes 00152 // !ah! we use the len-1 trick :-( 00153 Tuple tuple(mTuple) ; 00154 socklen_t slen = tuple.length() ; 00155 int len = recvfrom( mFd, 00156 buffer, 00157 UdpTransport::MaxBufferSize, 00158 0 /*flags */, 00159 &tuple.getMutableSockaddr(), 00160 &slen ) ; 00161 if ( len == SOCKET_ERROR ) 00162 { 00163 int err = getErrno() ; 00164 if ( err != EWOULDBLOCK ) 00165 { 00166 error( err ) ; 00167 } 00168 } 00169 00170 if (len == 0 || len == SOCKET_ERROR) 00171 { 00172 delete [] buffer ; 00173 buffer = 0 ; 00174 return ; 00175 } 00176 00177 if ( len + 1 >= UdpTransport::MaxBufferSize ) 00178 { 00179 InfoLog (<<"Datagram exceeded max length "<<UdpTransport::MaxBufferSize ) ; 00180 delete [] buffer ; buffer = 0 ; 00181 return ; 00182 } 00183 00184 //DebugLog ( << "UDP Rcv : " << len << " b" ); 00185 //DebugLog ( << Data(buffer, len).escaped().c_str()); 00186 00187 /* begin SSL stuff */ 00188 struct sockaddr peer = tuple.getMutableSockaddr() ; 00189 00190 ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ; 00191 00192 /* 00193 * If we don't have a binding for this peer, 00194 * then we're a server. 00195 */ 00196 if ( ssl == NULL ) 00197 { 00198 ssl = SSL_new( mServerCtx ) ; 00199 assert( ssl ) ; 00200 00201 // clear SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE set in SSL_CTX if we are a server 00202 SSL_set_verify(ssl, 0, 0); 00203 00204 InfoLog( << "DTLS handshake starting (Server mode)" ); 00205 00206 SSL_set_accept_state( ssl ) ; 00207 00208 wbio = BIO_new_dgram( (int)mFd, BIO_NOCLOSE ) ; 00209 assert( wbio ) ; 00210 00211 BIO_dgram_set_peer( wbio, &peer ) ; 00212 00213 SSL_set_bio( ssl, NULL, wbio ) ; 00214 00215 /* remember this connection */ 00216 mDtlsConnections[ *((struct sockaddr_in *)&peer) ] = ssl ; 00217 } 00218 00219 rbio = BIO_new_mem_buf( buffer, len ) ; 00220 BIO_set_mem_eof_return( rbio, -1 ) ; 00221 00222 ssl->rbio = rbio ; 00223 00224 len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ; 00225 int err = SSL_get_error( ssl, len ) ; 00226 00227 /* done with the rbio */ 00228 BIO_free( ssl->rbio ) ; 00229 ssl->rbio = mDummyBio ; 00230 delete [] buffer ; 00231 buffer = 0 ; 00232 00233 if ( len <= 0 ) 00234 { 00235 char errorString[1024]; 00236 00237 switch( err ) 00238 { 00239 case SSL_ERROR_NONE: 00240 break ; 00241 case SSL_ERROR_SSL: 00242 { 00243 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00244 DebugLog( << "Got DTLS read condition SSL_ERROR_SSL on" 00245 << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) 00246 << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) 00247 << " error = " << errorString ); 00248 } 00249 break ; 00250 case SSL_ERROR_WANT_READ: 00251 break ; 00252 case SSL_ERROR_WANT_WRITE: 00253 break ; 00254 case SSL_ERROR_SYSCALL: 00255 { 00256 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00257 DebugLog( << "Got DTLS read condition SSL_ERROR_SYSCALL on" 00258 << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) 00259 << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) 00260 << " error = " << errorString ); 00261 } 00262 break ; 00263 /* connection closed */ 00264 case SSL_ERROR_ZERO_RETURN: 00265 { 00266 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00267 DebugLog( << "Got DTLS read condition SSL_ERROR_ZERO_RETURN on" 00268 << " addr = " << inet_ntoa(((struct sockaddr_in *)&peer)->sin_addr) 00269 << " port = " << ntohs(((struct sockaddr_in *)&peer)->sin_port) 00270 << " error = " << errorString ); 00271 00272 _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ; 00273 } 00274 break ; 00275 case SSL_ERROR_WANT_CONNECT: 00276 break ; 00277 case SSL_ERROR_WANT_ACCEPT: 00278 break ; 00279 default: 00280 break ; 00281 } 00282 } 00283 00284 if ( len <= 0 ) 00285 return ; 00286 00287 if ( SSL_in_init( ssl ) ) 00288 mTimer.add( ssl, DtlsReceiveTimeout ) ; 00289 00290 #ifdef USE_SIGCOMP 00291 osc::StateChanges *sc = 0; 00292 #endif 00293 00294 if ((pt[0] & 0xf8) == 0xf8) 00295 { 00296 if(!mCompression.isEnabled()) 00297 { 00298 InfoLog(<< "Discarding unexpected SigComp message"); 00299 delete [] pt; 00300 return; 00301 } 00302 #ifdef USE_SIGCOMP 00303 unsigned char *newPt = new unsigned char[ bufferLen ] ; 00304 size_t uncompressedLength = 00305 mSigcompStack->uncompressMessage(pt, len, 00306 newPt, UdpTransport::MaxBufferSize, 00307 sc); 00308 00309 DebugLog (<< "Unompressed message from " 00310 << len << " bytes to " 00311 << uncompressedLength << " bytes"); 00312 00313 osc::SigcompMessage *nack = mSigcompStack->getNack(); 00314 00315 if (nack) 00316 { 00317 mTxFifo.add(new SendData(tuple, 00318 Data(nack->getDatagramMessage(), 00319 nack->getDatagramLength()), 00320 Data::Empty, 00321 Data::Empty, 00322 true) 00323 ); 00324 delete nack; 00325 } 00326 00327 delete[] buffer; 00328 buffer = newBuffer; 00329 len = uncompressedLength; 00330 #endif 00331 } 00332 00333 SipMessage* message = new SipMessage(this); 00334 00335 // set the received from information into the received= parameter in the 00336 // via 00337 00338 // It is presumed that UDP Datagrams are arriving atomically and that 00339 // each one is a unique SIP message 00340 00341 // Save all the info where this message came from 00342 tuple.transport = this ; 00343 message->setSource( tuple ) ; 00344 //DebugLog (<< "Received from: " << tuple); 00345 00346 // Tell the SipMessage about this datagram buffer. 00347 message->addBuffer( (char *)pt ) ; 00348 00349 mMsgHeaderScanner.prepareForMessage( message ) ; 00350 00351 char *unprocessedCharPtr ; 00352 if (mMsgHeaderScanner.scanChunk( (char *)pt, 00353 len, 00354 &unprocessedCharPtr ) != 00355 MsgHeaderScanner::scrEnd) 00356 { 00357 DebugLog( << "Scanner rejecting datagram as unparsable / fragmented from " 00358 << tuple ) ; 00359 DebugLog( << Data( pt, len ) ) ; 00360 delete message ; 00361 message = 0 ; 00362 return ; 00363 } 00364 00365 // no pp error 00366 int used = int(unprocessedCharPtr - (char *)pt); 00367 00368 if ( used < len ) 00369 { 00370 // body is present .. add it up. 00371 // NB. The Sip Message uses an overlay (again) 00372 // for the body. It ALSO expects that the body 00373 // will be contiguous (of course). 00374 // it doesn't need a new buffer in UDP b/c there 00375 // will only be one datagram per buffer. (1:1 strict) 00376 00377 message->setBody( (char *)pt + used, len - used ) ; 00378 //DebugLog(<<"added " << len-used << " byte body"); 00379 } 00380 00381 if ( ! basicCheck( *message ) ) 00382 { 00383 delete message ; // cannot use it, so, punt on it... 00384 // basicCheck queued any response required 00385 message = 0 ; 00386 return ; 00387 } 00388 00389 stampReceived( message) ; 00390 00391 #ifdef USE_SIGCOMP 00392 if (mCompression.isEnabled() && sc) 00393 { 00394 const Via &via = message->header(h_Vias).front(); 00395 if (message->isRequest()) 00396 { 00397 // For requests, the compartment ID is read out of the 00398 // top via header field; if not present, we use the 00399 // TCP connection for identification purposes. 00400 if (via.exists(p_sigcompId)) 00401 { 00402 Data compId = via.param(p_sigcompId); 00403 mSigcompStack->provideCompartmentId( 00404 sc, compId.data(), compId.size()); 00405 } 00406 else 00407 { 00408 mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); 00409 } 00410 } 00411 else 00412 { 00413 // For responses, the compartment ID is supposed to be 00414 // the same as the compartment ID of the request. We 00415 // *could* dig down into the transaction layer to try to 00416 // figure this out, but that's a royal pain, and a rather 00417 // severe layer violation. In practice, we're going to ferret 00418 // the ID out of the the Via header field, which is where we 00419 // squirreled it away when we sent this request in the first place. 00420 Data compId = via.param(p_branch).getSigcompCompartment(); 00421 mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); 00422 } 00423 00424 } 00425 #endif 00426 00427 mStateMachineFifo.add( message ) ; 00428 } 00429 00430 void DtlsTransport::_write( FdSet& fdset ) 00431 { 00432 SSL *ssl ; 00433 BIO *wBio ; 00434 int retry = 0 ; 00435 00436 SendData *sendData ; 00437 if ( mSendData != NULL ) 00438 sendData = mSendData ; 00439 else 00440 sendData = mTxFifo.getNext() ; 00441 00442 //DebugLog (<< "Sent: " << sendData->data); 00443 //DebugLog (<< "Sending message on udp."); 00444 00445 assert( &(*sendData) ); 00446 assert( sendData->destination.getPort() != 0 ); 00447 00448 sockaddr peer = sendData->destination.getSockaddr(); 00449 00450 ssl = mDtlsConnections[ *((struct sockaddr_in *)&peer) ] ; 00451 00452 /* If we don't have a binding, then we're a client */ 00453 if ( ssl == NULL ) 00454 { 00455 ssl = SSL_new( mClientCtx ) ; 00456 assert( ssl ) ; 00457 00458 00459 InfoLog( << "DTLS handshake starting (client mode)" ); 00460 00461 SSL_set_connect_state( ssl ) ; 00462 00463 wBio = BIO_new_dgram( (int)mFd, BIO_NOCLOSE ) ; 00464 assert( wBio ) ; 00465 00466 BIO_dgram_set_peer( wBio, &peer) ; 00467 00468 /* the real rbio will be set by _read */ 00469 SSL_set_bio( ssl, mDummyBio, wBio ) ; 00470 00471 /* we should be ready to take this out if the 00472 * connection fails later */ 00473 mDtlsConnections [ *((struct sockaddr_in *)&peer) ] = ssl ; 00474 } 00475 00476 int expected; 00477 int count; 00478 00479 #ifdef USE_SIGCOMP 00480 // If message needs to be compressed, compress it here. 00481 if (mSigcompStack && 00482 sendData->sigcompId.size() > 0 && 00483 !sendData->isAlreadyCompressed ) 00484 { 00485 osc::SigcompMessage *sm = mSigcompStack->compressMessage 00486 (sendData->data.data(), sendData->data.size(), 00487 sendData->sigcompId.data(), sendData->sigcompId.size(), 00488 isReliable()); 00489 00490 DebugLog (<< "Compressed message from " 00491 << sendData->data.size() << " bytes to " 00492 << sm->getDatagramLength() << " bytes"); 00493 00494 expected = sm->getDatagramLength(); 00495 00496 count = SSL_Write(ssl, 00497 sm->getDatagramMessage(), 00498 sm->getDatagramLength()); 00499 delete sm; 00500 } 00501 else 00502 #endif 00503 { 00504 expected = (int)sendData->data.size(); 00505 00506 count = SSL_write(ssl, sendData->data.data(), 00507 (int)sendData->data.size()); 00508 } 00509 00510 /* 00511 * all reads go through _read, so the most likely result during a handshake 00512 * will be SSL_ERROR_WANT_READ 00513 */ 00514 00515 if ( count <= 0 ) 00516 { 00517 /* cache unqueued data */ 00518 mSendData = sendData ; 00519 00520 int err = SSL_get_error( ssl, count ) ; 00521 00522 char errorString[1024]; 00523 00524 switch( err ) 00525 { 00526 case SSL_ERROR_NONE: 00527 break; 00528 case SSL_ERROR_SSL: 00529 { 00530 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00531 DebugLog( << "Got DTLS write condition SSL_ERROR_SSL on " 00532 << sendData->destination 00533 << " error = " << errorString ); 00534 } 00535 break; 00536 case SSL_ERROR_WANT_READ: 00537 retry = 1 ; 00538 break; 00539 case SSL_ERROR_WANT_WRITE: 00540 retry = 1 ; 00541 fdset.setWrite(mFd); 00542 break; 00543 case SSL_ERROR_SYSCALL: 00544 { 00545 int e = getErrno(); 00546 error(e); 00547 00548 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00549 DebugLog( << "Got DTLS write condition SSL_ERROR_SYSCALL " 00550 << "Failed (" << e << ") sending to " 00551 << sendData->destination 00552 << " error = " << errorString ); 00553 00554 fail(sendData->transactionId); 00555 } 00556 break; 00557 case SSL_ERROR_ZERO_RETURN: 00558 { 00559 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00560 DebugLog( << "Got DTLS write condition SSL_ERROR_ZERO_RETURN on " 00561 << sendData->destination 00562 << " error = " << errorString ); 00563 00564 _cleanupConnectionState( ssl, *((struct sockaddr_in *)&peer) ) ; 00565 } 00566 break ; 00567 case SSL_ERROR_WANT_CONNECT: 00568 break; 00569 case SSL_ERROR_WANT_ACCEPT: 00570 break; 00571 default: 00572 break ; 00573 } 00574 } 00575 else 00576 { 00577 mSendData = NULL ; 00578 } 00579 00580 /* 00581 * ngm: is sendData deleted by a higher layer? Seems to be the case after 00582 * checking with UdpTransport 00583 */ 00584 00585 if ( ! retry && count != int(sendData->data.size()) ) 00586 { 00587 ErrLog (<< "UDPTransport - send buffer full" ); 00588 fail(sendData->transactionId); 00589 } 00590 } 00591 00592 void 00593 DtlsTransport::_doHandshake( void ) 00594 { 00595 DtlsMessage *msg = mHandshakePending.getNext() ; 00596 SSL *ssl = msg->getSsl() ; 00597 00598 delete msg ; 00599 00600 ERR_clear_error(); 00601 00602 int ret = SSL_do_handshake( ssl ) ; 00603 00604 if (ret <= 0) { 00605 int err = SSL_get_error(ssl, ret); 00606 00607 char errorString[1024]; 00608 00609 switch (err) 00610 { 00611 case SSL_ERROR_NONE: 00612 break; 00613 case SSL_ERROR_SSL: 00614 { 00615 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00616 DebugLog( << "Got DTLS handshake code SSL_ERROR_SSL" 00617 << " error = " << errorString ); 00618 } 00619 break; 00620 case SSL_ERROR_WANT_READ: 00621 break; 00622 case SSL_ERROR_WANT_WRITE: 00623 break; 00624 case SSL_ERROR_SYSCALL: 00625 { 00626 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00627 DebugLog( << "Got DTLS handshake code SSL_ERROR_SYSCALL" 00628 << " error = " << errorString ); 00629 } 00630 break; 00631 case SSL_ERROR_ZERO_RETURN: 00632 { 00633 ERR_error_string_n(ERR_get_error(), errorString, sizeof(errorString)); 00634 DebugLog( << "Got DTLS handshake code SSL_ERROR_ZERO_RETURN" 00635 << " error = " << errorString ); 00636 } 00637 break; 00638 case SSL_ERROR_WANT_CONNECT: 00639 break; 00640 case SSL_ERROR_WANT_ACCEPT: 00641 break; 00642 default: 00643 break ; 00644 } 00645 } 00646 } 00647 00648 void 00649 DtlsTransport::process(FdSet& fdset) 00650 { 00651 // pull buffers to send out of TxFifo 00652 // receive datagrams from fd 00653 // preparse and stuff into RxFifo 00654 00655 mTimer.process() ; 00656 00657 while ( mHandshakePending.messageAvailable() ) 00658 _doHandshake() ; 00659 00660 if ( ( mSendData != NULL || mTxFifo.messageAvailable() ) 00661 && fdset.readyToWrite( mFd ) ) 00662 _write( fdset ) ; 00663 00664 // !jf! this may have to change - when we read a message that is too big 00665 if ( fdset.readyToRead(mFd) ) 00666 _read( fdset ) ; 00667 } 00668 00669 00670 void 00671 DtlsTransport::buildFdSet( FdSet& fdset ) 00672 { 00673 fdset.setRead(mFd); 00674 00675 if ( mSendData != NULL || mTxFifo.messageAvailable() ) 00676 { 00677 fdset.setWrite(mFd); 00678 } 00679 } 00680 00681 void 00682 DtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ) 00683 { 00684 /* 00685 * SSL_free decrements the ref-count for mDummyBio by 1, so 00686 * add 1 to the ref-count to make sure it does not get free'd 00687 */ 00688 CRYPTO_add(&mDummyBio->references, 1, CRYPTO_LOCK_BIO); 00689 SSL_shutdown(ssl); 00690 SSL_free(ssl) ; 00691 mDtlsConnections.erase(peer) ; 00692 } 00693 00694 void 00695 DtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl ) 00696 { 00697 fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ; 00698 fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ; 00699 } 00700 00701 void 00702 DtlsTransport::_printSock( const struct sockaddr_in *sock ) 00703 { 00704 fprintf( stderr, "addr = %s\t port = %d\n", inet_ntoa( sock->sin_addr ), 00705 ntohs( sock->sin_port ) ) ; 00706 } 00707 00708 #endif /* USE_DTLS */ 00709 #endif /* USE_SSL */ 00710 00711 /* ==================================================================== 00712 * The Vovida Software License, Version 1.0 00713 * 00714 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00715 * 00716 * Redistribution and use in source and binary forms, with or without 00717 * modification, are permitted provided that the following conditions 00718 * are met: 00719 * 00720 * 1. Redistributions of source code must retain the above copyright 00721 * notice, this list of conditions and the following disclaimer. 00722 * 00723 * 2. Redistributions in binary form must reproduce the above copyright 00724 * notice, this list of conditions and the following disclaimer in 00725 * the documentation and/or other materials provided with the 00726 * distribution. 00727 * 00728 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00729 * and "Vovida Open Communication Application Library (VOCAL)" must 00730 * not be used to endorse or promote products derived from this 00731 * software without prior written permission. For written 00732 * permission, please contact vocal@vovida.org. 00733 * 00734 * 4. Products derived from this software may not be called "VOCAL", nor 00735 * may "VOCAL" appear in their name, without prior written 00736 * permission of Vovida Networks, Inc. 00737 * 00738 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00739 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00740 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00741 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00742 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00743 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00744 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00745 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00746 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00747 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00748 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00749 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00750 * DAMAGE. 00751 * 00752 * ==================================================================== 00753 * 00754 * This software consists of voluntary contributions made by Vovida 00755 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00756 * Inc. For more information on Vovida Networks, Inc., please see 00757 * <http://www.vovida.org/>. 00758 * 00759 */
1.7.5.1