// Send a USB descriptor string. The string is stored in PROGMEM as a
// plain ASCII string but is sent out as UTF-16 with the correct 2-byte
// prefix
static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) {
        SendControl(2 + string_len * 2);
        SendControl(3);
        for(u8 i = 0; i < string_len; i++) {
                bool r = SendControl(pgm_read_byte(&string_P[i]));
                r &= SendControl(0); // high byte
                if(!r) {
                        return false;
                }
        }
        return true;
}
예제 #2
0
// Send a USB descriptor string. The string is stored in PROGMEM as a
// plain ASCII string but is sent out as UTF-16 with the correct 2-byte
// prefix
static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len, uint8_t flags) {
        SendControl(2 + string_len * 2);
        SendControl(3);
        bool pgm = flags & TRANSFER_PGM;
        for(u8 i = 0; i < string_len; i++) {
                bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]);
                r &= SendControl(0); // high byte
                if(!r) {
                        return false;
                }
        }
        return true;
}
예제 #3
0
TInt DDisplayLdd::SendMsg(TMessageBase* aMsg)
	{
	TThreadMessage& m=*(TThreadMessage*)aMsg;
    TInt id = m.iValue;
	
	TInt r = KErrNone;	
	 // close msg or cancel
	if (id == (TInt)ECloseMsg || id == KMaxTInt)
		{
		r = DLogicalChannel::SendMsg(aMsg);
		}
	//asynchronous request
	else if (id < 0)
		{
		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
		r = SendRequest(aMsg);
		if (r != KErrNone)
			Kern::RequestComplete(pS,r);
		}
	 // synchronous request
	else{
		r = SendControl(aMsg);
		}
	
	return r;
	}
