diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
| commit | 72c06a258940696093f255fb1061beb58e1cdd0b (patch) | |
| tree | 36b9a7712eec2d4f07837eab9c38ef1c5af85319 /src/engine/e_network_conn.cpp | |
| parent | e56feb597bc743677633432f77513b02907fd169 (diff) | |
| download | zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.tar.gz zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.zip | |
copied refactor to trunk
Diffstat (limited to 'src/engine/e_network_conn.cpp')
| -rw-r--r-- | src/engine/e_network_conn.cpp | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/src/engine/e_network_conn.cpp b/src/engine/e_network_conn.cpp deleted file mode 100644 index a54c9ce3..00000000 --- a/src/engine/e_network_conn.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include <base/system.h> -#include <string.h> -#include "e_config.h" -#include "e_network.h" - -void CNetConnection::ResetStats() -{ - mem_zero(&m_Stats, sizeof(m_Stats)); -} - -void CNetConnection::Reset() -{ - m_Sequence = 0; - m_Ack = 0; - m_RemoteClosed = 0; - - m_State = NET_CONNSTATE_OFFLINE; - m_LastSendTime = 0; - m_LastRecvTime = 0; - m_LastUpdateTime = 0; - m_Token = -1; - mem_zero(&m_PeerAddr, sizeof(m_PeerAddr)); - - m_Buffer.Init(); - - mem_zero(&m_Construct, sizeof(m_Construct)); -} - -const char *CNetConnection::ErrorString() -{ - return m_ErrorString; -} - -void CNetConnection::SetError(const char *pString) -{ - str_copy(m_ErrorString, pString, sizeof(m_ErrorString)); -} - -void CNetConnection::Init(NETSOCKET Socket) -{ - Reset(); - ResetStats(); - - m_Socket = Socket; - mem_zero(m_ErrorString, sizeof(m_ErrorString)); -} - -void CNetConnection::AckChunks(int Ack) -{ - while(1) - { - CNetChunkResend *pResend = m_Buffer.First(); - if(!pResend) - break; - - if(CNetBase::IsSeqInBackroom(pResend->m_Sequence, Ack)) - m_Buffer.PopFirst(); - else - break; - } -} - -void CNetConnection::SignalResend() -{ - m_Construct.m_Flags |= NET_PACKETFLAG_RESEND; -} - -int CNetConnection::Flush() -{ - int NumChunks = m_Construct.m_NumChunks; - if(!NumChunks && !m_Construct.m_Flags) - return 0; - - /* send of the packets */ - m_Construct.m_Ack = m_Ack; - CNetBase::SendPacket(m_Socket, &m_PeerAddr, &m_Construct); - - /* update send times */ - m_LastSendTime = time_get(); - - /* clear construct so we can start building a new package */ - mem_zero(&m_Construct, sizeof(m_Construct)); - return NumChunks; -} - -void CNetConnection::QueueChunkEx(int Flags, int DataSize, const void *pData, int Sequence) -{ - unsigned char *pChunkData; - - /* check if we have space for it, if not, flush the connection */ - if(m_Construct.m_DataSize + DataSize + NET_MAX_CHUNKHEADERSIZE > (int)sizeof(m_Construct.m_aChunkData)) - Flush(); - - /* pack all the data */ - CNetChunkHeader Header; - Header.m_Flags = Flags; - Header.m_Size = DataSize; - Header.m_Sequence = Sequence; - pChunkData = &m_Construct.m_aChunkData[m_Construct.m_DataSize]; - pChunkData = Header.Pack(pChunkData); - mem_copy(pChunkData, pData, DataSize); - pChunkData += DataSize; - - /* */ - m_Construct.m_NumChunks++; - m_Construct.m_DataSize = (int)(pChunkData-m_Construct.m_aChunkData); - - /* set packet flags aswell */ - - if(Flags&NET_CHUNKFLAG_VITAL && !(Flags&NET_CHUNKFLAG_RESEND)) - { - /* save packet if we need to resend */ - CNetChunkResend *pResend = m_Buffer.Allocate(sizeof(CNetChunkResend)+DataSize); - if(pResend) - { - pResend->m_Sequence = Sequence; - pResend->m_Flags = Flags; - pResend->m_DataSize = DataSize; - pResend->m_pData = (unsigned char *)(pResend+1); - pResend->m_FirstSendTime = time_get(); - pResend->m_LastSendTime = pResend->m_FirstSendTime; - mem_copy(pResend->m_pData, pData, DataSize); - } - else - { - /* out of buffer */ - Disconnect("too weak connection (out of buffer)"); - } - } -} - -void CNetConnection::QueueChunk(int Flags, int DataSize, const void *pData) -{ - if(Flags&NET_CHUNKFLAG_VITAL) - m_Sequence = (m_Sequence+1)%NET_MAX_SEQUENCE; - QueueChunkEx(Flags, DataSize, pData, m_Sequence); -} - -void CNetConnection::SendControl(int ControlMsg, const void *pExtra, int ExtraSize) -{ - /* send the control message */ - m_LastSendTime = time_get(); - CNetBase::SendControlMsg(m_Socket, &m_PeerAddr, m_Ack, ControlMsg, pExtra, ExtraSize); -} - -void CNetConnection::ResendChunk(CNetChunkResend *pResend) -{ - QueueChunkEx(pResend->m_Flags|NET_CHUNKFLAG_RESEND, pResend->m_DataSize, pResend->m_pData, pResend->m_Sequence); - pResend->m_LastSendTime = time_get(); -} - -void CNetConnection::Resend() -{ - for(CNetChunkResend *pResend = m_Buffer.First(); pResend; m_Buffer.Next(pResend)) - ResendChunk(pResend); -} - -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, 0, 0); - return 0; -} - -void CNetConnection::Disconnect(const char *pReason) -{ - if(State() == NET_CONNSTATE_OFFLINE) - return; - - if(m_RemoteClosed == 0) - { - if(pReason) - SendControl(NET_CTRLMSG_CLOSE, pReason, strlen(pReason)+1); - else - SendControl(NET_CTRLMSG_CLOSE, 0, 0); - - m_ErrorString[0] = 0; - if(pReason) - str_copy(m_ErrorString, pReason, sizeof(m_ErrorString)); - } - - Reset(); -} - -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) - { - 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(config.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(config.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(config.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(config.debug) - dbg_msg("connection", "connecting online"); - } - } - - if(State() == NET_CONNSTATE_ONLINE) - { - AckChunks(pPacket->m_Ack); - } - - return 1; -} - -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 && config.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; -} |