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.

473 lines
19 KiB

  1. /****************************************************************************/
  2. // td.h
  3. //
  4. // Transport driver - portable API.
  5. //
  6. // Copyright (C) 1997-1999 Microsoft Corporation
  7. /****************************************************************************/
  8. #ifndef _H_TD
  9. #define _H_TD
  10. extern "C" {
  11. #ifdef OS_WINCE
  12. #include <winsock.h>
  13. #include <wsasync.h>
  14. #endif
  15. #include <adcgdata.h>
  16. }
  17. #include "objs.h"
  18. #include "cd.h"
  19. #define TRC_FILE "td"
  20. #define TRC_GROUP TRC_GROUP_NETWORK
  21. /****************************************************************************/
  22. /* Define the TD buffer handle type. */
  23. /****************************************************************************/
  24. typedef ULONG_PTR TD_BUFHND;
  25. typedef TD_BUFHND DCPTR PTD_BUFHND;
  26. //
  27. // Internal
  28. //
  29. /****************************************************************************/
  30. /* FSM inputs. */
  31. /****************************************************************************/
  32. #define TD_EVT_TDINIT 0
  33. #define TD_EVT_TDTERM 1
  34. #define TD_EVT_TDCONNECT_IP 2
  35. #define TD_EVT_TDCONNECT_DNS 3
  36. #define TD_EVT_TDDISCONNECT 4
  37. #define TD_EVT_WMTIMER 5
  38. #define TD_EVT_OK 6
  39. #define TD_EVT_ERROR 7
  40. #define TD_EVT_CONNECTWITHENDPOINT 8
  41. #define TD_EVT_DROPLINK 9
  42. #define TD_FSM_INPUTS 10
  43. /****************************************************************************/
  44. /* FSM state definitions. */
  45. /****************************************************************************/
  46. #define TD_ST_NOTINIT 0
  47. #define TD_ST_DISCONNECTED 1
  48. #define TD_ST_WAITFORDNS 2
  49. #define TD_ST_WAITFORSKT 3
  50. #define TD_ST_CONNECTED 4
  51. #define TD_ST_WAITFORCLOSE 5
  52. #define TD_FSM_STATES 6
  53. /****************************************************************************/
  54. /* Send buffer sizes for the private and public queues. These must be */
  55. /* sorted in order of increasing size. Note that the buffer sizes are */
  56. /* chosen to minimize the runtime working set - under normal circumstances */
  57. /* only the two 2000 byte public buffers will be in-use, consuming 1 page */
  58. /* of memory. */
  59. /* */
  60. /* The two 4096-byte public buffers are provided to support virtual channel */
  61. /* data. If VCs are not in use, these buffers are unlikely to be used. */
  62. /* */
  63. /* NOTE: The constant TD_SNDBUF_PUBNUM must reflect the number of */
  64. /* buffers in the TD_SNDBUF_PUBSIZES array. */
  65. /* Similarily TD_SNDBUF_PRINUM must reflect the number of buffers in */
  66. /* the TD_SNDBUF_PRISIZES array. */
  67. /****************************************************************************/
  68. #define TD_SNDBUF_PUBSIZES {2000, 2000, 4096, 4096}
  69. #define TD_SNDBUF_PUBNUM 4
  70. #define TD_SNDBUF_PRISIZES {1024, 512}
  71. #define TD_SNDBUF_PRINUM 2
  72. /****************************************************************************/
  73. /* Limited broadcast address. */
  74. /****************************************************************************/
  75. #define TD_LIMITED_BROADCAST_ADDRESS "255.255.255.255"
  76. /****************************************************************************/
  77. /* Maximum number of bytes TD will receive on a single FD_READ */
  78. /****************************************************************************/
  79. #define TD_MAX_UNINTERRUPTED_RECV (16 * 1024)
  80. // Number of bytes to allocate to the recv buffer.
  81. //
  82. // The recv buffer size should be as large as the largest typical server
  83. // OUTBUF that will come our way (8K minus a bit). Most recv()
  84. // implementations try to copy all the data for a TCP sequence (an entire
  85. // OUTBUF) into the target buffer, if the space is available. This means
  86. // that, for code that can access an unaligned data stream, we can use the
  87. // data bytes straight out of the TD receive buffer most of the time, saving
  88. // a large memcpy to an aligned reassembly buffer.
  89. //
  90. // NOTE: Because of Win2000 bug 392510, we alloc a full 8K but only use
  91. // (8K - 2 bytes) because the MPPC decompression code in core\compress.c
  92. // does not stay within the source data buffer boundary.
  93. #define TD_RECV_BUFFER_SIZE 8192
  94. /****************************************************************************/
  95. /* Macro to trace out all the send buffers and the contents of the send */
  96. /* queue. This is used when a send-buffer error occurs. */
  97. /****************************************************************************/
  98. #if defined(DC_DEBUG) && (TRC_COMPILE_LEVEL < TRC_LEVEL_DIS)
  99. #define TD_TRACE_SENDINFO(level) \
  100. { \
  101. TD_TRACE_SENDBUFS(level, _TD.pubSndBufs, TD_SNDBUF_PUBNUM, "Pub"); \
  102. TD_TRACE_SENDBUFS(level, _TD.priSndBufs, TD_SNDBUF_PRINUM, "Pri"); \
  103. TD_TRACE_SENDQUEUE(level); \
  104. }
  105. #define TD_TRACE_SENDBUFS(level, queue, numBufs, pText) \
  106. { \
  107. DCUINT i; \
  108. for (i = 0; i < numBufs; i++) \
  109. { \
  110. TRCX(level, (TB, _T("%sQ[%u] <%p> pNxt:%p iU:%s ") \
  111. "size:%u pBuf:%p bLTS:%u pDLTS:%p owner %s", \
  112. pText, \
  113. i, \
  114. &queue[i], \
  115. queue[i].pNext, \
  116. queue[i].inUse ? "T" : "F", \
  117. queue[i].size, \
  118. queue[i].pBuffer, \
  119. queue[i].bytesLeftToSend, \
  120. queue[i].pDataLeftToSend, \
  121. queue[i].pOwner)); \
  122. } \
  123. }
  124. #define TD_TRACE_SENDQUEUE(level) \
  125. { \
  126. PTD_SNDBUF_INFO pBuf; \
  127. DCUINT i = 0; \
  128. \
  129. pBuf = _TD.pFQBuf; \
  130. if (NULL == pBuf) \
  131. { \
  132. TRCX(level, (TB, _T("SendQ is empty"))); \
  133. } \
  134. else \
  135. { \
  136. while (NULL != pBuf) \
  137. { \
  138. TRCX(level, (TB, _T("SendQ[%u] <%p> pNxt:%p size:%u bLTS:%u"), \
  139. i, \
  140. pBuf, \
  141. pBuf->pNext, \
  142. pBuf->size, \
  143. pBuf->bytesLeftToSend)); \
  144. pBuf = pBuf->pNext; \
  145. } \
  146. TRCX(level, (TB, _T("End of send queue"))); \
  147. } \
  148. }
  149. #else // defined(DC_DEBUG) && (TRC_COMPILE_LEVEL < TRC_LEVEL_DIS)
  150. #define TD_TRACE_SENDINFO(level)
  151. #endif // defined(DC_DEBUG) && (TRC_COMPILE_LEVEL < TRC_LEVEL_DIS)
  152. /****************************************************************************/
  153. /* Structure: TD_SNDBUF_INFO */
  154. /* */
  155. /* Description: Contains information about a TD send buffer. */
  156. /****************************************************************************/
  157. typedef struct tagTD_SNDBUF_INFO DCPTR PTD_SNDBUF_INFO;
  158. typedef struct tagTD_SNDBUF_INFO
  159. {
  160. PTD_SNDBUF_INFO pNext;
  161. DCBOOL inUse;
  162. DCUINT size;
  163. PDCUINT8 pBuffer;
  164. DCUINT bytesLeftToSend;
  165. PDCUINT8 pDataLeftToSend;
  166. #ifdef DC_DEBUG
  167. PDCTCHAR pOwner;
  168. #endif
  169. } TD_SNDBUF_INFO;
  170. /****************************************************************************/
  171. /* Structure: TD_RECV_BUFFER */
  172. /* */
  173. /* Description: Contains information about the buffer into which TD */
  174. /* receives data from Winsock. */
  175. /****************************************************************************/
  176. typedef struct tagTD_RCVBUF_INFO
  177. {
  178. DCUINT size;
  179. DCUINT dataStart;
  180. DCUINT dataLength;
  181. PDCUINT8 pData;
  182. } TD_RCVBUF_INFO;
  183. /****************************************************************************/
  184. /* Structure: TD_GLOBAL_DATA */
  185. /* */
  186. /* Description: TD global data */
  187. /****************************************************************************/
  188. typedef struct tagTD_GLOBAL_DATA
  189. {
  190. HWND hWnd;
  191. DCUINT fsmState;
  192. HANDLE hGHBN;
  193. SOCKET hSocket; // connection socket
  194. INT_PTR hTimer;
  195. DCBOOL dataInTD;
  196. PTD_SNDBUF_INFO pFQBuf;
  197. TD_SNDBUF_INFO pubSndBufs[TD_SNDBUF_PUBNUM];
  198. TD_SNDBUF_INFO priSndBufs[TD_SNDBUF_PRINUM];
  199. DCUINT recvByteCount;
  200. TD_RCVBUF_INFO recvBuffer;
  201. DCBOOL inFlushSendQueue;
  202. DCBOOL getBufferFailed;
  203. #ifdef OS_WINCE
  204. DCBOOL enableWSRecv;
  205. #if (_WIN32_WCE > 300)
  206. HANDLE hevtAddrChange;
  207. HANDLE hAddrChangeThread;
  208. #endif
  209. #endif // OS_WINCE
  210. #ifdef DC_DEBUG
  211. INT_PTR hThroughputTimer;
  212. DCUINT32 periodSendBytesLeft;
  213. DCUINT32 periodRecvBytesLeft;
  214. DCUINT32 currentThroughput;
  215. #endif /* DC_DEBUG */
  216. } TD_GLOBAL_DATA;
  217. #ifdef DC_DEBUG
  218. /****************************************************************************/
  219. /* State and event descriptions (debug build only) */
  220. /****************************************************************************/
  221. static const DCTCHAR tdStateText[TD_FSM_STATES][50]
  222. = {
  223. _T("TD_ST_NOTINIT"),
  224. _T("TD_ST_DISCONNECTED"),
  225. _T("TD_ST_WAITFORDNS"),
  226. _T("TD_ST_WAITFORSKT"),
  227. _T("TD_ST_CONNECTED"),
  228. _T("TD_ST_WAITFORCLOSE"),
  229. }
  230. ;
  231. static const DCTCHAR tdEventText[TD_FSM_INPUTS][50]
  232. = {
  233. _T("TD_EVT_TDINIT"),
  234. _T("TD_EVT_TDTERM"),
  235. _T("TD_EVT_TDCONNECT_IP"),
  236. _T("TD_EVT_TDCONNECT_DNS"),
  237. _T("TD_EVT_TDDISCONNECT"),
  238. _T("TD_EVT_WMTIMER"),
  239. _T("TD_EVT_OK"),
  240. _T("TD_EVT_ERROR"),
  241. _T("TD_EVT_CONNECTWITHENDPOINT")
  242. }
  243. ;
  244. #endif /* DC_DEBUG */
  245. class CUI;
  246. class CCD;
  247. class CNL;
  248. class CUT;
  249. class CXT;
  250. class CCD;
  251. class CTD
  252. {
  253. public:
  254. CTD(CObjs* objs);
  255. ~CTD();
  256. public:
  257. //
  258. // API functions
  259. //
  260. DCVOID DCAPI TD_Init(DCVOID);
  261. DCVOID DCAPI TD_Term(DCVOID);
  262. DCVOID DCAPI TD_Connect(BOOL bInitateConnect, PDCTCHAR pServerAddress);
  263. DCVOID DCAPI TD_Disconnect(DCVOID);
  264. //
  265. // Abortive disconnect
  266. //
  267. DCVOID DCAPI TD_DropLink(DCVOID);
  268. DCBOOL DCAPI TD_GetPublicBuffer(DCUINT dataLength,
  269. PPDCUINT8 ppBuffer,
  270. PTD_BUFHND pBufHandle);
  271. DCBOOL DCAPI TD_GetPrivateBuffer(DCUINT dataLength,
  272. PPDCUINT8 ppBuffer,
  273. PTD_BUFHND pBufHandle);
  274. DCVOID DCAPI TD_SendBuffer(PDCUINT8 pData,
  275. DCUINT dataLength,
  276. TD_BUFHND bufHandle);
  277. DCVOID DCAPI TD_FreeBuffer(TD_BUFHND bufHandle);
  278. DCUINT DCAPI TD_Recv(PDCUINT8 pData,
  279. DCUINT size);
  280. #ifdef DC_DEBUG
  281. DCVOID DCAPI TD_SetBufferOwner(TD_BUFHND bufHandle, PDCTCHAR pOwner);
  282. #endif
  283. /****************************************************************************/
  284. /* Name: TD_QueryDataAvailable */
  285. /* */
  286. /* Purpose: The return value indicates whether there is data available */
  287. /* in _TD. */
  288. /* */
  289. /* Returns: TRUE if there is data available in TD and FALSE otherwise. */
  290. /* */
  291. /* Operation: This function simply returns the global variable _TD.dataInTD */
  292. /* which is set to TRUE whenever we get a FD_READ from WinSock */
  293. /* and set to FALSE whenever a call to recv returns fewer bytes */
  294. /* than requested. */
  295. /****************************************************************************/
  296. inline DCBOOL DCAPI TD_QueryDataAvailable(DCVOID)
  297. {
  298. DC_BEGIN_FN("TD_QueryDataAvailable");
  299. TRC_DBG((TB, "Data is%s available in TD", _TD.dataInTD ? "" : _T(" NOT")));
  300. DC_END_FN();
  301. return(_TD.dataInTD);
  302. } /* TD_QueryDataAvailable */
  303. #ifdef OS_WINCE
  304. /****************************************************************************/
  305. /* Name: TD_EnableWSRecv */
  306. /* */
  307. /* Purpose: Perform only one recv per FD_READ */
  308. /****************************************************************************/
  309. inline DCVOID TD_EnableWSRecv(DCVOID)
  310. {
  311. DC_BEGIN_FN("TD_EnableWSRecv");
  312. TRC_DBG((TB, _T("_TD.enableWSRecv is currently set to %s."),
  313. _TD.enableWSRecv ? "TRUE" : "FALSE"));
  314. TRC_ASSERT((_TD.enableWSRecv == FALSE),
  315. (TB, _T("_TD.enableWSRecv is incorrectly set!")));
  316. _TD.enableWSRecv = TRUE;
  317. DC_END_FN();
  318. } /* TD_EnableWSRecv */
  319. #endif // OS_WINCE
  320. #ifdef DC_DEBUG
  321. DCVOID DCAPI TD_SetNetworkThroughput(DCUINT32 maxThroughput);
  322. DCUINT32 DCAPI TD_GetNetworkThroughput(DCVOID);
  323. #endif /* DC_DEBUG */
  324. /****************************************************************************/
  325. // TD_GetDataForLength
  326. //
  327. // Macro-function for XT to directly use recv()'d data from the TD data
  328. // buffer. If we have the requested data fully constructed in the receive
  329. // buffer, skip the data and pass back a pointer, otherwise pass back NULL.
  330. /****************************************************************************/
  331. #define TD_GetDataForLength(_len, _ppData, tdinst) \
  332. if ((tdinst)->_TD.recvBuffer.dataLength >= (_len)) { \
  333. *(_ppData) = (tdinst)->_TD.recvBuffer.pData + (tdinst)->_TD.recvBuffer.dataStart; \
  334. (tdinst)->_TD.recvBuffer.dataLength -= (_len); \
  335. if ((tdinst)->_TD.recvBuffer.dataLength == 0) \
  336. /* Used all the data from the recv buffer so reset start pos. */ \
  337. (tdinst)->_TD.recvBuffer.dataStart = 0; \
  338. else \
  339. /* Still some data left in recv buffer. */ \
  340. (tdinst)->_TD.recvBuffer.dataStart += (_len); \
  341. } \
  342. else { \
  343. *(_ppData) = NULL; \
  344. }
  345. #define TD_IgnoreRestofPacket(tdinst) \
  346. { \
  347. (tdinst)->_TD.recvBuffer.dataLength = 0; \
  348. (tdinst)->_TD.recvBuffer.dataStart = 0; \
  349. }
  350. unsigned DCINTERNAL TDDoWinsockRecv(BYTE FAR *, unsigned);
  351. void DCINTERNAL TDClearSendQueue(ULONG_PTR);
  352. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CTD, TDClearSendQueue);
  353. void DCINTERNAL TDSendError(ULONG_PTR);
  354. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CTD, TDSendError);
  355. public:
  356. //
  357. // public data members
  358. //
  359. TD_GLOBAL_DATA _TD;
  360. private:
  361. //
  362. // Internal member functions
  363. //
  364. /****************************************************************************/
  365. /* FUNCTIONS */
  366. /****************************************************************************/
  367. DCVOID DCINTERNAL TDConnectFSMProc(DCUINT fsmEvent, ULONG_PTR eventData);
  368. DCVOID DCINTERNAL TDAllocBuf(PTD_SNDBUF_INFO pSndBufInf, DCUINT size);
  369. DCVOID DCINTERNAL TDInitBufInfo(PTD_SNDBUF_INFO pSndBufInf);
  370. #include "wtdint.h"
  371. public:
  372. //Can be called by CD so has to be public
  373. void DCINTERNAL TDFlushSendQueue(ULONG_PTR);
  374. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CTD, TDFlushSendQueue);
  375. private:
  376. CNL* _pNl;
  377. CUT* _pUt;
  378. CXT* _pXt;
  379. CUI* _pUi;
  380. CCD* _pCd;
  381. private:
  382. CObjs* _pClientObjects;
  383. };
  384. #undef TRC_FILE
  385. #undef TRC_GROUP
  386. #endif // _H_TD