예제 #4
0
void CNetConnection::Disconnect(const char *pReason)
{
    if(State() == NET_CONNSTATE_OFFLINE)
        return;

    if(m_RemoteClosed == 0)
    {
        if(pReason)
            SendControl(NET_CTRLMSG_CLOSE, pReason, str_length(pReason)+1);
        else
            SendControl(NET_CTRLMSG_CLOSE, 0, 0);

        m_ErrorString[0] = 0;
        if(pReason && pReason != m_ErrorString)
            str_copy(m_ErrorString, pReason, sizeof(m_ErrorString));
    }

    Reset();
}
예제 #5
0
파일: Core.cpp 프로젝트: Dzenik/Cosa
int 
USB_SendControl(uint8_t flags, const void* d, int len)
{
  int sent = len;
  const uint8_t* data = (const uint8_t*)d;
  bool pgm = flags & TRANSFER_PGM;
  while (len--) {
    uint8_t c = pgm ? pgm_read_byte(data++) : *data++;
    if (!SendControl(c)) return (-1);
  }
  return (sent);
}
예제 #6
0
//	Clipped by _cmark/_cend
int USB_SendControl(u8 flags, const void* d, int len)
{
	int sent = len;
	const u8* data = (const u8*)d;
	bool pgm = flags & TRANSFER_PGM;
	while (len--)
	{
		u8 c = pgm ? pgm_read_byte(data++) : *data++;
		if (!SendControl(c))
			return -1;
	}
	return sent;
}
예제 #7
0
int CNetConnection::Connect(NETADDR *pAddr)
{
    if(State() != NET_CONNSTATE_OFFLINE)
        return -1;

    // init connection
    Reset();
    m_PeerAddr = *pAddr;
    mem_zero(m_ErrorString, sizeof(m_ErrorString));
    m_State = NET_CONNSTATE_CONNECT;
    SendControl(NET_CTRLMSG_CONNECT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
    return 0;
}
예제 #8
0
/*-----------------------------------------------------------------------------
-	FUNCTION:	PacketCheck
-
-	DATE:		November 21st, 2013
-
-	REVISIONS:	
-	2013/12/02 - Vincent - Created
-	
-
-	DESIGNER:	Vincent Lau
-
-	PROGRAMMER:	Vincent Lau
-				German Villarreal
-
-	INTERFACE:	BOOL PacketCheck(HWND hwnd, CHAR* packet)
-		
-	RETURNS:	void, nothing.
-				
-	PARAMETERS:	HWND hwnd - a dynamic char buffer that contains the whole file
-				CHAR* packet:  1024 bytes of data
-
-	NOTES:	This is a function that cecks the packet for data.
-			
-
-----------------------------------------------------------------------------*/
BOOL PacketCheck(HWND hwnd, CHAR* packet)
{
	char* data = (CHAR*) malloc(1020);
	data[1020] = '\0';
	int lengthOfData = strlen(data);
	
	 //Make sure we're getting our own packets, not some other packet
	switch (packet[0])
	{
	case SYN:
		break;
	default: // discard packet
		return FALSE;
	}

	switch (packet[1])
	{
	case ENQ:
		bENQReceived = TRUE;
		//SendControl(hComm, ACK);
		bWantToSendACK = TRUE;
		//	Set "what we're waiting for" flag to DC1
		waitForType = DC1;
	break;
	case ACK:
		// check if we wanted an ACK
		if (waitForType == ACK)
		{
			// check if we're actually bidding for the line
			if (bWantLine)
				ReleaseSemaphore(hWaitForLineSemaphore, 1, NULL);
			else
			// check if we're sending a file
				ReleaseSemaphore(hACKWaitSemaphore, 1, NULL);
		}
	break;

	case DC1:
		//if we're waiting for a DC2 packet

		if(waitForType == DC2 || !ErrorCheck(packet+2))//pass data+crcbits
		{
			SendControl(hComm, NAK);
			break;
		}
		waitForType = DC2;
		bWantToSendACK = TRUE;
		GetData(packet, data);
		AddToBuffer(data);
	break;
	case DC2:
		// if we're waiting for a DC1 packet
		if (waitForType == DC1 || !ErrorCheck(packet+2))
		{
			SendControl(hComm, NAK);
			break;
		}
		waitForType = DC1;
		bWantToSendACK = TRUE;
		GetData(packet, data);
		AddToBuffer(data);
	break;
	case NAK:
		//Set "What we're waiting for" flag to ACK
		waitForType = ACK;
		SendData(hComm, Packet); // send the previous packet
	break;
	case EOT:
		bENQReceived = FALSE;
		if (bENQToSend)
		{
			ReleaseSemaphore(hWaitForLineSemaphore, 1, NULL);
			break;
		}
	    // GO back to IDLE state
		waitForType = ENQ;
	break;
    }
	return TRUE;
}
예제 #9
0
// connection-less msg packet without token-support
void CNetServer::OnPreConnMsg(NETADDR &Addr, CNetPacketConstruct &Packet)
{
	bool IsCtrl = Packet.m_Flags&NET_PACKETFLAG_CONTROL;
	int CtrlMsg = m_RecvUnpacker.m_Data.m_aChunkData[0];

	// log flooding
	//TODO: remove
	if (g_Config.m_Debug)
	{
		int64 Now = time_get();

		if (Now - m_TimeNumConAttempts > time_freq())
			// reset
			m_NumConAttempts = 0;

		m_NumConAttempts++;

		if (m_NumConAttempts > 100)
		{
			dbg_msg("security", "flooding detected");

			m_TimeNumConAttempts = Now;
			m_NumConAttempts = 0;
		}
	}


	if (IsCtrl && CtrlMsg == NET_CTRLMSG_CONNECT)
	{
		if (g_Config.m_SvVanillaAntiSpoof && g_Config.m_Password[0] == '\0')
		{
			// detect flooding
			int64 Now = time_get();
			if(Now <= m_VConnFirst + time_freq())
			{
				m_VConnNum++;
			}
			else
			{
				m_VConnHighLoad = m_VConnNum > g_Config.m_SvVanConnPerSecond;
				m_VConnNum = 1;
				m_VConnFirst = Now;
			}

			bool Flooding = m_VConnNum > g_Config.m_SvVanConnPerSecond || m_VConnHighLoad;

			if (g_Config.m_Debug && Flooding)
			{
				dbg_msg("security", "vanilla connection flooding detected");
			}

			// simulate accept
			SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, NULL, 0, NET_SECURITY_TOKEN_UNSUPPORTED);

			// Begin vanilla compatible token handshake
			// The idea is to pack a security token in the gametick
			// parameter of NETMSG_SNAPEMPTY. The Client then will
			// return the token/gametick in NETMSG_INPUT, allowing
			// us to validate the token.
			// https://github.com/eeeee/ddnet/commit/b8e40a244af4e242dc568aa34854c5754c75a39a

			// Before we can send NETMSG_SNAPEMPTY, the client needs
			// to load a map, otherwise it might crash. The map
			// should be as small as is possible and directly available
			// to the client. Therefore a dummy map is sent in the same
			// packet. To reduce the traffic we'll fallback to a default
			// map if there are too many connection attempts at once.

			// send mapchange + map data + con_ready + 3 x empty snap (with token)
			CMsgPacker MapChangeMsg(NETMSG_MAP_CHANGE);

			if (Flooding)
			{
				// Fallback to dm1
				MapChangeMsg.AddString("dm1", 0);
				MapChangeMsg.AddInt(0xf2159e6e);
				MapChangeMsg.AddInt(5805);
			}
			else
			{
				// dummy map
				MapChangeMsg.AddString("dummy", 0);
				MapChangeMsg.AddInt(DummyMapCrc);
				MapChangeMsg.AddInt(sizeof(g_aDummyMapData));
			}

			CMsgPacker MapDataMsg(NETMSG_MAP_DATA);

			if (Flooding)
			{
				// send empty map data to keep 0.6.4 support
				MapDataMsg.AddInt(1); // last chunk
				MapDataMsg.AddInt(0); // crc
				MapDataMsg.AddInt(0); // chunk index
				MapDataMsg.AddInt(0); // map size
				MapDataMsg.AddRaw(NULL, 0); // map data
			}
			else
			{
				// send dummy map data
				MapDataMsg.AddInt(1); // last chunk
				MapDataMsg.AddInt(DummyMapCrc); // crc
				MapDataMsg.AddInt(0); // chunk index
				MapDataMsg.AddInt(sizeof(g_aDummyMapData)); // map size
				MapDataMsg.AddRaw(g_aDummyMapData, sizeof(g_aDummyMapData)); // map data
			}

			CMsgPacker ConReadyMsg(NETMSG_CON_READY);

			CMsgPacker SnapEmptyMsg(NETMSG_SNAPEMPTY);
			SECURITY_TOKEN SecurityToken = GetVanillaToken(Addr);
			SnapEmptyMsg.AddInt((int)SecurityToken);
			SnapEmptyMsg.AddInt((int)SecurityToken + 1);

			// send all chunks/msgs in one packet
			const CMsgPacker *Msgs[] = {&MapChangeMsg, &MapDataMsg, &ConReadyMsg,
										&SnapEmptyMsg, &SnapEmptyMsg, &SnapEmptyMsg};
			SendMsgs(Addr, Msgs, 6);
		}
		else
		{
			// accept client directly
			SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, NULL, 0, NET_SECURITY_TOKEN_UNSUPPORTED);

			TryAcceptClient(Addr, NET_SECURITY_TOKEN_UNSUPPORTED);
		}
	}
	else if(!IsCtrl && g_Config.m_SvVanillaAntiSpoof && g_Config.m_Password[0] == '\0')
	{
		CNetChunkHeader h;

		unsigned char *pData = Packet.m_aChunkData;
		pData = h.Unpack(pData);
		CUnpacker Unpacker;
		Unpacker.Reset(pData, h.m_Size);
		int Msg = Unpacker.GetInt() >> 1;

		if (Msg == NETMSG_INPUT)
		{
			SECURITY_TOKEN SecurityToken = Unpacker.GetInt();
			if (SecurityToken == GetVanillaToken(Addr))
			{
				if (g_Config.m_Debug)
					dbg_msg("security", "new client (vanilla handshake)");
				// try to accept client skipping auth state
				TryAcceptClient(Addr, NET_SECURITY_TOKEN_UNSUPPORTED, true);
			}
			else if (g_Config.m_Debug)
				dbg_msg("security", "invalid token (vanilla handshake)");

		}
		else
		{
			if (g_Config.m_Debug)
			{
				dbg_msg("security", "invalid preconn msg %d", Msg);
			}
		}
	}
