Beispiel #1
0
void Server::checkAndDispatchEpoll(int epollMillis) {
    constexpr int maxEvents = 256;
    epoll_event events[maxEvents];

    std::list<Connection*> toBeDeleted;
    int numEvents = epoll_wait(_epollFd, events, maxEvents, epollMillis);
    if (numEvents == -1) {
        if (errno != EINTR) {
            LS_ERROR(_logger, "Error from epoll_wait: " << getLastError());
        }
        return;
    }
    if (numEvents == maxEvents) {
        static time_t lastWarnTime = 0;
        time_t now = time(nullptr);
        if (now - lastWarnTime >= 60) {
            LS_WARNING(_logger, "Full event queue; may start starving connections. "
                    "Will warn at most once a minute");
            lastWarnTime = now;
        }
    }
    for (int i = 0; i < numEvents; ++i) {
        if (events[i].data.ptr == this) {
            if (events[i].events & ~EPOLLIN) {
                LS_SEVERE(_logger, "Got unexpected event on listening socket ("
                        << EventBits(events[i].events) << ") - terminating");
                _terminate = true;
                break;
            }
            handleAccept();
        } else if (events[i].data.ptr == &_eventFd) {
            if (events[i].events & ~EPOLLIN) {
                LS_SEVERE(_logger, "Got unexpected event on management pipe ("
                        << EventBits(events[i].events) << ") - terminating");
                _terminate = true;
                break;
            }
            handlePipe();
        } else {
            auto connection = reinterpret_cast<Connection*>(events[i].data.ptr);
            if (handleConnectionEvents(connection, events[i].events) == Close) {
                toBeDeleted.push_back(connection);
            }
        }
    }
    // The connections are all deleted at the end so we've processed any other subject's
    // closes etc before we call onDisconnect().
    for (auto it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it) {
        auto connection = *it;
        if (_connections.find(connection) == _connections.end()) {
            LS_SEVERE(_logger, "Attempt to delete connection we didn't know about: " << (void*)connection
                    << formatAddress(connection->getRemoteAddress()));
            _terminate = true;
            break;
        }
        LS_DEBUG(_logger, "Deleting connection: " << formatAddress(connection->getRemoteAddress()));
        delete connection;
    }
}
Beispiel #2
0
void Connection::fireSipXEvent(SIPX_CALLSTATE_EVENT eventCode, SIPX_CALLSTATE_CAUSE causeCode, void* pEventData)
{
    UtlString callId ;
    UtlString remoteAddress ;
    SipSession session ;
    UtlBoolean bDuplicateAudio =
            (   eventCode == CALLSTATE_AUDIO_EVENT
             && causeCode == m_eLastAudioMinor) ? TRUE : FALSE;

    // Avoid sending duplicate events
    if ((   (eventCode != m_eLastMajor)
         || (causeCode != m_eLastMinor))
        && validStateTransition(m_eLastMajor, eventCode)
        && !bDuplicateAudio)
    {
        if (eventCode != CALLSTATE_AUDIO_EVENT)
        {
            m_eLastMajor = eventCode;
            m_eLastMinor = causeCode;
        }
        else
        {
            m_eLastAudioMajor = eventCode;
            m_eLastAudioMinor = causeCode;
        }

        getCallId(&callId) ;
        getRemoteAddress(&remoteAddress);
        getSession(session) ;

        TapiMgr::getInstance().fireCallEvent(mpCallManager, callId.data(), &session, remoteAddress.data(), eventCode, causeCode, pEventData) ;
    }
}
Beispiel #3
0
void Connection::setRingingTimer(int seconds)
{
    UtlString callId;
    mpCall->getCallId(callId);
    UtlString remoteAddr;
    getRemoteAddress(&remoteAddr);
    CpMultiStringMessage* offeringExpiredMessage =
        new CpMultiStringMessage(CpCallManager::CP_RINGING_EXPIRED,
                    callId.data(), remoteAddr.data());
    OsTimer* timer = new OsTimer((mpCallManager->getMessageQueue()),
            offeringExpiredMessage);

#ifdef TEST_PRINT
    osPrintf("Setting ringing timeout in %d seconds\n",
        seconds);
#endif

    OsTime timerTime(seconds, 0);
    timer->oneshotAfter(timerTime);
#ifdef TEST_PRINT
    osPrintf("Connection::setRingingTimer message type: %d %d",
        OsMsg::PHONE_APP, CpCallManager::CP_RINGING_EXPIRED);
#endif
    callId.remove(0);
    remoteAddr.remove(0);
}
void PerfSocket::ReportClientSettings( const char* inHost,
                                       const char* inLocalhost ) {
    sReporting.Lock();

    // print settings
    printf( seperator_line );
    printf( client_port, inHost, 
	    (mUDP ? "UDP" : (mSettings->mProtocol == 0 ? "TCP" : "SCTP")),
	    mPort );

    if ( inLocalhost != NULL ) {
        SocketAddr local = getLocalAddress();
        char addr[ REPORT_ADDRLEN ];
        local.getHostAddress( addr, sizeof(addr));
        printf( bind_address, addr );
    }

    if ( mUDP ) {
        printf( client_datagram_size, mSettings->mBufLen );

        SocketAddr remote = getRemoteAddress();
        if ( remote.isMulticast() ) {
            printf( multicast_ttl, mSettings->mTTL);
        }
    }

    ReportWindowSize();
    printf( seperator_line );
    fflush( stdout );

    sReporting.Unlock();
}
void P2pNode::acceptLoop() {
  while (!m_stopRequested) {
    try {
      auto connection = m_listener.accept();
      auto ctx = new P2pContext(m_dispatcher, std::move(connection), true, 
        getRemoteAddress(connection), m_cfg.getTimedSyncInterval(), getGenesisPayload());
      logger(INFO) << "Incoming connection from " << ctx->getRemoteAddress();
      workingContextGroup.spawn([this, ctx] {
        preprocessIncomingConnection(ContextPtr(ctx));
      });
    } catch (InterruptedException&) {
      break;
    } catch (const std::exception& e) {
      logger(WARNING) << "Exception in acceptLoop: " << e.what();
    }
  }

  logger(DEBUGGING) << "acceptLoop finished";
}
std::string DownstreamMessageEvent::toString() const {
    std::string buf = this->channel.toString();
    buf.append(" WRITE: ");
    buf.append(message.toString());

    if (this->remoteAddress != this->channel.getRemoteAddress()) {
        buf.append(" to ");
        buf.append(getRemoteAddress().toString());
    }

    return buf;
}
Beispiel #7
0
    unsigned Socket::receive(void *data, const unsigned maxlen) {
        if(_myTimeOut) {
            struct timeval tv;

            fd_set readset;
            FD_ZERO(&readset);
#if defined(_MSC_VER)
#pragma warning(push,1)
#endif //defined(_MSC_VER)
            FD_SET(fd, &readset);
#if defined(_MSC_VER)
#pragma warning(pop)
#endif //defined(_MSC_VER)

            // Initialize time out struct
            tv.tv_sec = getConnectionTimeout();
            tv.tv_usec = 0;

            int result = select(fd + 1, &readset, NULL, NULL, &tv);
            if (result <= 0){
                int err = getLastSocketError();
                throw SocketError(err, std::string(
                                      "disconnect or timeout while receiveing from socket " +
                                      hostname(getRemoteAddress()) + ":" + as_string(getRemotePort())));
            }
        }

        int bytesread = recv(fd, (char*)data, maxlen, 0);

        if (bytesread>0){
            return bytesread;
        } else if (bytesread == 0) {
            _myIsConnected = false; // XXX: hack for tcp disconnect
            //throw SocketDisconnected(PLUS_FILE_LINE);
        } else {
            int err = getLastSocketError();
            if(err == OS_SOCKET_ERROR(EWOULDBLOCK)) {
                return 0;
            } else {
                throw SocketError(err, "receive() failed");
            }
        }

        return 0;
    }
