Ejemplo n.º 1
0
    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;
        }
    }
Ejemplo n.º 2
0
 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;
     }
 }
Ejemplo n.º 3
0
    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() );
            }
        }
    }
Ejemplo n.º 4
0
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;
    }
}
Ejemplo n.º 5
0
    // 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() );
            }
        }
    }