예제 #10
0
int CNetConnection::Update()
{
    int64 Now = time_get();

    if(State() == NET_CONNSTATE_ERROR && m_TimeoutSituation && (Now-m_LastRecvTime) > time_freq()*g_Config.m_ConnTimeoutProtection)
    {
        m_TimeoutSituation = false;
        SetError("Timeout Protection over");
    }

    if(State() == NET_CONNSTATE_OFFLINE || State() == NET_CONNSTATE_ERROR)
        return 0;

    m_TimeoutSituation = false;

    // check for timeout
    if(State() != NET_CONNSTATE_OFFLINE &&
            State() != NET_CONNSTATE_CONNECT &&
            (Now-m_LastRecvTime) > time_freq()*g_Config.m_ConnTimeout)
    {
        m_State = NET_CONNSTATE_ERROR;
        SetError("Timeout");
        m_TimeoutSituation = true;
    }

    // fix resends
    if(m_Buffer.First())
    {
        CNetChunkResend *pResend = m_Buffer.First();

        // check if we have some really old stuff laying around and abort if not acked
        if(Now-pResend->m_FirstSendTime > time_freq()*g_Config.m_ConnTimeout)
        {
            m_State = NET_CONNSTATE_ERROR;
            char aBuf[512];
            str_format(aBuf, sizeof(aBuf), "Too weak connection (not acked for %d seconds)", g_Config.m_ConnTimeout);
            SetError(aBuf);
            m_TimeoutSituation = true;
        }
        else
        {
            // resend packet if we havn't got it acked in 1 second
            if(Now-pResend->m_LastSendTime > time_freq())
                ResendChunk(pResend);
        }
    }

    // send keep alives if nothing has happend for 250ms
    if(State() == NET_CONNSTATE_ONLINE)
    {
        if(time_get()-m_LastSendTime > time_freq()/2) // flush connection after 500ms if needed
        {
            int NumFlushedChunks = Flush();
            if(NumFlushedChunks && g_Config.m_Debug)
                dbg_msg("connection", "flushed connection due to timeout. %d chunks.", NumFlushedChunks);
        }

        if(time_get()-m_LastSendTime > time_freq())
            SendControl(NET_CTRLMSG_KEEPALIVE, 0, 0);
    }
    else if(State() == NET_CONNSTATE_CONNECT)
    {
        if(time_get()-m_LastSendTime > time_freq()/2) // send a new connect every 500ms
            SendControl(NET_CTRLMSG_CONNECT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
    }
    else if(State() == NET_CONNSTATE_PENDING)
    {
        if(time_get()-m_LastSendTime > time_freq()/2) // send a new connect/accept every 500ms
            SendControl(NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
    }

    return 0;
}
예제 #11
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;
}
예제 #12
0
int CNetConnection::Update()
{
	int64 Now = time_get();

	if(State() == NET_CONNSTATE_OFFLINE || State() == NET_CONNSTATE_ERROR)
		return 0;
	
	// check for timeout
	if(State() != NET_CONNSTATE_OFFLINE &&
		State() != NET_CONNSTATE_CONNECT &&
		(Now-m_LastRecvTime) > time_freq()*10)
	{
		m_State = NET_CONNSTATE_ERROR;
		SetError("timeout");
	}

	// fix resends
	if(m_Buffer.First())
	{
		CNetChunkResend *pResend = m_Buffer.First();

		// check if we have some really old stuff laying around and abort if not acked
		if(Now-pResend->m_FirstSendTime > time_freq()*10)
		{
			m_State = NET_CONNSTATE_ERROR;
			SetError("too weak connection (not acked for 10 seconds)");
		}
		else
		{
			// resend packet if we havn't got it acked in 1 second
			if(Now-pResend->m_LastSendTime > time_freq())
				ResendChunk(pResend);
		}
	}
	
	// send keep alives if nothing has happend for 250ms
	if(State() == NET_CONNSTATE_ONLINE)
	{
		if(time_get()-m_LastSendTime > time_freq()/2) // flush connection after 500ms if needed
		{
			int NumFlushedChunks = Flush();
			if(NumFlushedChunks && g_Config.m_Debug)
				dbg_msg("connection", "flushed connection due to timeout. %d chunks.", NumFlushedChunks);
		}
			
		if(time_get()-m_LastSendTime > time_freq())
			SendControl(NET_CTRLMSG_KEEPALIVE, 0, 0);
	}
	else if(State() == NET_CONNSTATE_CONNECT)
	{
		if(time_get()-m_LastSendTime > time_freq()/2) // send a new connect every 500ms
			SendControl(NET_CTRLMSG_CONNECT, 0, 0);
	}
	else if(State() == NET_CONNSTATE_PENDING)
	{
		if(time_get()-m_LastSendTime > time_freq()/2) // send a new connect/accept every 500ms
			SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0);
	}
	
	return 0;
}
예제 #13
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;
}
예제 #14
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;
}