Beispiel #8
0
void CGI::logCGIData(const QString& filename)
{
	// create a QFile object to do the file I/O
	QFile file(filename);

	// open the file
	if (file.open(QIODevice::WriteOnly))
	{
		// create a QTextStream object on the file
		Q3TextStream textFile(&file);

		// get the environment
		textFile << "REQUEST_METHOD=" << getenv("REQUEST_METHOD") << endl;
		textFile << "CONTENT_LENGTH=" << getenv("CONTENT_LENGTH") << endl;

		// write the query string to the file
		textFile << "QUERY_STRING=" << query_string << endl;

		// write misc. CGI environment pieces
		textFile << "AUTH_TYPE=" << getAuthType() << endl;
		textFile << "GATEWAY_INTERFACE=" << getGatewayInterface() << endl;
		textFile << "HTTP_ACCEPT=" << getHTTPAccept() << endl;
		textFile << "HTTP_ACCEPT_ENCODING=" << getHTTPAcceptEncoding() << endl;
		textFile << "HTTP_ACCEPT_LANGUAGE=" << getHTTPAcceptLanguage() << endl;
		textFile << "HTTP_CONNECTION=" << getHTTPConnection() << endl;
		textFile << "HTTP_REFERER=" << getHTTPReferer() << endl;
		textFile << "HTTP_USER_AGENT=" << getHTTPUserAgent() << endl;
		textFile << "REMOTE_HOST=" << getRemoteHost() << endl;
		textFile << "REMOTE_ADDRESS=" << getRemoteAddress() << endl;
		textFile << "REMOTE_PORT=" << getRemotePort() << endl;
		textFile << "REQUEST_URI=" << getRequestURI() << endl;
		textFile << "SCRIPT_NAME=" << getScriptName() << endl;
		textFile << "SERVER_ADMIN=" << getServerAdmin() << endl;
		textFile << "SERVER_NAME=" << getServerName() << endl;
		textFile << "SERVER_PORT=" << getServerPort() << endl;
		textFile << "SERVER_PROTOCOL=" << getServerProtocol() << endl;
		textFile << "SERVER_SOFTWARE=" << getServerSoftware() << endl;
	}

	// close the file
	file.close();

}
Beispiel #9
0
void Server::processEventQueue() {
    runExecutables();
    time_t now = time(nullptr);
    if (now < _nextDeadConnectionCheck) return;
    std::list<Connection*> toRemove;
    for (auto it = _connections.cbegin(); it != _connections.cend(); ++it) {
        time_t numSecondsSinceConnection = now - it->second;
        auto connection = it->first;
        if (connection->bytesReceived() == 0
            && numSecondsSinceConnection >= _lameConnectionTimeoutSeconds) {
            LS_INFO(_logger, formatAddress(connection->getRemoteAddress())
                    << " : Killing lame connection - no bytes received after "
                             << numSecondsSinceConnection << "s");
            toRemove.push_back(connection);
        }
    }
    for (auto it = toRemove.begin(); it != toRemove.end(); ++it) {
        delete *it;
    }
}
Beispiel #10
0
std::string AbstractChannel::toString() const {
    char buf[512] = {0};

    bool connected = isConnected();
    if (connected && !strVal.empty()) {
        return strVal;
    }

    const SocketAddress& localAddress = getLocalAddress();
    const SocketAddress& remoteAddress = getRemoteAddress();

    if (remoteAddress.validated()) {
        if (NULL == getParent()) { // server channel or client channel
            sprintf(buf, "[id: 0x%08x, %s => %s]", getId().intValue(),
                localAddress.toString().c_str(),
                remoteAddress.toString().c_str());
        }
        else { // connection channel
            sprintf(buf, "[id: 0x%08x, %s => %s]", getId().intValue(),
                remoteAddress.toString().c_str(),
                localAddress.toString().c_str());
        }
    }
    else if (localAddress.validated()) {
        sprintf(buf, "[id: 0x%08x, %s]", getId().intValue(),
            localAddress.toString().c_str());
    }
    else {
        sprintf(buf, "[id: 0x%08x]", getId().intValue());
    }

    if (connected) {
        strVal = (const char*)buf;
    }
    else {
        strVal.empty();
    }

    return buf;
}
Beispiel #11
0
std::string Server::getStatsDocument() const {
    std::ostringstream doc;
    doc << "clear();" << std::endl;
    for (auto it = _connections.begin(); it != _connections.end(); ++it) {
        doc << "connection({";
        auto connection = it->first;
        jsonKeyPairToStream(doc,
                "since", EpochTimeAsLocal(it->second),
                "fd", connection->getFd(),
                "id", reinterpret_cast<uint64_t>(connection),
                "uri", connection->getRequestUri(),
                "addr", formatAddress(connection->getRemoteAddress()),
                "user", connection->credentials() ?
                        connection->credentials()->username : "******",
                "input", connection->inputBufferSize(),
                "read", connection->bytesReceived(),
                "output", connection->outputBufferSize(),
                "written", connection->bytesSent()
        );
        doc << "});" << std::endl;
    }
    return doc.str();
}
void PerfSocket::ReportPeer( int inSock ) {
    assert( inSock >= 0 );

    SocketAddr local  = getLocalAddress();
    SocketAddr remote = getRemoteAddress();

    // copy the inet_ntoa into temp buffers, to avoid overwriting
    char local_addr[ REPORT_ADDRLEN ];
    local.getHostAddress( local_addr, sizeof(local_addr));

    char remote_addr[ REPORT_ADDRLEN ];
    remote.getHostAddress( remote_addr, sizeof(remote_addr));

    sReporting.Lock();

    printf( report_peer,
            inSock,
            local_addr,  local.getPort(),
            remote_addr, remote.getPort());
    fflush( stdout );

    sReporting.Unlock();
}
Beispiel #13
0
void Server::processEventQueue() {
    for (;;) {
        std::shared_ptr<Runnable> runnable = popNextRunnable();
        if (!runnable) break;
        runnable->run();
    }
    time_t now = time(NULL);
    if (now >= _nextDeadConnectionCheck) {
        std::list<Connection*> toRemove;
        for (auto it = _connections.cbegin(); it != _connections.cend(); ++it) {
            time_t numSecondsSinceConnection = now - it->second;
            auto connection = it->first;
            if (connection->bytesReceived() == 0 && numSecondsSinceConnection >= _lameConnectionTimeoutSeconds) {
                LS_INFO(_logger, formatAddress(connection->getRemoteAddress())
                        << " : Killing lame connection - no bytes received after " << numSecondsSinceConnection << "s");
                toRemove.push_back(connection);
            }
        }
        for (auto it = toRemove.begin(); it != toRemove.end(); ++it) {
            delete *it;
        }
    }
}
Beispiel #14
0
/* //////////////////////////// PROTECTED ///////////////////////////////// */
void Connection::postTaoListenerMessage(int state, int newCause, int isLocal)
{
    int eventId = PtEvent::EVENT_INVALID;
    int termEventId = PtEvent::EVENT_INVALID;
    UtlString causeStr;
    causeStr.remove(0);

#ifdef TEST_PRINT
    Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                  "Enter- %s state %d cause %d "
                  "eventid-  %d termeventid %d",
                  (isLocal?"LOCAL":"REMOTE"),
                  state, newCause,
                  eventId, termEventId);
