00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Datagrams.h"
00026 #include "DatagramPart.h"
00027 #include "G2Packet.h"
00028 #include "Buffer.h"
00029
00030 #ifdef _DEBUG
00031 #undef THIS_FILE
00032 static char THIS_FILE[]=__FILE__;
00033 #define new DEBUG_NEW
00034 #endif
00035
00036
00038
00039
00040 CDatagramOut::CDatagramOut()
00041 {
00042 m_pBuffer = NULL;
00043 m_pLocked = NULL;
00044 m_nLocked = 0;
00045 }
00046
00047 CDatagramOut::~CDatagramOut()
00048 {
00049 if ( m_pLocked ) delete [] m_pLocked;
00050 }
00051
00053
00054
00055 void CDatagramOut::Create(SOCKADDR_IN* pHost, CG2Packet* pPacket, WORD nSequence, CBuffer* pBuffer, BOOL bAck)
00056 {
00057 ASSERT( m_pBuffer == NULL );
00058
00059 m_pHost = *pHost;
00060 m_nSequence = nSequence;
00061 m_pBuffer = pBuffer;
00062
00063 pPacket->ToBuffer( m_pBuffer );
00064
00065 m_bCompressed = m_pBuffer->Deflate( TRUE );
00066
00067 m_nPacket = Settings.Gnutella2.UdpMTU;
00068 m_nCount = (BYTE)( ( m_pBuffer->m_nLength + m_nPacket - 1 ) / m_nPacket );
00069 m_nAcked = m_nCount;
00070
00071 SGP_HEADER pHeader;
00072
00073 strncpy( pHeader.szTag, SGP_TAG_2, 3 );
00074 pHeader.nFlags = m_bCompressed ? SGP_DEFLATE : 0;
00075 if ( bAck ) pHeader.nFlags |= SGP_ACKNOWLEDGE;
00076
00077 pHeader.nSequence = m_nSequence;
00078 pHeader.nCount = m_nCount;
00079
00080 DWORD nOffset = 0;
00081 DWORD nPacket = m_nPacket + sizeof(SGP_HEADER);
00082
00083 for ( BYTE nPart = 0 ; nPart < m_nCount ; nPart++, nOffset += nPacket )
00084 {
00085 pHeader.nPart = nPart + 1;
00086 m_pBuffer->Insert( nOffset, &pHeader, sizeof(pHeader) );
00087 }
00088
00089 if ( m_nLocked < m_nCount )
00090 {
00091 if ( m_pLocked ) delete [] m_pLocked;
00092
00093 m_nLocked = m_nCount;
00094 m_pLocked = new DWORD[ m_nLocked ];
00095 }
00096
00097 ZeroMemory( m_pLocked, sizeof(DWORD) * m_nCount );
00098
00099 m_tSent = GetTickCount();
00100 }
00101
00103
00104
00105 BOOL CDatagramOut::GetPacket(DWORD tNow, BYTE** ppPacket, DWORD* pnPacket, BOOL bResend)
00106 {
00107 ASSERT( m_pBuffer != NULL );
00108
00109 int nPart = 0;
00110 for ( ; nPart < m_nCount ; nPart++ )
00111 {
00112 if ( m_pLocked[ nPart ] < 0xFFFFFFFF )
00113 {
00114 if ( bResend )
00115 {
00116 if ( tNow - m_pLocked[ nPart ] >= Settings.Gnutella2.UdpOutResend ) break;
00117 }
00118 else
00119 {
00120 if ( m_pLocked[ nPart ] == 0 ) break;
00121 }
00122 }
00123 }
00124
00125 if ( nPart >= m_nCount ) return FALSE;
00126
00127 m_pLocked[ nPart ] = bResend ? tNow : 0xFFFFFFFF;
00128
00129 DWORD nPacket = m_nPacket + sizeof(SGP_HEADER);
00130
00131 *ppPacket = m_pBuffer->m_pBuffer + ( nPart * nPacket );
00132 *pnPacket = min( nPacket, m_pBuffer->m_nLength - ( nPart * nPacket ) );
00133
00134 return TRUE;
00135 }
00136
00138
00139
00140 BOOL CDatagramOut::Acknowledge(BYTE nPart)
00141 {
00142 if ( nPart > 0 && nPart <= m_nCount && m_nAcked > 0 )
00143 {
00144 if ( m_pLocked[ nPart - 1 ] < 0xFFFFFFFF )
00145 {
00146 m_pLocked[ nPart - 1 ] = 0xFFFFFFFF;
00147
00148 if ( --m_nAcked == 0 ) return TRUE;
00149 }
00150 }
00151
00152 return FALSE;
00153 }