// sends all data or throws an exception void Socket::send( const char * data , int len, const char *context ) { while( len > 0 ) { int ret = ::send( _fd , data , len , portSendFlags ); if ( ret == -1 ) { if ( ( errno == EAGAIN || errno == EWOULDBLOCK ) && _timeout != 0 ) { log(_logLevel) << "Socket " << context << " send() timed out " << _remote.toString() << endl; throw SocketException( SocketException::SEND_TIMEOUT , remoteString() ); } else { SocketException::Type t = SocketException::SEND_ERROR; #if defined(_WINDOWS) if( e == WSAETIMEDOUT ) t = SocketException::SEND_TIMEOUT; #endif log(_logLevel) << "Socket " << context << " send() " << errnoWithDescription() << ' ' << remoteString() << endl; throw SocketException( t , remoteString() ); } } else { _bytesOut += ret; assert( ret <= len ); len -= ret; data += ret; } } }
// sends all data or throws an exception void Socket::send( const vector< pair< char *, int > > &data, const char *context ) { #if defined(_WIN32) // TODO use scatter/gather api 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 ); } #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 }
std::string Socket::doSSLHandshake(const char* firstBytes, int len) { if (!_sslManager) return ""; fassert(16506, _fd); if (_sslConnection.get()) { throw SocketException(SocketException::RECV_ERROR, "Attempt to call SSL_accept on already secure Socket from " + remoteString()); } _sslConnection.reset(_sslManager->accept(this, firstBytes, len)); return _sslManager->parseAndValidatePeerCertificate(_sslConnection.get(), ""); }
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::_handleSendError(int ret, const char* context) { #ifdef MONGO_SSL if (_ssl) { LOG(_logLevel) << "SSL Error ret: " << ret << " err: " << SSL_get_error(_ssl , ret) << " " << ERR_error_string(ERR_get_error(), NULL) << endl; throw SocketException(SocketException::SEND_ERROR , remoteString()); } #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 " << remoteString() << endl; throw SocketException(SocketException::SEND_TIMEOUT , remoteString()); } else { LOG(_logLevel) << "Socket " << context << " send() " << errnoWithDescription(mongo_errno) << ' ' << remoteString() << endl; throw SocketException(SocketException::SEND_ERROR , remoteString()); } } void Socket::_handleRecvError(int ret, int len, int* retries) { if (ret == 0 || MONGO_FAIL_POINT(throwSockExcep)) { LOG(3) << "Socket recv() conn closed? " << remoteString() << endl; throw SocketException(SocketException::CLOSED , remoteString()); } // ret < 0 #ifdef MONGO_SSL if (_ssl) { LOG(_logLevel) << "SSL Error ret: " << ret << " err: " << SSL_get_error(_ssl , ret) << " " << ERR_error_string(ERR_get_error(), NULL) << endl; throw SocketException(SocketException::RECV_ERROR, remoteString()); } #endif #if defined(_WIN32) int e = WSAGetLastError(); #else int e = errno; # if defined(EINTR) if (e == EINTR) { LOG(_logLevel) << "EINTR retry " << ++*retries << endl; return; } # endif #endif #if defined(_WIN32) // Windows if ((e == EAGAIN || e == WSAETIMEDOUT) && _timeout > 0) { #else if (e == EAGAIN && _timeout > 0) { #endif // 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::setTimeout( double secs ) { setSockTimeouts( _fd, secs ); } #if defined(_WIN32) struct WinsockInit { WinsockInit() { WSADATA d; if ( WSAStartup(MAKEWORD(2,2), &d) != 0 ) { out() << "ERROR: wsastartup failed " << errnoWithDescription() << endl; problem() << "ERROR: wsastartup failed " << errnoWithDescription() << endl; _exit(EXIT_NTSERVICE_ERROR); } } } winsock_init; #endif } // namespace mongo
void Socket::handleSendError(int ret, const char* context) { #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 " << remoteString() << endl; throw SocketException(SocketException::SEND_TIMEOUT , remoteString()); } else { LOG(_logLevel) << "Socket " << context << " send() " << errnoWithDescription(mongo_errno) << ' ' << remoteString() << endl; throw SocketException(SocketException::SEND_ERROR , remoteString()); } } void Socket::handleRecvError(int ret, int len) { if (ret == 0) { LOG(3) << "Socket recv() conn closed? " << remoteString() << endl; throw SocketException(SocketException::CLOSED , remoteString()); } // ret < 0 #if defined(_WIN32) int e = WSAGetLastError(); #else int e = errno; # if defined(EINTR) if (e == EINTR) { LOG(_logLevel) << "EINTR returned from recv(), retrying"; return; } # endif #endif #if defined(_WIN32) // Windows if ((e == EAGAIN || e == WSAETIMEDOUT) && _timeout > 0) { #else if (e == EAGAIN && _timeout > 0) { #endif // 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::setTimeout( double secs ) { setSockTimeouts( _fd, secs ); } // TODO: allow modification? // // <positive value> : secs to wait between stillConnected checks // 0 : always check // -1 : never check const int Socket::errorPollIntervalSecs( 5 ); // Patch to allow better tolerance of flaky network connections that get broken // while we aren't looking. // TODO: Remove when better async changes come. // // isStillConnected() polls the socket at max every Socket::errorPollIntervalSecs to determine // if any disconnection-type events have happened on the socket. bool Socket::isStillConnected() { if (_fd == -1) { // According to the man page, poll will respond with POLLVNAL for invalid or // unopened descriptors, but it doesn't seem to be properly implemented in // some platforms - it can return 0 events and 0 for revent. Hence this workaround. return false; } if ( errorPollIntervalSecs < 0 ) return true; if ( ! isPollSupported() ) return true; // nothing we can do time_t now = time( 0 ); time_t idleTimeSecs = now - _lastValidityCheckAtSecs; // Only check once every 5 secs if ( idleTimeSecs < errorPollIntervalSecs ) return true; // Reset our timer, we're checking the connection _lastValidityCheckAtSecs = now; // It's been long enough, poll to see if our socket is still connected pollfd pollInfo; pollInfo.fd = _fd; // We only care about reading the EOF message on clean close (and errors) pollInfo.events = POLLIN; // Poll( info[], size, timeout ) - timeout == 0 => nonblocking int nEvents = socketPoll( &pollInfo, 1, 0 ); LOG( 2 ) << "polling for status of connection to " << remoteString() << ", " << ( nEvents == 0 ? "no events" : nEvents == -1 ? "error detected" : "event detected" ) << endl; if ( nEvents == 0 ) { // No events incoming, return still connected AFAWK return true; } else if ( nEvents < 0 ) { // Poll itself failed, this is weird, warn and log errno warning() << "Socket poll() failed during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << causedBy(errnoWithDescription()) << endl; // Return true since it's not clear that we're disconnected. return true; } dassert( nEvents == 1 ); dassert( pollInfo.revents > 0 ); // Return false at this point, some event happened on the socket, but log what the // actual event was. if ( pollInfo.revents & POLLIN ) { // There shouldn't really be any data to recv here, so make sure this // is a clean hangup. const int testBufLength = 1024; char testBuf[testBufLength]; int recvd = ::recv( _fd, testBuf, testBufLength, portRecvFlags ); if ( recvd < 0 ) { // An error occurred during recv, warn and log errno warning() << "Socket recv() failed during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << causedBy(errnoWithDescription()) << endl; } else if ( recvd > 0 ) { // We got nonzero data from this socket, very weird? // Log and warn at runtime, log and abort at devtime // TODO: Dump the data to the log somehow? error() << "Socket found pending " << recvd << " bytes of data during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; DEV { std::string hex = hexdump(testBuf, recvd); error() << "Hex dump of stale log data: " << hex << endl; } dassert( false ); } else { // recvd == 0, socket closed remotely, just return false LOG( 0 ) << "Socket closed remotely, no longer connected" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; } }
/** 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_CONFIG_SSL if ( _sslConnection.get() ) { _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 = -1; if (MONGO_FAIL_POINT(throwSockExcep)) { #if defined(_WIN32) WSASetLastError(WSAENETUNREACH); #else errno = ENETUNREACH; #endif } else { 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 }
// 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() ); } } }
void Socket::_handleSendError(int ret, const char* context) { #ifdef MONGO_SSL if (_ssl) { LOG(_logLevel) << "SSL Error ret: " << ret << " err: " << _sslManager->SSL_get_error(_ssl , ret) << " " << _sslManager->ERR_error_string(_sslManager->ERR_get_error(), NULL) << endl; throw SocketException(SocketException::SEND_ERROR , remoteString()); } #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 " << remoteString() << endl; throw SocketException(SocketException::SEND_TIMEOUT , remoteString()); } else { LOG(_logLevel) << "Socket " << context << " send() " << errnoWithDescription(mongo_errno) << ' ' << remoteString() << endl; throw SocketException(SocketException::SEND_ERROR , remoteString()); } } void Socket::_handleRecvError(int ret, int len, int* retries) { if (ret == 0) { LOG(3) << "Socket recv() conn closed? " << remoteString() << endl; throw SocketException(SocketException::CLOSED , remoteString()); } // ret < 0 #ifdef MONGO_SSL if (_ssl) { LOG(_logLevel) << "SSL Error ret: " << ret << " err: " << _sslManager->SSL_get_error(_ssl , ret) << " " << _sslManager->ERR_error_string(_sslManager->ERR_get_error(), NULL) << endl; throw SocketException(SocketException::RECV_ERROR, remoteString()); } #endif #if defined(_WIN32) int e = WSAGetLastError(); #else int e = errno; # if defined(EINTR) if (e == EINTR) { LOG(_logLevel) << "EINTR retry " << ++*retries << endl; return; } # endif #endif #if defined(_WIN32) // Windows if ((e == EAGAIN || e == WSAETIMEDOUT) && _timeout > 0) { #else if (e == EAGAIN && _timeout > 0) { #endif // 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::setTimeout( double secs ) { setSockTimeouts( _fd, secs ); } // TODO: allow modification? // // <positive value> : secs to wait between stillConnected checks // 0 : always check // -1 : never check const int Socket::errorPollIntervalSecs( 5 ); #if defined(NTDDI_VERSION) && ( !defined(NTDDI_VISTA) || ( NTDDI_VERSION < NTDDI_VISTA ) ) // Windows XP // pre-Vista windows doesn't have WSAPoll, so don't test connections bool Socket::isStillConnected() { return true; } #else // Not Windows XP // Patch to allow better tolerance of flaky network connections that get broken // while we aren't looking. // TODO: Remove when better async changes come. // // isStillConnected() polls the socket at max every Socket::errorPollIntervalSecs to determine // if any disconnection-type events have happened on the socket. bool Socket::isStillConnected() { if ( errorPollIntervalSecs < 0 ) return true; time_t now = time( 0 ); time_t idleTimeSecs = now - _lastValidityCheckAtSecs; // Only check once every 5 secs if ( idleTimeSecs < errorPollIntervalSecs ) return true; // Reset our timer, we're checking the connection _lastValidityCheckAtSecs = now; // It's been long enough, poll to see if our socket is still connected pollfd pollInfo; pollInfo.fd = _fd; // We only care about reading the EOF message on clean close (and errors) pollInfo.events = POLLIN; // Poll( info[], size, timeout ) - timeout == 0 => nonblocking #if defined(_WIN32) int nEvents = WSAPoll( &pollInfo, 1, 0 ); #else int nEvents = ::poll( &pollInfo, 1, 0 ); #endif LOG( 2 ) << "polling for status of connection to " << remoteString() << ", " << ( nEvents == 0 ? "no events" : nEvents == -1 ? "error detected" : "event detected" ) << endl; if ( nEvents == 0 ) { // No events incoming, return still connected AFAWK return true; } else if ( nEvents < 0 ) { // Poll itself failed, this is weird, warn and log errno warning() << "Socket poll() failed during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << causedBy(errnoWithDescription()) << endl; // Return true since it's not clear that we're disconnected. return true; } dassert( nEvents == 1 ); dassert( pollInfo.revents > 0 ); // Return false at this point, some event happened on the socket, but log what the // actual event was. if ( pollInfo.revents & POLLIN ) { // There shouldn't really be any data to recv here, so make sure this // is a clean hangup. // Used concurrently, but we never actually read this data static char testBuf[1]; int recvd = ::recv( _fd, testBuf, 1, portRecvFlags ); if ( recvd < 0 ) { // An error occurred during recv, warn and log errno warning() << "Socket recv() failed during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << causedBy(errnoWithDescription()) << endl; } else if ( recvd > 0 ) { // We got nonzero data from this socket, very weird? // Log and warn at runtime, log and abort at devtime // TODO: Dump the data to the log somehow? error() << "Socket found pending data during connectivity check" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; dassert( false ); } else { // recvd == 0, socket closed remotely, just return false LOG( 0 ) << "Socket closed remotely, no longer connected" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; } } else if ( pollInfo.revents & POLLHUP ) { // A hangup has occurred on this socket LOG( 0 ) << "Socket hangup detected, no longer connected" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; } else if ( pollInfo.revents & POLLERR ) { // An error has occurred on this socket LOG( 0 ) << "Socket error detected, no longer connected" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; } else if ( pollInfo.revents & POLLNVAL ) { // Socket descriptor itself is weird // Log and warn at runtime, log and abort at devtime error() << "Socket descriptor detected as invalid" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; dassert( false ); } else { // Don't know what poll is saying here // Log and warn at runtime, log and abort at devtime error() << "Socket had unknown event (" << static_cast<int>(pollInfo.revents) << ")" << " (idle " << idleTimeSecs << " secs," << " remote host " << remoteString() << ")" << endl; dassert( false ); } return false; } #endif // End Not Windows XP #if defined(_WIN32) struct WinsockInit { WinsockInit() { WSADATA d; if ( WSAStartup(MAKEWORD(2,2), &d) != 0 ) { out() << "ERROR: wsastartup failed " << errnoWithDescription() << endl; problem() << "ERROR: wsastartup failed " << errnoWithDescription() << endl; _exit(EXIT_NTSERVICE_ERROR); } } } winsock_init; #endif } // namespace mongo