#endif

    switch(state)
    {
    case CONNECTION_IDLE:
        eventId = PtEvent::CONNECTION_CREATED;
        termEventId = PtEvent::TERMINAL_CONNECTION_IDLE;
        break;

    case CONNECTION_INITIATED:
        eventId = PtEvent::CONNECTION_INITIATED;
        termEventId = PtEvent::TERMINAL_CONNECTION_CREATED;
        break;

    case CONNECTION_QUEUED:
        eventId = PtEvent::CONNECTION_QUEUED;
        termEventId = PtEvent::CONNECTION_CREATED;
        break;

    case CONNECTION_OFFERING:
        eventId = PtEvent::CONNECTION_OFFERED;
        break;

    case CONNECTION_DIALING:
        eventId = PtEvent::CONNECTION_DIALING ;
        break;

    case CONNECTION_ALERTING:
        eventId = PtEvent::CONNECTION_ALERTING;
        termEventId = PtEvent::TERMINAL_CONNECTION_RINGING;
        break;

    case CONNECTION_ESTABLISHED:
        eventId = PtEvent::CONNECTION_ESTABLISHED;
        termEventId = PtEvent::TERMINAL_CONNECTION_TALKING;
        break;

    case CONNECTION_FAILED:
        eventId = PtEvent::CONNECTION_FAILED;
        termEventId = PtEvent::TERMINAL_CONNECTION_DROPPED;
        break;

    case CONNECTION_DISCONNECTED:
        eventId = PtEvent::CONNECTION_DISCONNECTED;
        termEventId = PtEvent::TERMINAL_CONNECTION_DROPPED;
        break;

    case PtEvent::TERMINAL_CONNECTION_HELD:
        termEventId = PtEvent::TERMINAL_CONNECTION_HELD;
        break;

    default:
        eventId = PtEvent::CONNECTION_UNKNOWN;
        termEventId = PtEvent::TERMINAL_CONNECTION_UNKNOWN;
        break;

    }

    int cause;
    switch(newCause)
    {
     case CONNECTION_CAUSE_UNKNOWN:
        cause = PtEvent::CAUSE_UNKNOWN;
        causeStr.append("CAUSE_UNKNOWN");
        break;
    case CONNECTION_CAUSE_REDIRECTED:
        cause = PtEvent::CAUSE_REDIRECTED;
        causeStr.append("CAUSE_REDIRECTED");
        break ;

     case CONNECTION_CAUSE_NETWORK_CONGESTION:
        cause = PtEvent::CAUSE_NETWORK_CONGESTION;
        causeStr.append("CAUSE_NETWORK_CONGESTION");
        break;

     case CONNECTION_CAUSE_NETWORK_NOT_OBTAINABLE:
        cause = PtEvent::CAUSE_NETWORK_NOT_OBTAINABLE;
        causeStr.append("CAUSE_NETWORK_NOT_OBTAINABLE");
        break;

     case CONNECTION_CAUSE_DEST_NOT_OBTAINABLE:
        cause = PtEvent::CAUSE_DESTINATION_NOT_OBTAINABLE;
        causeStr.append("CAUSE_DESTINATION_NOT_OBTAINABLE");
        break;

     case CONNECTION_CAUSE_INCOMPATIBLE_DESTINATION:
        cause = PtEvent::CAUSE_INCOMPATIBLE_DESTINATION;
        causeStr.append("CAUSE_INCOMPATIBLE_DESTINATION");
        break;

     case CONNECTION_CAUSE_NOT_ALLOWED:
        cause = PtEvent::CAUSE_NOT_ALLOWED;
        causeStr.append("CAUSE_NOT_ALLOWED");
        break;

     case CONNECTION_CAUSE_NETWORK_NOT_ALLOWED:
        cause = PtEvent::CAUSE_NETWORK_NOT_ALLOWED;
        causeStr.append("CAUSE_NETWORK_NOT_ALLOWED");
        break;

    case CONNECTION_CAUSE_BUSY:
    case CONNECTION_CAUSE_SERVICE_UNAVAILABLE:
        cause = PtEvent::CAUSE_BUSY;
        causeStr.append("CAUSE_BUSY");
        break ;

    case CONNECTION_CAUSE_CANCELLED:
        cause = PtEvent::CAUSE_CALL_CANCELLED;
        causeStr.append("CAUSE_CALL_CANCELLED");
        break ;

    case CONNECTION_CAUSE_TRANSFER:
        cause = PtEvent::CAUSE_TRANSFER;
        causeStr.append("CAUSE_TRANSFER");
        break;

    default:
    case CONNECTION_CAUSE_NORMAL:
        cause = PtEvent::CAUSE_NORMAL;
        causeStr.append("CAUSE_NORMAL");
        break;
    }

    int cnt = 0;
    if (mpListenerCnt)
        cnt = mpListenerCnt->getRef();

    if (cnt > 0)
    {
        TaoObjHandle* pListeners;
        pListeners = new TaoObjHandle[cnt];
        mpListeners->getActiveObjects(pListeners, cnt);

        UtlString callId;

        // Use the connection call id first -- followed by call if
        // unavailable
        getCallId(&callId);                          // arg[0], callId
        if (callId.isNull())
        {
            mpCall->getCallId(callId);
#ifdef TEST_PRINT
            Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                          "Connection call id not found, "
                          "Using CpCall Id = %s ",
                          callId.data());
#endif
        }

        callId += TAOMESSAGE_DELIMITER + mLocalAddress;        // arg[1], localAddress

        UtlString remoteAddress;
        getRemoteAddress(&remoteAddress, TRUE);

        if (remoteAddress.isNull())                            // arg[2], remote address
        {
            callId += TAOMESSAGE_DELIMITER + (UtlString)"UNKNOWN";    // not available yet
        }
        else
        {
            callId += TAOMESSAGE_DELIMITER + remoteAddress;
        }

        char buff[128];
        sprintf(buff, "%d", (int)mRemoteIsCallee);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[3], remoteIsCallee

        sprintf(buff, "%d", cause);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[4], cause

        if (mRemoteIsCallee)
        {
            remoteAddress.insert(0, "foreign-terminal-");
            callId += TAOMESSAGE_DELIMITER + remoteAddress;    // arg[5], remote terminal name
        }
        else
        {
            mpCall->getLocalTerminalId(buff, 127);
            callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[5], local terminal name
        }

        if (isLocal)                                        // TAO_OFFER_PARAM_LOCAL_CONNECTION
        {
            callId += TAOMESSAGE_DELIMITER + "1";            // arg[6], isLocal
        }
        else
        {
            callId += TAOMESSAGE_DELIMITER + "0";            // isLocal
        }

        sprintf(buff, "%d", mResponseCode);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[7], SIP response code

        callId += TAOMESSAGE_DELIMITER + mResponseText;        // arg[8], SIP response text

        int argCnt = 9;
        if(mpCall)
        {
            int metaEventId = 0;
            int metaEventType = PtEvent::META_EVENT_NONE;
            int numCalls = 0;
            const UtlString* metaEventCallIds = NULL;
            mpCall->getMetaEvent(metaEventId, metaEventType, numCalls,
                &metaEventCallIds);
            if (metaEventId != PtEvent::META_EVENT_NONE)
            {
                sprintf(buff, "%d", metaEventId);
                callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[9], meta event id
                sprintf(buff, "%d", metaEventType);
                callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[10], meta code
                argCnt += 2;
                for (int i = 0; i < numCalls; i++)
                {
                    if (metaEventCallIds && metaEventCallIds[i])
                    {
                        callId += TAOMESSAGE_DELIMITER + metaEventCallIds[i];    // meta call ids
                        argCnt++;
                    }
                }
            }
        }

        TaoMessage msg(TaoMessage::EVENT,
                       0,
                       0,
                       eventId,
                       0,
                       argCnt,
                       callId);

        UtlString eventIdStr;
        if (eventId != PtEvent::EVENT_INVALID)
        {
            for (int i = 0; i < cnt; i++) // post connection events
            {
                ((OsServerTask*) pListeners[i])->postMessage((OsMsg&)msg);
            }
            mpCall->getStateString(eventId, &eventIdStr);
            mpCallManager->logCallState(callId.data(), eventIdStr.data(), causeStr);
        }

        if (termEventId != PtEvent::EVENT_INVALID)    // post terminal connection events
        {
            msg.setObjHandle(termEventId);
            for (int i = 0; i < cnt; i++)
            {
                ((OsServerTask*) pListeners[i])->postMessage((OsMsg&)msg);
            }

            mpCall->getStateString(termEventId, &eventIdStr);
            mpCallManager->logCallState(callId.data(), eventIdStr.data(), causeStr);

        }

        delete[] pListeners;
        callId.remove(0);
        eventIdStr.remove(0);
        remoteAddress.remove(0);
    }
