Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

298 lines
12 KiB

  1. /*
  2. ** Direct Network Protocol
  3. **
  4. ** This file contains internal prototypes and global definitions.
  5. */
  6. // Protocol Version History /////////////////////////////////////////////////////////////
  7. //
  8. // 1.0 - DPlay8 original
  9. // 1.1 - Fix SACK frame bogus 2 bytes caused by bad packing (DPlay 8.1 beta period only)
  10. // 1.2 - Revert to original sack behavior with packing fixed, ie same as DPlay 8.0 (shipped in DPlay 8.1)
  11. // 1.3 - Increment for PocketPC release (RTM prior to DX9 Beta1)
  12. // 1.4 - DX9 Beta1 only
  13. // 1.5 - Add coalescence and hard disconnect support
  14. // 1.5 - .NET Server RTM
  15. // 1.6 - Added packet signing, new style keep alive and connection spoof prevention
  16. // 1.6 - DX9 Beta2 through RTM
  17. /////////////////////////////////////////////////////////////////////////////////////////
  18. // Global Constants
  19. #define DNET_VERSION_NUMBER 0x00010005 // The current protocol version
  20. #define DNET_COALESCE_VERSION 0x00010005 // The first version with coalescence
  21. #define DNET_SIGNING_VERSION 0x00010006 // The first version with signing
  22. #define DELAYED_ACK_TIMEOUT 100 // Delay before sending dedicated ACK packet
  23. #define SHORT_DELAYED_ACK_TIMEOUT 20 // Delay before sending dedicated NACK packet
  24. #define DELAYED_SEND_TIMEOUT 40 // Delay before sending dedicated SEND_INFO packet
  25. #define CONNECT_DEFAULT_TIMEOUT (200) // At .1 we saw too many retries, users can set in SetCaps
  26. #define CONNECT_DEFAULT_RETRIES 14 // Users can set in SetCaps
  27. #define DEFAULT_MAX_RECV_MSG_SIZE 0xFFFFFFFF //default maximum packet we accept
  28. #define DEFAULT_SEND_RETRIES_TO_DROP_LINK 10 //default number of send retries we attempt before link is dead
  29. #define DEFAULT_SEND_RETRY_INTERVAL_LIMIT 5000 //limit on period in msec between retries
  30. #define DEFAULT_HARD_DISCONNECT_SENDS 3 //default number of hard disconnect frames we send out
  31. //The value must be at least 2.
  32. #define DEFAULT_HARD_DISCONNECT_MAX_PERIOD 500 //The default for the maximum period we allow between
  33. //sending out hard disconnect frames
  34. #define DEFAULT_INITIAL_FRAME_WINDOW_SIZE 2 //The default initial frame window size
  35. #define LAN_INITIAL_FRAME_WINDOW_SIZE 32 //The initial frame window size if we asssume a LAN connection
  36. #define STANDARD_LONG_TIMEOUT_VALUE 30000
  37. #define DEFAULT_KEEPALIVE_INTERVAL 60000
  38. #define ENDPOINT_BACKGROUND_INTERVAL STANDARD_LONG_TIMEOUT_VALUE // this is really what its for...
  39. #define CONNECT_SECRET_CHANGE_INTERVAL 60000 //period between creations of new connect secrets
  40. #define DEFAULT_THROTTLE_BACK_OFF_RATE 25 // Percent throttle (backoff) rate
  41. #define DEFAULT_THROTTLE_THRESHOLD_RATE 7 // Percent packets dropped (out of 32)
  42. #define DPF_TIMER_LVL 9 // The level at which to spew calls into the Protocol
  43. #define DPF_CALLIN_LVL 2 // The level at which to spew calls into the Protocol
  44. #define DPF_CALLOUT_LVL 3 // The level at which to spew calls out of the Protocol
  45. #define DPF_ADAPTIVE_LVL 6 // The level at which to spew Adaptive Algorithm spew
  46. #define DPF_FRAMECNT_LVL 7 // The level at which to spew Adaptive Algorithm spew
  47. #define DPF_REFCNT_LVL 8 // The level at which to spew ref counts
  48. #define DPF_REFCNT_FINAL_LVL 5 // The level at which to spew creation and destruction ref counts
  49. // Separate ones for endpoints
  50. #define DPF_EP_REFCNT_LVL 8 // The level at which to spew ref counts
  51. #define DPF_EP_REFCNT_FINAL_LVL 2 // The level at which to spew creation and destruction ref counts
  52. #undef DPF_SUBCOMP
  53. #define DPF_SUBCOMP DN_SUBCOMP_PROTOCOL
  54. //handy macro for dumping a ULONGLONG out to a debug line
  55. #define DPFX_OUTPUT_ULL(ull) ((DWORD ) ull) , ((DWORD ) (ull>>32))
  56. typedef void CALLBACK LPCB(UINT, UINT, DWORD, DWORD, DWORD);
  57. // Global Variable definitions
  58. extern CFixedPool ChkPtPool;
  59. extern CFixedPool EPDPool;
  60. extern CFixedPool MSDPool;
  61. extern CFixedPool FMDPool;
  62. extern CFixedPool RCDPool;
  63. extern CFixedPool BufPool;
  64. extern CFixedPool MedBufPool;
  65. extern CFixedPool BigBufPool;
  66. // Pool functions
  67. BOOL Buf_Allocate(PVOID, PVOID pvContext);
  68. VOID Buf_Get(PVOID, PVOID pvContext);
  69. VOID Buf_GetMed(PVOID, PVOID pvContext);
  70. VOID Buf_GetBig(PVOID, PVOID pvContext);
  71. BOOL EPD_Allocate(PVOID, PVOID pvContext);
  72. VOID EPD_Get(PVOID, PVOID pvContext);
  73. VOID EPD_Release(PVOID);
  74. VOID EPD_Free(PVOID);
  75. BOOL FMD_Allocate(PVOID, PVOID pvContext);
  76. VOID FMD_Get(PVOID, PVOID pvContext);
  77. VOID FMD_Release(PVOID);
  78. VOID FMD_Free(PVOID);
  79. BOOL MSD_Allocate(PVOID, PVOID pvContext);
  80. VOID MSD_Get(PVOID, PVOID pvContext);
  81. VOID MSD_Release(PVOID);
  82. VOID MSD_Free(PVOID);
  83. BOOL RCD_Allocate(PVOID, PVOID pvContext);
  84. VOID RCD_Get(PVOID, PVOID pvContext);
  85. VOID RCD_Release(PVOID);
  86. VOID RCD_Free(PVOID);
  87. #ifdef DBG
  88. extern CBilink g_blProtocolCritSecsHeld;
  89. #endif // DBG
  90. // Internal function prototypes /////////////////////////////////
  91. // Timers
  92. VOID CALLBACK ConnectRetryTimeout(void * const pvUser, void * const pvHandle, const UINT uiUnique);
  93. VOID CALLBACK DelayedAckTimeout(void * const pvUser, void * const uID, const UINT uMsg);
  94. VOID CALLBACK EndPointBackgroundProcess(void * const pvUser, void * const pvTimerData, const UINT uiTimerUnique);
  95. VOID CALLBACK RetryTimeout(void * const pvUser, void * const uID, const UINT Unique);
  96. VOID CALLBACK ScheduledSend(void * const pvUser, void * const pvTimerData, const UINT uiTimerUnique);
  97. VOID CALLBACK TimeoutSend(void * const pvUser, void * const uID, const UINT uMsg);
  98. VOID CALLBACK HardDisconnectResendTimeout(void * const pvUser, void * const pvTimerData, const UINT uiTimerUnique);
  99. VOID AbortSendsOnConnection(PEPD);
  100. SPRECEIVEDBUFFER * AbortRecvsOnConnection(PEPD);
  101. VOID CancelEpdTimers(PEPD);
  102. ULONG WINAPI BackgroundThread(PVOID);
  103. HRESULT DoCancel(PMSD, HRESULT);
  104. VOID CompleteConnect(PMSD, PSPD, PEPD, HRESULT);
  105. VOID CompleteDisconnect(PMSD pMSD, PSPD pSPD, PEPD pEPD);
  106. VOID CompleteHardDisconnect(PEPD pEPD);
  107. VOID CompleteDatagramSend(PSPD, PMSD, HRESULT);
  108. VOID CompleteReliableSend(PSPD, PMSD, HRESULT);
  109. VOID CompleteSPConnect(PMSD, PSPD, HRESULT);
  110. VOID DisconnectConnection(PEPD);
  111. VOID DropLink(PEPD);
  112. PMSD BuildDisconnectFrame(PEPD);
  113. VOID EndPointDroppedFrame(PEPD, DWORD);
  114. VOID EnqueueMessage(PMSD, PEPD);
  115. VOID FlushCheckPoints(PEPD);
  116. VOID InitLinkParameters(PEPD, UINT, DWORD);
  117. PCHKPT LookupCheckPoint(PEPD, BYTE);
  118. PEPD NewEndPoint(PSPD, HANDLE);
  119. VOID SendKeepAlive(PEPD pEPD);
  120. VOID ReceiveComplete(PEPD);
  121. VOID SendAckFrame(PEPD, BOOL, BOOL fFinalAck = FALSE);
  122. HRESULT SendCommandFrame(PEPD, BYTE, BYTE, ULONG, BOOL);
  123. HRESULT SendConnectedSignedFrame(PEPD pEPD, CFRAME_CONNECTEDSIGNED * pCFrameRecv, DWORD tNow);
  124. ULONG WINAPI SendThread(PVOID);
  125. VOID ServiceCmdTraffic(PSPD);
  126. VOID ServiceEPD(PSPD, PEPD);
  127. VOID UpdateEndPoint(PEPD, UINT, DWORD);
  128. VOID UpdateXmitState(PEPD, BYTE, ULONG, ULONG, DWORD);
  129. VOID RejectInvalidPacket(PEPD);
  130. ULONGLONG GenerateConnectSig(DWORD dwSessID, DWORD dwAddressHash, ULONGLONG ullConnectSecret);
  131. ULONGLONG GenerateOutgoingFrameSig(PFMD pFMD, ULONGLONG ullSecret);
  132. ULONGLONG GenerateIncomingFrameSig(BYTE * pbyFrame, DWORD dwFrameSize, ULONGLONG ullSecret);
  133. ULONGLONG GenerateNewSecret(ULONGLONG ullCurrentSecret, ULONGLONG ullSecretModifier);
  134. ULONGLONG GenerateLocalSecretModifier(BUFFERDESC * pBuffers, DWORD dwNumBuffers);
  135. ULONGLONG GenerateRemoteSecretModifier(BYTE * pbyData, DWORD dwDataSize);
  136. //returns TRUE if supplied protocol version number indicates signing is supported
  137. inline BOOL VersionSupportsSigning(DWORD dwVersion)
  138. {
  139. return (((dwVersion>>16)==1) && ((dwVersion & 0xFFFF) >= (DNET_SIGNING_VERSION & 0xFFFF)));
  140. }
  141. //returns TRUE if supplied protocol version number indicates coalescence is supported
  142. inline BOOL VersionSupportsCoalescence(DWORD dwVersion)
  143. {
  144. return (((dwVersion>>16)==1) && ((dwVersion & 0xFFFF) >= (DNET_COALESCE_VERSION & 0xFFFF)));
  145. }
  146. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  147. extern PFNASSERTFUNC g_pfnAssertFunc;
  148. extern PFNMEMALLOCFUNC g_pfnMemAllocFunc;
  149. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  150. // Internal Macro definitions
  151. #undef ASSERT
  152. #ifndef DBG
  153. #define ASSERT(EXP) DNASSERT(EXP)
  154. #else // DBG
  155. #define ASSERT(EXP) \
  156. if (!(EXP)) \
  157. { \
  158. if (g_pfnAssertFunc) \
  159. { \
  160. g_pfnAssertFunc(#EXP); \
  161. } \
  162. DNASSERT(EXP); \
  163. }
  164. #endif // !DBG
  165. #ifdef DPNBUILD_NOPROTOCOLTESTITF
  166. #define MEMALLOC(memid, dwpSize) DNMalloc(dwpSize)
  167. #define POOLALLOC(memid, pool) (pool)->Get()
  168. #else // !DPNBUILD_NOPROTOCOLTESTITF
  169. #define MEMALLOC(memid, dwpSize) MemAlloc(memid, dwpSize)
  170. #define POOLALLOC(memid, pool) PoolAlloc(memid, pool)
  171. __inline VOID* MemAlloc(ULONG ulAllocID, DWORD_PTR dwpSize)
  172. {
  173. if (g_pfnMemAllocFunc)
  174. {
  175. if (!g_pfnMemAllocFunc(ulAllocID))
  176. {
  177. return NULL;
  178. }
  179. }
  180. return DNMalloc(dwpSize);
  181. }
  182. __inline VOID* PoolAlloc(ULONG ulAllocID, CFixedPool* pPool)
  183. {
  184. if (g_pfnMemAllocFunc)
  185. {
  186. if (!g_pfnMemAllocFunc(ulAllocID))
  187. {
  188. return NULL;
  189. }
  190. }
  191. return pPool->Get();
  192. }
  193. #endif // DPNBUILD_NOPROTOCOLTESTITF
  194. #define Lock(P) DNEnterCriticalSection(P)
  195. #define Unlock(P) DNLeaveCriticalSection(P)
  196. #define ASSERT_PPD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == PPD_SIGN)
  197. #define ASSERT_SPD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == SPD_SIGN)
  198. #define ASSERT_EPD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == EPD_SIGN)
  199. #define ASSERT_MSD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == MSD_SIGN)
  200. #define ASSERT_FMD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == FMD_SIGN)
  201. #define ASSERT_RCD(PTR) ASSERT((PTR) != NULL); ASSERT((PTR)->Sign == RCD_SIGN)
  202. #define INTER_INC(PTR) DNInterlockedIncrement(&(PTR)->lRefCnt)
  203. #define INTER_DEC(PTR) DNInterlockedDecrement(&(PTR)->lRefCnt)
  204. #ifdef DBG
  205. VOID LockEPD(PEPD, PTSTR);
  206. VOID ReleaseEPD(PEPD, PTSTR);
  207. VOID DecrementEPD(PEPD, PTSTR);
  208. VOID LockMSD(PMSD, PTSTR);
  209. VOID ReleaseMSD(PMSD, PTSTR);
  210. VOID DecrementMSD(PMSD, PTSTR);
  211. VOID ReleaseFMD(PFMD, PTSTR);
  212. VOID LockFMD(PFMD, PTSTR);
  213. #define LOCK_EPD(a, b) LockEPD(a, _T(b))
  214. #define RELEASE_EPD(a, b) ReleaseEPD(a, _T(b))
  215. #define DECREMENT_EPD(a, b) DecrementEPD(a, _T(b))
  216. #define LOCK_MSD(a, b) LockMSD(a, _T(b))
  217. #define RELEASE_MSD(a, b) ReleaseMSD(a, _T(b))
  218. #define DECREMENT_MSD(a, b) DecrementMSD(a, _T(b))
  219. #define RELEASE_FMD(a, b) ReleaseFMD(a, _T(b))
  220. #define LOCK_FMD(a, b) LockFMD(a, _T(b))
  221. #else // !DBG
  222. VOID LockEPD(PEPD);
  223. VOID ReleaseEPD(PEPD);
  224. VOID DecrementEPD(PEPD);
  225. VOID LockMSD(PMSD);
  226. VOID ReleaseMSD(PMSD);
  227. VOID DecrementMSD(PMSD);
  228. VOID ReleaseFMD(PFMD);
  229. VOID LockFMD(PFMD);
  230. #define LOCK_EPD(a, b) LockEPD(a)
  231. #define RELEASE_EPD(a, b) ReleaseEPD(a)
  232. #define DECREMENT_EPD(a, b) DecrementEPD(a)
  233. #define LOCK_MSD(a, b) LockMSD(a)
  234. #define RELEASE_MSD(a, b) ReleaseMSD(a)
  235. #define DECREMENT_MSD(a, b) DecrementMSD(a)
  236. #define RELEASE_FMD(a, b) ReleaseFMD(a)
  237. #define LOCK_FMD(a, b) LockFMD(a)
  238. #endif // DBG
  239. #define LOCK_RCD(PTR) (INTER_INC(PTR))
  240. #define RELEASE_RCD(PTR) ASSERT((PTR)->lRefCnt > 0); if( INTER_DEC(PTR) == 0) { RCDPool.Release((PTR)); }
  241. // This links the passed in pRcvBuff onto a passed in list
  242. #define RELEASE_SP_BUFFER(LIST, PTR) if((PTR) != NULL) { (PTR)->pNext = (LIST); (LIST) = (PTR); (PTR) = NULL;}
  243. #define RIGHT_SHIFT_64(HIGH_MASK, LOW_MASK) { ((LOW_MASK) >>= 1); if((HIGH_MASK) & 1){ (LOW_MASK) |= 0x80000000; } ((HIGH_MASK) >>= 1); }
  244. // CONVERT TO AND FROM 16.16 FIXED POINT REPRESENTATION
  245. #define TO_FP(X) (((X) << 16) & 0xFFFF0000)
  246. #define FP_INT(X) (((X) >> 16) & 0x0000FFFF)