void Socket::recv( char * buf , int len ) { int retries = 0; while( len > 0 ) { int ret = -1; if (MONGO_FAIL_POINT(throwSockExcep)) { #if defined(_WIN32) WSASetLastError(WSAENETUNREACH); #else errno = ENETUNREACH; #endif } else { ret = unsafe_recv(buf, len); } if (ret <= 0) { _handleRecvError(ret, len, &retries); continue; } if ( len <= 4 && ret != len ) LOG(_logLevel) << "Socket recv() got " << ret << " bytes wanted len=" << len << endl; fassert(16508, ret <= len); len -= ret; buf += ret; } }
void Socket::recv( char * buf , int len ) { int retries = 0; while( len > 0 ) { int ret = unsafe_recv( buf , len ); if ( ret <= 0 ) { _handleRecvError(ret, len, &retries); continue; } if ( len <= 4 && ret != len ) LOG(_logLevel) << "Socket recv() got " << ret << " bytes wanted len=" << len << endl; fassert(16508, ret <= len); len -= ret; buf += ret; } }
void Socket::recv( char * buf , int len ) { unsigned retries = 0; while( len > 0 ) { int ret = unsafe_recv( buf , len ); if ( ret > 0 ) { if ( len <= 4 && ret != len ) log(_logLevel) << "Socket recv() got " << ret << " bytes wanted len=" << len << endl; assert( ret <= len ); len -= ret; buf += ret; } else if ( ret == 0 ) { log(3) << "Socket recv() conn closed? " << remoteString() << endl; throw SocketException( SocketException::CLOSED , remoteString() ); } else { /* ret < 0 */ int e = errno; #if defined(EINTR) && !defined(_WIN32) if( e == EINTR ) { if( ++retries == 1 ) { log() << "EINTR retry" << endl; continue; } } #endif if ( ( e == EAGAIN #ifdef _WINDOWS || e == WSAETIMEDOUT #endif ) && _timeout > 0 ) { // this is a timeout log(_logLevel) << "Socket recv() timeout " << remoteString() <<endl; throw SocketException( SocketException::RECV_TIMEOUT, remoteString() ); } log(_logLevel) << "Socket recv() " << errnoWithDescription(e) << " " << remoteString() <<endl; throw SocketException( SocketException::RECV_ERROR , remoteString() ); } } }
void Socket::recv(char* buf, int len) { while (len > 0) { int ret = -1; if (MONGO_FAIL_POINT(throwSockExcep)) { #if defined(_WIN32) WSASetLastError(WSAENETUNREACH); #else errno = ENETUNREACH; #endif if (ret <= 0) { handleRecvError(ret, len); continue; } } else { ret = unsafe_recv(buf, len); } fassert(16508, ret <= len); len -= ret; buf += ret; } }
// sends all data or throws an exception void Socket::send( const char * data , int len, const char *context ) { while( len > 0 ) { int ret = _send( data , len ); if ( ret == -1 ) { #ifdef MONGO_SSL if ( _ssl ) { log() << "SSL Error ret: " << ret << " err: " << SSL_get_error( _ssl , ret ) << " " << ERR_error_string(ERR_get_error(), NULL) << endl; } #endif #if defined(_WIN32) const int mongo_errno = WSAGetLastError(); if ( mongo_errno == WSAETIMEDOUT && _timeout != 0 ) { #else const int mongo_errno = errno; if ( ( mongo_errno == EAGAIN || mongo_errno == EWOULDBLOCK ) && _timeout != 0 ) { #endif log(_logLevel) << "Socket " << context << " send() timed out " << _remote.toString() << endl; throw SocketException( SocketException::SEND_TIMEOUT , remoteString() ); } else { SocketException::Type t = SocketException::SEND_ERROR; log(_logLevel) << "Socket " << context << " send() " << errnoWithDescription(mongo_errno) << ' ' << remoteString() << endl; throw SocketException( t , remoteString() ); } } else { _bytesOut += ret; verify( ret <= len ); len -= ret; data += ret; } } } void Socket::_send( const vector< pair< char *, int > > &data, const char *context ) { for( vector< pair< char *, int > >::const_iterator i = data.begin(); i != data.end(); ++i ) { char * data = i->first; int len = i->second; send( data, len, context ); } } /** sends all data or throws an exception * @param context descriptive for logging */ void Socket::send( const vector< pair< char *, int > > &data, const char *context ) { #ifdef MONGO_SSL if ( _ssl ) { _send( data , context ); return; } #endif #if defined(_WIN32) // TODO use scatter/gather api _send( data , context ); #else vector< struct iovec > d( data.size() ); int i = 0; for( vector< pair< char *, int > >::const_iterator j = data.begin(); j != data.end(); ++j ) { if ( j->second > 0 ) { d[ i ].iov_base = j->first; d[ i ].iov_len = j->second; ++i; _bytesOut += j->second; } } struct msghdr meta; memset( &meta, 0, sizeof( meta ) ); meta.msg_iov = &d[ 0 ]; meta.msg_iovlen = d.size(); while( meta.msg_iovlen > 0 ) { int ret = ::sendmsg( _fd , &meta , portSendFlags ); if ( ret == -1 ) { if ( errno != EAGAIN || _timeout == 0 ) { log(_logLevel) << "Socket " << context << " send() " << errnoWithDescription() << ' ' << remoteString() << endl; throw SocketException( SocketException::SEND_ERROR , remoteString() ); } else { log(_logLevel) << "Socket " << context << " send() remote timeout " << remoteString() << endl; throw SocketException( SocketException::SEND_TIMEOUT , remoteString() ); } } else { struct iovec *& i = meta.msg_iov; while( ret > 0 ) { if ( i->iov_len > unsigned( ret ) ) { i->iov_len -= ret; i->iov_base = (char*)(i->iov_base) + ret; ret = 0; } else { ret -= i->iov_len; ++i; --(meta.msg_iovlen); } } } } #endif } void Socket::recv( char * buf , int len ) { unsigned retries = 0; while( len > 0 ) { int ret = unsafe_recv( buf , len ); if ( ret > 0 ) { if ( len <= 4 && ret != len ) log(_logLevel) << "Socket recv() got " << ret << " bytes wanted len=" << len << endl; verify( ret <= len ); len -= ret; buf += ret; } else if ( ret == 0 ) { log(3) << "Socket recv() conn closed? " << remoteString() << endl; throw SocketException( SocketException::CLOSED , remoteString() ); } else { /* ret < 0 */ #if defined(_WIN32) int e = WSAGetLastError(); #else int e = errno; # if defined(EINTR) if( e == EINTR ) { log() << "EINTR retry " << ++retries << endl; continue; } # endif #endif if ( ( e == EAGAIN #if defined(_WIN32) || e == WSAETIMEDOUT #endif ) && _timeout > 0 ) { // this is a timeout log(_logLevel) << "Socket recv() timeout " << remoteString() <<endl; throw SocketException( SocketException::RECV_TIMEOUT, remoteString() ); } log(_logLevel) << "Socket recv() " << errnoWithDescription(e) << " " << remoteString() <<endl; throw SocketException( SocketException::RECV_ERROR , remoteString() ); } } }