#ifdef TEST_PRINT
    Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                  "Leave- %s state %d cause %d "
                  "eventid-  %d termeventid %d",
                  (isLocal?"LOCAL":"REMOTE"),
                  state, newCause,
                  eventId, termEventId);
#endif

    causeStr.remove(0);
}
Beispiel #15
0
ChannelFuturePtr AbstractChannel::write(const ChannelMessage& message,
                                        bool withFuture /*= true*/) {
    return AbstractChannel::write(message, getRemoteAddress(), withFuture);
}
Beispiel #16
0
void PerfSocket::Recv_TCP( void ) {
    extern Mutex clients_mutex;
    extern Iperf_ListEntry *clients;

    // get the remote address and remove it later from the set of clients 
    SocketAddr remote = getRemoteAddress(); 
    iperf_sockaddr peer = *(iperf_sockaddr *) (remote.get_sockaddr()); 

    // keep track of read sizes -> gives some indication of MTU size
    // on SGI this must be dynamically allocated to avoid seg faults
    int currLen;
    int *readLenCnt = new int[ mSettings->mBufLen+1 ];
    for ( int i = 0; i <= mSettings->mBufLen; i++ ) {
        readLenCnt[ i ] = 0;
    }

    InitTransfer();
#ifndef WIN32
    signal (SIGPIPE, SIG_IGN);
#endif

    do {
        // perform read
        currLen = read( mSock, mBuf, mSettings->mBufLen );

        if ( false ) {
            DELETE_ARRAY( readLenCnt );
            Server_Send_TCP();
            return;
        }
        mPacketTime.setnow();

        // periodically report bandwidths
        ReportPeriodicBW();

        mTotalLen += currLen;

        // count number of reads of each size
        if ( currLen <= mSettings->mBufLen ) {
            readLenCnt[ currLen ]++;
        }

    } while ( currLen > 0  &&  sInterupted == false );

    // stop timing
    mEndTime.setnow();
    sReporting.Lock();
    ReportBW( mTotalLen, 0.0, mEndTime.subSec( mStartTime ));
    sReporting.Unlock();

    if ( mSettings->mPrintMSS ) {
        // read the socket option for MSS (maximum segment size)
        ReportMSS( getsock_tcp_mss( mSock ));

        // on WANs the most common read length is often the MSS
        // on fast LANs it is much harder to detect
        int totalReads  = 0;
        for ( currLen = 0; currLen < mSettings->mBufLen+1; currLen++ ) {
            totalReads += readLenCnt[ currLen ];
        }

        // print each read length that occured > 5% of reads
        int thresh = (int) (0.05 * totalReads);
        printf( report_read_lengths, mSock );
        for ( currLen = 0; currLen < mSettings->mBufLen+1; currLen++ ) {
            if ( readLenCnt[ currLen ] > thresh ) {
                printf( report_read_length_times, mSock,
                        (int) currLen, readLenCnt[ currLen ],
                        (100.0 * readLenCnt[ currLen ]) / totalReads );
            }
        }
    }
    DELETE_ARRAY( readLenCnt );

    clients_mutex.Lock();     
    Iperf_delete ( &peer, &clients ); 
    clients_mutex.Unlock(); 
}
Beispiel #17
0
Socket::Status TcpSocket::connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout)
{
    // Disconnect the socket if it is already connected
    disconnect();

    // Create the internal socket if it doesn't exist
    create();

    // Create the remote address
    sockaddr_in address = priv::SocketImpl::createAddress(remoteAddress.toInteger(), remotePort);

    if (timeout <= Time::Zero)
    {
        // ----- We're not using a timeout: just try to connect -----

        // Connect the socket
        if (::connect(getHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
            return priv::SocketImpl::getErrorStatus();

        // Connection succeeded
        return Done;
    }
    else
    {
        // ----- We're using a timeout: we'll need a few tricks to make it work -----

        // Save the previous blocking state
        bool blocking = isBlocking();

        // Switch to non-blocking to enable our connection timeout
        if (blocking)
            setBlocking(false);

        // Try to connect to the remote address
        if (::connect(getHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) >= 0)
        {
            // We got instantly connected! (it may no happen a lot...)
            setBlocking(blocking);
            return Done;
        }

        // Get the error status
        Status status = priv::SocketImpl::getErrorStatus();

        // If we were in non-blocking mode, return immediately
        if (!blocking)
            return status;

        // Otherwise, wait until something happens to our socket (success, timeout or error)
        if (status == Socket::NotReady)
        {
            // Setup the selector
            fd_set selector;
            FD_ZERO(&selector);
            FD_SET(getHandle(), &selector);

            // Setup the timeout
            timeval time;
            time.tv_sec  = static_cast<long>(timeout.asMicroseconds() / 1000000);
            time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);

            // Wait for something to write on our socket (which means that the connection request has returned)
            if (select(static_cast<int>(getHandle() + 1), NULL, &selector, NULL, &time) > 0)
            {
                // At this point the connection may have been either accepted or refused.
                // To know whether it's a success or a failure, we must check the address of the connected peer
                if (getRemoteAddress() != IpAddress::None)
                {
                    // Connection accepted
                    status = Done;
                }
                else
                {
                    // Connection refused
                    status = priv::SocketImpl::getErrorStatus();
                }
            }
            else
            {
                // Failed to connect before timeout is over
                status = priv::SocketImpl::getErrorStatus();
            }
        }

        // Switch back to blocking mode
        setBlocking(true);

        return status;
    }
}
Beispiel #18
0
IPAddress AsyncClient::remoteIP() {
    return IPAddress(getRemoteAddress());
}