Example #1
0
void CIcqProto::handleLoginReply(BYTE *buf, WORD datalen, serverthread_info *info)
{
    oscar_tlv_chain *chain = NULL;

    icq_sendCloseConnection(); // imitate icq5 behaviour

    if (!(chain = readIntoTLVChain(&buf, datalen, 0)))
    {
        NetLog_Server("Error: Missing chain on close channel");
        NetLib_CloseConnection(&hServerConn, TRUE);
        return; // Invalid data
    }

    // TLV 8 errors (signon errors?)
    WORD wError = chain->getWord(0x08, 1);
    if (wError)
    {
        handleSignonError(wError);

        // we return only if the server did not gave us cookie (possible to connect with soft error)
        if (!chain->getLength(0x06, 1))
        {
            disposeChain(&chain);
            SetCurrentStatus(ID_STATUS_OFFLINE);
            icq_serverDisconnect(FALSE);
            return; // Failure
        }
    }

    // We are in the login phase and no errors were reported.
    // Extract communication server info.
    info->newServer = chain->getString(0x05, 1);
    info->newServerSSL = chain->getNumber(0x8E, 1);
    info->cookieData = (BYTE*)chain->getString(0x06, 1);
    info->cookieDataLen = chain->getLength(0x06, 1);

    // We dont need this anymore
    disposeChain(&chain);

    if (!info->newServer || !info->cookieData)
    {
        icq_LogMessage(LOG_FATAL, LPGEN("You could not sign on because the server returned invalid data. Try again."));

        SAFE_FREE(&info->newServer);
        SAFE_FREE((void**)&info->cookieData);
        info->cookieDataLen = 0;

        SetCurrentStatus(ID_STATUS_OFFLINE);
        NetLib_CloseConnection(&hServerConn, TRUE);
        return; // Failure
    }

    NetLog_Server("Authenticated.");
    info->newServerReady = 1;

    return;
}
Example #2
0
void CIcqProto::sendServPacket(icq_packet *pPacket)
{
	// make sure to have the connection handle
	connectionHandleMutex->Enter();

	if (hServerConn)
	{
		int nSendResult;

		// This critsec makes sure that the sequence order doesn't get screwed up
		localSeqMutex->Enter();

		// :IMPORTANT:
		// The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to
		// 0x0000, otherwise we'll get kicked by server.
		wLocalSequence++;

		// Pack sequence number
		pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8);
		pPacket->pData[3] = (wLocalSequence & 0x00ff);

		nSendResult = Netlib_Send(hServerConn, (const char *)pPacket->pData, pPacket->wLen, 0);

		localSeqMutex->Leave();
		connectionHandleMutex->Leave();

		// Send error
		if (nSendResult == SOCKET_ERROR)
		{
			icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Your connection with the ICQ server was abortively closed"));
			icq_serverDisconnect(FALSE);

			if (m_iStatus != ID_STATUS_OFFLINE)
			{
				SetCurrentStatus(ID_STATUS_OFFLINE);
			}
		}
		else
		{ // Rates management
			icq_lock l(m_ratesMutex);
			m_rates->packetSent(pPacket);
		}

	}
	else
	{