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.

812 lines
37 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1998-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DnProt.h
  6. * Content: This file contains structure definitions for the Direct Net protocol
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 11/06/98 ejs Created
  12. * 07/01/2000 masonb Assumed Ownership
  13. *
  14. ****************************************************************************/
  15. #ifndef _DNPROT_INCLUDED_
  16. #define _DNPROT_INCLUDED_
  17. #define VOL volatile
  18. /*
  19. ** Internal Constants
  20. */
  21. //frames come in 1 of 2 forms, either data frames or cframes.
  22. //cframes
  23. //cframes come in 3 different sizes.
  24. //connect, connected and hard disconnect are all just a single CFRAME header. If the link is signed then hard disconnect frames
  25. //will also be followed by a signature value. On the wire these therefore look like:
  26. //<CFRAME header><optional signature (8 bytes)>
  27. //connected_signed frames extend the standard CFRAME with a fixed number of additional members. On the wire these frames look like:
  28. //<CFRAME_CONNECTEDSIGNED header>
  29. //sackframes have a fixed initial header and then between 0 and 4 ULONG values giving sack/send masks. If they're sent over
  30. //a signed link they also have a signature value appended. On the wire these frames look like:
  31. //<SACKFRAME header><optional sack/send masks (0 to 16 bytes)><optional signature (8 bytes)>
  32. //These define the largest possible size of header for each cframe type
  33. #define MAX_SEND_CFRAME_STANDARD_HEADER_SIZE (sizeof(CFRAME)+sizeof(ULONGLONG))
  34. #define MAX_SEND_CFRAME_CONNECTEDSIGNED_HEADER_SIZE (sizeof(CFRAME_CONNECTEDSIGNED))
  35. #define MAX_SEND_CFRAME_SACKFRAME_HEADER_SIZE (sizeof(SACKFRAME8)+sizeof(ULONG)*4+sizeof(ULONGLONG))
  36. //These respectively define the size of the smallest and largest possible cframe header
  37. #define MIN_SEND_CFRAME_HEADER_SIZE (_MIN(sizeof(SACKFRAME8), _MIN(sizeof(CFRAME), sizeof(CFRAME_CONNECTEDSIGNED))))
  38. #define MAX_SEND_CFRAME_HEADER_SIZE (_MAX(MAX_SEND_CFRAME_CONNECTEDSIGNED_HEADER_SIZE, _MAX(MAX_SEND_CFRAME_STANDARD_HEADER_SIZE, MAX_SEND_CFRAME_SACKFRAME_HEADER_SIZE)))
  39. //dframes
  40. //All dframes have a single fixed initial header (DFRAME). Depending on the data encapsulated there may be a number of additional
  41. //variable length data blocks following this.
  42. //Firstly, there may be 0 to 4 ULONG values giving sack/send masks. The presence or absence of these is determined by
  43. //the PACKET_CONTROL_SACK_MASK1/2 and PACKET_CONTROL_SEND_MASK1/2 bit flags within the bControl member of the DFRAME header
  44. //For a non-coalesced data message, there may then follow a signature (for signed links), followed by all the use data.
  45. //Hence, the packet on the wire looks like:
  46. //<DFRAME header><optional sack/send masks (0 to 16 bytes)><optional signature (8 bytes)><user data>
  47. //A coalesced data message is identified by the PACKET_CONTROL_COALESCE bit flag being set in the bControl member of the DFRAME header
  48. //For a coalesced data message, following the optional masks is an optional signature field (for a signed link). After this
  49. //is a set of coalesce headers. There are between 2 and MAX_USER_BUFFERS_IN_FRAME of these. Finally, at the end of the frame
  50. //is the coalesced user data. If necessary padding is inserted before and between the user data to ensure each block of user data
  51. //is DWORD aligned.
  52. //Hence, on the wire a coalesced data packet looks like:
  53. //<DFRAME header><optional sack/send masks (0 to 16 bytes)><optional signature (8 bytes)><coalesce header (2 bytes)>
  54. // <coalesce header (2 bytes)>.......<padding (0 or 2 bytes)><user data><padding (0 to 3 bytes)><user data>........
  55. //Finally, a dframe may be a keep alive, and not contain any user data at all. These frames are identified by the PACKET_CONTROL_KEEPALIVE
  56. //flag being flipped on in the frames bControl field. A keep alive contains the optional sack/send masks, a signature if the link is signed
  57. //and the session identity.
  58. //On the wire a keep alive packet looks like:
  59. //<DFRAME header><optional sack/send masks (0 to 16 bytes)><optional signature (8 bytes)><session identity (4 bytes)>
  60. //This defines the maximum number of user buffers we can send in a coalesced dframe
  61. #define MAX_USER_BUFFERS_IN_FRAME 32 // this number * sizeof(COALESCEHEADER) should stay DWORD aligned
  62. //This defines the maximum size of a user buffer than can be placed in a coalesced message
  63. //Anything larger than this can't be coalesced. For most SPs (i.e. IP) since we use an MTU smaller than this, we never
  64. //get close to reaching this value anyway
  65. #define MAX_COALESCE_SIZE 2047 // 1 byte + 3 bits = 11 bits worth of data
  66. //These define the largest possible size of header for each dframe type
  67. #define MAX_SEND_DFRAME_NOCOALESCE_HEADER_SIZE (sizeof(DFRAME)+sizeof(ULONG)*4+sizeof(ULONGLONG))
  68. #define MAX_SEND_DFRAME_COALESCE_HEADER_SIZE (sizeof(DFRAME)+sizeof(ULONG)*4+(MAX_USER_BUFFERS_IN_FRAME * sizeof(COALESCEHEADER))+(MAX_USER_BUFFERS_IN_FRAME * 3)+sizeof(ULONGLONG))
  69. #define MAX_SEND_DFRAME_KEEPALIVE_HEADER_SIZE (sizeof(DFRAME)+sizeof(ULONG)*4+sizeof(ULONG)+sizeof(ULONGLONG))
  70. //These respectively define the size of the smallest and the largest possible dframe header.
  71. #define MIN_SEND_DFRAME_HEADER_SIZE (sizeof(DFRAME))
  72. #define MAX_SEND_DFRAME_HEADER_SIZE (_MAX(MAX_SEND_DFRAME_NOCOALESCE_HEADER_SIZE, _MAX(MAX_SEND_DFRAME_COALESCE_HEADER_SIZE, MAX_SEND_DFRAME_KEEPALIVE_HEADER_SIZE)))
  73. //This defines the largest protocol header we can create.
  74. //Its the largest value out of the biggest possible cframe header and the biggest possible dframe header
  75. #define MAX_SEND_HEADER_SIZE (_MAX(MAX_SEND_DFRAME_HEADER_SIZE, MAX_SEND_CFRAME_HEADER_SIZE))
  76. //We must be able to send our largest cframe as a single packet and a keep alive as a single packet
  77. //N.B. since a keep alive is a standard DFRAME with a 4 byte payload this also guarantees we can send a none coalesced dframe
  78. #define MIN_SEND_MTU (_MAX(MAX_SEND_CFRAME_HEADER_SIZE, MAX_SEND_DFRAME_KEEPALIVE_HEADER_SIZE))
  79. #define SMALL_BUFFER_SIZE (1024 * 2)
  80. #define MEDIUM_BUFFER_SIZE (1024 * 4)
  81. #define LARGE_BUFFER_SIZE (1024 * 16)
  82. /*
  83. ** Signatures for data structures
  84. */
  85. #define PPD_SIGN ' DPP' // Protocol Data
  86. #define SPD_SIGN ' DPS' // Service Provider Descriptor
  87. #define EPD_SIGN ' DPE' // End Point Descriptor
  88. #define MSD_SIGN ' DSM' // Message Descriptor
  89. #define FMD_SIGN ' DMF' // Frame Descriptor
  90. #define RCD_SIGN ' DCR' // Receive Descriptor
  91. /*
  92. ** Internal Data Structures
  93. **
  94. */
  95. typedef struct protocoldata ProtocolData, *PProtocolData;
  96. typedef struct spdesc SPD, *PSPD;
  97. typedef struct endpointdesc EPD, *PEPD;
  98. typedef struct checkptdata CHKPT, *PCHKPT;
  99. typedef struct messagedesc MSD, *PMSD;
  100. typedef struct framedesc FMD, *PFMD;
  101. typedef struct recvdesc RCD, *PRCD;
  102. typedef struct _DN_PROTOCOL_INTERFACE_VTBL DN_PROTOCOL_INTERFACE_VTBL, *PDN_PROTOCOL_INTERFACE_VTBL;
  103. /*
  104. ** Protocol Data
  105. **
  106. ** This structure contains all of the global state information for the
  107. ** operating protocol. It is grouped into a structure for (in)convenience
  108. ** against the unlikely possibility that we ever need to run multiple instances
  109. ** out of the same code.
  110. */
  111. #define PFLAGS_PROTOCOL_INITIALIZED 0x00000001
  112. #define PFLAGS_FAIL_SCHEDULE_TIMER 0x00000002 //DEBUG flag. Allows scheduling of timers to be failed
  113. struct protocoldata
  114. {
  115. ULONG ulProtocolFlags; // State info about DN protocol
  116. PVOID Parent; // Direct Play Object
  117. UINT Sign;
  118. LONG lSPActiveCount; // Number of SPs currently bound to protocol
  119. DWORD tIdleThreshhold; // How long will we allow a link to be idle before Checkpointing
  120. DWORD dwConnectTimeout; // These two parameter control new connection commands
  121. DWORD dwConnectRetries;
  122. DWORD dwMaxRecvMsgSize; //largest message we accept on a receive
  123. DWORD dwSendRetriesToDropLink; //number of send retry attempts before
  124. //we decide link has died
  125. DWORD dwSendRetryIntervalLimit; //limit for the period between send retries
  126. DWORD dwDropThresholdRate; // Percentage of frames allowed to drop before throttling
  127. DWORD dwDropThreshold; // Actual number of frames allowed to drop before throttling
  128. DWORD dwThrottleRate; // Percentage backoff when throttling
  129. FLOAT fThrottleRate; // Actual backoff when throttling (0.0 - 1.0)
  130. DWORD dwNumHardDisconnectSends; // Number of hard disconnect frames sent when hard closing
  131. DWORD dwMaxHardDisconnectPeriod; // Maximum period between hard disconnect sends
  132. DWORD dwInitialFrameWindowSize; // Size of the initial frame window for a connection
  133. PDN_PROTOCOL_INTERFACE_VTBL pfVtbl; // Table of indication entry points in CORE
  134. IDirectPlay8ThreadPoolWork *pDPThreadPoolWork; // Pointer to thread pool interface
  135. #ifdef DBG
  136. // For Debugging we will track the total number of receives outstanding in the higher layers
  137. // at all times.
  138. long ThreadsInReceive;
  139. long BuffersInReceive;
  140. #endif // DBG
  141. };
  142. /*
  143. ** Service Provider Descriptor
  144. **
  145. ** This structure describes a Service Provider that we are bound to. It
  146. ** contains at a minimum the vector table to call the SP, and the SPID that
  147. ** is combined with player IDs to make external DPIDs. The SPID should also
  148. ** be the index in the SPTable where this descriptor lives.
  149. **
  150. ** We will have one send thread per service provider, so the thread handle
  151. ** and its wait-event will live in this structure too.
  152. **
  153. ** Lower Edge Protocol Object
  154. **
  155. ** We will also use the SPD as the COM Object given to SP for our lower edge
  156. ** interface. This means that our Lower Vector Table must be the first field in
  157. ** this structure, and ref count must be second.
  158. */
  159. // The following are functions that the Service Providers can call in the Protocol
  160. extern HRESULT WINAPI DNSP_IndicateEvent(IDP8SPCallback*, SP_EVENT_TYPE, PVOID);
  161. extern HRESULT WINAPI DNSP_CommandComplete(IDP8SPCallback*, HANDLE, HRESULT, PVOID);
  162. #define SPFLAGS_SEND_THREAD_SCHEDULED 0x0001 // SP has scheduled a thread to service command frames
  163. #define SPFLAGS_TERMINATING 0x4000 // SP is being removed
  164. struct spdesc
  165. {
  166. IDP8SPCallbackVtbl *LowerEdgeVtable; // table used by this SP to call into us, MUST BE FIRST!!!
  167. UINT Sign;
  168. ULONG ulSPFlags; // Flags describing this service provider
  169. IDP8ServiceProvider *IISPIntf; // ptr to SP Object
  170. PProtocolData pPData; // Ptr to owning protocol object
  171. UINT uiFrameLength; // Frame size available to us
  172. UINT uiUserFrameLength; // Frame size available to application
  173. UINT uiLinkSpeed; // Local link speed in BPS
  174. CBilink blSendQueue; // List of wire-ready packets to transmit over this SP
  175. CBilink blPendingQueue; // List of packets owned by SP - Shares Lock w/SendQ
  176. CBilink blEPDActiveList; // List of in use End Point Descriptors for this SP
  177. #ifndef DPNBUILD_ONLYONETHREAD
  178. DNCRITICAL_SECTION SPLock; // Guard access to sendQ
  179. #endif // !DPNBUILD_ONLYONETHREAD
  180. #ifdef DBG
  181. CBilink blMessageList; // List of in use Message Descriptors
  182. #endif // DBG
  183. };
  184. /*
  185. ** End Point Descriptor
  186. **
  187. ** An 'EPD' describes a Direct Network instance that we can communicate with.
  188. ** This structure includes all session related information, statistics, queues, etc.
  189. ** It will manage any of the three types of service simultaneously.
  190. */
  191. #define EPFLAGS_END_POINT_IN_USE 0x0001 // This EndPoint is allocated
  192. // We are always in exactly one of these 4 states
  193. #define EPFLAGS_STATE_DORMANT 0x0002 // Connection protocol has not yet run
  194. #define EPFLAGS_STATE_CONNECTING 0x0004 // Attempting to establish reliable link
  195. #define EPFLAGS_STATE_CONNECTED 0x0008 // Reliable link established
  196. #define EPFLAGS_STATE_TERMINATING 0x0010 // This end point is being closed down
  197. #define EPFLAGS_SP_DISCONNECTED 0x0020 // Set when the SP has called ProcessSPDisconnect
  198. #define EPFLAGS_IN_RECEIVE_COMPLETE 0x0040 // A thread is running in ReceiveComplete routine
  199. #define EPFLAGS_LINKED_TO_LISTEN 0x0080 // During CONNECT this EPD is linked into the Listen MSD's queue
  200. #define EPFLAGS_LINK_STABLE 0x0100 // We think we have found the best current transmit parameters
  201. #define EPFLAGS_STREAM_UNBLOCKED 0x0200 // Reliable traffic is stopped (window or throttle)
  202. #define EPFLAGS_SDATA_READY 0x0400 // Reliable traffic in the pipe
  203. #define EPFLAGS_IN_PIPELINE 0x0800 // Indicates that EPD is in the SPD pipeline queue
  204. #define EPFLAGS_CHECKPOINT_INIT 0x1000 // Need to send a check point packet
  205. #define EPFLAGS_DELAYED_SENDMASK 0x2000 // unacked check point on wire
  206. #define EPFLAGS_DELAYED_NACK 0x4000 // Need to send masks for missing receives
  207. #define EPFLAGS_DELAY_ACKNOWLEDGE 0x8000 // We are waiting for back-traffic before sending ACK frame
  208. #define EPFLAGS_KEEPALIVE_RUNNING 0x00010000 // Checkpoint is running (borrowed in debug to turn off keepalives)
  209. #define EPFLAGS_SENT_DISCONNECT 0x00020000 // We have sent a DISCONNECT and are waiting for confirm
  210. #define EPFLAGS_RECEIVED_DISCONNECT 0x00040000 // We have received a DISCONNECT and will send confirm when done sending
  211. #define EPFLAGS_DISCONNECT_ACKED 0x00080000 // We sent a DISCONNECT and it has been confirmed
  212. #define EPFLAGS_COMPLETE_SENDS 0x00100000 // There are Reliable MSDs waiting to be called back
  213. #define EPFLAGS_FILLED_WINDOW_BYTE 0x00200000 // Filled Byte-Based send window
  214. #define EPFLAGS_FILLED_WINDOW_FRAME 0x00400000 // We have filled the frame-based SendWindow at least once during last period
  215. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  216. #define EPFLAGS_NO_DELAYED_ACKS 0x00800000 // DEBUG_FLAG -- Turn off DelayedAckTimeout
  217. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  218. #define EPFLAGS_ACKED_DISCONNECT 0x01000000 // Partner sent a DISCONNECT and we have confirmed it
  219. #define EPFLAGS_RETRIES_QUEUED 0x02000000 // Frames are waiting for retransmission
  220. #define EPFLAGS_THROTTLED_BACK 0x04000000 // temporary throttle is engaged to relieve congestion
  221. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  222. #define EPFLAGS_LINK_FROZEN 0x08000000 // DEBUG FLAG -- Do not run dynamic algorithm on this link
  223. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  224. #define EPFLAGS_INDICATED_DISCONNECT 0x10000000 // Ensure that we onlly call CORE once to indicate disconnection
  225. #define EPFLAGS_TESTING_GROWTH 0x20000000 // We are currently taking a growth sample
  226. #define EPFLAGS_HARD_DISCONNECT_SOURCE 0x40000000 // We're the source for a hard disconnect sequence
  227. // i.e. Core has instigated a hard close on this ep
  228. #define EPFLAGS_HARD_DISCONNECT_TARGET 0x80000000 // We're the target for a hard disconnect sequence
  229. // i.e. We're received a hard disconnect request from remote ep
  230. #define MAX_RECEIVE_RANGE 64 // largest # of frames we will retain past a missing frame
  231. #define MAX_FRAME_OFFSET (MAX_RECEIVE_RANGE - 1)
  232. //sequence window as split into 4 quarters
  233. #define SEQ_WINDOW_1Q 64
  234. #define SEQ_WINDOW_2Q 128
  235. #define SEQ_WINDOW_3Q 192
  236. #define SEQ_WINDOW_4Q 256
  237. #define INITIAL_STATIC_PERIOD (10 * 1000) // How long does link remain static after finding set-point.
  238. // This value will double every time link finds the same set-point.
  239. #ifndef DPNBUILD_NOMULTICAST
  240. #define EPFLAGS2_MULTICAST_SEND 0x00000001 // multicast send placeholder endpoint
  241. #define EPFLAGS2_MULTICAST_RECEIVE 0x00000002 // multicast receive placeholder endpoint
  242. #endif // DPNBUILD_NOMULTICAST
  243. #ifndef DPNBUILD_NOPROTOCOLTESTITF
  244. #define EPFLAGS2_DEBUG_NO_RETRIES 0x00000004
  245. #endif // !DPNBUILD_NOPROTOCOLTESTITF
  246. #define EPFLAGS2_NOCOALESCENCE 0x00000008 // We are talking to an older partner and must not use coalescence
  247. #define EPFLAGS2_KILLED 0x00000010 // Someone has removed the 'base' reference to make this go away
  248. // We dont want to let this happen twice...
  249. #define EPFLAGS2_HARD_DISCONNECT_COMPLETE 0x00000020
  250. #define EPFLAGS2_SUPPORTS_SIGNING 0x00000040 // Remote partner supports signing on packets
  251. // This doesn't mean packets actually are signed, it just means
  252. // that their protocol version would support it
  253. #define EPFLAGS2_FAST_SIGNED_LINK 0x00000080 // Packets over link should be fast signed
  254. #define EPFLAGS2_FULL_SIGNED_LINK 0x00000100 // Packets over link should be fully signed
  255. #define EPFLAGS2_SIGNED_LINK 0x00000180 // Combination of both above flags
  256. struct endpointdesc
  257. {
  258. HANDLE hEndPt; // Together with SP index uniquely defines an End Point we can reach
  259. LONG lRefCnt; // Reference count
  260. UINT Sign; // Signature to validate data structure
  261. PSPD pSPD; // specifies the SP on which this remote instance lives
  262. ULONG VOL ulEPFlags; // End Point Flags
  263. ULONG VOL ulEPFlags2; // Extra endpoint flags
  264. PVOID Context; // Context value returned with all indications
  265. PMSD pCommand; // Connect or Listen command with which this end point was created or Disconnect cmd
  266. CBilink blActiveLinkage; // linkage for SPD list of active EndPoints
  267. CBilink blSPLinkage; // linkage to listen command during connect
  268. CBilink blChkPtQueue; // linkage for active CheckPoints
  269. UINT uiUserFrameLength; // Largest frame we can transmit
  270. UINT uiRTT; // Current RTT -- Integer portion
  271. UINT fpRTT; // Fixed Point 16.16 RTT
  272. UINT uiDropCount; // localized packet drop count (recent drops)
  273. DWORD dwDropBitMask; // bit mask of dropped frames (32 frame max)
  274. DWORD tThrottleTime; // Timestamp when last Checking occured
  275. UINT uiThrottleEvents; // count of temporary backoffs for all reasons
  276. UINT uiAdaptAlgCount; // Acknowledge count remaining before running adaptive algorithm
  277. DWORD tLastPacket; // Timestamp when last packet arrived
  278. UINT uiWindowFilled; // Count of times we fill the send window
  279. UINT uiPeriodAcksBytes; // frames acked since change in tuning
  280. UINT uiPeriodXmitTime; // time link has been transmitting since change in tuning
  281. UINT uiPeriodRateB;
  282. UINT uiPeakRateB; // Largest sample we ever measure
  283. PVOID pvHardDisconnectContext; //The context value passed down to us when a hard disconnect has been requested
  284. //For a normal disconnect this is stored as part of the disconnect MSD, but since
  285. //we don't have one of those for a hard disconnect it has to be added here
  286. //Signing. We store 2 secret values for signing, the local one for us to use when signing our packets, and the remote one
  287. //we use to check incoming packets. The type of signing is controlled by the EPFLAGS2_FAST/FULL_SIGNED_LINK flags
  288. //For full signing, where we update the secret's each time the sequence space wraps, we also store the values of the old
  289. //secret. This is needed when we send retries (old local secret) or we received delayed incoming packets (old remote secret)
  290. //We also track modifier values for the secrets. These are derived from the signatures of reliable messages we've sent (for local
  291. //modifier) or received (for remote modifier). Each time the sequence space is wrapped we update the secrets using the modifiers
  292. //to prevent replay attacks
  293. ULONGLONG ullCurrentLocalSecret;
  294. ULONGLONG ullOldLocalSecret;
  295. ULONGLONG ullCurrentRemoteSecret;
  296. ULONGLONG ullOldRemoteSecret;
  297. ULONGLONG ullLocalSecretModifier;
  298. ULONGLONG ullRemoteSecretModifier;
  299. BYTE byLocalSecretModifierSeqNum;
  300. BYTE byRemoteSecretModifierSeqNum;
  301. // While we are in DYNAMIC state we want to remember stats from our previous xmit parameters, at this
  302. // point that means RTT and AvgSendRate. This lets us compare the measurements at our new rate so we can
  303. // ensure that thruput increases with sendrate, and that RTT is not growing out of proportion.
  304. //
  305. // If either thru-put stops improving or RTT grows unreasonably then we can plateau our xmit parameters
  306. // and transition to STABLE state.
  307. UINT uiLastRateB;
  308. UINT uiLastBytesAcked;
  309. DWORD tLastThruPutSample;
  310. // Connection State - State of reliable connection
  311. //
  312. // Send Queuing is getting somewhat complex. Let me spell it out in Anglish.
  313. //
  314. // blXPriSendQ is the list of MSDs awaiting shipment (and being shipped)
  315. // CurrentSend pts to the MSD we are currently pulling frames out of.
  316. // CurrentFrame pts to the next FMD that we will put on the wire.
  317. // blSendWindow is a bilinked list of transmitted but unacknowledged frames. This list may span multi MSDs
  318. //
  319. // WindowF is our current MAX window size expressed in frames
  320. // WindowB is our current MAX window size expressed in bytes
  321. //
  322. // UnAckedFrames is the count of unacknowledged frames on the wire (actual window size)
  323. // UnAckedBytes is the count of unacknowledged bytes on the wire
  324. DWORD uiQueuedMessageCount; // How many MSDs are waiting on all three send queues
  325. CBilink blHighPriSendQ; // These are now mixed Reliable and Datagram traffic
  326. CBilink blNormPriSendQ;
  327. CBilink blLowPriSendQ;
  328. CBilink blCompleteSendList; // Reliable messages completed and awaiting indication to user
  329. DWORD dwSessID; // Session ID so we can detect re-started links
  330. PMSD pCurrentSend; // Head of queue is lead edge of window. window can span multiple frames.
  331. PFMD pCurrentFrame; // frame currently transmitting. this will be trailing edge of window
  332. CBilink blSendWindow;
  333. CBilink blRetryQueue; // Packets waiting for re-transmission
  334. // Lost Packet Lists
  335. //
  336. // When we need to retry a packet and we discover that it is not reliable, then we need to inform partner
  337. // that he can stop waiting for the data. We will piggyback this info on another frame if possible
  338. // Current Transmit Parameters:
  339. UINT uiWindowF; // window size (frames)
  340. UINT uiWindowB; // window size (bytes)
  341. UINT uiWindowBIndex; // index (scaler) for byte-based window
  342. UINT uiUnackedFrames; // outstanding frame count
  343. UINT uiUnackedBytes; // outstanding byte count
  344. UINT uiBurstGap; // number of ms to wait between bursts
  345. INT iBurstCredit; // Either credit or deficit from previous Transmit Burst
  346. // Last Known Good Transmit Parameters -- Values which we believe are safe...
  347. UINT uiGoodWindowF;
  348. UINT uiGoodWindowBI;
  349. UINT uiGoodBurstGap;
  350. UINT uiGoodRTT;
  351. UINT uiRestoreWindowF;
  352. UINT uiRestoreWindowBI;
  353. UINT uiRestoreBurstGap;
  354. DWORD tLastDelta; // Timestamp when we last modified xmit parms
  355. // Reliable Link State
  356. BYTE VOL bNextSend; // Next serial number to assign
  357. BYTE VOL bNextReceive; // Next frame serial we expect to receive
  358. // Group BYTE members for good packing
  359. BYTE VOL bNextMsgID; // Next ID for datagram frames ! NOW USED FOR CFRAMES ONLY
  360. BYTE bLastDataRetry; // Retry count on frame N(R) - 1
  361. BYTE bHighestAck; // The highest sequence number that has been ACK'd. This may not be the first frame in the SendWindow due to masks.
  362. // The following fields are all for tracking reliable receives
  363. // The next two fields allow us to return more state with every ACK packet. Since each ack explicitly
  364. // names one frame, the highest in-sequenced packet received so far, we want to remember the arrival time
  365. // and the Retry count of this packet so we can report it in each ACK. It will be the transmitter's
  366. // responsibility to ensure that a single data-point never gets processed more then once, skewing our calcs.
  367. DWORD tLastDataFrame; // Timestamp from the arrival of N(R) - 1
  368. ULONG ulReceiveMask; // mask representing first 32 frames in our rcv window
  369. ULONG ulReceiveMask2; // second 32 frames in our window
  370. DWORD tReceiveMaskDelta; // timestamp when a new bit was last set in ReceiveMask (full 64-bit mask)
  371. ULONG ulSendMask; // mask representing unreliable send frames that have timed out and need
  372. ULONG ulSendMask2; // to be reported to receiver as missing.
  373. PRCD pNewMessage; // singly linked list of message elements
  374. PRCD pNewTail; // tail pointer for singly linked list of msg elements
  375. CBilink blOddFrameList; // Out Of Order frames
  376. CBilink blCompleteList; // List of MESSAGES ready to be indicated
  377. UINT uiCompleteMsgCount; // Count of messages on the CompleteList
  378. PVOID SendTimer; // Timer for next send-burst opportunity
  379. UINT SendTimerUnique;
  380. UINT uiNumRetriesRemaining; // This is used during CONNECT and HARD_DISCONNECT processing
  381. //to track how many more times we should retry either the connect or
  382. //hard disconnect
  383. UINT uiRetryTimeout; // Current T1 timer value
  384. PVOID LinkTimer; // Used to generate timer events when link is connecting and hard disconnecting
  385. UINT LinkTimerUnique;
  386. PVOID RetryTimer; // window to receive Ack
  387. UINT RetryTimerUnique;
  388. PVOID DelayedAckTimer; // wait for piggyback opportunity before sending Ack
  389. UINT DelayedAckTimerUnique;
  390. PVOID DelayedMaskTimer; // wait for piggyback opportunity before sending
  391. UINT DelayedMaskTimerUnique;
  392. PVOID BGTimer; // Periodic background timer
  393. UINT BGTimerUnique; // serial for background timer
  394. UINT uiBytesAcked;
  395. // Link statistics
  396. //
  397. // All of the following stuff is calculated and stored here for the purpose of reporting in the ConnectionInfo structure
  398. UINT uiMsgSentHigh;
  399. UINT uiMsgSentNorm;
  400. UINT uiMsgSentLow;
  401. UINT uiMsgTOHigh;
  402. UINT uiMsgTONorm;
  403. UINT uiMsgTOLow;
  404. UINT uiMessagesReceived;
  405. UINT uiGuaranteedFramesSent;
  406. UINT uiGuaranteedBytesSent;
  407. UINT uiDatagramFramesSent;
  408. UINT uiDatagramBytesSent;
  409. UINT uiGuaranteedFramesReceived;
  410. UINT uiGuaranteedBytesReceived;
  411. UINT uiDatagramFramesReceived;
  412. UINT uiDatagramBytesReceived;
  413. UINT uiDatagramFramesDropped; // datagram frame we failed to deliver
  414. UINT uiDatagramBytesDropped; // datagram bytes we didnt deliver
  415. UINT uiGuaranteedFramesDropped;
  416. UINT uiGuaranteedBytesDropped;
  417. #ifndef DPNBUILD_ONLYONETHREAD
  418. DNCRITICAL_SECTION EPLock; // Serialize all access to Endpoint
  419. #endif // !DPNBUILD_ONLYONETHREAD
  420. #ifdef DBG
  421. UINT uiTotalThrottleEvents;
  422. BYTE bLastDataSeq; // for DEBUG porpoises
  423. CHAR LastPacket[MAX_SEND_HEADER_SIZE + 4]; // record first portion of last packet received on EPD
  424. #endif // DBG
  425. };
  426. /*
  427. ** Check Point Data
  428. **
  429. ** Keeps track of local-end info about a checkpoint in-progress.
  430. */
  431. struct checkptdata
  432. {
  433. CBilink blLinkage; // Linkage for list of CPs on an EndPoint
  434. DWORD tTimestamp; // Local time at start of checkpoint
  435. UCHAR bMsgID; // Msg ID expected in CP response
  436. };
  437. /*
  438. ** Descriptor IDs
  439. **
  440. ** Any Descriptor that may be submitted to an SP as a context must have
  441. ** a field which allows us to determine which structure is returned in a
  442. ** completion call. This field must obviously be in a uniform place in all
  443. ** structures, and could be expanded to be a command specifier as well.
  444. ** Done! Lets call it a command ID.
  445. */
  446. typedef enum CommandID
  447. {
  448. COMMAND_ID_NONE,
  449. COMMAND_ID_SEND_RELIABLE,
  450. COMMAND_ID_SEND_DATAGRAM,
  451. COMMAND_ID_SEND_COALESCE,
  452. COMMAND_ID_CONNECT,
  453. COMMAND_ID_LISTEN,
  454. COMMAND_ID_ENUM,
  455. COMMAND_ID_ENUMRESP,
  456. COMMAND_ID_DISCONNECT,
  457. COMMAND_ID_DISC_RESPONSE,
  458. COMMAND_ID_CFRAME,
  459. COMMAND_ID_KEEPALIVE,
  460. COMMAND_ID_COPIED_RETRY,
  461. COMMAND_ID_COPIED_RETRY_COALESCE,
  462. #ifndef DPNBUILD_NOMULTICAST
  463. COMMAND_ID_LISTEN_MULTICAST,
  464. COMMAND_ID_CONNECT_MULTICAST_SEND,
  465. COMMAND_ID_CONNECT_MULTICAST_RECEIVE,
  466. #endif // DPNBUILD_NOMULTICAST
  467. } COMMANDID;
  468. /* Message Descriptor
  469. **
  470. ** An 'MSD' describes a message being sent or received by the protocol. It keeps track
  471. ** of the message elements, tracking which have been sent/received/acknowledged.
  472. */
  473. // Flags ONE field is protected by the MSD->CommandLock
  474. #define MFLAGS_ONE_IN_USE 0x0001
  475. #define MFLAGS_ONE_IN_SERVICE_PROVIDER 0x0002 // This MSD is inside an SP call
  476. #define MFLAGS_ONE_CANCELLED 0x0004 // command was cancelled while owned by SP
  477. #define MFLAGS_ONE_TIMEDOUT 0x0008 // sends only: timed out while event was scheduled
  478. #define MFLAGS_ONE_COMPLETE 0x0010 // connect only: operation is complete and indicated to Core
  479. #define MFLAGS_ONE_FAST_SIGNED 0x0020 // listen only. Links should be established with fast signing
  480. #define MFLAGS_ONE_FULL_SIGNED 0x0040 // listen only. Links should be established with full signing
  481. #define MFLAGS_ONE_SIGNED (MFLAGS_ONE_FULL_SIGNED |MFLAGS_ONE_FAST_SIGNED)
  482. // combination of above two flags. Allows to check for signing easily
  483. #ifdef DBG
  484. #define MFLAGS_ONE_COMPLETED_TO_CORE 0x4000
  485. #define MFLAGS_ONE_ON_GLOBAL_LIST 0x8000
  486. #endif // DBG
  487. // Flags TWO field is protected by the EPD->EPLock
  488. #define MFLAGS_TWO_TRANSMITTING 0x0001
  489. #define MFLAGS_TWO_SEND_COMPLETE 0x0002 // send command completed
  490. #define MFLAGS_TWO_ABORT 0x0004 // Send/Disconnect has been aborted. Do no further processing
  491. #define MFLAGS_TWO_END_OF_STREAM 0x0008 // This MSD is an EOS frame. Could be a user cmd or a response
  492. #define MFLAGS_TWO_KEEPALIVE 0x0010 // This MSD is an empty frame to exercise the reliable engine
  493. #define MFLAGS_TWO_ABORT_WILL_COMPLETE 0x0020 // AbortSendsOnConnection intends to complete this to the core, other functions can clear it
  494. #ifdef DBG
  495. #define MFLAGS_TWO_ENQUEUED 0x1000 // This MSD is on one of the EPD SendQs
  496. #endif // DBG
  497. #pragma TODO(simonpow, "Should union some members of the structure below to share memory between those used in sends, connects and listen")
  498. struct messagedesc
  499. {
  500. COMMANDID CommandID; // THIS MUST BE FIRST FIELD
  501. LONG lRefCnt; // Reference count
  502. UINT Sign; // Signature
  503. ULONG VOL ulMsgFlags1; // State info serialized by MSD->CommandLock
  504. ULONG VOL ulMsgFlags2; // State info serialized by EPD->EPLock
  505. PEPD pEPD; // Destination End Point
  506. PSPD pSPD; // SP fielding this command
  507. PVOID Context; // User provided context value
  508. ULONG VOL ulSendFlags; // Flags submitted by User in send call
  509. INT iMsgLength; // Total length of user data
  510. UINT VOL uiFrameCount; // Number of frames needed to xmit data, protected by EPLock for reliables
  511. CBilink blFrameList; // List of frames to transport this message, or for a Listen, endpoints that are connecting
  512. CBilink blQLinkage; // linkage for various sendQs
  513. CBilink blSPLinkage; // linkage for SP command list, protected by SP->SPLock
  514. HANDLE hCommand; // handle when submitted to SP (used for connect & listen)
  515. DWORD dwCommandDesc; // Descriptor associated with hCommand
  516. HANDLE hListenEndpoint;
  517. PVOID TimeoutTimer;
  518. UINT TimeoutTimerUnique;
  519. //used for listen commands when signing is enabled
  520. //we periodically change the connect secret and hence have to keep the last one in case
  521. //an incoming connection straddles this change
  522. ULONGLONG ullCurrentConnectSecret;
  523. ULONGLONG ullLastConnectSecret;
  524. DWORD dwTimeConnectSecretChanged;
  525. #ifndef DPNBUILD_ONLYONETHREAD
  526. DNCRITICAL_SECTION CommandLock;
  527. #endif // !DPNBUILD_ONLYONETHREAD
  528. #ifdef DBG
  529. CCallStack CallStackCoreCompletion;
  530. #endif // DBG
  531. };
  532. /*
  533. ** Frame Descriptor
  534. **
  535. ** There are two non-obvious things about the FMD structure. First is that the built-in Buffer Descriptor array
  536. ** has two elements defined in front of it. The first element, Reserved1 and Reserved2 are present to allow the Service
  537. ** Provider to pre-pend a header buffer, and the second element, ImmediateLength and ImmediatePointer are for this
  538. ** protocol to prepend its header. The ImmediatePointer is initialized to point to the ImmediateData field.
  539. **
  540. ** The second thing is that the ulFFlags field is serialized with the ENDPOINTLOCK of the EPD which this frame is linked to.
  541. ** This is good because every time the FFlags fields is modified we have already taken the EPLock already. The exception to this
  542. ** rule is when we are initializing the FMD. In this case the FMD has not been loosed on the world yet so there cannot be any
  543. ** contention for it. We have seperated out the one flag, FRAME_SUBMITTED, into its own BOOL variable because this one is
  544. ** protected by the SP's SPLock, and like the EPLock above, it is already claimed when this flag gets modified.
  545. */
  546. //#define FFLAGS_IN_USE 0x0001
  547. #define FFLAGS_TRANSMITTED 0x0002
  548. #define FFLAGS_END_OF_MESSAGE 0x0004
  549. #define FFLAGS_END_OF_STREAM 0x0008
  550. //#define FFLAGS_FRAME_SUBMITTED 0x0010 // SP Currently owns this frame
  551. #define FFLAGS_RETRY_TIMER_SET 0x0020 // Just what it sounds like
  552. //#define FFLAGS_NACK_RETRANSMIT_SENT 0x0040 // We sent a NACK initiated retry.
  553. #define FFLAGS_IN_SEND_WINDOW 0x0080 // This reliable frame has been transmitted and is waiting for Ack
  554. #define FFLAGS_CHECKPOINT 0x0100 // We are asking for a response
  555. //#define FFLAGS_KEEPALIVE 0x0200
  556. //#define FFLAGS_ACKED_BY_MASK 0x0400 // This has been acked out-of-order so its still in the SendWindow
  557. #define FFLAGS_RETRY_QUEUED 0x0800 // Frame currently sitting on the retry queue
  558. //#define FFLAGS_NEW_MESSAGE 0x00010000
  559. #define FFLAGS_RELIABLE 0x00020000
  560. //#define FFLAGS_SEQUENTIAL 0x00040000
  561. #define FFLAGS_FINAL_ACK 0x00080000
  562. #define FFLAGS_DONT_COALESCE 0x00100000
  563. #define FFLAGS_FINAL_HARD_DISCONNECT 0x00200000
  564. struct framedesc
  565. {
  566. COMMANDID CommandID; // THIS MUST BE FIRST FIELD to match MSD
  567. LONG lRefCnt; // Reference count
  568. UINT Sign;
  569. UINT uiFrameLength;
  570. ULONG VOL ulFFlags; // Protected by EPLock
  571. BOOL VOL bSubmitted; // Pull out this one flag for protection by EPLock (data frames only)
  572. PMSD pMSD; // owning message
  573. PEPD pEPD; // owning link; ONLY VALID ON COMMAND FRAMES!
  574. BYTE bPacketFlags;
  575. CBilink blMSDLinkage;
  576. CBilink blQLinkage;
  577. CBilink blWindowLinkage;
  578. CBilink blCoalesceLinkage;
  579. PFMD pCSD; // pointer to containing coalesce header frame descriptor (non-retry coalesced frames only)
  580. UINT uiRetry; // number of times this frame has been transmitted
  581. DWORD dwFirstSendTime; // time when we first send the frame
  582. DWORD dwLastSendTime; // time when we last sent the frame (starts == to dwFirstSendTime and
  583. // updates on each resend)
  584. DWORD tAcked;
  585. SPSENDDATA SendDataBlock; // Block to submit frame to SP
  586. CHAR ImmediateData[MAX_SEND_HEADER_SIZE];
  587. // DO NOT MODIFY LAST FIVE FIELDS IN FRAME STRUCTURE
  588. UINT uiReserved1; // two resv fields are buf..
  589. LPVOID lpReserved2; // ..desc for SP to add header
  590. UINT uiImmediateLength; // These two lines constitute buffer descriptor
  591. LPVOID lpImmediatePointer; // for immediate data (our protocol headers)
  592. BUFFERDESC rgBufferList[MAX_USER_BUFFERS_IN_FRAME]; // KEEP THIS FIELD AT END SO WE CAN ADD BUFFERS DYNAMICALLY
  593. };
  594. /*
  595. ** Receive Descriptor
  596. **
  597. ** This data structure tracks a single buffer received from the network.
  598. ** It may or may not constitute an entire message.
  599. */
  600. typedef enum
  601. {
  602. RBT_SERVICE_PROVIDER_BUFFER,
  603. RBT_SERVICE_PROVIDER_BUFFER_COALESCE,
  604. RBT_PROTOCOL_NORM_BUFFER,
  605. RBT_PROTOCOL_MED_BUFFER,
  606. RBT_PROTOCOL_BIG_BUFFER,
  607. RBT_DYNAMIC_BUFFER
  608. } BUFFER_TYPE;
  609. //#define RFLAGS_FRAME_OUT_OF_ORDER 0x0001 // This buffer was received out-of-order
  610. #define RFLAGS_FRAME_INDICATED_NONSEQ 0x0002 // This buffer was indicated out of order, but is still in Out of Order list
  611. //#define RFLAGS_ON_OUT_OF_ORDER_LIST 0x0004 //
  612. //#define RFLAGS_IN_COMPLETE_PROCESS 0x0008
  613. #define RFLAGS_FRAME_LOST 0x0010 // This RCD represents and Unreliable frame that has been lost
  614. struct recvdesc
  615. {
  616. DWORD tTimestamp; // timestamp upon packets arrival
  617. LONG lRefCnt;
  618. UINT Sign; // Signature to identify data structure
  619. UINT uiDataSize; // data in this frame
  620. UINT uiFrameCount; // frames in message
  621. UINT uiMsgSize; // total byte count of message
  622. BYTE bSeq; // Sequence number of this frame
  623. BYTE bFrameFlags; // Flag field from actual frame
  624. BYTE bFrameControl;
  625. PBYTE pbData; // pointer to actual data
  626. UINT ulRFlags; // Receive flags
  627. CBilink blOddFrameLinkage; // BILINKage for queues
  628. CBilink blCompleteLinkage; // 2nd Bilink so RCD can remain in Out Of Order Queue after indication
  629. PRCD pMsgLink; // Single link for frame in message
  630. DWORD dwNumCoalesceHeaders; // number of coalesce headers in message
  631. PSPRECEIVEDBUFFER pRcvBuff; // ptr to SP's receive data structure
  632. };
  633. typedef struct buf BUF, *PBUF;
  634. typedef struct medbuf MEDBUF, *PMEDBUF;
  635. typedef struct bigbuf BIGBUF, *PBIGBUF;
  636. typedef struct dynbuf DYNBUF, *PDYNBUF;
  637. // NOTE: These structures Type members must stay lined up with the dwProtocolData member
  638. // of an SPRECEIVEDBUFFER!!!
  639. struct buf
  640. {
  641. PVOID pvReserved;
  642. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  643. BYTE data[SMALL_BUFFER_SIZE]; // 2K small buffer for combining multi-frame sends
  644. };
  645. struct medbuf
  646. {
  647. PVOID pvReserved;
  648. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  649. BYTE data[MEDIUM_BUFFER_SIZE]; // 4K mid size buffer
  650. };
  651. struct bigbuf
  652. {
  653. PVOID pvReserved;
  654. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  655. BYTE data[LARGE_BUFFER_SIZE]; // ARBITRARY SIZE OF MAX SEND (16K)
  656. };
  657. struct dynbuf
  658. {
  659. PVOID pvReserved;
  660. BUFFER_TYPE Type; // Identifies this as our buffer or SPs buffer
  661. };
  662. #endif // _DNPROT_INCLUDED_