Esempio n. 1
0
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr)
{
	int64 Now = time_get();
	m_LastRecvTime = Now;
	
	// check if resend is requested
	if(pPacket->m_Flags&NET_PACKETFLAG_RESEND)
		Resend();

	//
	if(pPacket->m_Flags&NET_PACKETFLAG_CONTROL)
	{
		int CtrlMsg = pPacket->m_aChunkData[0];
		
		if(CtrlMsg == NET_CTRLMSG_CLOSE)
		{
			if(net_addr_comp(&m_PeerAddr, pAddr) == 0)
			{
				m_State = NET_CONNSTATE_ERROR;
				m_RemoteClosed = 1;
				
				if(pPacket->m_DataSize)
				{
					// make sure to sanitize the error string form the other party
					char Str[128];
					if(pPacket->m_DataSize < 128)
						str_copy(Str, (char *)pPacket->m_aChunkData, pPacket->m_DataSize);
					else
						str_copy(Str, (char *)pPacket->m_aChunkData, sizeof(Str));
					str_sanitize_strong(Str);
					
					// set the error string
					SetError(Str);
				}
				else
					SetError("no reason given");
					
				if(g_Config.m_Debug)
					dbg_msg("conn", "closed reason='%s'", ErrorString());
			}
			return 0;			
		}
		else
		{
			if(State() == NET_CONNSTATE_OFFLINE)
			{
				if(CtrlMsg == NET_CTRLMSG_CONNECT)
				{
					// send response and init connection
					Reset();
					m_State = NET_CONNSTATE_PENDING;
					m_PeerAddr = *pAddr;
					m_LastSendTime = Now;
					m_LastRecvTime = Now;
					m_LastUpdateTime = Now;
					SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0);
					if(g_Config.m_Debug)
						dbg_msg("connection", "got connection, sending connect+accept");			
				}
			}
			else if(State() == NET_CONNSTATE_CONNECT)
			{
				// connection made
				if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT)
				{
					SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
					m_State = NET_CONNSTATE_ONLINE;
					if(g_Config.m_Debug)
						dbg_msg("connection", "got connect+accept, sending accept. connection online");
				}
			}
			else if(State() == NET_CONNSTATE_ONLINE)
			{
				// connection made
				/*
				if(ctrlmsg == NET_CTRLMSG_CONNECTACCEPT)
				{
					
				}*/
			}
		}
	}
	else
	{
		if(State() == NET_CONNSTATE_PENDING)
		{
			m_State = NET_CONNSTATE_ONLINE;
			if(g_Config.m_Debug)
				dbg_msg("connection", "connecting online");
		}
	}
	
	if(State() == NET_CONNSTATE_ONLINE)
	{
		AckChunks(pPacket->m_Ack);
	}
	
	return 1;
}
Esempio n. 2
0
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_TOKEN SecurityToken)
{
    if (State() != NET_CONNSTATE_OFFLINE && m_SecurityToken != NET_SECURITY_TOKEN_UNKNOWN && m_SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
    {
        // supposed to have a valid token in this packet, check it
        if (pPacket->m_DataSize < (int)sizeof(m_SecurityToken))
            return 0;
        pPacket->m_DataSize -= sizeof(m_SecurityToken);
        if (m_SecurityToken != ToSecurityToken(&pPacket->m_aChunkData[pPacket->m_DataSize]))
        {
            if(g_Config.m_Debug)
                dbg_msg("security", "token mismatch, expected %d got %d", m_SecurityToken, ToSecurityToken(&pPacket->m_aChunkData[pPacket->m_DataSize]));
            return 0;
        }
    }

    int64 Now = time_get();

    // check if resend is requested
    if(pPacket->m_Flags&NET_PACKETFLAG_RESEND)
        Resend();

    //
    if(pPacket->m_Flags&NET_PACKETFLAG_CONTROL)
    {
        int CtrlMsg = pPacket->m_aChunkData[0];

        if(CtrlMsg == NET_CTRLMSG_CLOSE)
        {
            if(net_addr_comp(&m_PeerAddr, pAddr) == 0)
            {
                m_State = NET_CONNSTATE_ERROR;
                m_RemoteClosed = 1;

                char Str[128] = {0};
                if(pPacket->m_DataSize > 1)
                {
                    // make sure to sanitize the error string form the other party
                    if(pPacket->m_DataSize < 128)
                        str_copy(Str, (char *)&pPacket->m_aChunkData[1], pPacket->m_DataSize);
                    else
                        str_copy(Str, (char *)&pPacket->m_aChunkData[1], sizeof(Str));
                    str_sanitize_strong(Str);
                }

                if(!m_BlockCloseMsg)
                {
                    // set the error string
                    SetError(Str);
                }

                if(g_Config.m_Debug)
                    dbg_msg("conn", "closed reason='%s'", Str);
            }
            return 0;
        }
        else
        {
            if(State() == NET_CONNSTATE_OFFLINE)
            {
                if(CtrlMsg == NET_CTRLMSG_CONNECT)
                {
                    NETADDR nAddr;
                    mem_copy(&nAddr, pAddr, sizeof(nAddr));
                    nAddr.port = 0;
                    m_PeerAddr.port = 0;
#ifndef FUZZING
                    if(net_addr_comp(&m_PeerAddr, &nAddr) == 0 && time_get() - m_LastUpdateTime < time_freq() * 3)
                        return 0;
#endif

                    // send response and init connection
                    Reset();
                    m_State = NET_CONNSTATE_PENDING;
                    m_PeerAddr = *pAddr;
                    mem_zero(m_ErrorString, sizeof(m_ErrorString));
                    m_LastSendTime = Now;
                    m_LastRecvTime = Now;
                    m_LastUpdateTime = Now;
                    if (m_SecurityToken == NET_SECURITY_TOKEN_UNKNOWN
                            && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(m_SecurityToken))
                            && !mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)))
                    {
                        m_SecurityToken = SecurityToken;
                        if(g_Config.m_Debug)
                            dbg_msg("security", "generated token %d", m_SecurityToken);
                    }
                    else
                    {
                        if(g_Config.m_Debug)
                            dbg_msg("security", "token not supported by client (packet size %d)", pPacket->m_DataSize);
                        m_SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED;
                    }
                    SendControl(NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
                    if(g_Config.m_Debug)
                        dbg_msg("connection", "got connection, sending connect+accept");
                }
            }
            else if(State() == NET_CONNSTATE_CONNECT)
            {
                // connection made
                if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT)
                {
                    if (m_SecurityToken == NET_SECURITY_TOKEN_UNKNOWN
                            && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(m_SecurityToken))
                            && !mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)))
                    {
                        m_SecurityToken = ToSecurityToken(&pPacket->m_aChunkData[1 + sizeof(SECURITY_TOKEN_MAGIC)]);
                        if(g_Config.m_Debug)
                            dbg_msg("security", "got token %d", m_SecurityToken);
                    }
                    else
                    {
                        m_SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED;
                        if(g_Config.m_Debug)
                            dbg_msg("security", "token not supported by server");
                    }
                    m_LastRecvTime = Now;
                    SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
                    m_State = NET_CONNSTATE_ONLINE;
                    if(g_Config.m_Debug)
                        dbg_msg("connection", "got connect+accept, sending accept. connection online");
                }
            }
        }
    }
    else
    {
        if(State() == NET_CONNSTATE_PENDING)
        {
            m_LastRecvTime = Now;
            m_State = NET_CONNSTATE_ONLINE;
            if(g_Config.m_Debug)
                dbg_msg("connection", "connecting online");
        }
    }

    if(State() == NET_CONNSTATE_ONLINE)
    {
        m_LastRecvTime = Now;
        AckChunks(pPacket->m_Ack);
    }

    return 1;
}
Esempio n. 3
0
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr)
{
	// check if actual ack value is valid(own sequence..latest peer ack)
	if(m_Sequence >= m_PeerAck)
	{
		if(pPacket->m_Ack < m_PeerAck || pPacket->m_Ack > m_Sequence)
			return 0;
	}
	else
	{
		if(pPacket->m_Ack < m_PeerAck && pPacket->m_Ack > m_Sequence)
			return 0;
	}
	m_PeerAck = pPacket->m_Ack;

	int64 Now = time_get();

	if(pPacket->m_Token == NET_TOKEN_NONE || pPacket->m_Token != m_Token)
		return 0;

	// check if resend is requested
	if(pPacket->m_Flags&NET_PACKETFLAG_RESEND)
		Resend();

	if(pPacket->m_Flags&NET_PACKETFLAG_CONNLESS)
		return 1;

	//
	if(pPacket->m_Flags&NET_PACKETFLAG_CONTROL)
	{
		int CtrlMsg = pPacket->m_aChunkData[0];

		if(CtrlMsg == NET_CTRLMSG_CLOSE)
		{
			if(net_addr_comp(&m_PeerAddr, pAddr) == 0)
			{
				m_State = NET_CONNSTATE_ERROR;
				m_RemoteClosed = 1;

				char Str[128] = {0};
				if(pPacket->m_DataSize > 1)
				{
					// make sure to sanitize the error string form the other party
					if(pPacket->m_DataSize < 128)
						str_copy(Str, (char *)&pPacket->m_aChunkData[1], pPacket->m_DataSize);
					else
						str_copy(Str, (char *)&pPacket->m_aChunkData[1], sizeof(Str));
					str_sanitize_strong(Str);
				}

				if(!m_BlockCloseMsg)
				{
					// set the error string
					SetError(Str);
				}

				if(g_Config.m_Debug)
					dbg_msg("conn", "closed reason='%s'", Str);
			}
			return 0;
		}
		else
		{
			if(CtrlMsg == NET_CTRLMSG_TOKEN)
			{
				m_PeerToken = pPacket->m_ResponseToken;

				if(State() == NET_CONNSTATE_TOKEN)
				{
					m_LastRecvTime = Now;
					m_State = NET_CONNSTATE_CONNECT;
					SendControlWithToken(NET_CTRLMSG_CONNECT);
					dbg_msg("connection", "got token, replying, token=%x mytoken=%x", m_PeerToken, m_Token);
				}
				else if(g_Config.m_Debug)
					dbg_msg("connection", "got token, token=%x", m_PeerToken);
			}
			else
			{
				if(State() == NET_CONNSTATE_OFFLINE)
				{
					if(CtrlMsg == NET_CTRLMSG_CONNECT)
					{
						// send response and init connection
						TOKEN Token = m_Token;
						Reset();
						m_State = NET_CONNSTATE_PENDING;
						m_PeerAddr = *pAddr;
						m_PeerToken = pPacket->m_ResponseToken;
						m_Token = Token;
						m_LastSendTime = Now;
						m_LastRecvTime = Now;
						m_LastUpdateTime = Now;
						SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0);
						if(g_Config.m_Debug)
							dbg_msg("connection", "got connection, sending connect+accept");
					}
				}
				else if(State() == NET_CONNSTATE_CONNECT)
				{
					// connection made
					if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT)
					{
						m_LastRecvTime = Now;
						SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
						m_State = NET_CONNSTATE_ONLINE;
						if(g_Config.m_Debug)
							dbg_msg("connection", "got connect+accept, sending accept. connection online");
					}
				}
			}
		}
	}
	else
	{
		if(State() == NET_CONNSTATE_PENDING)
		{
			m_LastRecvTime = Now;
			m_State = NET_CONNSTATE_ONLINE;
			if(g_Config.m_Debug)
				dbg_msg("connection", "connecting online");
		}
	}

	if(State() == NET_CONNSTATE_ONLINE)
	{
		m_LastRecvTime = Now;
		AckChunks(pPacket->m_Ack);
	}

	return 1;
}