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.

2232 lines
58 KiB

  1. /*++
  2. Copyright (c) 1996,1997 Microsoft Corporation
  3. Module Name:
  4. RECEIVE.C
  5. Abstract:
  6. Receive Handler and Receive Thread.
  7. Author:
  8. Aaron Ogus (aarono)
  9. Environment:
  10. Win32/COM
  11. Revision History:
  12. Date Author Description
  13. ====== ====== ============================================================
  14. 12/10/96 aarono Original
  15. 02/18/98 aarono Added support for SendEx
  16. 6/6/98 aarono Turn on throttling and windowing
  17. 6/10/98 aarono Allow out of order receives when requested by application
  18. 4/15/99 aarono Take a Send reference in NACK and ACK handlers
  19. --*/
  20. #include <windows.h>
  21. #include "newdpf.h"
  22. #include <dplay.h>
  23. #include <dplaysp.h>
  24. #include <dplaypr.h>
  25. #include "mydebug.h"
  26. #include "arpd.h"
  27. #include "arpdint.h"
  28. #include "protocol.h"
  29. #include "macros.h"
  30. #include "command.h"
  31. // Note: WaitForMultipleObjects has a bug where it restarts the wait in
  32. // the middle of the list and can run off the end. We put an extra
  33. // entry at the end of the object list to deal with this and when
  34. // we get an invalid_handle error, we just re-wait.
  35. // First object is an event that is signalled when
  36. // the wait list needs to be changed.
  37. // Receive List Semantics. The Receive thread
  38. VOID ProcessACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo);
  39. VOID ProcessNACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PUCHAR pNACKmask, UINT nNACK);
  40. VOID ProcessAbort(PPROTOCOL pProtocol, DPID idFrom, DPID idTo, pABT1 pABT, BOOL fBig);
  41. VOID SendACK(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo);
  42. // Function table for received commands.
  43. UINT (*ProtocolFn[MAX_COMMAND+1])(REQUEST_PARAMS)={
  44. AssertMe, // 0x00
  45. Ping, // 0x01
  46. PingResp, // 0x02
  47. GetTime, // 0x03
  48. GetTimeResp, // 0x04
  49. SetTime, // 0x05
  50. SetTimeResp // 0x06
  51. };
  52. VOID FreeReceiveBuffers(PRECEIVE pReceive)
  53. {
  54. BILINK *pBilink;
  55. PBUFFER pBuffer;
  56. pBilink=pReceive->RcvBuffList.next;
  57. while(pBilink != &pReceive->RcvBuffList){
  58. pBuffer=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  59. pBilink=pBilink->next;
  60. FreeFrameBuffer(pBuffer);
  61. }
  62. }
  63. VOID CopyReceiveBuffers(PRECEIVE pReceive,PVOID pBuffers,UINT nBuffers)
  64. {
  65. #define MemDesc(_i) (*(((PMEMDESC)pBuffers)+(_i)))
  66. PBUFFER pBuffer;
  67. UINT BytesToCopy;
  68. UINT BuffLen;
  69. UINT BuffOffset;
  70. UINT mdlen;
  71. UINT mdoffset;
  72. UINT i=0;
  73. PUCHAR src;
  74. PUCHAR dest;
  75. UINT len;
  76. BytesToCopy=pReceive->MessageSize;
  77. pBuffer=(PBUFFER)pReceive->RcvBuffList.next;
  78. BuffLen=(UINT)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData));
  79. BuffOffset=0;
  80. mdlen=MemDesc(0).len;
  81. mdoffset=0;
  82. while(BytesToCopy){
  83. if(!mdlen){
  84. i++;
  85. mdlen=MemDesc(i).len;
  86. mdoffset=0;
  87. ASSERT(i<nBuffers);
  88. }
  89. if(!BuffLen){
  90. pBuffer=pBuffer->pNext;
  91. ASSERT(pBuffer);
  92. BuffLen=(UINT)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData));
  93. BuffOffset=0;
  94. }
  95. src=&pBuffer->pCmdData[BuffOffset];
  96. dest=&(MemDesc(i).pData[mdoffset]);
  97. if(BuffLen > mdlen){
  98. len=mdlen;
  99. BuffOffset+=len;
  100. } else {
  101. len=BuffLen;
  102. mdoffset+=len;
  103. }
  104. DPF(9,"CopyReceiveBuffers src,dest,len: %x %x %x\n",dest,src,len);
  105. memcpy(dest,src,len);
  106. BuffLen-=len;
  107. mdlen-=len;
  108. BytesToCopy-=len;
  109. }
  110. #undef MemDesc
  111. }
  112. HRESULT _inline ParseHeader(
  113. FLAGS *pflags,
  114. PUCHAR pData,
  115. DWORD cbData,
  116. UINT * pCommand,
  117. UINT *piEOF,
  118. UINT *piEOA,
  119. UINT *piEON,
  120. UINT *pnNACK)
  121. {
  122. if(pflags->flag1 & BIG){
  123. // big frame
  124. if(pflags->flag1 & CMD){
  125. // big command frame
  126. if(pflags->flag1 & EXT){
  127. // big command frame with explicit command
  128. *pCommand=pflags->flag2 & ~EXT;
  129. if(pflags->flag2 & EXT){
  130. // big command frame with explicit command and NACK
  131. *pnNACK=pflags->flag3 & ~EXT;
  132. *piEOF=3;
  133. } else {
  134. // big command frame with explicit command, no NACK
  135. *pnNACK=0;
  136. *piEOF=2;
  137. }
  138. } else {
  139. // big -I- frame, no NACK
  140. *pCommand=0;
  141. *pnNACK=0;
  142. *piEOF=1;
  143. }
  144. } else {
  145. // big supervisory (non-command) frame
  146. if(pflags->flag1 & EXT){
  147. // big supervisory frame with nNACK
  148. *pnNACK=pflags->flag2 & ~EXT;
  149. ASSERT(*pnNACK);
  150. *piEOF=2;
  151. } else {
  152. // big supervisory frame with no-nNACK
  153. *pnNACK=0;
  154. *piEOF=1;
  155. }
  156. }
  157. } else {
  158. // small frame
  159. if(pflags->flag1 & CMD){
  160. // small command frame
  161. if(pflags->flag1 & EXT){
  162. // small command frame (with NACK?) and explicit command
  163. DPF(0,"ERROR PARSING FRAME, NOT RECOGNIZED, ABORTING DECODE\n");
  164. return DPERR_ABORTED;
  165. *pCommand = pflags->flag2 & CMD_MSK;
  166. *pnNACK = (pflags->flag2 & nNACK_MSK) >> nNACK_SHIFT;
  167. *piEOF = 2;
  168. } else {
  169. // small -I- frame, no NACK
  170. *pCommand = 0;
  171. *pnNACK = 0;
  172. *piEOF = 1;
  173. }
  174. } else {
  175. // small supervisory (non-command) frame
  176. if(pflags->flag1 & EXT){
  177. *pnNACK = (pflags->flag2 & nNACK_MSK) >> nNACK_SHIFT;
  178. *piEOF = 2;
  179. } else {
  180. *pnNACK=0;
  181. *piEOF=1;
  182. }
  183. }
  184. }
  185. while(pData[(*piEOF)-1]&EXT){
  186. // Skip past any flags extensions we don't understand.
  187. // small command frame (with NACK?) and explicit command
  188. DPF(0,"ERROR PARSING FRAME, NOT RECOGNIZED, ABORTING DECODE\n");
  189. return DPERR_ABORTED;
  190. (*piEOF)++;
  191. }
  192. *piEOA=*piEOF;
  193. // Update any ACK information.
  194. if((pflags->flag1 & ACK)){
  195. if((pflags->flag1 & BIG)){
  196. // LARGE ACK
  197. *piEOA+=sizeof(ACK2);
  198. } else {
  199. // SMALL ACK
  200. *piEOA+=sizeof(ACK1);
  201. }
  202. }
  203. *piEON = *piEOA;
  204. // Update any NACK information.
  205. if(*pnNACK){
  206. if((pflags->flag1 & BIG)){
  207. *piEON+=sizeof(NACK2);
  208. }else{
  209. *piEON+=sizeof(NACK1);
  210. }
  211. *piEON+=*pnNACK;
  212. }
  213. // SECURITY
  214. if(*piEON > cbData)
  215. {
  216. DPF(1,"SECURITY WARN: invalid protocol header");
  217. return DPERR_ABORTED;
  218. }
  219. return DP_OK;
  220. }
  221. /*=============================================================================
  222. ProtocolReceive - Receive handler for protocol, called when we've
  223. verified the message is a protocol message and
  224. we've been able to allocate receive space for the
  225. message
  226. Description:
  227. Cracks the protocol header on the message and fills in a CMDINFO
  228. structure to describe the protocol information in the frame. Then
  229. dispatches the message along with the CMDINFO to the appropriate
  230. handler.
  231. A packet may have ACK or NACK information in the header and still
  232. be a command packet. We do ACK/NACK processing first, then we
  233. do command processing.
  234. This routine will dispatch to
  235. ProcessACK
  236. ProcessNACK
  237. CommandReceive
  238. Parameters:
  239. idFrom - index in player table of sending player
  240. idTo - " " receiving player
  241. pBuffer - a buffer we own with a copy of the message
  242. pSPHeader - if present can be used to issue a reply without an id.
  243. Return Values:
  244. None.
  245. Notes:
  246. -----------------------------------------------------------------------------*/
  247. VOID ProtocolReceive(PPROTOCOL pProtocol, WORD idFrom, WORD idTo, PBUFFER pBuffer, PVOID pSPHeader)
  248. {
  249. #define pFrame ((pPacket1)(pBuffer->pData))
  250. #define pBigFrame ((pPacket2)(pBuffer->pData))
  251. #define pACK ((pACK1)(&pData[iEOF]))
  252. #define pBigACK ((pACK2)(&pData[iEOF]))
  253. #define pABT ((pABT1)(&pData[iEOF]))
  254. #define pBigABT ((pABT2)(&pData[iEOF]))
  255. #define pNACK ((pNACK1)(&pData[iEOA]))
  256. #define pBigNACK ((pNACK2)(&pData[iEOA]))
  257. #define pCMD ((pCMD1)(&pData[iEON]))
  258. #define pBigCMD ((pCMD2)(&pData[iEON]))
  259. #define cbBuf (pBuffer->len)
  260. // pFrameEnd points to the byte after the last frame byte, the first invalid byte.
  261. #define pFrameEnd (&pBuffer->pData[cbBuf])
  262. PUCHAR pData;
  263. FLAGS flags;
  264. UINT command; // the command if a command frame.
  265. UINT nNACK; // if this is a NACK frame, sizeof bitfield
  266. UINT iEOF; // index past end of flags
  267. UINT iEOA; // index past end of any ACK or ABT information
  268. UINT iEON; // index past end of any NACK information
  269. UINT rc=0;
  270. PUCHAR pNACKmask;
  271. HRESULT hr;
  272. CMDINFO CmdInfo;
  273. PCMDINFO pCmdInfo=&CmdInfo;
  274. CmdInfo.tReceived=timeGetTime();
  275. if(cbBuf < sizeof(flags)){
  276. DPF(1,"SECURITY WARN: received protocol frame too short");
  277. return; //ignore frame
  278. }
  279. pData=pBuffer->pData;
  280. memcpy(&flags,pData,sizeof(flags));
  281. hr=ParseHeader(&flags, pData, cbBuf, &command, &iEOF, &iEOA, &iEON, &nNACK);
  282. if(FAILED(hr)){
  283. goto exit;
  284. }
  285. // Get the DPLAY id's for the indicies
  286. CmdInfo.idFrom = GetDPIDByIndex(pProtocol, idFrom);
  287. if(CmdInfo.idFrom == 0xFFFFFFFF){
  288. DPF(1,"Rejecting packet with invalid From Id\n",idFrom);
  289. goto exit;
  290. }
  291. CmdInfo.idTo = GetDPIDByIndex(pProtocol, idTo);
  292. if(CmdInfo.idTo == 0xFFFFFFFF){
  293. DPF(1,"Rejecting packet with invalid To Id\n");
  294. goto exit;
  295. }
  296. DPF(9,"Protocol Receive idFrom %x idTo %x\n",CmdInfo.idFrom,CmdInfo.idTo);
  297. CmdInfo.wIdFrom = idFrom;
  298. CmdInfo.wIdTo = idTo;
  299. CmdInfo.flags = flags.flag1;
  300. CmdInfo.pSPHeader = pSPHeader;
  301. // determine masks to use for this size frame
  302. if(flags.flag1 & BIG){
  303. IDMSK = 0xFFFF;
  304. SEQMSK = 0xFFFF;
  305. } else {
  306. IDMSK = 0xFF;
  307. SEQMSK = 0xFF;
  308. }
  309. if((flags.flag1 & ACK))
  310. {
  311. // Process the ACK field (could be piggyback).
  312. if(flags.flag1 & BIG){
  313. pCmdInfo->messageid = pBigACK->messageid;
  314. pCmdInfo->sequence = pBigACK->sequence;
  315. pCmdInfo->serial = pBigACK->serial;
  316. pCmdInfo->bytes = pBigACK->bytes;
  317. pCmdInfo->tRemoteACK= pBigACK->time;
  318. } else {
  319. pCmdInfo->messageid = pACK->messageid;
  320. pCmdInfo->sequence = pACK->sequence;
  321. pCmdInfo->serial = pACK->serial;
  322. pCmdInfo->bytes = pACK->bytes;
  323. pCmdInfo->tRemoteACK= pACK->time;
  324. }
  325. DPF(9,"ACK: msgid: %d seq %d serial %d\n",CmdInfo.messageid, CmdInfo.sequence, CmdInfo.serial);
  326. if(CmdInfo.serial==150){
  327. // this is a little excessive for retries, break out so we can debug this.
  328. DPF(0,"ProtocolReceive: WHOOPS, 150 retries is a little excessive\n");
  329. ASSERT(0);
  330. }
  331. ProcessACK(pProtocol, &CmdInfo);
  332. }
  333. if(nNACK){
  334. if(flags.flag1 & BIG){
  335. CmdInfo.messageid = pBigNACK->messageid;
  336. CmdInfo.sequence = pBigNACK->sequence;
  337. CmdInfo.bytes = pBigNACK->bytes;
  338. CmdInfo.tRemoteACK= pBigNACK->time;
  339. pNACKmask = pBigNACK->mask;
  340. } else {
  341. CmdInfo.messageid = pNACK->messageid;
  342. CmdInfo.sequence = pNACK->sequence;
  343. CmdInfo.bytes = pNACK->bytes;
  344. CmdInfo.tRemoteACK= pNACK->time;
  345. pNACKmask = pNACK->mask;
  346. }
  347. DPF(9,"NACK: msgid: %d seq %d\n",CmdInfo.messageid, CmdInfo.sequence);
  348. ProcessNACK(pProtocol, &CmdInfo, pNACKmask, nNACK);
  349. }
  350. #ifdef DEBUG
  351. if((flags.flag1 & ACK) || nNACK)
  352. {
  353. IN_WRITESTATS InWS;
  354. memset((PVOID)&InWS,0xFF,sizeof(IN_WRITESTATS));
  355. InWS.stat_RemBytesReceived=CmdInfo.bytes;
  356. DbgWriteStats(&InWS);
  357. }
  358. #endif
  359. if((flags.flag1 & CMD)){
  360. CmdInfo.command = command;
  361. if((flags.flag1 & BIG)){
  362. // SECURITY
  363. if(iEON+5 > cbBuf)
  364. {
  365. DPF(1,"SECURITY WARN: illegally formated BIG protocol message");
  366. goto exit;
  367. }
  368. CmdInfo.messageid= pBigCMD->messageid;
  369. CmdInfo.sequence = pBigCMD->sequence;
  370. CmdInfo.serial = pBigCMD->serial;
  371. pBuffer->pCmdData = pData+iEON+5;//(+5 for messageid(2), sequence(2), serial(1))
  372. } else {
  373. // SECURITY
  374. if(iEON+3 > cbBuf)
  375. {
  376. DPF(1,"SECURITY WARN: illegally formated NORMAL protocol message");
  377. goto exit;
  378. }
  379. CmdInfo.messageid= pCMD->messageid;
  380. CmdInfo.sequence = pCMD->sequence;
  381. CmdInfo.serial = pCMD->serial;
  382. pBuffer->pCmdData = pData+iEON+3;//(+3 for byte messageid,seq,serial)
  383. }
  384. if(pBuffer->pData + pBuffer->len <= pBuffer->pCmdData){
  385. DPF(1,"SECURITY WARN: illegally fromated message, data message w/no data");
  386. goto exit;
  387. }
  388. rc=CommandReceive(pProtocol, &CmdInfo, pBuffer);
  389. }
  390. if(!rc){
  391. exit:
  392. FreeFrameBuffer(pBuffer);
  393. }
  394. return;
  395. #undef pNACK
  396. #undef pBigNACK
  397. #undef pCMD
  398. #undef pBigCMD
  399. #undef pABT
  400. #undef pBigABT
  401. #undef pACK
  402. #undef pBigACK
  403. #undef pBigFrame
  404. #undef pFrame
  405. #undef cbBuf
  406. }
  407. VOID FreeReceive(PPROTOCOL pProtocol, PRECEIVE pReceive)
  408. {
  409. DPF(9,"Freeing Receive %x\n",pReceive);
  410. FreeReceiveBuffers(pReceive);
  411. ReleaseRcvDesc(pProtocol, pReceive);
  412. }
  413. #ifdef DEBUG
  414. VOID DebugScanForMessageId(BILINK *pBilink, UINT messageid)
  415. {
  416. BILINK *pBilinkWalker;
  417. PRECEIVE pReceive;
  418. pBilinkWalker=pBilink->next;
  419. while(pBilinkWalker!=pBilink){
  420. pReceive=CONTAINING_RECORD(pBilinkWalker,RECEIVE,pReceiveQ);
  421. if(pReceive->messageid==messageid){
  422. DPF(0,"ERROR: MESSAGEID x%x already exists in pReceive %x\n",pReceive);
  423. DEBUG_BREAK();
  424. }
  425. pBilinkWalker=pBilinkWalker->next;
  426. }
  427. }
  428. #else
  429. #define DebugScanForMessageId(_a,_b)
  430. #endif
  431. #ifdef DEBUG
  432. VOID DbgCheckReceiveStart(PSESSION pSession,PRECEIVE pReceive,PBUFFER pBuffer)
  433. {
  434. BILINK *pBilink;
  435. PBUFFER pBuffWalker;
  436. pBilink=pReceive->RcvBuffList.next;
  437. if (pBilink == &pReceive->RcvBuffList)
  438. {
  439. DPF(0,"No items in list, pSession %x, pReceive %x, pBuffer %x\n",pSession,pReceive,pBuffer);
  440. DEBUG_BREAK();
  441. }
  442. while(pBilink != &pReceive->RcvBuffList){
  443. pBuffWalker=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  444. pBilink=pBilink->next;
  445. if(pBuffWalker->sequence==1){
  446. break;
  447. }
  448. }
  449. if( ((pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)) != (pBuffWalker->len-(pBuffWalker->pCmdData-pBuffWalker->pData))) ||
  450. (memcmp(pBuffWalker->pCmdData,
  451. pBuffer->pCmdData,
  452. (UINT32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)))) )
  453. {
  454. DPF(0,"Different retry start buffer, pSession %x, pReceive %x, pBufferOnList %x, pBuffer %x\n",pSession,pReceive,pBuffWalker,pBuffer);
  455. DEBUG_BREAK();
  456. }
  457. // compare the buffers
  458. }
  459. #else
  460. #define DbgCheckReceiveStart
  461. #endif
  462. // If a receive is returned, it is locked on behalf of the caller.
  463. /*=============================================================================
  464. GetReceive - for a received data message find the receive structure
  465. or create one. If this message is a retry of a completed
  466. message, send an extra ACK.
  467. Description:
  468. Parameters:
  469. pProtocol
  470. pSession
  471. pCmdInfo
  472. Return Values:
  473. PRECEIVE - pointer to receive for this frame
  474. Notes:
  475. -----------------------------------------------------------------------------*/
  476. PRECEIVE GetReceive(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  477. {
  478. #define flags pCmdInfo->flags
  479. BOOL fFoundReceive=FALSE;
  480. BILINK *pBiHead, *pBilink;
  481. PRECEIVE pReceive=NULL,pReceiveWalker;
  482. DPF(9,"==>GetReceive pSession %x\n",pSession);
  483. Lock(&pSession->SessionLock);
  484. // Scan the queue on the SESSION for a RECEIVE with this messageid.
  485. if(flags & RLY){
  486. pBiHead = &pSession->pRlyReceiveQ;
  487. if(!pSession->fReceiveSmall){
  488. IDMSK = 0xFFFF;
  489. }
  490. } else {
  491. pBiHead = &pSession->pDGReceiveQ;
  492. if(!pSession->fReceiveSmallDG){
  493. IDMSK = 0xFFFF;
  494. }
  495. }
  496. pBilink = pBiHead->next;
  497. while(pBilink != pBiHead){
  498. pReceive=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  499. ASSERT_SIGN(pReceive, RECEIVE_SIGN);
  500. pBilink=pBilink->next;
  501. if(pReceive->messageid==pCmdInfo->messageid){
  502. Lock(&pReceive->ReceiveLock);
  503. if(!pReceive->fBusy){
  504. ASSERT(pReceive->command == pCmdInfo->command);
  505. ASSERT(pReceive->fReliable == (flags & RLY));
  506. fFoundReceive=TRUE;
  507. break;
  508. } else {
  509. Unlock(&pReceive->ReceiveLock);
  510. // its moving, so its done. Ignore.
  511. // there is probably a racing ACK already so ignore is fine.
  512. DPF(9,"GetReceive: Receive %x for messageid x%x is completing already, so ignoring receive\n",pReceive,pReceive->messageid);
  513. ASSERT(0);
  514. pReceive=NULL;
  515. goto exit;
  516. }
  517. }
  518. }
  519. if(!fFoundReceive){
  520. DPF(9,"GetReceive: Didn't find a receive for messageid x%x\n",pCmdInfo->messageid);
  521. pReceive=NULL;
  522. } else {
  523. DPF(9,"GetReceive: Found receive %x for messageid x%x\n",pReceive, pCmdInfo->messageid);
  524. }
  525. if(pReceive && ( flags & STA )){
  526. // Should get blown away below - this is the start frame, but we already got it
  527. DPF(9,"GetReceive: Got start for receive %x messageid x%x we already have going\n",pReceive, pCmdInfo->messageid);
  528. DbgCheckReceiveStart(pSession,pReceive,pBuffer);
  529. Unlock(&pReceive->ReceiveLock);
  530. pReceive=NULL;
  531. goto ACK_EXIT;
  532. }
  533. if(!pReceive){
  534. if(flags & RLY){
  535. UINT MsgIdDelta;
  536. DWORD bit;
  537. MsgIdDelta=(pCmdInfo->messageid - pSession->FirstRlyReceive)&IDMSK;
  538. bit=MsgIdDelta-1;
  539. if((bit > MAX_LARGE_CSENDS) || (pSession->InMsgMask & (1<<bit))){
  540. DPF(9,"GetReceive: dropping extraneous rexmit data\n");
  541. if(flags & (EOM|SAK)) {
  542. // RE-ACK the message.
  543. DPF(9,"GetReceive: Sending extra ACK anyway\n");
  544. goto ACK_EXIT;
  545. }
  546. goto exit; // Drop it, this is for an old message.
  547. } else {
  548. // if( (MsgIdDelta==0) ||
  549. // ((pSession->fReceiveSmall)?(MsgIdDelta > MAX_SMALL_CSENDS):(MsgIdDelta > MAX_LARGE_CSENDS))){
  550. // DPF(5,"GetReceive: dropping extraneous rexmit data\n");
  551. // if(flags & EOM|SAK) {
  552. // // RE-ACK the message.
  553. // DPF(5,"GetReceive: Sending extra ACK anyway\n");
  554. // goto ACK_EXIT;
  555. // }
  556. // goto exit; // Drop it, this is for an old message.
  557. // } else {
  558. if(flags & STA){
  559. if(pSession->LastRlyReceive==pCmdInfo->messageid){
  560. DPF(9,"RECEIVE: dropping resend for messageid x%x, but ACKING\n",pCmdInfo->messageid);
  561. // RE-ACK the message.
  562. goto ACK_EXIT;
  563. }
  564. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive)&IDMSK)<MsgIdDelta){
  565. pSession->LastRlyReceive=pCmdInfo->messageid;
  566. DPF(9,"GetReceive: New messageid x%x FirstRcv %x LastRcv %x\n",pCmdInfo->messageid,pSession->FirstRlyReceive,pSession->LastRlyReceive);
  567. #ifdef DEBUG
  568. if(!pSession->fReceiveSmall){
  569. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive) & 0xFFFF) > MAX_LARGE_CSENDS){
  570. ASSERT(0);
  571. }
  572. } else {
  573. if(((pSession->LastRlyReceive-pSession->FirstRlyReceive) & 0x0FF) > MAX_SMALL_CSENDS){
  574. ASSERT(0);
  575. }
  576. }
  577. #endif
  578. }
  579. }
  580. }
  581. } else {
  582. // Nonreliable, blow away any messages outside the window.
  583. // also blow away any residual messages with same number if we are a START.
  584. pBiHead = &pSession->pDGReceiveQ;
  585. pBilink = pBiHead->next;
  586. while( pBilink != pBiHead ){
  587. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  588. ASSERT_SIGN(pReceiveWalker, RECEIVE_SIGN);
  589. pBilink=pBilink->next;
  590. if(!pReceiveWalker->fBusy &&
  591. ( (((pCmdInfo->messageid - pReceiveWalker->messageid) & IDMSK ) > ((pSession->fReceiveSmallDG)?(MAX_SMALL_DG_CSENDS):(MAX_LARGE_DG_CSENDS))) ||
  592. ((flags&STA) && pCmdInfo->messageid==pReceiveWalker->messageid)
  593. )
  594. ){
  595. Lock(&pReceiveWalker->ReceiveLock);
  596. if(!pReceiveWalker->fBusy){
  597. DPF(9,"GetReceive: Got Id %d Throwing Out old Datagram Receive id %d\n",pCmdInfo->messageid,pReceiveWalker->messageid);
  598. Delete(&pReceiveWalker->pReceiveQ);
  599. Unlock(&pReceiveWalker->ReceiveLock);
  600. FreeReceive(pProtocol,pReceiveWalker);
  601. } else {
  602. ASSERT(0);
  603. DPF(0,"GetReceive: Got Id %d Couldn't throw out DG id %d\n",pCmdInfo->messageid,pReceiveWalker->messageid);
  604. Unlock(&pReceiveWalker->ReceiveLock);
  605. }
  606. }
  607. }
  608. }
  609. // Allocate a receive structure
  610. if(flags & STA){
  611. pReceive=GetRcvDesc(pProtocol);
  612. DPF(9,"allocated new receive %x messageid x%x\n",pReceive,pCmdInfo->messageid);
  613. if(!pReceive){
  614. // no memory, drop it.
  615. ASSERT(0);
  616. DPF(0,"RECEIVE: no memory! dropping packet\n");
  617. goto exit;
  618. }
  619. pReceive->pSession = pSession;
  620. pReceive->fBusy = FALSE;
  621. pReceive->fReliable = flags&RLY;
  622. pReceive->fEOM = FALSE;
  623. pReceive->command = pCmdInfo->command;
  624. pReceive->messageid = pCmdInfo->messageid;
  625. pReceive->iNR = 0;
  626. pReceive->NR = 0;
  627. pReceive->NS = 0;
  628. pReceive->RCVMask = 0;
  629. pReceive->MessageSize = 0;
  630. InitBilink(&pReceive->RcvBuffList);
  631. Lock(&pReceive->ReceiveLock);
  632. if(flags & RLY){
  633. // Set bit in incoming receive mask;
  634. DebugScanForMessageId(&pSession->pRlyReceiveQ, pCmdInfo->messageid);
  635. InsertAfter(&pReceive->pReceiveQ,&pSession->pRlyReceiveQ);
  636. } else {
  637. DebugScanForMessageId(&pSession->pDGReceiveQ, pCmdInfo->messageid);
  638. InsertAfter(&pReceive->pReceiveQ,&pSession->pDGReceiveQ);
  639. }
  640. // Save the SP header for indications
  641. if(pCmdInfo->pSPHeader){
  642. pReceive->pSPHeader=&pReceive->SPHeader[0];
  643. memcpy(pReceive->pSPHeader, pCmdInfo->pSPHeader, pProtocol->m_dwSPHeaderSize);
  644. } else {
  645. pReceive->pSPHeader=NULL;
  646. }
  647. }
  648. }
  649. exit:
  650. Unlock(&pSession->SessionLock);
  651. unlocked_exit:
  652. DPF(9,"<==GetReceive pSession %x pReceive %x\n",pSession, pReceive);
  653. return pReceive;
  654. #undef flags
  655. ACK_EXIT:
  656. Unlock(&pSession->SessionLock);
  657. SendACK(pProtocol,pSession,pCmdInfo);
  658. goto unlocked_exit;
  659. }
  660. VOID PutBufferOnReceive(PRECEIVE pReceive, PBUFFER pBuffer)
  661. {
  662. BILINK *pBilink;
  663. PBUFFER pBuffWalker;
  664. pBilink=pReceive->RcvBuffList.prev;
  665. while(pBilink != &pReceive->RcvBuffList){
  666. pBuffWalker=CONTAINING_RECORD(pBilink, BUFFER, BuffList);
  667. #ifdef DEBUG
  668. if(pBuffWalker->sequence==pBuffer->sequence){
  669. DPF(0,"already have sequence queued?\n");
  670. DEBUG_BREAK();
  671. break;
  672. }
  673. #endif
  674. if(pBuffWalker->sequence < pBuffer->sequence){
  675. break;
  676. }
  677. pBilink=pBilink->prev;
  678. }
  679. InsertAfter(&pBuffer->BuffList, pBilink);
  680. }
  681. // Chains receives that must be also be completed on this Receive
  682. VOID ChainReceiveFromQueue(PSESSION pSession, PRECEIVE pReceive, UINT messageid)
  683. {
  684. BOOL bFound=FALSE;
  685. BILINK *pBilink;
  686. PRECEIVE pReceiveWalker;
  687. DPF(9,"==>ChainReceiveFromQueue on pReceive %x, chain messageid x%x\n",pReceive,messageid);
  688. ASSERT(messageid!=pReceive->messageid);
  689. ASSERT(!EMPTY_BILINK(&pSession->pRlyWaitingQ));
  690. pBilink=pSession->pRlyWaitingQ.next;
  691. while(pBilink != &pSession->pRlyWaitingQ){
  692. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  693. if(pReceiveWalker->messageid==messageid){
  694. bFound=TRUE;
  695. break;
  696. }
  697. pBilink=pBilink->next;
  698. }
  699. if(bFound){
  700. // store in order on pReceive->pReceiveQ
  701. Delete(&pReceiveWalker->pReceiveQ);
  702. InsertBefore(&pReceiveWalker->pReceiveQ,&pReceive->pReceiveQ);
  703. DPF(9,"<==ChainReceiveFromQueue: Chained pReceiveWalker %x messageid x%x on pReceive %x\n",pReceiveWalker, pReceiveWalker->messageid, pReceive);
  704. } else {
  705. #ifdef DEBUG
  706. DPF(9,"<==ChainReceiveFromQueue, messageid x%x NOT FOUND!!!, Maybe out of order receive\n",messageid);
  707. if(!(pSession->pProtocol->m_lpDPlay->dwFlags & DPLAYI_DPLAY_PROTOCOLNOORDER)){
  708. DPF(0,"<==ChainReceiveFromQueue, messageid x%x NOT FOUND!!!, NOT ALLOWED with PRESERVE ORDER\n",messageid);
  709. DEBUG_BREAK();
  710. }
  711. #endif
  712. }
  713. }
  714. VOID BlowAwayOldReceives(PSESSION pSession, DWORD messageid, DWORD MASK)
  715. {
  716. BOOL fFoundReceive=FALSE;
  717. BILINK *pBiHead, *pBilink;
  718. PRECEIVE pReceive=NULL;
  719. pBiHead = &pSession->pRlyReceiveQ;
  720. pBilink = pBiHead->next;
  721. while(pBilink != pBiHead){
  722. pReceive=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  723. ASSERT_SIGN(pReceive, RECEIVE_SIGN);
  724. pBilink=pBilink->next;
  725. if((int)((pReceive->messageid-messageid)&MASK) <= 0){
  726. Lock(&pReceive->ReceiveLock);
  727. if(!pReceive->fBusy){
  728. DPF(8,"Blowing away duplicate receive %x id\n",pReceive, pReceive->messageid);
  729. Delete(&pReceive->pReceiveQ);
  730. Unlock(&pReceive->ReceiveLock);
  731. FreeReceive(pSession->pProtocol, pReceive);
  732. } else {
  733. DPF(0,"Huston, we have a problem pSession %x, pReceive %x, messageid %d\n",pSession,pReceive,messageid);
  734. DEBUG_BREAK();
  735. Unlock(&pReceive->ReceiveLock);
  736. }
  737. }
  738. }
  739. }
  740. // called with receive lock held, SESSIONion lock unheld,
  741. // returns with receivelock unheld, but receive not on any lists.
  742. // 0xFFFFFFFF means receive was bogus and blown away
  743. UINT DeQueueReceive(PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  744. {
  745. UINT bit;
  746. UINT nComplete=0;
  747. DPF(9,"==>DQReceive pReceive %x, messageid x%x\n",pReceive, pReceive->messageid);
  748. pReceive->fBusy=TRUE;
  749. Unlock(&pReceive->ReceiveLock);
  750. Lock(&pSession->SessionLock);
  751. Lock(&pReceive->ReceiveLock);
  752. // Pull off of receive Q
  753. Delete(&pReceive->pReceiveQ);
  754. InitBilink(&pReceive->pReceiveQ); // so we can chain on here.
  755. pReceive->fBusy=FALSE;
  756. bit=((pReceive->messageid-pSession->FirstRlyReceive)&IDMSK)-1;
  757. if(bit >= MAX_LARGE_CSENDS){
  758. // Duplicate receive, blow it away
  759. Unlock(&pReceive->ReceiveLock);
  760. FreeReceive(pSession->pProtocol,pReceive);
  761. Unlock(&pSession->SessionLock);
  762. return 0xFFFFFFFF;
  763. }
  764. #ifdef DEBUG
  765. if(pSession->InMsgMask > (UINT)((1<<((pSession->LastRlyReceive-pSession->FirstRlyReceive)&IDMSK))-1)){
  766. DPF(0,"Bad InMsgMask %x pSession %x\n", pSession->InMsgMask, pSession);
  767. DEBUG_BREAK();
  768. }
  769. #endif
  770. pSession->InMsgMask |= 1<<bit;
  771. while(pSession->InMsgMask&1){
  772. nComplete++;
  773. pSession->FirstRlyReceive=(pSession->FirstRlyReceive+1)&IDMSK;
  774. BlowAwayOldReceives(pSession, pSession->FirstRlyReceive,IDMSK);
  775. if(nComplete > 1){
  776. // Chain extra receives to be indicated on this receive.
  777. ChainReceiveFromQueue(pSession, pReceive,pSession->FirstRlyReceive);
  778. }
  779. pSession->InMsgMask>>=1;
  780. }
  781. #ifdef DEBUG
  782. DPF(9,"DQ: FirstRcv %x LastRcv %x\n",pSession->FirstRlyReceive,pSession->LastRlyReceive);
  783. if((pSession->LastRlyReceive-pSession->FirstRlyReceive & IDMSK) > MAX_LARGE_CSENDS){
  784. DEBUG_BREAK();
  785. }
  786. #endif
  787. Unlock(&pReceive->ReceiveLock);
  788. Unlock(&pSession->SessionLock);
  789. DPF(9,"<==DQReceive pReceive %x nComplete %d\n",pReceive,nComplete);
  790. return nComplete;
  791. }
  792. // called with receive lock held, SESSIONion lock unheld,
  793. // returns with receivelock unheld, but receive not on any lists.
  794. VOID DGDeQueueReceive(PSESSION pSession, PRECEIVE pReceive)
  795. {
  796. pReceive->fBusy=TRUE;
  797. Unlock(&pReceive->ReceiveLock);
  798. Lock(&pSession->SessionLock);
  799. Lock(&pReceive->ReceiveLock);
  800. // Pull off of receive Q
  801. Delete(&pReceive->pReceiveQ);
  802. InitBilink(&pReceive->pReceiveQ);
  803. pReceive->fBusy=FALSE;
  804. Unlock(&pReceive->ReceiveLock);
  805. Unlock(&pSession->SessionLock);
  806. }
  807. #ifdef DEBUG
  808. VOID CheckWaitingQ(PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  809. {
  810. BILINK *pBilink;
  811. PRECEIVE pReceiveWalker;
  812. UINT iReceiveWalker;
  813. UINT iReceive; // our index based on FirstRlyReceive
  814. DPF(9,"==>Check WaitingQ\n");
  815. Lock(&pSession->SessionLock);
  816. iReceive=(pReceive->messageid-pSession->FirstRlyReceive)&IDMSK;
  817. pBilink=pSession->pRlyWaitingQ.next;
  818. while(pBilink != &pSession->pRlyWaitingQ){
  819. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  820. iReceiveWalker=(pReceiveWalker->messageid-pSession->FirstRlyReceive)&IDMSK;
  821. if((int)iReceiveWalker < 0){
  822. DEBUG_BREAK();
  823. }
  824. if(iReceiveWalker == iReceive){
  825. DPF(9,"Found Duplicate Receive index %d on WaitingQ %x pSession %x\n",iReceiveWalker, &pSession->pRlyWaitingQ, pSession);
  826. // found our insert point.
  827. break;
  828. }
  829. pBilink=pBilink->next;
  830. }
  831. Unlock(&pSession->SessionLock);
  832. DPF(9,"<==CheckWaitingQ\n");
  833. }
  834. #else
  835. #define CheckWaitingQ
  836. #endif
  837. #ifdef DEBUG
  838. VOID DUMPBYTES(PCHAR pBytes, DWORD nBytes)
  839. {
  840. UCHAR Target[16];
  841. INT i;
  842. i=0;
  843. while(nBytes){
  844. memset(Target,0,16);
  845. if(nBytes > 16){
  846. memcpy(Target,pBytes+i*16,16);
  847. nBytes-=16;
  848. } else {
  849. memcpy(Target,pBytes+i*16,nBytes);
  850. nBytes=0;
  851. }
  852. DPF(9,"%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i*16,
  853. Target[0],Target[1],Target[2],Target[3],Target[4],Target[5],Target[6],Target[7],
  854. Target[8],Target[9],Target[10],Target[11],Target[12],Target[13],Target[14],Target[15]);
  855. i++;
  856. }
  857. }
  858. #else
  859. #define DUMPBYTES(a,b)
  860. #endif
  861. // Out of order reliable message, queue it up on the session.
  862. VOID QueueReceive(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo)
  863. {
  864. BILINK *pBilink;
  865. PRECEIVE pReceiveWalker;
  866. UINT iReceiveWalker;
  867. UINT iReceive; // our index based on FirstRlyReceive
  868. DPF(9,"==>QueueReceive Out of order pReceive %x messageid x%x\n",pReceive,pReceive->messageid);
  869. Lock(&pSession->SessionLock);
  870. // Don't need the receive lock since receive already dequeued.
  871. // insert the receive into the pRlyWaitingQ, in order -
  872. // based pSession->FirstRlyReceive IDMSK
  873. // list is ordered left to right, scan from end for our slot.
  874. CheckWaitingQ(pSession, pReceive, pCmdInfo);
  875. iReceive=(pReceive->messageid-pSession->FirstRlyReceive)&IDMSK;
  876. pBilink=pSession->pRlyWaitingQ.prev;
  877. while(pBilink != &pSession->pRlyWaitingQ){
  878. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  879. iReceiveWalker=(pReceiveWalker->messageid-pSession->FirstRlyReceive)&IDMSK;
  880. if((int)iReceiveWalker < 0){
  881. DEBUG_BREAK();
  882. }
  883. if(iReceiveWalker < iReceive){
  884. // found our insert point.
  885. break;
  886. }
  887. pBilink=pBilink->prev;
  888. }
  889. // insert in the list.
  890. InsertAfter(&pReceive->pReceiveQ,pBilink);
  891. Unlock(&pSession->SessionLock);
  892. DPF(9,"<==QueueReceive Out of order pReceive\n");
  893. }
  894. VOID IndicateReceive(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, UINT nToIndicate)
  895. {
  896. PDOUBLEBUFFER pDoubleBuffer;
  897. MEMDESC memdesc;
  898. BILINK *pBilink, *pBilinkAnchor;
  899. PRECEIVE pReceiveWalker;
  900. DPF(9,"==>IndicateReceive pReceive %x nToIndicate %d\n",pReceive,nToIndicate);
  901. pBilink=pBilinkAnchor=&pReceive->pReceiveQ;
  902. do{
  903. pReceiveWalker=CONTAINING_RECORD(pBilink, RECEIVE, pReceiveQ);
  904. // Assemble the message into one frame (if it isn't already)
  905. if(pReceiveWalker->iNR==1){
  906. // one frame.
  907. PBUFFER pBuffer;
  908. pBuffer=CONTAINING_RECORD(pReceiveWalker->RcvBuffList.next, BUFFER, BuffList);
  909. LEAVE_DPLAY();
  910. DPF(9,"Single Indicating pReceive %x messageid x%x\n",pReceiveWalker, pReceiveWalker->messageid);
  911. DUMPBYTES(pBuffer->pCmdData, min((UINT32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)),48));
  912. InternalHandleMessage(pProtocol->m_lpISP,
  913. pBuffer->pCmdData,
  914. (ULONG32)(pBuffer->len-(pBuffer->pCmdData-pBuffer->pData)),
  915. pReceiveWalker->pSPHeader,0);
  916. ENTER_DPLAY();
  917. } else {
  918. // multiple frames, copy to a contiguous chunk.
  919. pDoubleBuffer=GetDoubleBuffer(pReceiveWalker->MessageSize);
  920. if(pDoubleBuffer){
  921. memdesc.pData=pDoubleBuffer->pData;
  922. memdesc.len=pDoubleBuffer->len;
  923. CopyReceiveBuffers(pReceiveWalker,&memdesc,1);
  924. LEAVE_DPLAY();
  925. DPF(9,"Multi Indicating pReceive %x messageid x%x\n",pReceiveWalker, pReceiveWalker->messageid);
  926. DUMPBYTES(memdesc.pData, min(memdesc.len,48));
  927. InternalHandleMessage(pProtocol->m_lpISP,
  928. memdesc.pData,
  929. memdesc.len,
  930. pReceiveWalker->pSPHeader,0);
  931. ENTER_DPLAY();
  932. FreeDoubleBuffer((PBUFFER)pDoubleBuffer);
  933. } else {
  934. DPF(0,"NO MEMORY, MESSAGE DROPPED!\n");
  935. ASSERT(0);
  936. }
  937. }
  938. pBilink=pBilink->next;
  939. FreeReceive(pProtocol, pReceiveWalker);
  940. } while (pBilink != pBilinkAnchor);
  941. DPF(9,"<==IndicateReceive\n");
  942. }
  943. // called with receive lock held, must release
  944. int ReliableAccept(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  945. {
  946. int rc=0,rc2;
  947. UINT sequence;
  948. UINT bit;
  949. UINT bitmask;
  950. UINT nToIndicate;
  951. // if its moving, we already have all the data, so drop this.(OPTIMIZATION: maybe ACK again?)
  952. if(!pReceive->fBusy){
  953. bit=(pCmdInfo->sequence-pReceive->NR-1 ) & SEQMSK;
  954. if(bit < 32){
  955. // Calculate absolute sequence number of this packet.
  956. pBuffer->sequence = sequence = (bit+1) + pReceive->iNR;
  957. bitmask=1<<bit;
  958. if((pReceive->RCVMask & bitmask)){
  959. rc=FALSE; // already got this one - reject.
  960. } else {
  961. // Accept it.
  962. PutBufferOnReceive(pReceive,pBuffer);
  963. pReceive->MessageSize+=(UINT)((pBuffer->pData+pBuffer->len)-pBuffer->pCmdData);
  964. pReceive->RCVMask |= bitmask;
  965. if( ((pReceive->NS-pReceive->NR)&SEQMSK) <= bit){
  966. pReceive->NS=(pReceive->NR+bit+1)&SEQMSK;
  967. }
  968. // update NR based on set received bits.
  969. while(pReceive->RCVMask & 1){
  970. pReceive->RCVMask >>= 1;
  971. pReceive->iNR++;
  972. pReceive->NR=(pReceive->NR+1)&SEQMSK;
  973. }
  974. DPF(9,"Reliable ACCEPT: pReceive %x messageid %x iNR %8x NR %2x, NS %2x RCVMask %8x, SEQMSK %2x\n",pReceive, pReceive->messageid, pReceive->iNR, pReceive->NR,pReceive->NS,pReceive->RCVMask,SEQMSK);
  975. rc=TRUE; // packet accepted.
  976. }
  977. } else {
  978. DPF(9,"Reliable ACCEPT: Rejecting Packet Seq %x, NR %x, SEQMSK %x\n",pCmdInfo->sequence, pReceive->NR, SEQMSK);
  979. }
  980. if(pCmdInfo->flags & (SAK|EOM)) {
  981. //ACKrc=SendAppropriateResponse, check code, if ACK on EOM, then POST receive.
  982. rc2=SendAppropriateResponse(pProtocol, pSession, pCmdInfo, pReceive);
  983. if(pCmdInfo->flags & EOM){
  984. if(rc2==SAR_ACK){
  985. goto ReceiveDone;
  986. } else {
  987. pReceive->fEOM=TRUE;
  988. }
  989. } else if(pReceive->fEOM){
  990. if(!pReceive->RCVMask){
  991. goto ReceiveDone;
  992. }
  993. }
  994. }
  995. } else {
  996. ASSERT(0);
  997. }
  998. Unlock(&pReceive->ReceiveLock);
  999. return rc;
  1000. ReceiveDone:
  1001. DPF(9,"++>ReceiveDone\n");
  1002. if(nToIndicate=DeQueueReceive(pSession, pReceive, pCmdInfo)){ // unlocks pReceive->ReceiveLock
  1003. if(nToIndicate != 0xFFFFFFFF){
  1004. IndicateReceive(pProtocol, pSession, pReceive, nToIndicate);
  1005. }
  1006. } else if(pProtocol->m_lpDPlay->dwFlags & DPLAYI_DPLAY_PROTOCOLNOORDER){
  1007. // Out of order receives are OK
  1008. IndicateReceive(pProtocol, pSession, pReceive, 1);
  1009. } else {
  1010. QueueReceive(pProtocol,pSession,pReceive, pCmdInfo);
  1011. }
  1012. DPF(9,"<--ReceiveDone\n");
  1013. return rc;
  1014. }
  1015. // Returns highest order byte in n with set bits.
  1016. UINT SetBytes(UINT n)
  1017. {
  1018. UINT nr;
  1019. if(n==(n&0xFFFF)){
  1020. if(n==(n&0xFF)){
  1021. nr=1;
  1022. } else {
  1023. nr=2;
  1024. }
  1025. } else {
  1026. if(n==(n&0xFFFFFF)){
  1027. nr=3;
  1028. } else {
  1029. nr=4;
  1030. }
  1031. }
  1032. return nr;
  1033. }
  1034. VOID InternalSendComplete(PVOID Context, UINT Status)
  1035. {
  1036. PSEND pSend=(PSEND)Context;
  1037. if(pSend->dwFlags & ASEND_PROTOCOL){
  1038. // nothing to do?
  1039. } else if(pSend->bSendEx){
  1040. // send completion if required
  1041. if(pSend->dwFlags & DPSEND_ASYNC){
  1042. DP_SP_SendComplete(pSend->pProtocol->m_lpISP, pSend->lpvUserMsgID, Status);
  1043. }
  1044. }
  1045. }
  1046. // Used by internal routines for sending.
  1047. VOID FillInAndSendBuffer(
  1048. PPROTOCOL pProtocol,
  1049. PSESSION pSession,
  1050. PSEND pSend,
  1051. PBUFFER pBuffer,
  1052. PCMDINFO pCmdInfo)
  1053. {
  1054. pSend->pMessage = pBuffer;
  1055. pSend->MessageSize = pBuffer->len;
  1056. pSend->pSession = pSession;
  1057. pSend->SendOffset = 0;
  1058. pSend->pCurrentBuffer = pBuffer;
  1059. pSend->CurrentBufferOffset = 0;
  1060. pSend->RefCount = 0;
  1061. pSend->pProtocol = pProtocol;
  1062. pSend->dwMsgID = 0;
  1063. pSend->bSendEx = FALSE;
  1064. // pSend->BytesThisSend = 0;
  1065. // Internal sends MUST be highest pri - else can deadlock head to head.
  1066. pSend->Priority = 0xFFFFFFFF;
  1067. pSend->dwFlags = ASEND_PROTOCOL;
  1068. pSend->dwTimeOut = 0;
  1069. pSend->pAsyncInfo = 0;
  1070. pSend->AsyncInfo.hEvent = 0;
  1071. pSend->AsyncInfo.SendCallBack = InternalSendComplete;
  1072. pSend->AsyncInfo.CallBackContext = pSend;
  1073. pSend->AsyncInfo.pStatus = &pSend->Status;
  1074. pSend->SendState = Start;
  1075. pSend->RetryCount = 0;
  1076. pSend->PacketSize = pSession->MaxPacketSize;
  1077. pSend->NR = 0;
  1078. pSend->NS = 0;
  1079. pSend->idFrom = pCmdInfo->idTo;
  1080. pSend->idTo = pCmdInfo->idFrom;
  1081. pSend->wIdTo = pCmdInfo->wIdFrom;
  1082. pSend->serial = 0;
  1083. ISend(pProtocol,pSession,pSend);
  1084. }
  1085. UINT WrapBuffer(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1086. {
  1087. PUCHAR pMessage,pMessageStart;
  1088. DWORD dwWrapSize=0;
  1089. DWORD dwIdTo=0;
  1090. DWORD dwIdFrom=0;
  1091. pMessageStart = &pBuffer->pData[pProtocol->m_dwSPHeaderSize];
  1092. pMessage = pMessageStart;
  1093. dwIdFrom = pCmdInfo->wIdTo;
  1094. dwIdTo = pCmdInfo->wIdFrom;
  1095. if(dwIdFrom==0x70){ // avoid looking like a system message 'play'
  1096. dwIdFrom=0xFFFF;
  1097. }
  1098. if(dwIdFrom){
  1099. while(dwIdFrom){
  1100. *pMessage=(UCHAR)(dwIdFrom & 0x7F);
  1101. dwIdFrom >>= 7;
  1102. if(dwIdFrom){
  1103. *pMessage|=0x80;
  1104. }
  1105. pMessage++;
  1106. }
  1107. } else {
  1108. *(pMessage++)=0;
  1109. }
  1110. if(dwIdTo){
  1111. while(dwIdTo){
  1112. *pMessage=(UCHAR)(dwIdTo & 0x7F);
  1113. dwIdTo >>= 7;
  1114. if(dwIdTo){
  1115. *pMessage|=0x80;
  1116. }
  1117. pMessage++;
  1118. }
  1119. } else {
  1120. *(pMessage++)=0;
  1121. }
  1122. return (UINT)(pMessage-pMessageStart);
  1123. }
  1124. UINT SendAppropriateResponse(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo, PRECEIVE pReceive)
  1125. {
  1126. #define pBigACK ((pACK2)pACK)
  1127. #define pBigNACK ((pNACK2)pNACK)
  1128. UINT rc=SAR_FAIL;
  1129. PSEND pSend;
  1130. PBUFFER pBuffer;
  1131. pFLAGS pFlags;
  1132. pACK1 pACK;
  1133. pNACK1 pNACK;
  1134. UINT RCVMask;
  1135. UINT WrapSize;
  1136. // OPTIMIZATION: piggyback ACK on pending send if available.
  1137. pSend=GetSendDesc();
  1138. if(!pSend){
  1139. goto exit1;
  1140. }
  1141. pBuffer = GetFrameBuffer(pProtocol->m_dwSPHeaderSize+MAX_SYS_HEADER);
  1142. if(!pBuffer){
  1143. goto exit2; // out of memory, bail
  1144. }
  1145. WrapSize = pProtocol->m_dwSPHeaderSize;
  1146. WrapSize += WrapBuffer(pProtocol, pCmdInfo, pBuffer);
  1147. pFlags=(pFLAGS)&pBuffer->pData[WrapSize];
  1148. // See if we need to ACK or NACK.
  1149. if(pReceive->RCVMask){
  1150. UINT nNACK=SetBytes(pReceive->RCVMask);
  1151. rc=SAR_NACK;
  1152. // Send a NACK
  1153. if(pCmdInfo->flags & BIG){
  1154. // BIG HEADER FORMAT NACK
  1155. pNACK=(pNACK1)(&pFlags->flag3);
  1156. pFlags->flag1 = EXT|BIG|RLY;
  1157. pFlags->flag2 = (byte)nNACK;
  1158. pBigNACK->sequence = (word)pReceive->NR;
  1159. pBigNACK->messageid = (word)pReceive->messageid;
  1160. pBigNACK->time = pCmdInfo->tReceived;
  1161. pBigNACK->bytes = pSession->LocalBytesReceived;
  1162. RCVMask=pReceive->RCVMask;
  1163. memcpy(&pBigNACK->mask, &RCVMask, nNACK);
  1164. pBuffer->len=WrapSize+2+sizeof(NACK2)+nNACK; // 2 for flags
  1165. } else {
  1166. // SMALL HEADER FORMAT NACK
  1167. pNACK=(pNACK1)(&pFlags->flag3);
  1168. pFlags->flag1 = EXT|RLY;
  1169. ASSERT(nNACK < 4);
  1170. ASSERT(pReceive->NR < 32);
  1171. pFlags->flag2 = nNACK << nNACK_SHIFT;
  1172. pNACK->messageid=(byte)pReceive->messageid;
  1173. pNACK->sequence=(byte)pReceive->NR;
  1174. pNACK->time = pCmdInfo->tReceived;
  1175. pNACK->bytes = pSession->LocalBytesReceived;
  1176. RCVMask=pReceive->RCVMask;
  1177. memcpy(&pNACK->mask, &RCVMask, nNACK);
  1178. pBuffer->len=WrapSize+2+sizeof(NACK1)+nNACK; // 2 for flags
  1179. DPF(9,"RcvMask %x Send Appropriate response nNACK=%d\n",pReceive->RCVMask,nNACK);
  1180. }
  1181. } else {
  1182. // Send an ACK
  1183. rc=SAR_ACK;
  1184. pACK = (pACK1)(&pFlags->flag2);
  1185. if(pCmdInfo->flags & BIG){
  1186. // Big packet
  1187. pFlags->flag1 = ACK|BIG;
  1188. pBigACK->messageid= (word)pReceive->messageid;
  1189. pBigACK->sequence = pCmdInfo->sequence;
  1190. pBigACK->serial = pCmdInfo->serial;
  1191. pBigACK->time = pCmdInfo->tReceived;
  1192. pBigACK->bytes = pSession->LocalBytesReceived;
  1193. pBuffer->len = sizeof(ACK2)+1+WrapSize;
  1194. } else {
  1195. // Small packet
  1196. pFlags->flag1 = ACK;
  1197. pACK->messageid = (byte)pReceive->messageid;
  1198. pACK->sequence = (UCHAR)pCmdInfo->sequence;
  1199. pACK->serial = pCmdInfo->serial;
  1200. pACK->time = pCmdInfo->tReceived;
  1201. pACK->bytes = pSession->LocalBytesReceived;
  1202. pBuffer->len = sizeof(ACK1)+1+WrapSize;
  1203. DPF(9,"RcvMask %x Send Appropriate response ACK seq=%x\n",pReceive->RCVMask,pACK->sequence);
  1204. }
  1205. }
  1206. pFlags->flag1 |= (pCmdInfo->flags & RLY);
  1207. FillInAndSendBuffer(pProtocol,pSession,pSend,pBuffer,pCmdInfo);
  1208. exit1:
  1209. return rc;
  1210. exit2:
  1211. ReleaseSendDesc(pSend);
  1212. return rc;
  1213. #undef pBigACK
  1214. #undef pBigNACK
  1215. }
  1216. // ACKs CmdInfo packet.
  1217. VOID SendACK(PPROTOCOL pProtocol, PSESSION pSession, PCMDINFO pCmdInfo)
  1218. {
  1219. #define pBigACK ((pACK2)pACK)
  1220. PSEND pSend;
  1221. PBUFFER pBuffer;
  1222. pFLAGS pFlags;
  1223. pACK1 pACK;
  1224. UINT WrapSize;
  1225. // OPTIMIZATION: piggyback ACK on pending send if available.
  1226. pSend=GetSendDesc();
  1227. if(!pSend){
  1228. goto exit1;
  1229. }
  1230. // allocation here is bigger than necessary but should
  1231. // recyle ACK/NACK buffers.
  1232. pBuffer = GetFrameBuffer(pProtocol->m_dwSPHeaderSize+MAX_SYS_HEADER);
  1233. if(!pBuffer){
  1234. goto exit2; // out of memory, bail
  1235. }
  1236. WrapSize = pProtocol->m_dwSPHeaderSize;
  1237. WrapSize += WrapBuffer(pProtocol, pCmdInfo, pBuffer);
  1238. pFlags=(pFLAGS)&pBuffer->pData[WrapSize];
  1239. pACK = (pACK1)(&pFlags->flag2);
  1240. if(pCmdInfo->flags & BIG){
  1241. // Big packet
  1242. pFlags->flag1 = ACK|BIG;
  1243. pBigACK->sequence = pCmdInfo->sequence;
  1244. pBigACK->serial = pCmdInfo->serial;
  1245. pBigACK->messageid= pCmdInfo->messageid;
  1246. pBigACK->bytes = pSession->LocalBytesReceived;
  1247. pBigACK->time = pCmdInfo->tReceived;
  1248. pBuffer->len = sizeof(ACK2)+1+WrapSize;
  1249. } else {
  1250. // Small packet
  1251. pFlags->flag1 = ACK;
  1252. pACK->messageid = (UCHAR)pCmdInfo->messageid;
  1253. pACK->sequence = (UCHAR)pCmdInfo->sequence;
  1254. pACK->serial = pCmdInfo->serial;
  1255. pACK->bytes = pSession->LocalBytesReceived;
  1256. pACK->time = pCmdInfo->tReceived;
  1257. pBuffer->len = sizeof(ACK1)+1+WrapSize;
  1258. DPF(9,"Send Extra ACK seq=%x, serial=%x\n",pACK->sequence,pACK->serial);
  1259. }
  1260. pFlags->flag1 |= (pCmdInfo->flags & RLY);
  1261. FillInAndSendBuffer(pProtocol,pSession,pSend,pBuffer,pCmdInfo);
  1262. exit1:
  1263. return;
  1264. exit2:
  1265. ReleaseSendDesc(pSend);
  1266. return;
  1267. }
  1268. // Called with receive lock. Returns without lock.
  1269. UINT DGAccept(PPROTOCOL pProtocol, PSESSION pSession, PRECEIVE pReceive, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1270. {
  1271. ASSERT(!pReceive->fBusy);
  1272. //if(!pReceive->fBusy){
  1273. // Allows datagram receive to start on any serial.
  1274. if(pCmdInfo->flags & STA){
  1275. pReceive->NR=pCmdInfo->serial;
  1276. }
  1277. if(pReceive->NR == pCmdInfo->serial){
  1278. pReceive->iNR++; //really unnecessary, but interesting.
  1279. pReceive->NR = (pReceive->NR+1) & SEQMSK;
  1280. // Add the buffer to the receive buffer list.
  1281. InsertBefore(&pBuffer->BuffList, &pReceive->RcvBuffList);
  1282. pReceive->MessageSize+=(UINT)((pBuffer->pData+pBuffer->len)-pBuffer->pCmdData);
  1283. if(pCmdInfo->flags & EOM){
  1284. DGDeQueueReceive(pSession, pReceive); //unlock's receive.
  1285. IndicateReceive(pProtocol, pSession, pReceive,1);
  1286. } else {
  1287. Unlock(&pReceive->ReceiveLock);
  1288. }
  1289. return TRUE; // ate the buffer.
  1290. } else {
  1291. // Throw this puppy out.
  1292. ASSERT(!pReceive->fBusy);
  1293. DGDeQueueReceive(pSession, pReceive);
  1294. FreeReceive(pProtocol, pReceive);
  1295. }
  1296. //}
  1297. return FALSE;
  1298. }
  1299. UINT CommandReceive(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PBUFFER pBuffer)
  1300. {
  1301. #define flags pCmdInfo->flags
  1302. PSESSION pSession;
  1303. UINT rc=0; // by default, buffer not accepted.
  1304. PRECEIVE pReceive;
  1305. pSession=GetSysSessionByIndex(pProtocol, pCmdInfo->wIdFrom);
  1306. if(!pSession) {
  1307. DPF(9,"CommandReceive: Throwing out receive for gone session\n");
  1308. goto drop_exit;
  1309. }
  1310. if(flags & BIG){
  1311. if(flags & RLY) {
  1312. pSession->fReceiveSmall=FALSE;
  1313. } else {
  1314. pSession->fReceiveSmallDG=FALSE;
  1315. }
  1316. }
  1317. // See if this receive is already ongoing - if found, it is locked.
  1318. pReceive=GetReceive(pProtocol, pSession, pCmdInfo, pBuffer);
  1319. if(pCmdInfo->command==0){
  1320. pSession->LocalBytesReceived+=pBuffer->len;
  1321. }
  1322. if(!(flags & RLY)){
  1323. if(flags & (SAK|EOM)) {
  1324. SendACK(pProtocol, pSession, pCmdInfo);
  1325. }
  1326. }
  1327. if(pReceive){
  1328. if(flags & RLY){
  1329. // unlocks receive when done.
  1330. rc=ReliableAccept(pProtocol, pSession, pReceive, pCmdInfo, pBuffer);
  1331. } else {
  1332. rc=DGAccept(pProtocol, pSession, pReceive, pCmdInfo, pBuffer);
  1333. }
  1334. }
  1335. DecSessionRef(pSession);
  1336. drop_exit:
  1337. return rc;
  1338. #undef flags
  1339. }
  1340. BOOL CompleteSend(PSESSION pSession, PSEND pSend, PCMDINFO pCmdInfo)
  1341. {
  1342. UINT bit;
  1343. UINT MsgMask;
  1344. pSend->SendState=Done;
  1345. if(pCmdInfo->flags & BIG){
  1346. MsgMask = 0xFFFF;
  1347. } else {
  1348. MsgMask = 0xFF;
  1349. }
  1350. DPF(9,"CompleteSend, pSession %x pSend %x\n",pSession,pSend);
  1351. //
  1352. // Update Session information for completion of this send.
  1353. //
  1354. bit = ((pCmdInfo->messageid-pSession->FirstMsg) & MsgMask)-1;
  1355. // clear the message mask bit for the completed send.
  1356. if(pSession->OutMsgMask & 1<<bit){
  1357. pSession->OutMsgMask &= ~(1<<bit);
  1358. } else {
  1359. Unlock(&pSession->SessionLock);
  1360. return TRUE;
  1361. }
  1362. // slide the first message count forward for each low
  1363. // bit clear in Message mask.
  1364. while(pSession->LastMsg-pSession->FirstMsg){
  1365. if(!(pSession->OutMsgMask & 1)){
  1366. pSession->FirstMsg=(pSession->FirstMsg+1)&MsgMask;
  1367. pSession->OutMsgMask >>= 1;
  1368. if(pSession->nWaitingForMessageid){
  1369. pSession->pProtocol->m_bRescanQueue=TRUE;
  1370. DPF(9,"Signalling reliable ID Sem, nWaitingForMessageid was %d\n",pSession->nWaitingForMessageid);
  1371. SetEvent(pSession->pProtocol->m_hSendEvent);
  1372. }
  1373. } else {
  1374. break;
  1375. }
  1376. }
  1377. //
  1378. // Return the Send to the pool and complete the waiting client.
  1379. //
  1380. Unlock(&pSession->SessionLock);
  1381. ASSERT(pSend->RefCount);
  1382. // Send completed, do completion
  1383. DoSendCompletion(pSend, DP_OK);
  1384. DecSendRef(pSession->pProtocol, pSend); // for completion.
  1385. return TRUE;
  1386. }
  1387. // called with session lock held
  1388. VOID ProcessDGACK(PSESSION pSession, PCMDINFO pCmdInfo)
  1389. {
  1390. BILINK *pBilink;
  1391. PSENDSTAT pStatWalker,pStat=NULL;
  1392. Lock(&pSession->SessionStatLock);
  1393. pBilink=pSession->DGStatList.next;
  1394. while(pBilink != &pSession->DGStatList){
  1395. pStatWalker=CONTAINING_RECORD(pBilink, SENDSTAT, StatList);
  1396. if((pStatWalker->messageid == pCmdInfo->messageid) && // correct messageid
  1397. (pStatWalker->sequence == pCmdInfo->sequence) // correct sequence
  1398. // don't check serial, since datagrams are always serial 0, never retried.
  1399. )
  1400. {
  1401. pStat=pStatWalker;
  1402. break;
  1403. }
  1404. pBilink=pBilink->next;
  1405. }
  1406. if(pStat){
  1407. UpdateSessionStats(pSession,pStat,pCmdInfo,FALSE);
  1408. // Unlink All Previous SENDSTATS;
  1409. pStat->StatList.next->prev=&pSession->DGStatList;
  1410. pSession->DGStatList.next=pStat->StatList.next;
  1411. // Put the SENDSTATS back in the pool.
  1412. while(pBilink != &pSession->DGStatList){
  1413. pStatWalker=CONTAINING_RECORD(pBilink, SENDSTAT, StatList);
  1414. pBilink=pBilink->prev;
  1415. ReleaseSendStat(pStatWalker);
  1416. }
  1417. }
  1418. Unlock(&pSession->SessionStatLock);
  1419. }
  1420. // update a send's information for an ACK.
  1421. // called with SESSIONion lock held.
  1422. // now always drops the sessionlock
  1423. BOOL ProcessReliableACK(PSESSION pSession, PCMDINFO pCmdInfo)
  1424. {
  1425. PSEND pSend=NULL, pSendWalker;
  1426. BILINK *pBilink;
  1427. UINT nFrame;
  1428. UINT nAdvance;
  1429. Unlock(&pSession->SessionLock);
  1430. Lock(&pSession->pProtocol->m_SendQLock);
  1431. Lock(&pSession->SessionLock);
  1432. pBilink=pSession->SendQ.next;
  1433. while(pBilink != &pSession->SendQ){
  1434. pSendWalker=CONTAINING_RECORD(pBilink, SEND, SendQ);
  1435. if((pSendWalker->messageid == pCmdInfo->messageid) && // correct messageid
  1436. (!(pSendWalker->dwFlags & ASEND_PROTOCOL)) && // not and internal message
  1437. (pSendWalker->dwFlags & DPSEND_GUARANTEED)){ // guaranteed
  1438. pSend=pSendWalker;
  1439. break;
  1440. }
  1441. pBilink=pBilink->next;
  1442. }
  1443. // need a reference to avoid processing a send as
  1444. // it is being recycled for another send.
  1445. if(pSend){
  1446. if(!AddSendRef(pSend,1)){
  1447. pSend=NULL;
  1448. }
  1449. }
  1450. Unlock(&pSession->pProtocol->m_SendQLock);
  1451. // SessionLock still held.
  1452. if(pSend){
  1453. Lock(&pSend->SendLock);
  1454. UpdateSessionSendStats(pSession,pSend,pCmdInfo,FALSE);
  1455. // we need to make sure this send isn't already finished.
  1456. switch(pSend->SendState){
  1457. case Sending:
  1458. case Throttled:
  1459. case WaitingForAck:
  1460. case WaitingForId:
  1461. case ReadyToSend:
  1462. break;
  1463. case Start: // shouldn't be getting an ACK for a send in the start state.
  1464. case TimedOut:
  1465. case Cancelled:
  1466. case UserTimeOut:
  1467. case Done:
  1468. // this send is already done, don't do processing on it.
  1469. DPF(4,"PRACK:Not processing ACK on send in State (B#22359 avoided)%x\n",pSend->SendState);
  1470. Unlock(&pSend->SendLock);
  1471. Unlock(&pSession->SessionLock);
  1472. DecSendRef(pSession->pProtocol,pSend); // balances AddSendRef in this fn
  1473. return TRUE; // SessionLock dropped
  1474. break;
  1475. default:
  1476. break;
  1477. }
  1478. pSend->fUpdate=TRUE;
  1479. nFrame=(pCmdInfo->sequence-pSend->NR)&pSend->SendSEQMSK;
  1480. if(nFrame > (pSend->NS - pSend->NR)){
  1481. // Out of range.
  1482. DPF(9,"ReliableACK:Got out of range ACK, SQMSK=%x NS=%d NR=%d ACK=%d\n",pSend->SendSEQMSK,pSend->NS&pSend->SendSEQMSK, pSend->NR&pSend->SendSEQMSK, (pSend->NR+nFrame)&pSend->SendSEQMSK);
  1483. Unlock(&pSend->SendLock);
  1484. Unlock(&pSession->SessionLock);
  1485. DecSendRef(pSession->pProtocol,pSend);
  1486. return TRUE; // SessionLock dropped
  1487. }
  1488. CancelRetryTimer(pSend);
  1489. DPF(9,"ProcessReliableACK (before): pSend->NR %x pSend->OpenWindow %x, pSend->NACKMask %x\n",pSend->NR, pSend->OpenWindow, pSend->NACKMask);
  1490. pSend->NR=(pSend->NR+nFrame);
  1491. pSend->OpenWindow -= nFrame;
  1492. pSend->NACKMask >>= nFrame;
  1493. ASSERT_NACKMask(pSend);
  1494. AdvanceSend(pSend,pSend->FrameDataLen*nFrame); // can put us past on the last frame, but that's ok.
  1495. DPF(9,"ProcessReliableACK: Send->nFrames %2x NR %2x NS %2x nFrame %2x NACKMask %x\n",pSend->nFrames,pSend->NR, pSend->NS, nFrame, pSend->NACKMask);
  1496. if(pSend->NR==pSend->nFrames){
  1497. // LAST ACK, we're done!
  1498. pSend->SendState=Done;
  1499. Unlock(&pSend->SendLock);
  1500. // SessionLock still held
  1501. CompleteSend(pSession, pSend, pCmdInfo);// drops SessionLock
  1502. DecSendRef(pSession->pProtocol,pSend);
  1503. return TRUE;
  1504. } else {
  1505. // set new "NACK bits" for extra window opening
  1506. if(pSend->NR+pSend->OpenWindow+nFrame > pSend->nFrames){
  1507. nAdvance=pSend->nFrames-(pSend->NR+pSend->OpenWindow);
  1508. DPF(9,"A nAdvance %d\n",nAdvance);
  1509. } else {
  1510. nAdvance=nFrame;
  1511. DPF(9,"B nAdvance %d\n",nAdvance);
  1512. }
  1513. pSend->NACKMask |= ((1<<nAdvance)-1)<<pSend->OpenWindow;
  1514. pSend->OpenWindow += nAdvance;
  1515. DPF(9,"pSend->NACKMask=%x\n",pSend->NACKMask);
  1516. ASSERT_NACKMask(pSend);
  1517. }
  1518. switch(pSend->SendState){
  1519. case Start:
  1520. DPF(1,"ERROR, ACK ON UNSTARTED SEND!\n");
  1521. ASSERT(0);
  1522. break;
  1523. case Done:
  1524. DPF(1,"ERROR, ACK ON DONE SEND!\n");
  1525. ASSERT(0);
  1526. break;
  1527. case WaitingForAck:
  1528. pSend->SendState=ReadyToSend;
  1529. SetEvent(pSession->pProtocol->m_hSendEvent);
  1530. break;
  1531. case ReadyToSend:
  1532. case Sending:
  1533. case Throttled:
  1534. default:
  1535. break;
  1536. }
  1537. Unlock(&pSend->SendLock);
  1538. } else {
  1539. DPF(9,"ProcessReliableACK: dup ACK ignoring\n");
  1540. }
  1541. Unlock(&pSession->SessionLock);
  1542. if(pSend){
  1543. DecSendRef(pSession->pProtocol, pSend);
  1544. }
  1545. return TRUE; // SessionLock dropped
  1546. }
  1547. //called with session lock held, always drops lock.
  1548. BOOL ProcessReliableNACK(PSESSION pSession, PCMDINFO pCmdInfo,PUCHAR pNACKmask, UINT nNACK)
  1549. {
  1550. UINT NACKmask=0;
  1551. UINT NACKshift=0;
  1552. PSEND pSend=NULL, pSendWalker;
  1553. BILINK *pBilink;
  1554. UINT nFrame;
  1555. UINT nAdvance;
  1556. UINT nAdvanceShift;
  1557. DWORD nDropped=0;
  1558. DPF(9,"==>ProcessReliableNACK\n");
  1559. Unlock(&pSession->SessionLock);
  1560. Lock(&pSession->pProtocol->m_SendQLock);
  1561. Lock(&pSession->SessionLock);
  1562. pBilink=pSession->SendQ.next;
  1563. while(pBilink != &pSession->SendQ){
  1564. pSendWalker=CONTAINING_RECORD(pBilink, SEND, SendQ);
  1565. if(pSendWalker->dwFlags & DPSEND_GUARANTEE &&
  1566. pSendWalker->messageid == pCmdInfo->messageid){
  1567. pSend=pSendWalker;
  1568. break;
  1569. }
  1570. pBilink=pBilink->next;
  1571. }
  1572. // need a reference to avoid processing a send as
  1573. // it is being recycled for another send.
  1574. if(pSend){
  1575. if(!AddSendRef(pSend,1)){
  1576. pSend=NULL;
  1577. }
  1578. }
  1579. Unlock(&pSession->pProtocol->m_SendQLock);
  1580. // SessionLock still held.
  1581. if(pSend){
  1582. Lock(&pSend->SendLock);
  1583. UpdateSessionSendStats(pSession,pSend,pCmdInfo,FALSE);
  1584. // we need to make sure this send isn't already finished.
  1585. switch(pSend->SendState){
  1586. case Sending:
  1587. case Throttled:
  1588. case WaitingForAck:
  1589. case WaitingForId:
  1590. case ReadyToSend:
  1591. break;
  1592. case Start: // shouldn't be getting an ACK for a send in the start state.
  1593. case TimedOut:
  1594. case Cancelled:
  1595. case UserTimeOut:
  1596. case Done:
  1597. // this send is already done, don't do processing on it.
  1598. DPF(4,"PRNACK:Not processing NACK on send in State (B#22359 avoided)%x\n",pSend->SendState);
  1599. Unlock(&pSend->SendLock);
  1600. Unlock(&pSession->SessionLock);
  1601. DecSendRef(pSession->pProtocol,pSend); // balances AddSendRef in this fn
  1602. return TRUE; // SessionLock dropped
  1603. break;
  1604. default:
  1605. break;
  1606. }
  1607. DPF(9,"Reliable NACK for Send %x, pCmdInfo %x\n",pSend, pCmdInfo);
  1608. pSend->fUpdate=TRUE;
  1609. // Do regular NR updates (OPTIMIZATION: fold with process reliable ACK)
  1610. nFrame=(pCmdInfo->sequence-pSend->NR) & pSend->SendSEQMSK;
  1611. if(nFrame > (pSend->NS - pSend->NR)){
  1612. // Out of range.
  1613. DPF(9,"ReliableNACK:Got out of range NACK, SQMSK=%x NS=%d NR=%d ACK=%d\n",pSend->SendSEQMSK,pSend->NS&pSend->SendSEQMSK, pSend->NR&pSend->SendSEQMSK, (pSend->NR+nFrame)&pSend->SendSEQMSK);
  1614. Unlock(&pSend->SendLock);
  1615. Unlock(&pSession->SessionLock);
  1616. DecSendRef(pSession->pProtocol,pSend);
  1617. return TRUE;
  1618. }
  1619. CancelRetryTimer(pSend);
  1620. DPF(9,"NACK0: pSend->NACKMask %x, OpenWindow %d\n",pSend->NACKMask, pSend->OpenWindow);
  1621. pSend->NR=(pSend->NR+nFrame);
  1622. pSend->OpenWindow -= nFrame;
  1623. pSend->NACKMask >>= nFrame;
  1624. ASSERT_NACKMask(pSend);
  1625. AdvanceSend(pSend,pSend->FrameDataLen*nFrame);
  1626. DPF(9,"ProcessReliableNACK: Send->nFrames %2x NR %2x NS %2x nFrame %2x NACKMask %x\n",pSend->nFrames,pSend->NR, pSend->NS, nFrame, pSend->NACKMask);
  1627. ASSERT(pSend->NR != pSend->nFrames);
  1628. // set new "NACK bits" for extra window opening
  1629. if(pSend->NR+pSend->OpenWindow+nFrame > pSend->nFrames){
  1630. nAdvance=pSend->nFrames-(pSend->NR+pSend->OpenWindow);
  1631. DPF(9, "NACK: 1 nAdvance %d\n",nAdvance);
  1632. } else {
  1633. nAdvance=nFrame;
  1634. DPF(9, "NACK: 2 nAdvance %d\n",nAdvance);
  1635. }
  1636. pSend->NACKMask |= ((1<<nAdvance)-1)<<pSend->OpenWindow;
  1637. DPF(9, "NACK Mask %x\n",pSend->NACKMask);
  1638. pSend->OpenWindow += nAdvance;
  1639. ASSERT_NACKMask(pSend);
  1640. while(nNACK--){
  1641. NACKmask |= (*(pNACKmask++))<<NACKshift;
  1642. NACKshift+=8;
  1643. }
  1644. DPF(9,"NACKmask in NACK %x\n",NACKmask);
  1645. // set the NACK mask.
  1646. nAdvanceShift=0;
  1647. while(NACKmask){
  1648. if(NACKmask&1){
  1649. // set bits are ACKs.
  1650. pSend->NACKMask&=~(1<<nAdvanceShift);
  1651. } else {
  1652. // clear bits are NACKs.
  1653. pSend->NACKMask|=1<<nAdvanceShift;
  1654. nDropped++;
  1655. }
  1656. NACKmask >>= 1;
  1657. nAdvanceShift++;
  1658. }
  1659. DPF(9,"ProcessReliableNACK: pSend->NACKMask=%x\n",pSend->NACKMask);
  1660. ASSERT_NACKMask(pSend);
  1661. UpdateSessionSendStats(pSession,pSend,pCmdInfo, ((nDropped > 1) ? TRUE:FALSE) );
  1662. switch(pSend->SendState){
  1663. case Start:
  1664. DPF(5,"ERROR, NACK ON UNSTARTED SEND!\n");
  1665. ASSERT(0);
  1666. break;
  1667. case Done:
  1668. DPF(5,"ERROR, NACK ON DONE SEND!\n");
  1669. ASSERT(0);
  1670. break;
  1671. case WaitingForAck:
  1672. pSend->SendState=ReadyToSend;
  1673. SetEvent(pSession->pProtocol->m_hSendEvent);
  1674. break;
  1675. case ReadyToSend:
  1676. case Sending:
  1677. case Throttled:
  1678. default:
  1679. break;
  1680. }
  1681. Unlock(&pSend->SendLock);
  1682. } else {
  1683. // OPTIMIZATION: reliable NACK for send we aren't doing? Ignore or send abort?
  1684. DPF(0,"Reliable NACK for send we aren't doing? Ignore?\n");
  1685. }
  1686. Unlock(&pSession->SessionLock);
  1687. if(pSend){
  1688. DecSendRef(pSession->pProtocol,pSend);
  1689. }
  1690. return TRUE;
  1691. #undef pBigNACK
  1692. }
  1693. VOID ProcessACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo)
  1694. {
  1695. PSESSION pSession;
  1696. UINT rc=0; // by default, buffer not accepted.
  1697. BOOL fUnlockedSession=FALSE;
  1698. // Find the Send for this ACK.
  1699. DPF(9,"ProcessACK\n");
  1700. pSession=GetSysSessionByIndex(pProtocol,pCmdInfo->wIdFrom);
  1701. if(!pSession) {
  1702. goto exit;
  1703. }
  1704. Lock(&pSession->SessionLock);
  1705. // Find the message with the id, make sure its the same type of send.
  1706. if(pCmdInfo->flags & RLY){
  1707. if(pCmdInfo->flags & BIG){
  1708. //NOTE: if messageid, FirstMsg and LastMsg are SHORT, no masking req'd
  1709. if((pCmdInfo->messageid==pSession->FirstMsg)||((pCmdInfo->messageid-pSession->FirstMsg)&0xFFFF) > ((pSession->LastMsg-pSession->FirstMsg)&0xFFFF)){
  1710. DPF(9,"Ignoring out of range ACK\n");
  1711. goto exit1;
  1712. }
  1713. } else {
  1714. if((pCmdInfo->messageid==pSession->FirstMsg)||((pCmdInfo->messageid-pSession->FirstMsg)&0xFF) > ((pSession->LastMsg-pSession->FirstMsg)&0xFF)){
  1715. // out of range, ignore
  1716. DPF(9,"Ignoring out of range ACK\n");
  1717. goto exit1;
  1718. }
  1719. }
  1720. ProcessReliableACK(pSession,pCmdInfo); //now always unlocks session.
  1721. fUnlockedSession=TRUE;
  1722. } else {
  1723. ProcessDGACK(pSession,pCmdInfo);
  1724. }
  1725. exit1:
  1726. if(!fUnlockedSession){
  1727. Unlock(&pSession->SessionLock);
  1728. }
  1729. DecSessionRef(pSession);
  1730. exit:
  1731. return;
  1732. #undef pBigACK
  1733. }
  1734. VOID ProcessNACK(PPROTOCOL pProtocol, PCMDINFO pCmdInfo, PUCHAR pNACKmask, UINT nNACK)
  1735. {
  1736. #define pBigNACK ((pNACK2)pNACK)
  1737. PSESSION pSession;
  1738. pSession=GetSysSessionByIndex(pProtocol, pCmdInfo->wIdFrom);
  1739. if(!pSession) {
  1740. ASSERT(0);
  1741. goto exit;
  1742. }
  1743. Lock(&pSession->SessionLock);
  1744. if(pCmdInfo->flags & RLY){
  1745. ProcessReliableNACK(pSession,pCmdInfo,pNACKmask, nNACK); // drops SessionLock
  1746. } else {
  1747. Unlock(&pSession->SessionLock);
  1748. DPF(0,"FATAL: non-reliable NACK???\n");
  1749. ASSERT(0);
  1750. }
  1751. DecSessionRef(pSession);
  1752. exit:
  1753. return;
  1754. }
  1755. UINT AssertMe(REQUEST_PARAMS)
  1756. {
  1757. DEBUG_BREAK();
  1758. return TRUE;
  1759. }
  1760. UINT Ping(REQUEST_PARAMS){return TRUE;}
  1761. UINT PingResp(REQUEST_PARAMS){return TRUE;}
  1762. UINT GetTime(REQUEST_PARAMS){return TRUE;}
  1763. UINT GetTimeResp(REQUEST_PARAMS){return TRUE;}
  1764. UINT SetTime(REQUEST_PARAMS){return TRUE;}
  1765. UINT SetTimeResp(REQUEST_PARAMS){return TRUE;}
  1766. VOID ProcessAbort(PPROTOCOL pProtocol, DPID idFrom, DPID idTo, pABT1 pABT, BOOL fBig){}