HRESULT CBasicBindingTest::ProcessResponse(CRefCountedBuffer& spMsg, CSocketAddress& addrRemote, CSocketAddress& addrLocal)
{
    HRESULT hr = S_OK;
    CStunMessageReader reader;
    CSocketAddress addrMapped;
    CSocketAddress addrOther;
    bool fHasOtherAddress = false;

    // todo - figure out a way to make buffering TCP fragments work
    Chk(BasicReaderValidation(spMsg, reader));

    hr = reader.GetXorMappedAddress(&addrMapped);
    if (FAILED(hr))
    {
        hr = reader.GetMappedAddress(&addrMapped);
    }
    Chk(hr); // again drop the message if we can't parse the binding response

    fHasOtherAddress = SUCCEEDED(reader.GetOtherAddress(&addrOther));

    // ok, we got a response.  So we are done
    _fCompleted = true;
    _pResults->fBindingTestSuccess = true;
    _pResults->fIsDirect = addrLocal.IsSameIP_and_Port(addrMapped);
    _pResults->addrLocal = addrLocal;
    _pResults->addrMapped = addrMapped;
    _pResults->fHasOtherAddress = fHasOtherAddress;


    if (fHasOtherAddress)
    {
        _pResults->addrAA = addrOther;

        _pResults->addrPA = _pConfig->addrServer;
        _pResults->addrPA.SetPort(addrOther.GetPort());

        _pResults->addrAP = addrOther;
        _pResults->addrAP.SetPort(_pConfig->addrServer.GetPort());

        if (Logging::GetLogLevel() >= LL_DEBUG)
        {
            char sz[100];
            addrOther.ToStringBuffer(sz, 100);
            Logging::LogMsg(LL_DEBUG, "Other address is %s\n",sz);
        }

    }

Cleanup:
    return hr;
}
Exemplo n.º 2
0
StunConnection* CTCPStunThread::AcceptConnection(CStunSocket* pListenSocket)
{
    int listensock = pListenSocket->GetSocketHandle();
    SocketRole role = pListenSocket->GetRole();
    int clientsock = -1;
    int socktmp = -1;
    sockaddr_storage addrClient;
    socklen_t socklen = sizeof(addrClient);
    StunConnection* pConn = NULL;
    HRESULT hr = S_OK;
    int insertresult;
    int err;
    
    ASSERT(listensock != -1);
    ASSERT(::IsValidSocketRole(role));

    socktmp = ::accept(listensock, (sockaddr*)&addrClient, &socklen);

    err = errno;
    Logging::LogMsg(LL_VERBOSE, "accept returns %d (errno == %d)", socktmp, (socktmp<0)?err:0);
    ChkIfA(socktmp == -1, E_FAIL);
    
    // --- rate limit check-------
    if (_spLimiter.get())
    {
        CSocketAddress addr = CSocketAddress(addrClient);
        bool allowed_to_pass = _spLimiter->RateCheck(addr);
        
        if (allowed_to_pass == false)
        {
            if (Logging::GetLogLevel() >= LL_VERBOSE)
            {
                char szIP[100];
                addr.ToStringBuffer(szIP, 100);
                Logging::LogMsg(LL_VERBOSE, "Rate Limiter has blocked incoming connection from IP %s", szIP);
            }
            ChkIf(false, E_FAIL); // this will trigger the socket to be immediately closed
        }
    }
    // --------------------------
    
    
    clientsock = socktmp;
    
    pConn = _connectionpool.GetConnection(clientsock, role);
    ChkIfA(pConn == NULL, E_FAIL); // Our connection pool has nothing left to give, only thing to do is abort this connection and close the socket
    socktmp = -1;
    
    ChkA(pConn->_stunsocket.SetNonBlocking(true));
    
    ChkA(_spPolling->Add(clientsock, EPOLL_CLIENT_READ_EVENT_SET));
    
    // add connection to our tracking tables
    pConn->_idHashTable = (_pNewConnList == &_hashConnections1) ? 1 : 2;
    insertresult = _pNewConnList->Insert(clientsock, pConn);
    
    // out of space in the lookup tables?
    ChkIfA(insertresult == -1, E_FAIL);
    
    if (Logging::GetLogLevel() >= LL_VERBOSE)
    {
        char szIPRemote[100];
        char szIPLocal[100];
        pConn->_stunsocket.GetLocalAddress().ToStringBuffer(szIPLocal, ARRAYSIZE(szIPLocal));
        pConn->_stunsocket.GetRemoteAddress().ToStringBuffer(szIPRemote, ARRAYSIZE(szIPRemote));
        Logging::LogMsg(LL_VERBOSE, "accepting new connection on socket %d from %s on interface %s", pConn->_stunsocket.GetSocketHandle(), szIPRemote, szIPLocal);
    }
    
    
Cleanup:
    
    if (FAILED(hr))
    {
        CloseConnection(pConn);
        pConn = NULL;
        if (socktmp != -1)
        {
            close(socktmp);
        }
    }

    return pConn;
}