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; }
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; }
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; }