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.

3673 lines
118 KiB

  1. // Copyright (c) 1997, Microsoft Corporation, all rights reserved
  2. //
  3. // receive.c
  4. // RAS L2TP WAN mini-port/call-manager driver
  5. // Receive routines
  6. //
  7. // 01/07/97 Steve Cobb
  8. #include "l2tpp.h"
  9. #include "receive.tmh"
  10. extern LONG g_lPacketsIndicated;
  11. //-----------------------------------------------------------------------------
  12. // Local prototypes (alphabetically)
  13. //-----------------------------------------------------------------------------
  14. SHORT
  15. CompareSequence(
  16. USHORT us1,
  17. USHORT us2 );
  18. VOID
  19. ControlAcknowledged(
  20. IN TUNNELCB* pTunnel,
  21. IN USHORT usReceivedNr );
  22. VOID
  23. ControlAckTimerEvent(
  24. IN TIMERQITEM* pItem,
  25. IN VOID* pContext,
  26. IN TIMERQEVENT event );
  27. USHORT
  28. ExplodeAvpHeader(
  29. IN CHAR* pAvp,
  30. IN USHORT usMaxAvpLength,
  31. OUT AVPINFO* pInfo );
  32. VOID
  33. ExplodeControlAvps(
  34. IN CHAR* pFirstAvp,
  35. IN CHAR* pEndOfBuffer,
  36. OUT CONTROLMSGINFO* pControl );
  37. USHORT
  38. ExplodeL2tpHeader(
  39. IN CHAR* pL2tpHeader,
  40. IN ULONG ulBufferLength,
  41. IN OUT L2TPHEADERINFO* pInfo );
  42. USHORT
  43. GetAvpValueFixedAch(
  44. IN AVPINFO* pAvp,
  45. IN USHORT usArraySize,
  46. OUT CHAR** ppch );
  47. USHORT
  48. GetAvpValueFixedAul(
  49. IN AVPINFO* pAvp,
  50. IN USHORT usArraySize,
  51. OUT UNALIGNED ULONG** paulArray );
  52. USHORT
  53. GetAvpValueFlag(
  54. IN AVPINFO* pAvp,
  55. OUT UNALIGNED BOOLEAN* pf );
  56. USHORT
  57. GetAvpValueUl(
  58. IN AVPINFO* pAvp,
  59. OUT UNALIGNED ULONG** ppul );
  60. USHORT
  61. GetAvpValueUs(
  62. IN AVPINFO* pAvp,
  63. OUT UNALIGNED USHORT** ppus );
  64. USHORT
  65. GetAvpValue2UsAndVariableAch(
  66. IN AVPINFO* pAvp,
  67. OUT UNALIGNED USHORT** ppus1,
  68. OUT UNALIGNED USHORT** ppus2,
  69. OUT CHAR** ppch,
  70. OUT USHORT* pusArraySize );
  71. USHORT
  72. GetAvpValueVariableAch(
  73. IN AVPINFO* pAvp,
  74. OUT CHAR** ppch,
  75. OUT USHORT* pusArraySize );
  76. VOID
  77. GetCcAvps(
  78. IN TUNNELCB* pTunnel,
  79. IN CONTROLMSGINFO* pControl,
  80. OUT USHORT* pusResult,
  81. OUT USHORT* pusError );
  82. VOID
  83. HelloTimerEvent(
  84. IN TIMERQITEM* pItem,
  85. IN VOID* pContext,
  86. IN TIMERQEVENT event );
  87. VOID
  88. IndicateReceived(
  89. IN VCCB* pVc,
  90. IN CHAR* pBuffer,
  91. IN ULONG ulOffset,
  92. IN ULONG ulLength,
  93. IN LONGLONG llTimeReceived );
  94. BOOLEAN
  95. LookUpTunnelAndVcCbs(
  96. IN ADAPTERCB* pAdapter,
  97. IN USHORT* pusTunnelId,
  98. IN USHORT* pusCallId,
  99. IN L2TPHEADERINFO* pHeader,
  100. IN CONTROLMSGINFO* pControl,
  101. OUT TUNNELCB** ppTunnel,
  102. OUT VCCB** ppVc );
  103. VOID
  104. PayloadAcknowledged(
  105. IN TUNNELCB* pTunnel,
  106. IN VCCB* pVc,
  107. IN USHORT usReceivedNr );
  108. VOID
  109. PayloadAckTimerEvent(
  110. IN TIMERQITEM* pItem,
  111. IN VOID* pContext,
  112. IN TIMERQEVENT event );
  113. BOOLEAN
  114. ReceiveControl(
  115. IN ADAPTERCB* pAdapter,
  116. IN TUNNELCB* pTunnel,
  117. IN VCCB* pVc,
  118. IN CHAR* pBuffer,
  119. IN ULONG ulAvpOffset,
  120. IN ULONG ulAvpLength,
  121. IN TDIXRDGINFO* pRdg,
  122. IN L2TPHEADERINFO* pInfo,
  123. IN CONTROLMSGINFO* pControl );
  124. BOOLEAN
  125. ReceiveFromOutOfOrder(
  126. IN VCCB* pVc );
  127. BOOLEAN
  128. ReceivePayload(
  129. IN ADAPTERCB* pAdapter,
  130. IN TUNNELCB* pTunnel,
  131. IN VCCB* pVc,
  132. IN CHAR* pBuffer,
  133. IN ULONG ulPayloadOffset,
  134. IN ULONG ulPayloadLength,
  135. IN L2TPHEADERINFO* pInfo );
  136. VOID
  137. ScheduleControlAck(
  138. IN TUNNELCB* pTunnel,
  139. IN USHORT usMsgTypeToAcknowledge );
  140. VOID
  141. SchedulePayloadAck(
  142. IN TUNNELCB* pTunnel,
  143. IN VCCB* pVc );
  144. VCCB*
  145. VcCbFromCallId(
  146. IN TUNNELCB* pTunnel,
  147. IN USHORT usCallId );
  148. VOID
  149. ZombieAckIfNecessary(
  150. IN TUNNELCB* pTunnel,
  151. IN L2TPHEADERINFO* pHeader,
  152. IN CONTROLMSGINFO* pControl );
  153. //-----------------------------------------------------------------------------
  154. // Main receive handlers
  155. //-----------------------------------------------------------------------------
  156. VOID
  157. L2tpReceive(
  158. IN TDIXCONTEXT* pTdix,
  159. IN TDIXRDGINFO* pRdg,
  160. IN CHAR* pBuffer,
  161. IN ULONG ulOffset,
  162. IN ULONG ulBufferLength )
  163. // TDIXRECEIVEDG handler that receives all incoming L2TP traffic. 'PTdix'
  164. // is our TDI extension context. 'PRdg' points to the RDGINFO context
  165. // 'PBuffer' is the address of the virtual buffer associated with an NDIS
  166. // buffer from our pool passed to TDIX during initialization. We are
  167. // responsible for eventually calling FreeBufferToPool on 'pBuffer'.
  168. // 'UlOffset' is the offset to the first usable data in 'pBuffer'.
  169. // 'UlBufferLen' is the data byte count of 'pBuffer'.
  170. //
  171. {
  172. USHORT usXError;
  173. NDIS_STATUS status;
  174. L2TPHEADERINFO info;
  175. CONTROLMSGINFO* pControl;
  176. ADAPTERCB* pAdapter;
  177. TUNNELCB* pTunnel;
  178. VCCB* pVc;
  179. BOOLEAN fFreeBuffer;
  180. ULONG ulAvpOffset = 0;
  181. ULONG ulAvpLength = 0;
  182. TDIXIPADDRESS* pAddress = &pRdg->source;
  183. DUMPW( TL_A, TM_MDmp, pBuffer + ulOffset, 16 );
  184. pAdapter = CONTAINING_RECORD( pTdix, ADAPTERCB, tdix );
  185. fFreeBuffer = TRUE;
  186. pTunnel = NULL;
  187. pVc = NULL;
  188. pControl = NULL;
  189. do
  190. {
  191. // Parse the packet's L2TP header into a conveniently usable form,
  192. // checking that it is consistent with itself and indicates a protocol
  193. // version we know.
  194. //
  195. if(ulOffset >= ulBufferLength || (ulBufferLength - ulOffset < L2TP_MinHeaderSize))
  196. {
  197. // Invalid length
  198. TRACE( TL_A, TM_Recv, ( "Discard: invalid recv buffer length" ) );
  199. WPLOG( LL_A, LM_Recv, ( "Discard: invalid recv buffer length" ) );
  200. break;
  201. }
  202. usXError = ExplodeL2tpHeader(pBuffer + ulOffset, ulBufferLength - ulOffset, &info );
  203. if (usXError != GERR_None)
  204. {
  205. // Not a coherent L2TP header. Discard the packet.
  206. //
  207. TRACE( TL_A, TM_Recv, ( "Discard: invalid L2TP Header" ) );
  208. WPLOG( LL_A, LM_Recv, ( "Discard: invalid L2TP Header" ) );
  209. break;
  210. }
  211. ASSERT( info.ulDataLength <= L2TP_MaxFrameSize );
  212. if (*info.pusBits & HBM_T)
  213. {
  214. WPLOG( LL_M, LM_CMsg,
  215. ( "RECV <- %!IPADDR!/%d Length=%d, Tid %d, Cid %d, Ns=%d, Nr=%d",
  216. pAddress->ulIpAddress, ntohs(pAddress->sUdpPort),
  217. ulBufferLength - ulOffset, *info.pusTunnelId, *info.pusCallId,
  218. info.pusNs ? *info.pusNs : 0, info.pusNr ? *info.pusNr : 0) );
  219. // Explode the control message into the conveniently usable
  220. // 'control' form, while checking it for coherency. This must be
  221. // done here so the LookUp routine can peek ahead at the assigned
  222. // call ID in CallDisconnNotify, if necessary. Ugly, but that's
  223. // the way L2TP is defined.
  224. //
  225. pControl = ALLOC_CONTROLMSGINFO( pAdapter );
  226. if (pControl)
  227. {
  228. ulAvpOffset = (ULONG )(info.pData - pBuffer);
  229. ulAvpLength = info.ulDataLength;
  230. if (ulAvpLength)
  231. {
  232. ExplodeControlAvps(
  233. pBuffer + ulAvpOffset,
  234. pBuffer + ulAvpOffset + ulAvpLength,
  235. pControl );
  236. }
  237. else
  238. {
  239. // No AVPs. Most likely a ZACK.
  240. //
  241. pControl->usXError = GERR_BadValue;
  242. }
  243. }
  244. else
  245. {
  246. TRACE( TL_A, TM_Recv, ( "***Failed to allocate CONTROLMSGINFO" ) );
  247. WPLOG( LL_A, LM_Recv, ( "***Failed to allocate CONTROLMSGINFO" ) );
  248. break;
  249. }
  250. }
  251. // Find the tunnel and VC control blocks based on the header values.
  252. //
  253. if (!LookUpTunnelAndVcCbs(
  254. pAdapter, info.pusTunnelId, info.pusCallId,
  255. &info, pControl, &pTunnel, &pVc ))
  256. {
  257. // Invalid Tunnel-ID/Call-ID combination. Discard the packet.
  258. // Zombie acknowledge may have been performed if the packet was a
  259. // CDN.
  260. //
  261. // The draft/RFC says the tunnel should be closed and restarted on
  262. // receipt of a malformed Control Connection message. Seems
  263. // pretty harsh. For now, just discard such packets.
  264. //
  265. break;
  266. }
  267. if (pTunnel)
  268. {
  269. // Verify this packet comes from the right source address
  270. if(pTunnel->address.ulIpAddress != pAddress->ulIpAddress)
  271. {
  272. // Drop this packet
  273. break;
  274. }
  275. // Any message received on a tunnel resets it's Hello timer.
  276. //
  277. ResetHelloTimer( pTunnel );
  278. }
  279. if (*info.pusBits & HBM_T)
  280. {
  281. // It's a tunnel or call control packet.
  282. //
  283. if (pControl)
  284. {
  285. fFreeBuffer =
  286. ReceiveControl(
  287. pAdapter, pTunnel, pVc,
  288. pBuffer, ulAvpOffset, ulAvpLength,
  289. pRdg, &info, pControl );
  290. }
  291. }
  292. else
  293. {
  294. // It's a VC payload packet.
  295. //
  296. if (!pVc)
  297. {
  298. TRACE( TL_A, TM_Recv, ( "Payload w/o VC?" ) );
  299. WPLOG( LL_A, LM_Recv, ( "Payload w/o VC?" ) );
  300. break;
  301. }
  302. #if 0
  303. // !!! This is a hack to force NDISWAN into PPP framing mode.
  304. // Need a cleaner way to do this, or simply have NDISWAN assume it
  305. // for L2TP links. (NDISWAN bug 152167)
  306. //
  307. if (pVc->usNr == 0)
  308. {
  309. CHAR* pBufferX;
  310. pBufferX = GetBufferFromPool( &pAdapter->poolFrameBuffers );
  311. if (pBufferX)
  312. {
  313. pBufferX[ 0 ] = (CHAR )0xFF;
  314. pBufferX[ 1 ] = (CHAR )0x03;
  315. pBufferX[ 2 ] = (CHAR )0xC0;
  316. pBufferX[ 3 ] = (CHAR )0x21;
  317. pBufferX[ 4 ] = (CHAR )0x01;
  318. pBufferX[ 5 ] = (CHAR )0x06;
  319. IndicateReceived( pVc, pBufferX, 0, 6, (ULONGLONG )0 );
  320. }
  321. }
  322. #endif
  323. if (ReferenceCall( pVc ))
  324. {
  325. fFreeBuffer =
  326. ReceivePayload(
  327. pAdapter, pTunnel, pVc,
  328. pBuffer,
  329. (ULONG )(info.pData - pBuffer),
  330. info.ulDataLength,
  331. &info );
  332. DereferenceCall( pVc );
  333. }
  334. else
  335. {
  336. TRACE( TL_A, TM_Recv, ( "Discard: Call $%p not active", pVc ) );
  337. WPLOG( LL_A, LM_Recv, ( "Discard: Call $%p not active", pVc ) );
  338. }
  339. }
  340. }
  341. while (FALSE);
  342. if (pControl)
  343. {
  344. FREE_CONTROLMSGINFO( pAdapter, pControl );
  345. }
  346. if (fFreeBuffer)
  347. {
  348. FreeBufferToPool( &pAdapter->poolFrameBuffers, pBuffer, TRUE );
  349. }
  350. if (pTunnel)
  351. {
  352. DereferenceTunnel( pTunnel );
  353. }
  354. if (pVc)
  355. {
  356. DereferenceVc( pVc );
  357. }
  358. }
  359. BOOLEAN
  360. ReceiveControl(
  361. IN ADAPTERCB* pAdapter,
  362. IN TUNNELCB* pTunnel,
  363. IN VCCB* pVc,
  364. IN CHAR* pBuffer,
  365. IN ULONG ulAvpOffset,
  366. IN ULONG ulAvpLength,
  367. IN TDIXRDGINFO* pRdg,
  368. IN L2TPHEADERINFO* pInfo,
  369. IN CONTROLMSGINFO* pControl )
  370. // Receive processing for control packet in 'pBuffer'. The AVPs following
  371. // the header start at 'ulAvpOffset' and are 'ulAvpLength' bytes long.
  372. // 'PBuffer' is the receive buffer TDIX retrieved with
  373. // 'GetBufferFromPool'. 'PAdapter' is the adapter control block.
  374. // 'PTunnel' and 'pVc' are the tunnel and VC control blocks associated
  375. // with the received buffer, or NULL if none. 'pAddress' is the IP
  376. // address/port of the sending peer. 'PInfo' is the exploded header
  377. // information. 'PControl' is the control message information, which was
  378. // exploded earlier.
  379. //
  380. // Returns true if caller should free 'pBuffer', or false if this routine
  381. // has taken ownership of the buffer and will see it's freed.
  382. //
  383. {
  384. LIST_ENTRY* pLink;
  385. BOOLEAN fCallerFreesBuffer;
  386. SHORT sDiff;
  387. VCCB** ppVcs;
  388. ULONG ulcpVcs;
  389. TDIXIPADDRESS* pAddress = &pRdg->source;
  390. TRACE( TL_V, TM_Recv, ( "ReceiveControl" ) );
  391. ASSERT( !(pVc && !pTunnel) );
  392. if (ulAvpLength > 0)
  393. {
  394. if (pControl->usXError != GERR_None)
  395. {
  396. // The message was incoherent or contained "mandatory" AVPs we
  397. // don't recognize.
  398. //
  399. if (pVc && pControl->usXError == GERR_BadValue)
  400. {
  401. // "Bad values", which includes unrecognized mandatories,
  402. // terminate the call.
  403. //
  404. ScheduleTunnelWork(
  405. pTunnel, pVc, FsmCloseCall,
  406. (ULONG_PTR )CRESULT_GeneralWithError,
  407. (ULONG_PTR )pControl->usXError,
  408. 0, 0, FALSE, FALSE );
  409. }
  410. else if (pTunnel)
  411. {
  412. // Any other corruption terminates the tunnel.
  413. //
  414. ScheduleTunnelWork(
  415. pTunnel, NULL, FsmCloseTunnel,
  416. (ULONG_PTR )TRESULT_GeneralWithError,
  417. (ULONG_PTR )pControl->usXError,
  418. 0, 0, FALSE, FALSE );
  419. }
  420. return TRUE;
  421. }
  422. if (!pTunnel)
  423. {
  424. // IPSec should ensure this is valid source IP address.
  425. ASSERT(pAddress->ulIpAddress != 0 &&
  426. !IPADDR_IS_BROADCAST(pAddress->ulIpAddress) &&
  427. !IPADDR_IS_MULTICAST(pAddress->ulIpAddress));
  428. if (*(pControl->pusMsgType) == CMT_SCCRQ
  429. && pControl->pusAssignedTunnelId
  430. && *(pControl->pusAssignedTunnelId) != 0)
  431. {
  432. // Peer wants to start a new tunnel. Find a tunnel block with
  433. // peer's IP address and assigned Tunnel-ID, or create, if
  434. // necessary. The returned block is linked in the adapter's
  435. // list and and referenced. The reference is the one for peer
  436. // initiation, i.e. case (b).
  437. //
  438. // If this is a retransmit SCCRQ, this is undone after the
  439. // sequence check below. It must be done/undone rather than
  440. // never done because each message, including retransmits,
  441. // must have Ns/Nr processing performed and that processing
  442. // requires a tunnel control block.
  443. //
  444. pTunnel = SetupTunnel(
  445. pAdapter, pAddress->ulIpAddress, pAddress->sUdpPort,
  446. *(pControl->pusAssignedTunnelId), FALSE );
  447. if (!pTunnel)
  448. {
  449. return TRUE;
  450. }
  451. }
  452. else
  453. {
  454. // Don't know what tunnel the message if for and it's not a
  455. // "create new tunnel" request, so there's nothing useful to
  456. // do. Ignore it.
  457. //
  458. TRACE( TL_A, TM_Recv, ( "CMT %d w/o tunnel?", *(pControl->pusMsgType) ) );
  459. WPLOG( LL_A, LM_Recv, ( "CMT %d w/o tunnel?", *(pControl->pusMsgType) ) );
  460. return TRUE;
  461. }
  462. }
  463. if (*(pControl->pusMsgType) == CMT_SCCRQ
  464. || *(pControl->pusMsgType) == CMT_SCCRP)
  465. {
  466. // The source UDP port of the received message is recorded for
  467. // SCCRQ and SCCRP only, i.e. for the first message received
  468. // from peer.
  469. //
  470. pTunnel->address.sUdpPort = pAddress->sUdpPort;
  471. TRACE( TL_I, TM_Recv,
  472. ( "Peer UDP=%d", (UINT )ntohs( pAddress->sUdpPort ) ) );
  473. pTunnel->localaddress.ulIpAddress = pRdg->dest.ulIpAddress;
  474. pTunnel->localaddress.ifindex = pRdg->dest.ifindex;
  475. pTunnel->localaddress.sUdpPort = (SHORT)( htons( L2TP_UdpPort ));
  476. pTunnel->ulFlags |= TCBF_LocalAddrSet;
  477. TRACE( TL_I, TM_CMsg, ("L2TP-- dest %d.%d.%d.%d ifindex %d",
  478. IPADDRTRACE(pRdg->dest.ulIpAddress), pRdg->dest.ifindex));
  479. WPLOG( LL_M, LM_CMsg, ("Received on %!IPADDR!", pRdg->dest.ulIpAddress));
  480. }
  481. }
  482. else if (!pTunnel)
  483. {
  484. // Peer messed up and sent an ACK on tunnel ID 0, which is impossible
  485. // according to the protocol.
  486. //
  487. TRACE( TL_A, TM_Recv, ( "ZACK w/o tunnel?" ) );
  488. WPLOG( LL_A, LM_Recv, ( "ZACK w/o tunnel?" ) );
  489. return TRUE;
  490. }
  491. ASSERT( pTunnel );
  492. NdisAcquireSpinLock( &pTunnel->lockT );
  493. {
  494. // Do "acknowledged" handling on sends acknowledged by peer in the
  495. // received packet.
  496. //
  497. ControlAcknowledged( pTunnel, *(pInfo->pusNr) );
  498. if (ulAvpLength == 0)
  499. {
  500. // There are no AVPs so this was an acknowledgement only. We're
  501. // done.
  502. //
  503. NdisReleaseSpinLock( &pTunnel->lockT );
  504. return TRUE;
  505. }
  506. fCallerFreesBuffer = TRUE;
  507. do
  508. {
  509. // Further packet processing depends on where the packet's
  510. // sequence number falls relative to what we've already received.
  511. //
  512. sDiff = CompareSequence( *(pInfo->pusNs), pTunnel->usNr );
  513. if (sDiff == 0)
  514. {
  515. // It's the expected packet. Process it, setting up the VC
  516. // and popping from the out-of-order list as indicated. The
  517. // 'Next Received' is incremented outside, because that step
  518. // should not happen on a SetupVcAsynchronously restart.
  519. //
  520. ++pTunnel->usNr;
  521. fCallerFreesBuffer =
  522. ReceiveControlExpected( pTunnel, pVc, pBuffer, pControl );
  523. break;
  524. }
  525. else if (sDiff < 0)
  526. {
  527. // The received 'Next Sent' is before our 'Next Receive'.
  528. // Peer may have retransmitted while our acknowledge was in
  529. // transit, or the acknowledge may have been lost. Schedule
  530. // another acknowledge.
  531. //
  532. TRACE( TL_A, TM_Recv, ( "Control re-ack" ) );
  533. WPLOG( LL_A, LM_Recv, ( "Control re-ack" ) );
  534. ScheduleControlAck( pTunnel, 0 );
  535. if (*(pControl->pusMsgType) == CMT_SCCRQ)
  536. {
  537. // Since SCCRQ is a duplicate, the reference added by
  538. // SetupTunnel above must be undone. In this special case
  539. // the TCBF_PeerInitRef flag was never set and so need not
  540. // be cleared.
  541. //
  542. DereferenceTunnel( pTunnel );
  543. }
  544. break;
  545. }
  546. else if (sDiff < pAdapter->sMaxOutOfOrder)
  547. {
  548. CONTROLRECEIVED* pCr;
  549. BOOLEAN fDiscard;
  550. // The packet is beyond the one we expected, but within our
  551. // out-of-order window.
  552. //
  553. if (ReadFlags( &pTunnel->ulFlags ) & TCBF_Closing)
  554. {
  555. // The tunnel is closing and the out-of-order queue has
  556. // been flushed, so just discard the packet.
  557. //
  558. TRACE( TL_A, TM_Recv, ( "Control discarded: ooo but closing" ) );
  559. WPLOG( LL_A, LM_Recv, ( "Control discarded: ooo but closing" ) );
  560. break;
  561. }
  562. // Allocate a control-received context
  563. // and queue the packet on the out-of-order list.
  564. //
  565. pCr = ALLOC_CONTROLRECEIVED( pAdapter );
  566. if (!pCr)
  567. {
  568. break;
  569. }
  570. // Fill in the context with the relevant packet information.
  571. //
  572. pCr->usNs = *(pInfo->pusNs);
  573. pCr->pVc = pVc;
  574. pCr->pBuffer = pBuffer;
  575. NdisMoveMemory(
  576. &pCr->control, pControl, sizeof(pCr->control) );
  577. if (pCr->pVc)
  578. {
  579. // Add a VC reference covering the reference stored in the
  580. // context, which will be removed when the context is
  581. // freed.
  582. //
  583. ReferenceVc( pCr->pVc );
  584. }
  585. // Find the first link on the out-of-order list with an 'Ns'
  586. // greater than that in the received message, or the head if
  587. // none.
  588. //
  589. fDiscard = FALSE;
  590. for (pLink = pTunnel->listOutOfOrder.Flink;
  591. pLink != &pTunnel->listOutOfOrder;
  592. pLink = pLink->Flink)
  593. {
  594. CONTROLRECEIVED* pThisCr;
  595. SHORT sThisDiff;
  596. pThisCr = CONTAINING_RECORD(
  597. pLink, CONTROLRECEIVED, linkOutOfOrder );
  598. sThisDiff = CompareSequence( pCr->usNs, pThisCr->usNs );
  599. if (sThisDiff < 0)
  600. {
  601. break;
  602. }
  603. if (sThisDiff == 0)
  604. {
  605. // It's a retransmit that's already on our queue.
  606. //
  607. if (pCr->pVc)
  608. {
  609. DereferenceVc( pCr->pVc );
  610. }
  611. FREE_CONTROLRECEIVED( pAdapter, pCr );
  612. fDiscard = TRUE;
  613. break;
  614. }
  615. }
  616. if (fDiscard)
  617. {
  618. break;
  619. }
  620. // Queue up the context as out-of-order.
  621. //
  622. TRACE( TL_I, TM_Recv,
  623. ( "Control %d out-of-order %d",
  624. *(pInfo->pusNs), (LONG )sDiff ) );
  625. InsertBefore( &pCr->linkOutOfOrder, pLink );
  626. fCallerFreesBuffer = FALSE;
  627. break;
  628. }
  629. DBG_else
  630. {
  631. TRACE( TL_A, TM_Recv,
  632. ( "Control discarded: Beyond ooo" ) );
  633. }
  634. }
  635. while (FALSE);
  636. // Complete any VCs listed as completing.
  637. //
  638. CompleteVcs( pTunnel );
  639. }
  640. NdisReleaseSpinLock( &pTunnel->lockT );
  641. return fCallerFreesBuffer;
  642. }
  643. BOOLEAN
  644. ReceiveControlExpected(
  645. IN TUNNELCB* pTunnel,
  646. IN VCCB* pVc,
  647. IN CHAR* pBuffer,
  648. IN CONTROLMSGINFO* pControl )
  649. // Called to do packet processing when the packet received is the expected
  650. // 'Next Receive' packet. 'PBuffer' is the receive buffer. 'PTunnel' is
  651. // the valid tunnel control block. 'PVc' is the call's VC control block
  652. // and may be NULL, if the VC for the call has not yet been set up.
  653. // 'PControl' is the expoded control message information.
  654. //
  655. // Returns true if the buffer should be freed by caller, false if it was
  656. // queued for further processing.
  657. //
  658. // IMPORTANT: Caller must hold the 'pTunnel->lockT'.
  659. //
  660. {
  661. ADAPTERCB* pAdapter;
  662. BOOLEAN fProcessed;
  663. SHORT sDiff;
  664. pAdapter = pTunnel->pAdapter;
  665. // Schedule an acknowledge-only packet to be sent if no outgoing traffic
  666. // appears to piggyback on within a reasonable time. Note this occurs
  667. // even if the asynchronous VC set up was invoked. Ns/Nr processing must
  668. // occur before any data processing that may cause delays.
  669. //
  670. ScheduleControlAck( pTunnel, *(pControl->pusMsgType) );
  671. // Pass the packet to the control FSMs.
  672. //
  673. fProcessed = FsmReceive( pTunnel, pVc, pBuffer, pControl );
  674. if (fProcessed)
  675. {
  676. // The VC is setup and the packet has been processed. See if any
  677. // packets on the received out-of-order queue can now be processed.
  678. //
  679. for (;;)
  680. {
  681. LIST_ENTRY* pFirstLink;
  682. CONTROLRECEIVED* pFirstCr;
  683. BOOLEAN fOutOfOrderProcessed;
  684. pFirstLink = pTunnel->listOutOfOrder.Flink;
  685. if (pFirstLink == &pTunnel->listOutOfOrder)
  686. {
  687. break;
  688. }
  689. pFirstCr = CONTAINING_RECORD(
  690. pFirstLink, CONTROLRECEIVED, linkOutOfOrder );
  691. sDiff = CompareSequence( pFirstCr->usNs, pTunnel->usNr );
  692. if (sDiff == 0)
  693. {
  694. // Yes, it's the next expected packet. Update 'Next Receive'
  695. // and pass the packet to the control FSMs.
  696. //
  697. TRACE( TL_I, TM_Recv,
  698. ( "Control %d from queue", (UINT )pFirstCr->usNs ) );
  699. RemoveEntryList( pFirstLink );
  700. InitializeListHead( pFirstLink );
  701. ++pTunnel->usNr;
  702. fOutOfOrderProcessed =
  703. FsmReceive(
  704. pTunnel, pFirstCr->pVc,
  705. pFirstCr->pBuffer, &pFirstCr->control );
  706. ScheduleControlAck(
  707. pTunnel, *(pFirstCr->control.pusMsgType) );
  708. if (fOutOfOrderProcessed)
  709. {
  710. FreeBufferToPool(
  711. &pAdapter->poolFrameBuffers, pFirstCr->pBuffer, TRUE );
  712. }
  713. if (pFirstCr->pVc)
  714. {
  715. DereferenceVc( pFirstCr->pVc );
  716. }
  717. FREE_CONTROLRECEIVED( pAdapter, pFirstCr );
  718. }
  719. else if (sDiff > 0)
  720. {
  721. // No, there's still some missing.
  722. //
  723. TRACE( TL_I, TM_Recv,
  724. ( "Control %d still missing", pTunnel->usNr ) );
  725. break;
  726. }
  727. else
  728. {
  729. ASSERT( "Old control queued?" );
  730. break;
  731. }
  732. }
  733. }
  734. return fProcessed;
  735. }
  736. BOOLEAN
  737. ReceivePayload(
  738. IN ADAPTERCB* pAdapter,
  739. IN TUNNELCB* pTunnel,
  740. IN VCCB* pVc,
  741. IN CHAR* pBuffer,
  742. IN ULONG ulPayloadOffset,
  743. IN ULONG ulPayloadLength,
  744. IN L2TPHEADERINFO* pInfo )
  745. // Receive processing for payload in 'pBuffer' of 'ulPayloadLength' bytes
  746. // starting at offset 'ulPayloadOffset'. 'PBuffer' is the receive buffer
  747. // TDIX retrieved with 'GetBufferFromPool'. 'PAdapter, 'pTunnel' and
  748. // 'PVc' are the adapter, tunnel, and VC control blocks associated with
  749. // the received buffer. 'PInfo' is the exploded header information.
  750. //
  751. // Returns true if caller should free 'pBuffer', or false if this routine
  752. // has taken ownership of the buffer and will see it's freed.
  753. //
  754. {
  755. LONGLONG llTimeReceived;
  756. BOOLEAN fCallerFreesBuffer;
  757. TRACE( TL_V, TM_Recv, ( "ReceivePayload" ) );
  758. if (!pTunnel || !pVc)
  759. {
  760. // Both control blocks are always required to receive payload.
  761. //
  762. TRACE( TL_A, TM_Recv, ( "Discard: No CB" ) );
  763. WPLOG( LL_A, LM_Recv, ( "Discard: No CB" ) );
  764. return TRUE;
  765. }
  766. // Note the time if client's call parameters indicated interest in time
  767. // received.
  768. //
  769. if (ReadFlags( &pVc->ulFlags ) & VCBF_IndicateTimeReceived)
  770. {
  771. NdisGetCurrentSystemTime( (LARGE_INTEGER* )&llTimeReceived );
  772. }
  773. else
  774. {
  775. llTimeReceived = 0;
  776. }
  777. if (!(ReadFlags( &pVc->ulFlags ) & VCBF_Sequencing) || !pInfo->pusNr)
  778. {
  779. DBG_if (ReadFlags( &pVc->ulFlags ) & VCBF_Sequencing)
  780. TRACE( TL_A, TM_Recv, ( "No Nr field?" ) );
  781. if (ulPayloadLength > 0)
  782. {
  783. // Flow control was disabled during negotiation. This should be
  784. // extremely rare, since a compliant peer MUST implement flow
  785. // control.
  786. //
  787. IndicateReceived(
  788. pVc, pBuffer, ulPayloadOffset,
  789. ulPayloadLength, llTimeReceived );
  790. return FALSE;
  791. }
  792. else
  793. {
  794. NdisAcquireSpinLock( &pVc->lockV );
  795. {
  796. ++pVc->stats.ulRecdZlbs;
  797. }
  798. NdisReleaseSpinLock( &pVc->lockV );
  799. return TRUE;
  800. }
  801. }
  802. fCallerFreesBuffer = TRUE;
  803. NdisAcquireSpinLock( &pVc->lockV );
  804. do
  805. {
  806. SHORT sDiff;
  807. // All R-bit handling occurs first. Peer sends a packet with the
  808. // R-bit set to indicate that all packets expected between the last
  809. // packet and this packet should be assumed lost.
  810. //
  811. if (*(pInfo->pusBits) & HBM_R)
  812. {
  813. ++pVc->stats.ulRecdResets;
  814. sDiff = CompareSequence( *(pInfo->pusNs), pVc->usNr );
  815. if (sDiff > 0)
  816. {
  817. TRACE( TL_I, TM_Recv,
  818. ( "Reset Nr=%d from %d",
  819. (LONG )*(pInfo->pusNs), (LONG )pVc->usNr ) );
  820. pVc->usNr = *(pInfo->pusNs);
  821. }
  822. else
  823. {
  824. ++pVc->stats.ulRecdResetsIgnored;
  825. TRACE( TL_I, TM_Recv,
  826. ( "Reset Nr=%d from %d ignored",
  827. (LONG )*(pInfo->pusNs), (LONG )pVc->usNr ) );
  828. }
  829. }
  830. // Do "acknowledged" handling on sends acknowledged by peer in the
  831. // received packet.
  832. //
  833. PayloadAcknowledged( pTunnel, pVc, *(pInfo->pusNr) );
  834. // If there's no payload and the R-bit is not set, this was an
  835. // acknowledgement only and we're done.
  836. //
  837. if (ulPayloadLength == 0)
  838. {
  839. ++pVc->stats.ulRecdZlbs;
  840. if (*(pInfo->pusBits) & HBM_R)
  841. {
  842. BOOLEAN fReceivedFromOutOfOrder;
  843. // Indicate up any packet on the out-of-order list made
  844. // receivable by the R-bit reset.
  845. //
  846. fReceivedFromOutOfOrder = FALSE;
  847. while (ReceiveFromOutOfOrder( pVc ))
  848. {
  849. fReceivedFromOutOfOrder = TRUE;
  850. }
  851. if (fReceivedFromOutOfOrder)
  852. {
  853. // Schedule an acknowledge-only packet to be sent if no
  854. // outgoing traffic appears to piggyback on within a
  855. // reasonable time.
  856. //
  857. SchedulePayloadAck( pTunnel, pVc );
  858. }
  859. }
  860. break;
  861. }
  862. DBG_if (pInfo->pusNs && pInfo->pusNr)
  863. {
  864. TRACE( TL_N, TM_Recv, ( "len=%d Ns=%d Nr=%d",
  865. (ULONG )*(pInfo->pusLength),
  866. (ULONG )*(pInfo->pusNs),
  867. (ULONG )*(pInfo->pusNr) ) );
  868. }
  869. // Further packet processing depends on where the packet's sequence
  870. // number falls relative to what we've already received.
  871. //
  872. sDiff = CompareSequence( *(pInfo->pusNs), pVc->usNr );
  873. if (sDiff == 0)
  874. {
  875. // It's the next expected packet. Update 'Next Receive' and
  876. // indicate the payload received to the driver above.
  877. //
  878. pVc->usNr = *(pInfo->pusNs) + 1;
  879. NdisReleaseSpinLock( &pVc->lockV );
  880. {
  881. IndicateReceived(
  882. pVc, pBuffer, ulPayloadOffset, ulPayloadLength,
  883. llTimeReceived );
  884. }
  885. NdisAcquireSpinLock( &pVc->lockV );
  886. // Indicate up any packets on the out-of-order list that were
  887. // waiting for this one.
  888. //
  889. while (ReceiveFromOutOfOrder( pVc ))
  890. ;
  891. // Schedule an acknowledge-only packet to be sent if no outgoing
  892. // traffic appears to piggyback on within a reasonable time.
  893. //
  894. SchedulePayloadAck( pTunnel, pVc );
  895. }
  896. else if (sDiff < 0)
  897. {
  898. // The received 'Next Sent' is before our 'Next Receive'. Maybe
  899. // an out-of-order packet we didn't wait for long enough. It's
  900. // useless at this point.
  901. //
  902. TRACE( TL_A, TM_Recv, ( "Payload discarded: Old Ns" ) );
  903. WPLOG( LL_A, LM_Recv, ( "Payload discarded: Old Ns" ) );
  904. break;
  905. }
  906. else if (sDiff < pAdapter->sMaxOutOfOrder)
  907. {
  908. LIST_ENTRY* pLink;
  909. PAYLOADRECEIVED* pPr;
  910. BOOLEAN fDiscard;
  911. TRACE( TL_I, TM_Recv,
  912. ( "%d out-of-order %d", *(pInfo->pusNs), (LONG )sDiff ) );
  913. // The packet is beyond the one we expected, but within our
  914. // out-of-order window. Allocate a payload-received context and
  915. // queue it up on the out-of-order list.
  916. //
  917. pPr = ALLOC_PAYLOADRECEIVED( pAdapter );
  918. if (!pPr)
  919. {
  920. TRACE( TL_A, TM_Recv, ( "Alloc PR?" ) );
  921. WPLOG( LL_A, LM_Recv, ( "Failed to allocate PAYLOADRECEIVED" ) );
  922. break;
  923. }
  924. // Fill in the context with the relevant packet information.
  925. //
  926. pPr->usNs = *(pInfo->pusNs);
  927. pPr->pBuffer = pBuffer;
  928. pPr->ulPayloadOffset = ulPayloadOffset;
  929. pPr->ulPayloadLength = ulPayloadLength;
  930. pPr->llTimeReceived = llTimeReceived;
  931. // Queue up the context on the out-of-order list, keeping the list
  932. // correctly sorted by 'Ns'.
  933. //
  934. fDiscard = FALSE;
  935. for (pLink = pVc->listOutOfOrder.Flink;
  936. pLink != &pVc->listOutOfOrder;
  937. pLink = pLink->Flink)
  938. {
  939. PAYLOADRECEIVED* pThisPr;
  940. SHORT sThisDiff;
  941. pThisPr = CONTAINING_RECORD(
  942. pLink, PAYLOADRECEIVED, linkOutOfOrder );
  943. sThisDiff = CompareSequence( pPr->usNs, pThisPr->usNs );
  944. if (sThisDiff < 0)
  945. {
  946. break;
  947. }
  948. if (sThisDiff == 0)
  949. {
  950. // This shouldn't happen because payloads are not
  951. // retransmitted, but do the right thing just in case.
  952. //
  953. TRACE( TL_A, TM_Recv, ( "Payload on ooo queue?" ) );
  954. fDiscard = TRUE;
  955. break;
  956. }
  957. }
  958. if (fDiscard)
  959. {
  960. FREE_PAYLOADRECEIVED( pAdapter, pPr );
  961. break;
  962. }
  963. InsertBefore( &pPr->linkOutOfOrder, pLink );
  964. }
  965. else
  966. {
  967. // The packet is beyond the one we expected and outside our
  968. // out-of-order window. Discard it.
  969. //
  970. TRACE( TL_A, TM_Recv, ( "Out-of-order %d too far" , (LONG )sDiff ) );
  971. WPLOG( LL_A, LM_Recv, ( "Out-of-order %d too far" , (LONG )sDiff ) );
  972. break;
  973. }
  974. fCallerFreesBuffer = FALSE;
  975. }
  976. while (FALSE);
  977. NdisReleaseSpinLock( &pVc->lockV );
  978. return fCallerFreesBuffer;
  979. }
  980. //-----------------------------------------------------------------------------
  981. // Receive utility routines (alphabetically)
  982. //-----------------------------------------------------------------------------
  983. SHORT
  984. CompareSequence(
  985. USHORT us1,
  986. USHORT us2 )
  987. // Returns the "logical" difference between sequence numbers 'us1' and
  988. // 'us2' accounting for the possibility of rollover.
  989. //
  990. {
  991. USHORT usDiff = us1 - us2;
  992. if (usDiff == 0)
  993. return 0;
  994. if (usDiff < 0x4000)
  995. return (SHORT )usDiff;
  996. return -((SHORT )(0 - usDiff));
  997. }
  998. VOID
  999. ControlAcknowledged(
  1000. IN TUNNELCB* pTunnel,
  1001. IN USHORT usReceivedNr )
  1002. // Dequeues and cancels the timer of all control-sent contexts in the
  1003. // tunnel's 'listSendsOut' queue with 'Next Sent' less than
  1004. // 'usReceivedNr'.
  1005. //
  1006. // IMPORTANT: Caller must hold 'pTunnel->lockT'.
  1007. //
  1008. {
  1009. ADAPTERCB* pAdapter;
  1010. BOOLEAN fFoundOne;
  1011. pAdapter = pTunnel->pAdapter;
  1012. fFoundOne = FALSE;
  1013. while (!IsListEmpty( &pTunnel->listSendsOut ))
  1014. {
  1015. CONTROLSENT* pCs;
  1016. LIST_ENTRY* pLink;
  1017. pLink = pTunnel->listSendsOut.Flink;
  1018. pCs = CONTAINING_RECORD( pLink, CONTROLSENT, linkSendsOut );
  1019. // The list is in 'Ns' order so as soon as a non-acknowledge is hit
  1020. // we're done.
  1021. //
  1022. if (CompareSequence( pCs->usNs, usReceivedNr ) >= 0)
  1023. {
  1024. break;
  1025. }
  1026. fFoundOne = TRUE;
  1027. // Remove the context from the "outstanding send" list and cancel the
  1028. // associated timer. Doesn't matter if the cancel fails because the
  1029. // expire handler will recognize that the context is not linked into
  1030. // the "out" list and do nothing.
  1031. //
  1032. RemoveEntryList( pLink );
  1033. InitializeListHead( pLink );
  1034. TimerQCancelItem( pTunnel->pTimerQ, pCs->pTqiSendTimeout );
  1035. // Per the draft/RFC, adjustments to the send window and send timeouts
  1036. // are necessary. Per Karn's Algorithm, if the packet was
  1037. // retransmitted it is useless for timeout adjustment because it's not
  1038. // known if peer responded to the original send or the retransmission.
  1039. //
  1040. if (pCs->ulRetransmits == 0)
  1041. {
  1042. AdjustTimeoutsAtAckReceived(
  1043. pCs->llTimeSent,
  1044. pAdapter->ulMaxSendTimeoutMs,
  1045. &pTunnel->ulSendTimeoutMs,
  1046. &pTunnel->ulRoundTripMs,
  1047. &pTunnel->lDeviationMs );
  1048. }
  1049. // See if it's time to open the send window a bit further.
  1050. //
  1051. AdjustSendWindowAtAckReceived(
  1052. pTunnel->ulMaxSendWindow,
  1053. &pTunnel->ulAcksSinceSendTimeout,
  1054. &pTunnel->ulSendWindow );
  1055. TRACE( TL_N, TM_Send,
  1056. ( "T%d: ACK(%d) new rtt=%d dev=%d ato=%d sw=%d",
  1057. (ULONG )pTunnel->usTunnelId, (ULONG )pCs->usNs,
  1058. pTunnel->ulRoundTripMs, pTunnel->lDeviationMs,
  1059. pTunnel->ulSendTimeoutMs, pTunnel->ulSendWindow ) );
  1060. // Execute any "on ACK" options and note that delayed action
  1061. // processing is now required.
  1062. //
  1063. if (pCs->ulFlags & CSF_TunnelIdleOnAck)
  1064. {
  1065. TRACE( TL_N, TM_Send, ( "Tunnel idle on ACK" ) );
  1066. ScheduleTunnelWork(
  1067. pTunnel, NULL, CloseTunnel,
  1068. 0, 0, 0, 0, FALSE, FALSE );
  1069. }
  1070. else if (pCs->ulFlags & CSF_CallIdleOnAck)
  1071. {
  1072. TRACE( TL_N, TM_Send, ( "Call idle on ACK" ) );
  1073. ASSERT( pCs->pVc );
  1074. ScheduleTunnelWork(
  1075. pTunnel, pCs->pVc, CloseCall,
  1076. 0, 0, 0, 0, FALSE, FALSE );
  1077. }
  1078. if (pCs->ulFlags & CSF_Pending)
  1079. {
  1080. // The context is queued for retransmission, so de-queue it. In
  1081. // this state the context has already been assumed "not
  1082. // outstanding" so no need to adjust the counter as below.
  1083. //
  1084. pCs->ulFlags &= ~(CSF_Pending);
  1085. }
  1086. else
  1087. {
  1088. // The context is not queued for retranmission, so adjust the
  1089. // counter to indicate it is no longer outstanding.
  1090. //
  1091. --pTunnel->ulSendsOut;
  1092. }
  1093. // Remove the reference corresponding to linkage in the "outstanding
  1094. // send" list.
  1095. //
  1096. DereferenceControlSent( pCs );
  1097. }
  1098. if (fFoundOne)
  1099. {
  1100. // See if any sends were pending on a closed send window.
  1101. //
  1102. ScheduleTunnelWork(
  1103. pTunnel, NULL, SendPending,
  1104. 0, 0, 0, 0, FALSE, FALSE );
  1105. }
  1106. }
  1107. VOID
  1108. ControlAckTimerEvent(
  1109. IN TIMERQITEM* pItem,
  1110. IN VOID* pContext,
  1111. IN TIMERQEVENT event )
  1112. // PTIMERQEVENT handler that fires when it's time to stop waiting for an
  1113. // outgoing control packet on which to piggyback an acknowledge.
  1114. //
  1115. {
  1116. TUNNELCB* pTunnel;
  1117. ADAPTERCB* pAdapter;
  1118. BOOLEAN fSendAck;
  1119. TRACE( TL_N, TM_Recv,
  1120. ( "ControlAckTimerEvent(%s)", TimerQPszFromEvent( event ) ) );
  1121. // Unpack context information.
  1122. //
  1123. pTunnel = (TUNNELCB* )pContext;
  1124. pAdapter = pTunnel->pAdapter;
  1125. if (event == TE_Expire)
  1126. {
  1127. NdisAcquireSpinLock( &pTunnel->lockT );
  1128. {
  1129. if (pItem == pTunnel->pTqiDelayedAck)
  1130. {
  1131. pTunnel->pTqiDelayedAck = NULL;
  1132. fSendAck = TRUE;
  1133. }
  1134. else
  1135. {
  1136. fSendAck = FALSE;
  1137. }
  1138. }
  1139. NdisReleaseSpinLock( &pTunnel->lockT );
  1140. if (fSendAck)
  1141. {
  1142. // The timer expired and was not been cancelled or terminated
  1143. // while the expire processing was being set up, meaning it's time
  1144. // to send a zero-AVP control packet to give peer the acknowledge
  1145. // we were hoping to piggyback onto a random outgoing control
  1146. // packet.
  1147. //
  1148. ScheduleTunnelWork(
  1149. pTunnel, NULL, SendControlAck, 0, 0, 0, 0, FALSE, FALSE );
  1150. }
  1151. DBG_else
  1152. {
  1153. TRACE( TL_I, TM_Send, ( "CAck aborted" ) );
  1154. }
  1155. }
  1156. // Free the timer event descriptor and remove the reference covering the
  1157. // scheduled timer.
  1158. //
  1159. FREE_TIMERQITEM( pAdapter, pItem );
  1160. DereferenceTunnel( pTunnel );
  1161. }
  1162. VOID
  1163. PayloadAckTimerEvent(
  1164. IN TIMERQITEM* pItem,
  1165. IN VOID* pContext,
  1166. IN TIMERQEVENT event )
  1167. // PTIMERQEVENT handler that fires when it's time to stop waiting for an
  1168. // outgoing payload packet on which to piggyback an acknowledge.
  1169. //
  1170. {
  1171. VCCB* pVc;
  1172. ADAPTERCB* pAdapter;
  1173. BOOLEAN fSendAck;
  1174. TRACE( TL_N, TM_Recv,
  1175. ( "PayloadAckTimerEvent(%s)=$%p",
  1176. TimerQPszFromEvent( event ), pItem ) );
  1177. // Unpack context information.
  1178. //
  1179. pVc = (VCCB* )pContext;
  1180. pAdapter = pVc->pAdapter;
  1181. if (event == TE_Expire)
  1182. {
  1183. if (ReferenceCall( pVc ))
  1184. {
  1185. NdisAcquireSpinLock( &pVc->lockV );
  1186. {
  1187. if (pItem == pVc->pTqiDelayedAck)
  1188. {
  1189. fSendAck = TRUE;
  1190. pVc->pTqiDelayedAck = NULL;
  1191. ++pVc->stats.ulSentZAcks;
  1192. }
  1193. else
  1194. {
  1195. fSendAck = FALSE;
  1196. }
  1197. }
  1198. NdisReleaseSpinLock( &pVc->lockV );
  1199. if (fSendAck)
  1200. {
  1201. // The timer expired and was not been cancelled or terminated
  1202. // while the expire processing was being set up, plus the call
  1203. // is still up, meaning it's time to send a zero-AVP control
  1204. // packet to give peer the acknowledge we were hoping to
  1205. // piggyback onto a random outgoing payload packet.
  1206. //
  1207. ScheduleTunnelWork(
  1208. pVc->pTunnel, pVc, SendPayloadAck,
  1209. 0, 0, 0, 0, FALSE, FALSE );
  1210. }
  1211. else
  1212. {
  1213. TRACE( TL_I, TM_Send, ( "PAck aborted" ) );
  1214. DereferenceCall( pVc );
  1215. }
  1216. }
  1217. else
  1218. {
  1219. NdisAcquireSpinLock( &pVc->lockV );
  1220. {
  1221. if (pItem == pVc->pTqiDelayedAck)
  1222. {
  1223. pVc->pTqiDelayedAck = NULL;
  1224. }
  1225. }
  1226. NdisReleaseSpinLock( &pVc->lockV );
  1227. }
  1228. }
  1229. // Free the timer event descriptor and remove the reference covering the
  1230. // scheduled timer.
  1231. //
  1232. FREE_TIMERQITEM( pAdapter, pItem );
  1233. DereferenceVc( pVc );
  1234. }
  1235. USHORT
  1236. ExplodeAvpHeader(
  1237. IN CHAR* pAvp,
  1238. IN USHORT usMaxAvpLength,
  1239. OUT AVPINFO* pInfo )
  1240. // Fills caller's '*pInfo' with the addresses of the various fields in the
  1241. // AVP header at 'pAvp'. The byte order of the fields in 'pAvpHeader',
  1242. // with the exception of the Value field, are flipped to host-byte-order
  1243. // in place. The length and value length are extracted. 'UsMaxAvpLength'
  1244. // is the maximum size of the AVP in bytes.
  1245. //
  1246. // Returns GERR_None if 'pAvpHeader' is a coherent AVP header, or a
  1247. // GERR_* failure code.
  1248. //
  1249. {
  1250. UNALIGNED USHORT* pusCur;
  1251. USHORT usBits;
  1252. if (usMaxAvpLength < L2TP_AvpHeaderSize)
  1253. {
  1254. TRACE( TL_A, TM_Recv, ( "Avp: Short buffer?" ) );
  1255. WPLOG( LL_A, LM_Recv, ( "Avp: Short buffer?" ) );
  1256. return GERR_BadLength;
  1257. }
  1258. pusCur = (UNALIGNED USHORT* )pAvp;
  1259. // The first 2 bytes contain bits that indicate the presence/absence of
  1260. // the other header fields.
  1261. //
  1262. *pusCur = ntohs( *pusCur );
  1263. pInfo->pusBits = pusCur;
  1264. usBits = *pusCur;
  1265. ++pusCur;
  1266. // As of draft-09, AVPs with reserved bits not set to zero MUST be treated
  1267. // as unrecognized.
  1268. //
  1269. if ((usBits & ABM_Reserved) != 0)
  1270. {
  1271. return GERR_BadValue;
  1272. }
  1273. // Extract the Overall Length sub-field and verify that it says the AVP is
  1274. // at least as long as the fixed portion of the header.
  1275. //
  1276. pInfo->usOverallLength = (usBits & ABM_OverallLength);
  1277. if (pInfo->usOverallLength > usMaxAvpLength
  1278. || pInfo->usOverallLength < L2TP_AvpHeaderSize)
  1279. {
  1280. TRACE( TL_A, TM_Recv, ( "Avp: Bad length?" ) );
  1281. WPLOG( LL_A, LM_Recv, ( "Avp: Bad length?" ) );
  1282. return GERR_BadLength;
  1283. }
  1284. // Vendor-ID field.
  1285. //
  1286. *pusCur = ntohs( *pusCur );
  1287. pInfo->pusVendorId = pusCur;
  1288. ++pusCur;
  1289. // Attribute field.
  1290. //
  1291. *pusCur = ntohs( *pusCur );
  1292. pInfo->pusAttribute = pusCur;
  1293. ++pusCur;
  1294. // Value field.
  1295. //
  1296. pInfo->pValue = (CHAR* )pusCur;
  1297. pInfo->usValueLength = pInfo->usOverallLength - L2TP_AvpHeaderSize;
  1298. return GERR_None;
  1299. }
  1300. #define MAX_NAME_LENGTH 64
  1301. VOID
  1302. ExplodeControlAvps(
  1303. IN CHAR* pFirstAvp,
  1304. IN CHAR* pEndOfBuffer,
  1305. OUT CONTROLMSGINFO* pControl )
  1306. // Fills caller's '*pControl' buffer with the exploded interpretation of
  1307. // the message with AVP list starting at 'pFirstAvp'. 'PEndOfBuffer'
  1308. // points to the first byte beyond the end of the received buffer. The
  1309. // AVP values are returned as addresses of the corresponding value field
  1310. // in the AVPs. Fields not present are returned as NULL. The byte order
  1311. // of the fields in 'pControl' is flipped to host-byte-order in place.
  1312. // The values themselves are not validated, only the message format. Sets
  1313. // 'pControl->usXError' to GERR_None if successful, or the GERR_* failure
  1314. // code.
  1315. //
  1316. {
  1317. USHORT usXError;
  1318. AVPINFO avp;
  1319. CHAR* pCur;
  1320. CHAR szName[MAX_NAME_LENGTH];
  1321. int NameLength;
  1322. DUMPW( TL_A, TM_MDmp, pFirstAvp, (ULONG )(pEndOfBuffer - pFirstAvp) );
  1323. NdisZeroMemory( pControl, sizeof(*pControl) );
  1324. pCur = pFirstAvp;
  1325. // Read and validate the Message Type AVP, which is the first AVP of all
  1326. // control messages.
  1327. //
  1328. usXError = ExplodeAvpHeader( pCur, (USHORT )(pEndOfBuffer - pCur), &avp );
  1329. if (usXError != GERR_None)
  1330. {
  1331. TRACE( TL_A, TM_CMsg, ( "Bad AVP header" ) );
  1332. WPLOG( LL_A, LM_CMsg, ( "Bad AVP header" ) );
  1333. pControl->usXError = usXError;
  1334. return;
  1335. }
  1336. if (*(avp.pusAttribute) != ATTR_MsgType
  1337. || *(avp.pusVendorId) != 0
  1338. || (*(avp.pusBits) & ABM_H))
  1339. {
  1340. TRACE( TL_A, TM_CMsg, ( "Bad MsgType AVP" ) );
  1341. WPLOG( LL_A, LM_CMsg, ( "Bad MsgType AVP" ) );
  1342. pControl->usXError = GERR_BadValue;
  1343. return;
  1344. }
  1345. usXError = GetAvpValueUs( &avp, &pControl->pusMsgType );
  1346. if (usXError != GERR_None)
  1347. {
  1348. TRACE( TL_A, TM_CMsg, ( "Bad MsgType Us" ) );
  1349. WPLOG( LL_A, LM_CMsg, ( "Bad MsgType Us" ) );
  1350. pControl->usXError = usXError;
  1351. return;
  1352. }
  1353. pCur += avp.usOverallLength;
  1354. TRACE( TL_I, TM_CMsg, ( "*MsgType=%s", MsgTypePszFromUs( *(pControl->pusMsgType) ) ) );
  1355. WPLOG( LL_M, LM_CMsg, ( "*MsgType=%s", MsgTypePszFromUs( *(pControl->pusMsgType) ) ) );
  1356. // Make sure the message type code is valid, and if it is, explode any
  1357. // additional AVPs in the message.
  1358. //
  1359. switch (*(pControl->pusMsgType))
  1360. {
  1361. case CMT_SCCRQ:
  1362. case CMT_SCCRP:
  1363. case CMT_SCCCN:
  1364. case CMT_StopCCN:
  1365. case CMT_Hello:
  1366. {
  1367. // Mark the messages above as tunnel control rather than call
  1368. // control.
  1369. //
  1370. pControl->fTunnelMsg = TRUE;
  1371. // ...fall thru...
  1372. }
  1373. case CMT_OCRQ:
  1374. case CMT_OCRP:
  1375. case CMT_OCCN:
  1376. case CMT_ICRQ:
  1377. case CMT_ICRP:
  1378. case CMT_ICCN:
  1379. case CMT_CDN:
  1380. case CMT_WEN:
  1381. case CMT_SLI:
  1382. {
  1383. // Walk the list of AVPs, exploding each AVP in turn. Excepting
  1384. // the Message Type, the order of the AVPs is not defined.
  1385. //
  1386. for ( ; pCur < pEndOfBuffer; pCur += avp.usOverallLength )
  1387. {
  1388. usXError = ExplodeAvpHeader(
  1389. pCur, (USHORT )(pEndOfBuffer - pCur), &avp );
  1390. if (usXError != GERR_None)
  1391. {
  1392. break;
  1393. }
  1394. if (*avp.pusVendorId != 0)
  1395. {
  1396. // The AVP has a non-IETF vendor ID, and we don't
  1397. // recognize any. If the AVP is optional, just ignore it.
  1398. // If it's mandatory, then fail.
  1399. //
  1400. if (*avp.pusBits & ABM_M)
  1401. {
  1402. TRACE( TL_A, TM_CMsg, ( "Non-0 Vendor ID %d, M-bit is set", *avp.pusVendorId ) );
  1403. WPLOG( LL_A, LM_CMsg, ( "Non-0 Vendor ID %d, M-bit is set", *avp.pusVendorId ) );
  1404. usXError = GERR_BadValue;
  1405. break;
  1406. }
  1407. continue;
  1408. }
  1409. if (*avp.pusBits & ABM_H)
  1410. {
  1411. BOOLEAN fIgnore;
  1412. TRACE( TL_A, TM_CMsg, ( "Hidden bit on AVP %d", (LONG )(*avp.pusAttribute) ) );
  1413. // !!! Remove this when H-bit support is added.
  1414. //
  1415. switch (*avp.pusAttribute)
  1416. {
  1417. case ATTR_ProxyAuthName:
  1418. case ATTR_ProxyAuthChallenge:
  1419. case ATTR_ProxyAuthId:
  1420. case ATTR_ProxyAuthResponse:
  1421. case ATTR_DialedNumber:
  1422. case ATTR_DialingNumber:
  1423. case ATTR_SubAddress:
  1424. case ATTR_InitialLcpConfig:
  1425. case ATTR_LastSLcpConfig:
  1426. case ATTR_LastRLcpConfig:
  1427. case ATTR_Accm:
  1428. case ATTR_PrivateGroupId:
  1429. {
  1430. fIgnore = TRUE;
  1431. break;
  1432. }
  1433. default:
  1434. {
  1435. fIgnore = FALSE;
  1436. break;
  1437. }
  1438. }
  1439. if (fIgnore)
  1440. {
  1441. TRACE( TL_A, TM_CMsg, ( "Hidden AVP ignored" ) );
  1442. break;
  1443. }
  1444. // The AVP has the "hidden" bit set meaning the value is
  1445. // hashed with MD5. This requires a shared secret from
  1446. // the tunnel authentication, which we don't do. If the
  1447. // AVP is optional, just ignore it. If it's mandatory,
  1448. // fail.
  1449. //
  1450. if (*avp.pusBits & ABM_M)
  1451. {
  1452. usXError = GERR_BadValue;
  1453. break;
  1454. }
  1455. continue;
  1456. }
  1457. switch (*avp.pusAttribute)
  1458. {
  1459. case ATTR_Result:
  1460. {
  1461. usXError = GetAvpValue2UsAndVariableAch(
  1462. &avp,
  1463. &pControl->pusResult,
  1464. &pControl->pusError,
  1465. &pControl->pchResultMsg,
  1466. &pControl->usResultMsgLength );
  1467. DBG_if (usXError == GERR_None)
  1468. {
  1469. TRACE( TL_A, TM_CMsg, ( "*Result=%d",
  1470. (ULONG )(*(pControl->pusResult))));
  1471. }
  1472. WPLOG( LL_M, LM_CMsg, ( "*Result=%d",
  1473. (usXError == GERR_None) ? (ULONG )(*(pControl->pusResult)) : -1 ));
  1474. break;
  1475. }
  1476. case ATTR_HostName:
  1477. {
  1478. usXError = GetAvpValueVariableAch(
  1479. &avp,
  1480. &pControl->pchHostName,
  1481. &pControl->usHostNameLength );
  1482. if(usXError == GERR_None)
  1483. {
  1484. NameLength = (pControl->usHostNameLength < MAX_NAME_LENGTH) ? pControl->usHostNameLength : MAX_NAME_LENGTH - 1;
  1485. NdisMoveMemory(szName, pControl->pchHostName, NameLength);
  1486. szName[NameLength] = '\0';
  1487. TRACE( TL_A, TM_CMsg, ( "*HostName=%s", szName));
  1488. WPLOG( LL_M, LM_CMsg, ( "*HostName=%s", szName));
  1489. }
  1490. else
  1491. {
  1492. WPLOG( LL_M, LM_CMsg, ( "*HostName is bad"));
  1493. }
  1494. break;
  1495. }
  1496. case ATTR_VendorName:
  1497. {
  1498. PCHAR pchVendorName;
  1499. USHORT usVendorNameLength;
  1500. usXError = GetAvpValueVariableAch(
  1501. &avp,
  1502. &pchVendorName,
  1503. &usVendorNameLength);
  1504. if(usXError == GERR_None)
  1505. {
  1506. NameLength = (usVendorNameLength < MAX_NAME_LENGTH) ? usVendorNameLength : MAX_NAME_LENGTH - 1;
  1507. NdisMoveMemory(szName, pchVendorName, NameLength);
  1508. szName[NameLength] = '\0';
  1509. TRACE( TL_A, TM_CMsg, ( "*VendorName=%s", szName));
  1510. WPLOG( LL_M, LM_CMsg, ( "*VendorName=%s", szName));
  1511. }
  1512. else
  1513. {
  1514. WPLOG( LL_M, LM_CMsg, ( "*VendorName is bad"));
  1515. }
  1516. break;
  1517. }
  1518. case ATTR_FirmwareRevision:
  1519. {
  1520. usXError = GetAvpValueUs(
  1521. &avp, &pControl->pusFirmwareRevision );
  1522. DBG_if (usXError == GERR_None)
  1523. {
  1524. TRACE( TL_A, TM_CMsg, ( "*FirmwareVer=$%04x",
  1525. (ULONG )(*(pControl->pusFirmwareRevision)) ) );
  1526. }
  1527. WPLOG( LL_M, LM_CMsg, ( "*FirmwareVer=%04x",
  1528. (usXError == GERR_None) ? (ULONG )(*(pControl->pusFirmwareRevision)) : 0xBAD ));
  1529. break;
  1530. }
  1531. case ATTR_ProtocolVersion:
  1532. {
  1533. usXError = GetAvpValueUs(
  1534. &avp, &pControl->pusProtocolVersion );
  1535. DBG_if (usXError == GERR_None)
  1536. {
  1537. TRACE( TL_A, TM_CMsg, ( "*ProtVer=$%04x",
  1538. (ULONG )(*(pControl->pusProtocolVersion)) ) );
  1539. }
  1540. WPLOG( LL_M, LM_CMsg, ( "*ProtVer=%04x",
  1541. (usXError == GERR_None) ? (ULONG )(*(pControl->pusProtocolVersion)) : 0xBAD ));
  1542. break;
  1543. }
  1544. case ATTR_FramingCaps:
  1545. {
  1546. usXError = GetAvpValueUl(
  1547. &avp, &pControl->pulFramingCaps );
  1548. DBG_if (usXError == GERR_None)
  1549. {
  1550. TRACE( TL_A, TM_CMsg, ( "*FramingCaps=$%08x",
  1551. *(pControl->pulFramingCaps) ) );
  1552. }
  1553. WPLOG( LL_M, LM_CMsg, ( "*FramingCaps=%08x",
  1554. (usXError == GERR_None) ? *(pControl->pulFramingCaps) : (ULONG) 0xBAD ));
  1555. break;
  1556. }
  1557. case ATTR_BearerCaps:
  1558. {
  1559. usXError = GetAvpValueUl(
  1560. &avp, &pControl->pulBearerCaps );
  1561. DBG_if (usXError == GERR_None)
  1562. {
  1563. TRACE( TL_A, TM_CMsg, ( "*BearerCaps=$%08x",
  1564. *(pControl->pulBearerCaps) ) );
  1565. }
  1566. WPLOG( LL_M, LM_CMsg, ( "*BearerCaps=%08x",
  1567. (usXError == GERR_None) ? *(pControl->pulBearerCaps) : (ULONG) 0xBAD ));
  1568. break;
  1569. }
  1570. case ATTR_TieBreaker:
  1571. {
  1572. usXError = GetAvpValueFixedAch(
  1573. &avp, 8, &pControl->pchTieBreaker );
  1574. DBG_if (usXError == GERR_None)
  1575. {
  1576. TRACE( TL_A, TM_CMsg, ( "*Tiebreaker" ) );
  1577. }
  1578. WPLOG( LL_M, LM_CMsg, ( "*Tiebreaker %s",
  1579. (usXError == GERR_None) ? "*" : "bad" ));
  1580. break;
  1581. }
  1582. case ATTR_AssignedTunnelId:
  1583. {
  1584. usXError = GetAvpValueUs(
  1585. &avp, &pControl->pusAssignedTunnelId );
  1586. DBG_if (usXError == GERR_None)
  1587. {
  1588. TRACE( TL_A, TM_CMsg, ( "*AssignTid=%d",
  1589. (ULONG )(*(pControl->pusAssignedTunnelId)) ) );
  1590. }
  1591. WPLOG( LL_M, LM_CMsg, ( "*AssignTid=%d",
  1592. (usXError == GERR_None) ? (ULONG )(*(pControl->pusAssignedTunnelId)) : -1 ));
  1593. break;
  1594. }
  1595. case ATTR_RWindowSize:
  1596. {
  1597. usXError = GetAvpValueUs(
  1598. &avp, &pControl->pusRWindowSize );
  1599. DBG_if (usXError == GERR_None)
  1600. {
  1601. TRACE( TL_A, TM_CMsg, ( "*RWindow=%d",
  1602. (ULONG )(*(pControl->pusRWindowSize)) ) );
  1603. }
  1604. WPLOG( LL_M, LM_CMsg, ( "*RWindow=%d",
  1605. (usXError == GERR_None) ? (ULONG )(*(pControl->pusRWindowSize)) : -1 ));
  1606. break;
  1607. }
  1608. case ATTR_AssignedCallId:
  1609. {
  1610. usXError = GetAvpValueUs(
  1611. &avp, &pControl->pusAssignedCallId );
  1612. DBG_if (usXError == GERR_None)
  1613. {
  1614. TRACE( TL_A, TM_CMsg, ( "*AssignCid=%d",
  1615. (ULONG )(*(pControl->pusAssignedCallId)) ) );
  1616. }
  1617. WPLOG( LL_M, LM_CMsg, ( "*AssignCid=%d",
  1618. (usXError == GERR_None) ? (ULONG )(*(pControl->pusAssignedCallId)) : -1 ));
  1619. break;
  1620. }
  1621. case ATTR_CallSerialNumber:
  1622. {
  1623. usXError = GetAvpValueUl(
  1624. &avp, &pControl->pulCallSerialNumber );
  1625. if (usXError == GERR_BadLength)
  1626. {
  1627. // Be tolerant here because the meaning in the
  1628. // draft has changed a few times.
  1629. //
  1630. TRACE( TL_A, TM_CMsg,
  1631. ( "Weird CallSerial# length ignored" ) );
  1632. usXError = GERR_None;
  1633. }
  1634. DBG_if (usXError == GERR_None)
  1635. {
  1636. TRACE( TL_A, TM_CMsg, ( "*CallSerial#" ) );
  1637. }
  1638. WPLOG( LL_M, LM_CMsg, ( "*CallSerial# %s",
  1639. (usXError == GERR_None) ? "*" : "bad" ));
  1640. break;
  1641. }
  1642. case ATTR_MinimumBps:
  1643. {
  1644. usXError = GetAvpValueUl(
  1645. &avp, &pControl->pulMinimumBps );
  1646. DBG_if (usXError == GERR_None)
  1647. {
  1648. TRACE( TL_A, TM_CMsg, ( "*MinBps=%d",
  1649. *(pControl->pulMinimumBps) ) );
  1650. }
  1651. WPLOG( LL_M, LM_CMsg, ( "*MinBps=%d",
  1652. (usXError == GERR_None) ? *(pControl->pulMinimumBps) : -1 ));
  1653. break;
  1654. }
  1655. case ATTR_MaximumBps:
  1656. {
  1657. usXError = GetAvpValueUl(
  1658. &avp, &pControl->pulMaximumBps );
  1659. DBG_if (usXError == GERR_None)
  1660. {
  1661. TRACE( TL_A, TM_CMsg, ( "*MaxBps=%d",
  1662. *(pControl->pulMaximumBps) ) );
  1663. }
  1664. WPLOG( LL_M, LM_CMsg, ( "*MaxBps=%d",
  1665. (usXError == GERR_None) ? *(pControl->pulMaximumBps) : -1 ));
  1666. break;
  1667. }
  1668. case ATTR_BearerType:
  1669. {
  1670. usXError = GetAvpValueUl(
  1671. &avp, &pControl->pulBearerType );
  1672. DBG_if (usXError == GERR_None)
  1673. {
  1674. TRACE( TL_A, TM_CMsg, ( "*BearerType=$%08x",
  1675. *(pControl->pulBearerType) ) );
  1676. }
  1677. WPLOG( LL_M, LM_CMsg, ( "*BearerType=%08x",
  1678. (usXError == GERR_None) ? *(pControl->pulBearerType) : (ULONG)'BAD' ));
  1679. break;
  1680. }
  1681. case ATTR_FramingType:
  1682. {
  1683. usXError = GetAvpValueUl(
  1684. &avp, &pControl->pulFramingType );
  1685. DBG_if (usXError == GERR_None)
  1686. {
  1687. TRACE( TL_A, TM_CMsg, ( "*FramingType=$%08x",
  1688. *(pControl->pulFramingType) ) );
  1689. }
  1690. WPLOG( LL_M, LM_CMsg, ( "*FramingType=$%08x",
  1691. (usXError == GERR_None) ? *(pControl->pulFramingType) : (ULONG)'BAD' ));
  1692. break;
  1693. }
  1694. case ATTR_PacketProcDelay:
  1695. {
  1696. usXError = GetAvpValueUs(
  1697. &avp, &pControl->pusPacketProcDelay );
  1698. DBG_if (usXError == GERR_None)
  1699. {
  1700. TRACE( TL_A, TM_CMsg, ( "*PPD=%d",
  1701. (ULONG )(*(pControl->pusPacketProcDelay)) ) );
  1702. }
  1703. WPLOG( LL_M, LM_CMsg, ( "*PPD=%d",
  1704. (usXError == GERR_None) ? (ULONG )(*(pControl->pusPacketProcDelay)) : -1 ));
  1705. break;
  1706. }
  1707. case ATTR_DialedNumber:
  1708. {
  1709. usXError = GetAvpValueVariableAch(
  1710. &avp,
  1711. &pControl->pchDialedNumber,
  1712. &pControl->usDialedNumberLength );
  1713. DBG_if (usXError == GERR_None)
  1714. {
  1715. TRACE( TL_A, TM_CMsg, ( "*Dialed#" ) );
  1716. }
  1717. WPLOG( LL_M, LM_CMsg, ( "*Dialed# %s",
  1718. (usXError == GERR_None) ? "*" : "bad" ));
  1719. break;
  1720. }
  1721. case ATTR_DialingNumber:
  1722. {
  1723. usXError = GetAvpValueVariableAch(
  1724. &avp,
  1725. &pControl->pchDialingNumber,
  1726. &pControl->usDialingNumberLength );
  1727. DBG_if (usXError == GERR_None)
  1728. {
  1729. TRACE( TL_A, TM_CMsg, ( "*Dialing#" ) );
  1730. }
  1731. WPLOG( LL_M, LM_CMsg, ( "*Dialing# %s",
  1732. (usXError == GERR_None) ? "*" : "bad" ));
  1733. break;
  1734. }
  1735. case ATTR_SubAddress:
  1736. {
  1737. usXError = GetAvpValueVariableAch(
  1738. &avp,
  1739. &pControl->pchSubAddress,
  1740. &pControl->usSubAddressLength );
  1741. DBG_if (usXError == GERR_None)
  1742. {
  1743. TRACE( TL_A, TM_CMsg, ( "*SubAddr" ) );
  1744. }
  1745. WPLOG( LL_M, LM_CMsg, ( "*SubAddr %s",
  1746. (usXError == GERR_None) ? "*" : "bad" ));
  1747. break;
  1748. }
  1749. case ATTR_TxConnectSpeed:
  1750. {
  1751. usXError = GetAvpValueUl(
  1752. &avp, &pControl->pulTxConnectSpeed );
  1753. DBG_if (usXError == GERR_None)
  1754. {
  1755. TRACE( TL_A, TM_CMsg, ( "*TxSpeed=%d",
  1756. *(pControl->pulTxConnectSpeed) ) );
  1757. }
  1758. WPLOG( LL_M, LM_CMsg, ( "*TxSpeed=%d",
  1759. (usXError == GERR_None) ? *(pControl->pulTxConnectSpeed) : -1 ));
  1760. break;
  1761. }
  1762. case ATTR_PhysicalChannelId:
  1763. {
  1764. usXError = GetAvpValueUl(
  1765. &avp, &pControl->pulPhysicalChannelId );
  1766. DBG_if (usXError == GERR_None)
  1767. {
  1768. TRACE( TL_A, TM_CMsg, ( "*PhysChannelId=$%08x",
  1769. *(pControl->pulPhysicalChannelId) ) );
  1770. }
  1771. WPLOG( LL_M, LM_CMsg, ( "*PhysChannelId=%08x",
  1772. (usXError == GERR_None) ? *(pControl->pulPhysicalChannelId) : (ULONG)'BAD' ));
  1773. break;
  1774. }
  1775. case ATTR_Challenge:
  1776. {
  1777. usXError = GetAvpValueVariableAch(
  1778. &avp,
  1779. &pControl->pchChallenge,
  1780. &pControl->usChallengeLength );
  1781. DBG_if (usXError == GERR_None)
  1782. {
  1783. TRACE( TL_A, TM_CMsg, ( "*Challenge" ) );
  1784. }
  1785. WPLOG( LL_M, LM_CMsg, ( "*Challenge %s",
  1786. (usXError == GERR_None) ? "*" : "bad" ));
  1787. break;
  1788. }
  1789. case ATTR_ChallengeResponse:
  1790. {
  1791. usXError = GetAvpValueFixedAch(
  1792. &avp, 16, &pControl->pchResponse );
  1793. DBG_if (usXError == GERR_None)
  1794. {
  1795. TRACE( TL_A, TM_CMsg, ( "*ChallengeResp" ) );
  1796. }
  1797. WPLOG( LL_M, LM_CMsg, ( "*ChallengeResp %s",
  1798. (usXError == GERR_None) ? "*" : "bad" ));
  1799. break;
  1800. }
  1801. case ATTR_ProxyAuthType:
  1802. {
  1803. usXError = GetAvpValueUs(
  1804. &avp, &pControl->pusProxyAuthType );
  1805. DBG_if (usXError == GERR_None)
  1806. {
  1807. TRACE( TL_A, TM_CMsg, ( "*ProxyAuthType=%d",
  1808. (ULONG )(*(pControl->pusProxyAuthType)) ) );
  1809. }
  1810. WPLOG( LL_M, LM_CMsg, ( "*ProxyAuthType=%d",
  1811. (usXError == GERR_None) ? (ULONG )(*(pControl->pusProxyAuthType)) : -1 ));
  1812. break;
  1813. }
  1814. case ATTR_ProxyAuthResponse:
  1815. {
  1816. usXError = GetAvpValueVariableAch(
  1817. &avp,
  1818. &pControl->pchProxyAuthResponse,
  1819. &pControl->usProxyAuthResponseLength );
  1820. DBG_if (usXError == GERR_None)
  1821. {
  1822. TRACE( TL_A, TM_CMsg, ( "*ProxyAuthResponse" ) );
  1823. }
  1824. WPLOG( LL_M, LM_CMsg, ( "*ProxyAuthResponse %s",
  1825. (usXError == GERR_None) ? "*" : "bad" ));
  1826. break;
  1827. }
  1828. case ATTR_CallErrors:
  1829. {
  1830. usXError = GetAvpValueFixedAul(
  1831. &avp, 6, &pControl->pulCallErrors );
  1832. DBG_if (usXError == GERR_None)
  1833. {
  1834. TRACE( TL_A, TM_CMsg, ( "*CallErrors" ) );
  1835. }
  1836. WPLOG( LL_M, LM_CMsg, ( "*CallErrors %s",
  1837. (usXError == GERR_None) ? "*" : "bad" ));
  1838. break;
  1839. }
  1840. case ATTR_Accm:
  1841. {
  1842. usXError = GetAvpValueFixedAul(
  1843. &avp, 2, &pControl->pulAccm );
  1844. DBG_if (usXError == GERR_None)
  1845. {
  1846. TRACE( TL_A, TM_CMsg, ( "*Accm" ) );
  1847. }
  1848. WPLOG( LL_M, LM_CMsg, ( "*Accm %s",
  1849. (usXError == GERR_None) ? "*" : "bad" ));
  1850. break;
  1851. }
  1852. case ATTR_SequencingRequired:
  1853. {
  1854. usXError = GetAvpValueFlag(
  1855. &avp, &pControl->fSequencingRequired );
  1856. DBG_if (usXError == GERR_None)
  1857. {
  1858. TRACE( TL_A, TM_CMsg, ( "*SeqReqd" ) );
  1859. }
  1860. WPLOG( LL_M, LM_CMsg, ( "*SeqReqd %s",
  1861. (usXError == GERR_None) ? "*" : "bad" ));
  1862. break;
  1863. }
  1864. default:
  1865. {
  1866. // The AVP is not one we handle. If optional, just
  1867. // ignore it, but if mandatory, fail.
  1868. //
  1869. TRACE( TL_A, TM_CMsg, ( "*AVP %d ignored", (ULONG )*avp.pusAttribute ) );
  1870. WPLOG( LL_A, LM_CMsg, ( "*AVP %d ignored", (ULONG )*avp.pusAttribute ) );
  1871. if (*avp.pusBits & ABM_M)
  1872. {
  1873. if (*avp.pusAttribute <= ATTR_MAX)
  1874. {
  1875. // This is a bug in the peer, but ignoring it
  1876. // is the best action.
  1877. //
  1878. TRACE( TL_A, TM_CMsg,
  1879. ( "Known AVP %d marked mandatory ignored",
  1880. (LONG )(*avp.pusAttribute) ) );
  1881. WPLOG( LL_A, LM_CMsg,
  1882. ( "Known AVP %d marked mandatory ignored",
  1883. (LONG )(*avp.pusAttribute) ) );
  1884. }
  1885. else
  1886. {
  1887. usXError = GERR_BadValue;
  1888. }
  1889. }
  1890. break;
  1891. }
  1892. }
  1893. if (usXError != GERR_None)
  1894. {
  1895. break;
  1896. }
  1897. }
  1898. ASSERT( pCur <= pEndOfBuffer );
  1899. break;
  1900. }
  1901. default:
  1902. {
  1903. TRACE( TL_A, TM_CMsg, ( "Unknown CMT %d", (ULONG )*(pControl->pusMsgType) ) );
  1904. WPLOG( LL_A, LM_CMsg, ( "Unknown CMT %d", (ULONG )*(pControl->pusMsgType) ) );
  1905. usXError = GERR_BadValue;
  1906. break;
  1907. }
  1908. }
  1909. DBG_if (usXError != GERR_None)
  1910. TRACE( TL_A, TM_CMsg, ( "XError=%d", (UINT )usXError ) );
  1911. pControl->usXError = usXError;
  1912. }
  1913. USHORT
  1914. ExplodeL2tpHeader(
  1915. IN CHAR* pL2tpHeader,
  1916. IN ULONG ulBufferLength,
  1917. IN OUT L2TPHEADERINFO* pInfo )
  1918. // Fills caller's '*pInfo' with the addresses of the various fields in the
  1919. // L2TP header at 'pL2tpHeader'. Fields not present are returned as NULL.
  1920. // The byte order of the fields in 'pL2tpHeader' is flipped to
  1921. // host-byte-order in place. 'UlBufferLength' is the length in bytes from
  1922. // 'pL2tpHeader' to the end of the buffer.
  1923. //
  1924. // Returns GERR_None if 'pL2tpHeader' is a coherent L2TP header, or a
  1925. // GERR_* failure code.
  1926. //
  1927. {
  1928. USHORT *pusCur;
  1929. USHORT usOffset;
  1930. USHORT usBits;
  1931. PUSHORT pusEndBuffer = (PUSHORT)(pL2tpHeader + ulBufferLength) - 1;
  1932. pusCur = (USHORT*)pL2tpHeader;
  1933. // The first 2 bytes contain bits that indicate the presence/absence of
  1934. // the other header fields.
  1935. //
  1936. *pusCur = ntohs( *pusCur );
  1937. pInfo->pusBits = pusCur;
  1938. usBits = *pusCur;
  1939. ++pusCur;
  1940. // The T bit indicates a control packet, as opposed to a payload packet.
  1941. //
  1942. if (usBits & HBM_T)
  1943. {
  1944. // Verify the field-present bits guaranteed to be set/clear in a
  1945. // control header are set correctly.
  1946. //
  1947. if ((usBits & HBM_Bits) != HBM_Control)
  1948. {
  1949. TRACE( TL_A, TM_CMsg, ( "Header: Bad bits=$%04x?", (ULONG )usBits ) );
  1950. WPLOG( LL_A, LM_CMsg, ( "Header: Bad bits=$%04x?", (ULONG )usBits ) );
  1951. return GERR_BadValue;
  1952. }
  1953. }
  1954. // Verify the version indicates L2TP. Cisco's L2F can theoretically
  1955. // co-exist on the same media address, though we don't support that.
  1956. //
  1957. if ((usBits & HBM_Ver) != VER_L2tp)
  1958. {
  1959. TRACE( TL_A, TM_Recv, ( "Header: Non-L2TP Ver=%d?", (usBits & HBM_Ver )) );
  1960. WPLOG( LL_A, LM_Recv, ( "Header: Non-L2TP Ver=%d?", (usBits & HBM_Ver )) );
  1961. return GERR_BadValue;
  1962. }
  1963. // The L bit indicates a Length field is present.
  1964. //
  1965. if (usBits & HBM_L)
  1966. {
  1967. *pusCur = ntohs( *pusCur );
  1968. pInfo->pusLength = pusCur;
  1969. ++pusCur;
  1970. }
  1971. else
  1972. {
  1973. pInfo->pusLength = NULL;
  1974. }
  1975. // The Tunnel-ID field is always present.
  1976. //
  1977. *pusCur = ntohs( *pusCur );
  1978. pInfo->pusTunnelId = pusCur;
  1979. ++pusCur;
  1980. // The Call-ID field is always present.
  1981. //
  1982. if(pusCur > pusEndBuffer)
  1983. {
  1984. return GERR_BadValue;
  1985. }
  1986. *pusCur = ntohs( *pusCur );
  1987. pInfo->pusCallId = pusCur;
  1988. ++pusCur;
  1989. // The F bit indicates the Ns and Nr fields are present.
  1990. //
  1991. if (usBits & HBM_F)
  1992. {
  1993. if(pusCur > pusEndBuffer)
  1994. {
  1995. return GERR_BadValue;
  1996. }
  1997. *pusCur = ntohs( *pusCur );
  1998. pInfo->pusNs = pusCur;
  1999. ++pusCur;
  2000. if(pusCur > pusEndBuffer)
  2001. {
  2002. return GERR_BadValue;
  2003. }
  2004. *pusCur = ntohs( *pusCur );
  2005. pInfo->pusNr = pusCur;
  2006. ++pusCur;
  2007. }
  2008. else
  2009. {
  2010. pInfo->pusNs = NULL;
  2011. pInfo->pusNr = NULL;
  2012. }
  2013. // The S bit indicates the Offset field is present. The S bit appears in
  2014. // the payload header only, as was verified above.
  2015. //
  2016. if (usBits & HBM_S)
  2017. {
  2018. if(pusCur > pusEndBuffer)
  2019. {
  2020. return GERR_BadValue;
  2021. }
  2022. *pusCur = ntohs( *pusCur );
  2023. usOffset = *pusCur;
  2024. ++pusCur;
  2025. }
  2026. else
  2027. {
  2028. usOffset = 0;
  2029. }
  2030. // End and length of header.
  2031. //
  2032. pInfo->pData = ((CHAR* )pusCur) + usOffset;
  2033. pInfo->ulHeaderLength = (ULONG )(pInfo->pData - pL2tpHeader);
  2034. // "Official" data length.
  2035. //
  2036. if (pInfo->pusLength)
  2037. {
  2038. // Verify any specified length is at least as long as the set header
  2039. // bits imply and no longer than the received buffer.
  2040. //
  2041. if (*(pInfo->pusLength) < pInfo->ulHeaderLength
  2042. || *(pInfo->pusLength) > ulBufferLength)
  2043. {
  2044. TRACE( TL_A, TM_Recv, ( "Header: Bad Length?" ) );
  2045. WPLOG( LL_A, LM_Recv, ( "Header: Bad Length? Length = %d, HeaderLength = %d",
  2046. *(pInfo->pusLength), pInfo->ulHeaderLength) );
  2047. return GERR_BadLength;
  2048. }
  2049. // Use the L2TP length as the "official" length, i.e. any strange
  2050. // bytes received beyond what the L2TP header says it sent will be
  2051. // ignored.
  2052. //
  2053. pInfo->ulDataLength = *(pInfo->pusLength) - pInfo->ulHeaderLength;
  2054. DBG_if( *(pInfo->pusLength) != ulBufferLength )
  2055. TRACE( TL_A, TM_Recv, ( "EOB padding ignored" ) );
  2056. }
  2057. else
  2058. {
  2059. // Verify any implied length is at least as long as the set header
  2060. // bits imply.
  2061. //
  2062. if (ulBufferLength < pInfo->ulHeaderLength)
  2063. {
  2064. TRACE( TL_A, TM_Recv, ( "Header: Bad Length?" ) );
  2065. WPLOG( LL_A, LM_Recv, ( "Header: Bad Length? BufferLength = %d, HeaderLength = %d",
  2066. ulBufferLength, pInfo->ulHeaderLength) );
  2067. return GERR_BadLength;
  2068. }
  2069. // No length field so the received buffer length is the "official"
  2070. // length.
  2071. //
  2072. pInfo->ulDataLength = ulBufferLength - pInfo->ulHeaderLength;
  2073. }
  2074. return GERR_None;
  2075. }
  2076. USHORT
  2077. GetAvpValueFixedAch(
  2078. IN AVPINFO* pAvp,
  2079. IN USHORT usArraySize,
  2080. OUT CHAR** ppch )
  2081. // Set callers '*ppch' to point to value field of AVP 'pAvp' containing an
  2082. // array of 'usArraySize' bytes. No byte ordering is done.
  2083. //
  2084. // Returns GERR_None if successful, or a GERR_* error code.
  2085. //
  2086. {
  2087. // Make sure it's the right size.
  2088. //
  2089. if (pAvp->usValueLength != usArraySize)
  2090. {
  2091. return GERR_BadLength;
  2092. }
  2093. *ppch = pAvp->pValue;
  2094. return GERR_None;
  2095. }
  2096. USHORT
  2097. GetAvpValueFixedAul(
  2098. IN AVPINFO* pAvp,
  2099. IN USHORT usArraySize,
  2100. OUT UNALIGNED ULONG** paulArray )
  2101. // Set callers '*paulArray' to point to value field of AVP 'pAvp'
  2102. // containing an array of 'usArraySize' ULONGs, converted to host
  2103. // byte-order. A 2-byte reserved field is assumed to preceed the first
  2104. // ULONG.
  2105. //
  2106. // Returns GERR_None if successful, or a GERR_* error code.
  2107. //
  2108. {
  2109. USHORT* pusCur;
  2110. UNALIGNED ULONG* pulCur;
  2111. ULONG i;
  2112. // Make sure it's the right size.
  2113. //
  2114. if (pAvp->usValueLength != sizeof(USHORT) + (usArraySize * sizeof(ULONG)))
  2115. {
  2116. return GERR_BadLength;
  2117. }
  2118. pusCur = (USHORT* )pAvp->pValue;
  2119. // Skip over and ignore the 'Reserved' field.
  2120. //
  2121. ++pusCur;
  2122. *paulArray = (UNALIGNED ULONG* )pusCur;
  2123. for (i = 0, pulCur = *paulArray;
  2124. i < usArraySize;
  2125. ++i, ++pulCur)
  2126. {
  2127. // Convert to host byte-order.
  2128. //
  2129. *pulCur = ntohl( *pulCur );
  2130. }
  2131. return GERR_None;
  2132. }
  2133. USHORT
  2134. GetAvpValueFlag(
  2135. IN AVPINFO* pAvp,
  2136. OUT UNALIGNED BOOLEAN* pf )
  2137. // Set callers '*pf' to true since with a flag AVP the existence is the
  2138. // data, and performs the routine AVP validations.
  2139. //
  2140. // Returns GERR_None if successful, or a GERR_* error code.
  2141. //
  2142. {
  2143. // Make sure it's the right size.
  2144. //
  2145. if (pAvp->usValueLength != 0)
  2146. {
  2147. return GERR_BadLength;
  2148. }
  2149. *pf = TRUE;
  2150. return GERR_None;
  2151. }
  2152. USHORT
  2153. GetAvpValueUs(
  2154. IN AVPINFO* pAvp,
  2155. OUT UNALIGNED USHORT** ppus )
  2156. // Set callers '*ppus' to point to the USHORT value field of AVP 'pAvp'.
  2157. // The field is host byte-ordered.
  2158. //
  2159. // Returns GERR_None if successful, or a GERR_* error code.
  2160. //
  2161. {
  2162. UNALIGNED USHORT* pusCur;
  2163. // Make sure it's the right size.
  2164. //
  2165. if (pAvp->usValueLength != sizeof(USHORT))
  2166. {
  2167. return GERR_BadLength;
  2168. }
  2169. // Convert in place to host byte-order.
  2170. //
  2171. pusCur = (USHORT* )pAvp->pValue;
  2172. *pusCur = ntohs( *pusCur );
  2173. *ppus = pusCur;
  2174. return GERR_None;
  2175. }
  2176. USHORT
  2177. GetAvpValue2UsAndVariableAch(
  2178. IN AVPINFO* pAvp,
  2179. OUT UNALIGNED USHORT** ppus1,
  2180. OUT UNALIGNED USHORT** ppus2,
  2181. OUT CHAR** ppch,
  2182. OUT USHORT* pusArraySize )
  2183. // Gets the data from an AVP with 2 USHORTs followed by a variable length
  2184. // array. Sets '*ppus1' and '*ppus2' to the two short integers and
  2185. // '*ppus' to the variable length array. '*PusArraySize is set to the
  2186. // length of the '*ppch' array. 'pAvp'. The field is host byte-ordered.
  2187. //
  2188. // Returns GERR_None if successful, or a GERR_* error code.
  2189. //
  2190. {
  2191. UNALIGNED USHORT* pusCur;
  2192. // Make sure it's the right size.
  2193. //
  2194. if (pAvp->usValueLength < sizeof(USHORT))
  2195. {
  2196. return GERR_BadLength;
  2197. }
  2198. // Convert in place to host byte-order.
  2199. //
  2200. pusCur = (USHORT* )pAvp->pValue;
  2201. *pusCur = ntohs( *pusCur );
  2202. *ppus1 = pusCur;
  2203. ++pusCur;
  2204. // NOTE: second ushort value and the rest are optional
  2205. if (pAvp->usValueLength >= (2 * sizeof(USHORT)))
  2206. {
  2207. *pusCur = ntohs( *pusCur );
  2208. *ppus2 = pusCur;
  2209. }
  2210. else
  2211. {
  2212. *ppus2 = NULL;
  2213. }
  2214. ++pusCur;
  2215. if (pAvp->usValueLength > (2 * sizeof(USHORT)))
  2216. {
  2217. *ppch = (CHAR* )pusCur;
  2218. *pusArraySize = pAvp->usValueLength - (2 * sizeof(USHORT));
  2219. }
  2220. else
  2221. {
  2222. *ppch = NULL;
  2223. *pusArraySize = 0;
  2224. }
  2225. return GERR_None;
  2226. }
  2227. USHORT
  2228. GetAvpValueUl(
  2229. IN AVPINFO* pAvp,
  2230. OUT UNALIGNED ULONG** ppul )
  2231. // Set callers '*ppul' to point to the ULONG value field of AVP 'pAvp'.
  2232. // The field is host byte-ordered.
  2233. //
  2234. // Returns GERR_None if successful, or a GERR_* error code.
  2235. //
  2236. {
  2237. UNALIGNED ULONG* pulCur;
  2238. // Make sure it's the right size.
  2239. //
  2240. if (pAvp->usValueLength != sizeof(ULONG))
  2241. {
  2242. return GERR_BadLength;
  2243. }
  2244. // Convert in place to host byte-order.
  2245. //
  2246. pulCur = (UNALIGNED ULONG* )pAvp->pValue;
  2247. *pulCur = ntohl( *pulCur );
  2248. *ppul = pulCur;
  2249. return GERR_None;
  2250. }
  2251. USHORT
  2252. GetAvpValueVariableAch(
  2253. IN AVPINFO* pAvp,
  2254. OUT CHAR** ppch,
  2255. OUT USHORT* pusArraySize )
  2256. // Set callers '*ppch' to point to value field of AVP 'pAvp' containing an
  2257. // array of bytes, where '*pusArraySize' is set to the length in bytes.
  2258. // No byte ordering is done.
  2259. //
  2260. // Returns GERR_None if successful, or a GERR_* error code.
  2261. //
  2262. {
  2263. // The win9x clients send null host names. Remove the check.
  2264. //if(pAvp->usValueLength == 0 || pAvp->pValue[0] == '\0')
  2265. //{
  2266. // return GERR_BadLength;
  2267. //}
  2268. *pusArraySize = pAvp->usValueLength;
  2269. *ppch = pAvp->pValue;
  2270. return GERR_None;
  2271. }
  2272. VOID
  2273. HelloTimerEvent(
  2274. IN TIMERQITEM* pItem,
  2275. IN VOID* pContext,
  2276. IN TIMERQEVENT event )
  2277. // PTIMERQEVENT handler set to expire when a "Hello" interval has expired.
  2278. //
  2279. {
  2280. ADAPTERCB* pAdapter;
  2281. TUNNELCB* pTunnel;
  2282. BOOLEAN fReusedTimerQItem;
  2283. TRACE( TL_V, TM_Send,
  2284. ( "HelloTimerEvent(%s)", TimerQPszFromEvent( event ) ) );
  2285. // Unpack context information.
  2286. //
  2287. pTunnel = (TUNNELCB* )pContext;
  2288. pAdapter = pTunnel->pAdapter;
  2289. fReusedTimerQItem = FALSE;
  2290. if (event == TE_Expire)
  2291. {
  2292. NdisAcquireSpinLock( &pTunnel->lockT );
  2293. {
  2294. if (pTunnel->ulHelloResetsThisInterval == 0
  2295. && pTunnel->ulRemainingHelloMs == 0)
  2296. {
  2297. if (pTunnel->state != CCS_Idle && pItem == pTunnel->pTqiHello)
  2298. {
  2299. // The full timeout period has expired, the tunnel's not
  2300. // idle, and the hello timer was not cancelled or
  2301. // terminated since the expire timer fired. It's time to
  2302. // send a "Hello" message to make sure the media is still
  2303. // up.
  2304. //
  2305. SendControl( pTunnel, NULL, CMT_Hello, 0, 0, NULL, 0 );
  2306. }
  2307. DBG_else
  2308. {
  2309. TRACE( TL_A, TM_Send, ( "Hello aborted" ) );
  2310. }
  2311. pTunnel->pTqiHello = NULL;
  2312. }
  2313. else
  2314. {
  2315. ULONG ulTimeoutMs;
  2316. // Not a full timeout expiration event. Adjust interval
  2317. // counters and schedule next interval timeout.
  2318. //
  2319. if (pTunnel->ulHelloResetsThisInterval > 0)
  2320. {
  2321. pTunnel->ulRemainingHelloMs = pAdapter->ulHelloMs;
  2322. pTunnel->ulHelloResetsThisInterval = 0;
  2323. }
  2324. if (pTunnel->ulRemainingHelloMs >= L2TP_HelloIntervalMs)
  2325. {
  2326. ulTimeoutMs = L2TP_HelloIntervalMs;
  2327. pTunnel->ulRemainingHelloMs -= L2TP_HelloIntervalMs;
  2328. }
  2329. else
  2330. {
  2331. ulTimeoutMs = pTunnel->ulRemainingHelloMs;
  2332. pTunnel->ulRemainingHelloMs = 0;
  2333. }
  2334. TimerQInitializeItem( pItem );
  2335. TimerQScheduleItem(
  2336. pTunnel->pTimerQ,
  2337. pItem,
  2338. ulTimeoutMs,
  2339. HelloTimerEvent,
  2340. pTunnel );
  2341. fReusedTimerQItem = TRUE;
  2342. }
  2343. }
  2344. NdisReleaseSpinLock( &pTunnel->lockT );
  2345. }
  2346. if (!fReusedTimerQItem)
  2347. {
  2348. FREE_TIMERQITEM( pAdapter, pItem );
  2349. }
  2350. }
  2351. VOID
  2352. IndicateReceived(
  2353. IN VCCB* pVc,
  2354. IN CHAR* pBuffer,
  2355. IN ULONG ulOffset,
  2356. IN ULONG ulLength,
  2357. IN LONGLONG llTimeReceived )
  2358. // Indicates to the client above a packet received on VC 'pVc' containing
  2359. // 'ulLength' bytes of data from NDIS_BUFFER 'pBuffer' starting 'ulOffset'
  2360. // bytes in. Caller must not reference 'pBuffer' after calling this
  2361. // routine. 'UllTimeReceived' is the time the packet was received from
  2362. // the net, or 0 if call parameters said client doesn't care.
  2363. //
  2364. // IMPORTANT: Caller should not hold any spinlocks as this routine make
  2365. // NDIS indications.
  2366. //
  2367. {
  2368. NDIS_STATUS status;
  2369. NDIS_PACKET* pPacket;
  2370. NDIS_BUFFER* pTrimmedBuffer;
  2371. ADAPTERCB* pAdapter;
  2372. PACKETHEAD* pHead;
  2373. LONG* plRef;
  2374. LONG lRef;
  2375. pAdapter = pVc->pAdapter;
  2376. pPacket = GetPacketFromPool( &pAdapter->poolPackets, &pHead );
  2377. if (!pPacket)
  2378. {
  2379. // Packet descriptor pool is maxed.
  2380. //
  2381. FreeBufferToPool( &pAdapter->poolFrameBuffers, pBuffer, TRUE );
  2382. return;
  2383. }
  2384. // Lop off the L2TP header and hook the corresponding NDIS_BUFFER to the
  2385. // packet. The "copy" here refers to descriptor information only. The
  2386. // packet data is not copied.
  2387. //
  2388. NdisCopyBuffer(
  2389. &status,
  2390. &pTrimmedBuffer,
  2391. PoolHandleForNdisCopyBufferFromBuffer( pBuffer ),
  2392. NdisBufferFromBuffer( pBuffer ),
  2393. ulOffset,
  2394. ulLength );
  2395. if (status != STATUS_SUCCESS)
  2396. {
  2397. // Can't get a MDL which likely means the system is toast.
  2398. //
  2399. TRACE( TL_A, TM_Recv, ( "NdisCopyBuffer=%08x?", status ) );
  2400. WPLOG( LL_A, LM_Recv, ( "NdisCopyBuffer=%08x?", status ) );
  2401. FreePacketToPool( &pAdapter->poolPackets, pHead, TRUE );
  2402. FreeBufferToPool( &pAdapter->poolFrameBuffers, pBuffer, TRUE );
  2403. return;
  2404. }
  2405. else
  2406. {
  2407. extern ULONG g_ulNdisCopyBuffers;
  2408. NdisInterlockedIncrement( &g_ulNdisCopyBuffers );
  2409. }
  2410. NdisChainBufferAtFront( pPacket, pTrimmedBuffer );
  2411. // Stash the time the packet was received in the packet.
  2412. //
  2413. NDIS_SET_PACKET_TIME_RECEIVED( pPacket, llTimeReceived );
  2414. // Pre-set the packet to success, since a random value of
  2415. // NDIS_STATUS_RESOURCES would prevent our ReturnPackets handler from
  2416. // getting called.
  2417. //
  2418. NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_SUCCESS );
  2419. // Stash our context information with the packet for clean-up use in
  2420. // LmpReturnPacket, then indicate the packet to NDISWAN.
  2421. //
  2422. *((PACKETHEAD** )(&pPacket->MiniportReserved[ 0 ])) = pHead;
  2423. *((CHAR** )(&pPacket->MiniportReserved[ sizeof(VOID*) ])) = pBuffer;
  2424. TRACE( TL_N, TM_Recv, ( "NdisMCoIndRecPkt(len=%d)...", ulLength ) );
  2425. NdisMCoIndicateReceivePacket( pVc->NdisVcHandle, &pPacket, 1 );
  2426. TRACE( TL_N, TM_Recv, ( "NdisMCoIndRecPkt done" ) );
  2427. // Tell NDIS our "receive process" is complete. Since we deal with one
  2428. // packet at a time and NDISWAN does also, this doesn't accomplish
  2429. // anything, but the consensus is it's bad form to omit it.
  2430. //
  2431. TRACE( TL_N, TM_Recv, ( "NdisMCoRecComp..." ) );
  2432. NdisMCoReceiveComplete( pAdapter->MiniportAdapterHandle );
  2433. TRACE( TL_N, TM_Recv, ( "NdisMCoRecComp done" ) );
  2434. NdisInterlockedIncrement( &g_lPacketsIndicated );
  2435. NdisAcquireSpinLock( &pVc->lockV );
  2436. {
  2437. ++pVc->stats.ulRecdDataPackets;
  2438. pVc->stats.ulDataBytesRecd += ulLength;
  2439. }
  2440. NdisReleaseSpinLock( &pVc->lockV );
  2441. }
  2442. TUNNELCB*
  2443. TunnelCbFromTunnelId(
  2444. IN ADAPTERCB* pAdapter,
  2445. IN USHORT usTunnelId )
  2446. // Return the tunnel control block associated with 'ulIpAddress' in
  2447. // 'pAdapter's list of TUNNELCBs or NULL if not found.
  2448. //
  2449. // IMPORTANT: Caller must hold 'pAdapter->lockTunnels'.
  2450. //
  2451. {
  2452. TUNNELCB* pTunnel;
  2453. LIST_ENTRY* pLink;
  2454. pTunnel = NULL;
  2455. for (pLink = pAdapter->listTunnels.Flink;
  2456. pLink != &pAdapter->listTunnels;
  2457. pLink = pLink->Flink)
  2458. {
  2459. TUNNELCB* pThis;
  2460. pThis = CONTAINING_RECORD( pLink, TUNNELCB, linkTunnels );
  2461. if (pThis->usTunnelId == usTunnelId)
  2462. {
  2463. pTunnel = pThis;
  2464. break;
  2465. }
  2466. }
  2467. return pTunnel;
  2468. }
  2469. BOOLEAN
  2470. LookUpTunnelAndVcCbs(
  2471. IN ADAPTERCB* pAdapter,
  2472. IN USHORT* pusTunnelId,
  2473. IN USHORT* pusCallId,
  2474. IN L2TPHEADERINFO* pHeader,
  2475. IN CONTROLMSGINFO* pControl,
  2476. OUT TUNNELCB** ppTunnel,
  2477. OUT VCCB** ppVc )
  2478. // Fill caller's '*ppTunnel' and '*ppVc' with the control blocks implied
  2479. // by the Tunnel-ID and Call-ID found in the header, if any. 'PHeader' is
  2480. // the exploded L2TP header. 'PControl' is the exploded control message
  2481. // info or NULL if payload.
  2482. //
  2483. // Returns true if a valid combination is found. This does not
  2484. // necessarily mean that both tunnel and VC outputs are non-NULL.
  2485. //
  2486. // Returns false if the combination is invalid. In this case, the packet
  2487. // is zombie acked if necessary. See ZombieAckIfNecessary routine.
  2488. //
  2489. {
  2490. BOOLEAN fFail;
  2491. *ppVc = NULL;
  2492. *ppTunnel = NULL;
  2493. // As of draft-05 Tunnel-ID and Call-ID are no longer optional.
  2494. //
  2495. ASSERT( pusCallId );
  2496. ASSERT( pusTunnelId );
  2497. if (*pusCallId)
  2498. {
  2499. // Non-0 Call-ID must have non-0 Tunnel-ID
  2500. if(!*pusTunnelId)
  2501. {
  2502. return FALSE;
  2503. }
  2504. if (*pusCallId > pAdapter->usMaxVcs)
  2505. {
  2506. // Non-0 Call-ID out of range of the table, i.e. it's a VC that is
  2507. // being used for graceful termination and is not passed up. Look
  2508. // up tunnel and VC blocks by walking lists.
  2509. //
  2510. // Search the adapter's list of active tunnels for the one
  2511. // with peer's specified Tunnel-ID.
  2512. //
  2513. NdisAcquireSpinLock( &pAdapter->lockTunnels );
  2514. {
  2515. *ppTunnel = TunnelCbFromTunnelId( pAdapter, *pusTunnelId );
  2516. if (*ppTunnel)
  2517. {
  2518. ReferenceTunnel( *ppTunnel, TRUE );
  2519. }
  2520. }
  2521. NdisReleaseSpinLock( &pAdapter->lockTunnels );
  2522. if (*ppTunnel)
  2523. {
  2524. // Search the tunnel's list of active VCs for the one with
  2525. // peer's specified Call-ID.
  2526. //
  2527. NdisAcquireSpinLock( &((*ppTunnel)->lockVcs) );
  2528. {
  2529. *ppVc = VcCbFromCallId( *ppTunnel, *pusCallId );
  2530. if (*ppVc)
  2531. {
  2532. ReferenceVc( *ppVc );
  2533. }
  2534. }
  2535. NdisReleaseSpinLock( &((*ppTunnel)->lockVcs) );
  2536. if (!*ppVc)
  2537. {
  2538. // Non-0 Call-ID out of range of table with no
  2539. // associated VC control block.
  2540. //
  2541. TRACE( TL_A, TM_Recv, ( "CBs bad: Big CID w/!pV" ) );
  2542. WPLOG( LL_A, LM_Recv, ( "CBs bad: Big CID w/!pV" ) );
  2543. ZombieAckIfNecessary( *ppTunnel, pHeader, pControl );
  2544. DereferenceTunnel( *ppTunnel );
  2545. *ppTunnel = NULL;
  2546. return FALSE;
  2547. }
  2548. }
  2549. else
  2550. {
  2551. // Non-0 Call-ID out of range of table with no tunnel
  2552. // control block associated with the Tunnel-ID.
  2553. //
  2554. TRACE( TL_A, TM_Recv, ( "CBs bad: Big CID w/!pT" ) );
  2555. WPLOG( LL_A, LM_Recv, ( "CBs bad: Big CID w/!pT" ) );
  2556. return FALSE;
  2557. }
  2558. }
  2559. else
  2560. {
  2561. // Read the VCCB* from the adapter's table.
  2562. //
  2563. fFail = FALSE;
  2564. NdisDprAcquireSpinLock( &pAdapter->lockVcs );
  2565. {
  2566. *ppVc = pAdapter->ppVcs[ *pusCallId - 1 ];
  2567. if (*ppVc && *ppVc != (VCCB* )-1)
  2568. {
  2569. ReferenceVc( *ppVc );
  2570. *ppTunnel = (*ppVc)->pTunnel;
  2571. ASSERT( *ppTunnel );
  2572. ReferenceTunnel( *ppTunnel, FALSE );
  2573. if(*pusTunnelId != (*ppTunnel)->usTunnelId)
  2574. {
  2575. // Non-0 Call-ID is associated with a tunnel different
  2576. // than the one indicated by peer in the header.
  2577. //
  2578. TRACE( TL_A, TM_Recv,
  2579. ( "CBs bad: TIDs=%d,%d?",
  2580. (ULONG )*pusTunnelId,
  2581. (ULONG )(*ppTunnel)->usTunnelId ) );
  2582. WPLOG( LL_A, LM_Recv,
  2583. ( "CBs bad: TIDs=%d,%d?",
  2584. (ULONG )*pusTunnelId,
  2585. (ULONG )(*ppTunnel)->usTunnelId ) );
  2586. DereferenceTunnel( *ppTunnel );
  2587. *ppTunnel = NULL;
  2588. DereferenceVc( *ppVc );
  2589. *ppVc = NULL;
  2590. fFail = TRUE;
  2591. }
  2592. }
  2593. else
  2594. {
  2595. // Non-0 Call-ID without an active VC.
  2596. //
  2597. TRACE( TL_A, TM_Recv,
  2598. ( "CBs bad: CID=%d, pV=$%p?",
  2599. (ULONG )*pusCallId, *ppVc ) );
  2600. WPLOG( LL_A, LM_Recv,
  2601. ( "CBs bad: CID=%d, pV=$%p?",
  2602. (ULONG )*pusCallId, *ppVc ) );
  2603. // Search the adapter's list of active tunnels for the one
  2604. // with peer's specified Tunnel-ID.
  2605. //
  2606. NdisAcquireSpinLock( &pAdapter->lockTunnels );
  2607. {
  2608. *ppTunnel = TunnelCbFromTunnelId(
  2609. pAdapter, *pusTunnelId );
  2610. if (*ppTunnel)
  2611. {
  2612. ReferenceTunnel( *ppTunnel, TRUE );
  2613. }
  2614. }
  2615. NdisReleaseSpinLock( &pAdapter->lockTunnels );
  2616. *ppVc = NULL;
  2617. fFail = TRUE;
  2618. }
  2619. }
  2620. NdisDprReleaseSpinLock( &pAdapter->lockVcs );
  2621. if (fFail)
  2622. {
  2623. if (*ppTunnel)
  2624. {
  2625. ZombieAckIfNecessary( *ppTunnel, pHeader, pControl );
  2626. DereferenceTunnel( *ppTunnel );
  2627. *ppTunnel = NULL;
  2628. }
  2629. return FALSE;
  2630. }
  2631. }
  2632. }
  2633. else if (*pusTunnelId)
  2634. {
  2635. // 0 Call-ID with non-0 Tunnel-ID. Search the list of active tunnels
  2636. // for the one with peer's specified Tunnel-ID.
  2637. //
  2638. NdisAcquireSpinLock( &pAdapter->lockTunnels );
  2639. {
  2640. *ppTunnel = TunnelCbFromTunnelId( pAdapter, *pusTunnelId );
  2641. if (*ppTunnel)
  2642. {
  2643. ReferenceTunnel( *ppTunnel, TRUE );
  2644. }
  2645. }
  2646. NdisReleaseSpinLock( &pAdapter->lockTunnels );
  2647. if (!*ppTunnel)
  2648. {
  2649. // 0 Call-Id with bogus Tunnel-ID.
  2650. //
  2651. TRACE( TL_A, TM_Recv,
  2652. ( "CBs bad: Cid=0, Tid=%d, pT=0?",
  2653. (ULONG )*pusTunnelId ) );
  2654. WPLOG( LL_A, LM_Recv,
  2655. ( "CBs bad: Cid=0, Tid=%d, pT=0?",
  2656. (ULONG )*pusTunnelId ) );
  2657. return FALSE;
  2658. }
  2659. if (pControl
  2660. && pControl->usXError == GERR_None
  2661. && pControl->pusMsgType
  2662. && *(pControl->pusMsgType) == CMT_CDN
  2663. && pControl->pusAssignedCallId)
  2664. {
  2665. // The CallDisconnectNotify message includes the sender's assigned
  2666. // Call-ID as an AVP so that it may be sent before sender receives
  2667. // peer's assigned Call-ID. Unfortunately, this requires this
  2668. // routine to have AVP knowledge. Search the tunnel's list of
  2669. // associated VCs for the one with peer's specified Assigned
  2670. // Call-ID.
  2671. //
  2672. NdisDprAcquireSpinLock( &((*ppTunnel)->lockVcs) );
  2673. {
  2674. *ppVc = VcCbFromCallId(
  2675. *ppTunnel, *(pControl->pusAssignedCallId) );
  2676. if (*ppVc)
  2677. {
  2678. ReferenceVc( *ppVc );
  2679. }
  2680. }
  2681. NdisDprReleaseSpinLock( &((*ppTunnel)->lockVcs) );
  2682. if (!*ppVc)
  2683. {
  2684. // 0 Call-Id CDN with no associated VC.
  2685. //
  2686. TRACE( TL_A, TM_Recv,
  2687. ( "CBs bad: CDN Tid %d, !pVc?", (ULONG )*pusTunnelId ) );
  2688. WPLOG( LL_A, LM_Recv,
  2689. ( "CBs bad: CDN Tid %d, !pVc?", (ULONG )*pusTunnelId ) );
  2690. ZombieAckIfNecessary( *ppTunnel, pHeader, pControl );
  2691. DereferenceTunnel( *ppTunnel );
  2692. *ppTunnel = NULL;
  2693. return FALSE;
  2694. }
  2695. }
  2696. }
  2697. // Note: 0 Call-ID with 0 Tunnel-ID should only occur on peer's SCCRQ to
  2698. // start a tunnel, but that means it's not an error here, even though we
  2699. // report back neither control block.
  2700. ASSERT( !*ppTunnel || (*ppTunnel)->ulTag == MTAG_TUNNELCB );
  2701. ASSERT( !*ppVc || (*ppVc)->ulTag == MTAG_VCCB );
  2702. TRACE( TL_N, TM_Recv,
  2703. ( "CBs good: pT=$%p, pV=$%p", *ppTunnel, *ppVc ) );
  2704. return TRUE;
  2705. }
  2706. VOID
  2707. PayloadAcknowledged(
  2708. IN TUNNELCB* pTunnel,
  2709. IN VCCB* pVc,
  2710. IN USHORT usReceivedNr )
  2711. // Cancels the timer of all payload-sent contexts in the VCs
  2712. // 'listSendsOut' queue with 'Next Sent' less than 'usReceivedNr'.
  2713. //
  2714. // IMPORTANT: Caller must hold 'pVc->lockV', which may be released and
  2715. // re-acquired by this routine. Caller must not hold any other
  2716. // locks.
  2717. //
  2718. {
  2719. while (!IsListEmpty( &pVc->listSendsOut ))
  2720. {
  2721. PAYLOADSENT* pPs;
  2722. LIST_ENTRY* pLink;
  2723. BOOLEAN fUpdateSendWindow;
  2724. LINKSTATUSINFO info;
  2725. pLink = pVc->listSendsOut.Flink;
  2726. pPs = CONTAINING_RECORD( pLink, PAYLOADSENT, linkSendsOut );
  2727. // The list is in 'Ns' order so as soon as a non-acknowledge is hit
  2728. // we're done.
  2729. //
  2730. if (CompareSequence( pPs->usNs, usReceivedNr ) >= 0)
  2731. {
  2732. break;
  2733. }
  2734. // This packet has been acknowledged.
  2735. //
  2736. pPs->status = NDIS_STATUS_SUCCESS;
  2737. // Remove the context from the head of the "outstanding send" list.
  2738. // The corresponding dereference occurs below.
  2739. //
  2740. RemoveEntryList( &pPs->linkSendsOut );
  2741. InitializeListHead( &pPs->linkSendsOut );
  2742. // Doesn't matter if this cancel fails because the expire handler will
  2743. // recognize that the context is not linked into the "out" list and do
  2744. // nothing.
  2745. //
  2746. TimerQCancelItem( pTunnel->pTimerQ, pPs->pTqiSendTimeout );
  2747. // Adjust the timeouts and, if necessary, the send window as suggested
  2748. // in the draft/RFC.
  2749. //
  2750. AdjustTimeoutsAtAckReceived(
  2751. pPs->llTimeSent,
  2752. pTunnel->pAdapter->ulMaxSendTimeoutMs,
  2753. &pVc->ulSendTimeoutMs,
  2754. &pVc->ulRoundTripMs,
  2755. &pVc->lDeviationMs );
  2756. fUpdateSendWindow =
  2757. AdjustSendWindowAtAckReceived(
  2758. pVc->ulMaxSendWindow,
  2759. &pVc->ulAcksSinceSendTimeout,
  2760. &pVc->ulSendWindow );
  2761. TRACE( TL_V, TM_Send,
  2762. ( "C%d: ACK(%d) new rtt=%d dev=%d ato=%d sw=%d",
  2763. (ULONG )pVc->usCallId, (ULONG )pPs->usNs,
  2764. pVc->ulRoundTripMs, pVc->ulSendTimeoutMs,
  2765. pVc->lDeviationMs, pVc->ulSendWindow ) );
  2766. // Update the statistics the reflect the acknowledge, it's round trip
  2767. // time, and any change in the send window. The field
  2768. // 'pVc->UlRoundTripMs' is really an "estimate" of the next round trip
  2769. // rather than the actual trip time. However, just after an
  2770. // acknowledge has been received, the two are identical so it can be
  2771. // used in the statistics here.
  2772. //
  2773. ++pVc->stats.ulSentPacketsAcked;
  2774. ++pVc->stats.ulRoundTrips;
  2775. pVc->stats.ulRoundTripMsTotal += pVc->ulRoundTripMs;
  2776. if (pVc->ulRoundTripMs > pVc->stats.ulMaxRoundTripMs)
  2777. {
  2778. pVc->stats.ulMaxRoundTripMs = pVc->ulRoundTripMs;
  2779. }
  2780. if (pVc->ulRoundTripMs < pVc->stats.ulMinRoundTripMs
  2781. || pVc->stats.ulRoundTrips == 1)
  2782. {
  2783. pVc->stats.ulMinRoundTripMs = pVc->ulRoundTripMs;
  2784. }
  2785. if (fUpdateSendWindow)
  2786. {
  2787. ++pVc->stats.ulSendWindowChanges;
  2788. if (pVc->ulSendWindow > pVc->stats.ulMaxSendWindow)
  2789. {
  2790. pVc->stats.ulMaxSendWindow = pVc->ulSendWindow;
  2791. }
  2792. else if (pVc->ulSendWindow < pVc->stats.ulMinSendWindow)
  2793. {
  2794. pVc->stats.ulMinSendWindow = pVc->ulSendWindow;
  2795. }
  2796. // Indicate the send window change to NDISWAN. The lock is
  2797. // released first since this involves a call outside our driver.
  2798. //
  2799. TransferLinkStatusInfo( pVc, &info );
  2800. NdisReleaseSpinLock( &pVc->lockV );
  2801. {
  2802. IndicateLinkStatus( pVc, &info );
  2803. }
  2804. NdisAcquireSpinLock( &pVc->lockV );
  2805. }
  2806. // This dereference corresponds to the removal of the context from the
  2807. // "outstanding send" list above.
  2808. //
  2809. DereferencePayloadSent( pPs );
  2810. }
  2811. }
  2812. BOOLEAN
  2813. ReceiveFromOutOfOrder(
  2814. IN VCCB* pVc )
  2815. // "Receives" the first buffer queued on 'pVc's out-of-order list if it is
  2816. // the next expected packet.
  2817. //
  2818. // Returns true if a buffer was "received", false otherwise. If true is
  2819. // returned, caller should call SchedulePayloadAck. It's not called here
  2820. // so caller can receive multiple packets from the out-of-order queue and
  2821. // set the timer once.
  2822. //
  2823. // IMPORTANT: Caller must hold 'pVc->lockV'. Also, be aware this routine
  2824. // may release and re-acquire the lock to make the NDIS receive
  2825. // indication.
  2826. //
  2827. {
  2828. ADAPTERCB* pAdapter;
  2829. LIST_ENTRY* pFirstLink;
  2830. PAYLOADRECEIVED* pFirstPr;
  2831. SHORT sDiff;
  2832. TRACE( TL_N, TM_Recv, ( "ReceiveFromOutOfOrder Nr=%d", pVc->usNr ) );
  2833. if (IsListEmpty( &pVc->listOutOfOrder ))
  2834. {
  2835. // No out-of-order buffers queued.
  2836. //
  2837. TRACE( TL_N, TM_Recv, ( "None queued" ) );
  2838. return FALSE;
  2839. }
  2840. pAdapter = pVc->pAdapter;
  2841. pFirstLink = pVc->listOutOfOrder.Flink;
  2842. pFirstPr = CONTAINING_RECORD( pFirstLink, PAYLOADRECEIVED, linkOutOfOrder );
  2843. // Verify the next queued buffer is in sequence first.
  2844. //
  2845. sDiff = CompareSequence( pFirstPr->usNs, pVc->usNr );
  2846. if (sDiff > 0)
  2847. {
  2848. // No, first queued packet is still beyond the next one expected.
  2849. //
  2850. TRACE( TL_I, TM_Recv,
  2851. ( "Still out-of-order, Ns=%d", pFirstPr->usNs ) );
  2852. return FALSE;
  2853. }
  2854. // De-queue the first out-of-order buffer and if it's exactly the one we
  2855. // expected, update 'Next Receive'to be the one following it's 'Next
  2856. // Send'. When peer sends an R-bit to set 'Next Receive' ahead, packets
  2857. // prior to the new expected packet may be queued before the expected
  2858. // packet. These packets are still good and are immediately indicated up,
  2859. // but since 'Next Receive' is already updated in that case, it is not
  2860. // adjusted here.
  2861. //
  2862. RemoveEntryList( pFirstLink );
  2863. InitializeListHead( pFirstLink );
  2864. if (sDiff == 0)
  2865. {
  2866. pVc->usNr = pFirstPr->usNs + 1;
  2867. }
  2868. TRACE( TL_I, TM_Recv, ( "%d from queue", (UINT )pFirstPr->usNs ) );
  2869. ++pVc->stats.ulDataPacketsDequeued;
  2870. NdisReleaseSpinLock( &pVc->lockV );
  2871. {
  2872. // Indicate the buffer to the driver above, and free it's out-of-order
  2873. // context.
  2874. //
  2875. IndicateReceived(
  2876. pVc,
  2877. pFirstPr->pBuffer,
  2878. pFirstPr->ulPayloadOffset,
  2879. pFirstPr->ulPayloadLength,
  2880. pFirstPr->llTimeReceived );
  2881. FREE_PAYLOADRECEIVED( pAdapter, pFirstPr );
  2882. }
  2883. NdisAcquireSpinLock( &pVc->lockV );
  2884. return TRUE;
  2885. }
  2886. VOID
  2887. ResetHelloTimer(
  2888. IN TUNNELCB* pTunnel )
  2889. // Resets (logically anyway) the 'pTunnel' Hello timer.
  2890. //
  2891. {
  2892. ADAPTERCB* pAdapter;
  2893. pAdapter = pTunnel->pAdapter;
  2894. if (pAdapter->ulHelloMs)
  2895. {
  2896. NdisAcquireSpinLock( &pTunnel->lockT );
  2897. {
  2898. if (pTunnel->state != CCS_Idle)
  2899. {
  2900. if (pTunnel->pTqiHello)
  2901. {
  2902. TRACE( TL_V, TM_Send, ( "Reset HelloTimer" ) );
  2903. // Timer's running so just note that a reset has occurred
  2904. // since it was started.
  2905. //
  2906. ++pTunnel->ulHelloResetsThisInterval;
  2907. }
  2908. else
  2909. {
  2910. TRACE( TL_I, TM_Send, ( "Kickstart HelloTimer" ) );
  2911. // Timer is not running. Kickstart it by scheduling an
  2912. // "instant expire" event that will reset the interval.
  2913. //
  2914. pTunnel->pTqiHello = ALLOC_TIMERQITEM( pAdapter );
  2915. if (pTunnel->pTqiHello)
  2916. {
  2917. pTunnel->ulHelloResetsThisInterval = 1;
  2918. pTunnel->ulRemainingHelloMs = 0;
  2919. TimerQInitializeItem( pTunnel->pTqiHello );
  2920. TimerQScheduleItem(
  2921. pTunnel->pTimerQ,
  2922. pTunnel->pTqiHello,
  2923. 0,
  2924. HelloTimerEvent,
  2925. pTunnel );
  2926. }
  2927. }
  2928. }
  2929. }
  2930. NdisReleaseSpinLock( &pTunnel->lockT );
  2931. }
  2932. }
  2933. VOID
  2934. ScheduleControlAck(
  2935. IN TUNNELCB* pTunnel,
  2936. IN USHORT usMsgTypeToAcknowledge )
  2937. // Schedule a 'ControlAckTimerEvent' to occur in 1/4 of the standard send
  2938. // timeout. If one's already ticking no action is taken, because any
  2939. // packet that goes out will get it done. Doesn't matter who requested
  2940. // it. 'UsMsgTypeToAcknowledge' is the CMT_* code of the message to be
  2941. // acknowledged and is used for performance tuning.
  2942. //
  2943. // IMPORTANT: Caller must hold 'pTunnel->lockT'.
  2944. //
  2945. {
  2946. TIMERQITEM* pTqi;
  2947. ADAPTERCB* pAdapter;
  2948. ULONG ulDelayMs;
  2949. BOOLEAN fFastAck;
  2950. if ((usMsgTypeToAcknowledge == CMT_StopCCN
  2951. || usMsgTypeToAcknowledge == CMT_ICCN
  2952. || usMsgTypeToAcknowledge == CMT_OCCN
  2953. || usMsgTypeToAcknowledge == CMT_CDN)
  2954. || (pTunnel->ulSendsOut < pTunnel->ulSendWindow))
  2955. {
  2956. TRACE( TL_N, TM_Recv, ( "Fast ACK" ) );
  2957. // Certain messages where follow-on messages are unlikely are
  2958. // acknowledged without delay, as are all messages when the send
  2959. // window is closed.
  2960. //
  2961. fFastAck = TRUE;
  2962. }
  2963. else
  2964. {
  2965. fFastAck = FALSE;
  2966. }
  2967. if (pTunnel->pTqiDelayedAck)
  2968. {
  2969. if (fFastAck)
  2970. {
  2971. TimerQExpireItem( pTunnel->pTimerQ, pTunnel->pTqiDelayedAck );
  2972. }
  2973. }
  2974. else
  2975. {
  2976. pAdapter = pTunnel->pAdapter;
  2977. pTqi = ALLOC_TIMERQITEM( pAdapter );
  2978. if (!pTqi)
  2979. {
  2980. return;
  2981. }
  2982. pTunnel->pTqiDelayedAck = pTqi;
  2983. if (fFastAck)
  2984. {
  2985. ulDelayMs = 0;
  2986. }
  2987. else
  2988. {
  2989. ulDelayMs = pTunnel->ulSendTimeoutMs >> 2;
  2990. if (ulDelayMs > pAdapter->ulMaxAckDelayMs)
  2991. {
  2992. ulDelayMs = pAdapter->ulMaxAckDelayMs;
  2993. }
  2994. }
  2995. TRACE( TL_N, TM_Recv, ( "SchedControlAck(%dms)", ulDelayMs ) );
  2996. ReferenceTunnel( pTunnel, FALSE );
  2997. TimerQInitializeItem( pTqi );
  2998. TimerQScheduleItem(
  2999. pTunnel->pTimerQ,
  3000. pTqi,
  3001. ulDelayMs,
  3002. ControlAckTimerEvent,
  3003. pTunnel );
  3004. }
  3005. }
  3006. VOID
  3007. SchedulePayloadAck(
  3008. IN TUNNELCB* pTunnel,
  3009. IN VCCB* pVc )
  3010. // Schedule a 'PayloadAckTimerEvent' to occur in 1/4 of the standard send
  3011. // timeout. If one's already ticking no action is taken, because any
  3012. // packet that goes out will get it done. Doesn't matter who requested
  3013. // it.
  3014. //
  3015. // IMPORTANT: Caller must hold 'pVc->lockV'.
  3016. //
  3017. {
  3018. ADAPTERCB* pAdapter;
  3019. TIMERQITEM* pTqi;
  3020. ULONG ulDelayMs;
  3021. if (!pVc->pTqiDelayedAck)
  3022. {
  3023. pAdapter = pVc->pAdapter;
  3024. pTqi = ALLOC_TIMERQITEM( pAdapter );
  3025. if (!pTqi)
  3026. {
  3027. return;
  3028. }
  3029. pVc->pTqiDelayedAck = pTqi;
  3030. ulDelayMs = pVc->ulSendTimeoutMs >> 2;
  3031. if (ulDelayMs > pAdapter->ulMaxAckDelayMs)
  3032. {
  3033. ulDelayMs = pAdapter->ulMaxAckDelayMs;
  3034. }
  3035. TRACE( TL_N, TM_Recv,
  3036. ( "SchedPayloadAck(%dms)=$%p", ulDelayMs, pTqi ) );
  3037. ReferenceVc( pVc );
  3038. TimerQInitializeItem( pTqi );
  3039. TimerQScheduleItem(
  3040. pTunnel->pTimerQ,
  3041. pTqi,
  3042. ulDelayMs,
  3043. PayloadAckTimerEvent,
  3044. pVc );
  3045. }
  3046. }
  3047. VCCB*
  3048. VcCbFromCallId(
  3049. IN TUNNELCB* pTunnel,
  3050. IN USHORT usCallId )
  3051. // Return the VC control block associated with 'usCallId' in 'pTunnel's
  3052. // list of active VCs or NULL if not found.
  3053. //
  3054. // IMPORTANT: Caller must hold 'pTunnel->lockVcs'.
  3055. //
  3056. {
  3057. VCCB* pVc;
  3058. LIST_ENTRY* pLink;
  3059. pVc = NULL;
  3060. for (pLink = pTunnel->listVcs.Flink;
  3061. pLink != &pTunnel->listVcs;
  3062. pLink = pLink->Flink)
  3063. {
  3064. VCCB* pThis;
  3065. pThis = CONTAINING_RECORD( pLink, VCCB, linkVcs );
  3066. if (pThis->usCallId == usCallId)
  3067. {
  3068. pVc = pThis;
  3069. break;
  3070. }
  3071. }
  3072. return pVc;
  3073. }
  3074. VOID
  3075. ZombieAckIfNecessary(
  3076. IN TUNNELCB* pTunnel,
  3077. IN L2TPHEADERINFO* pHeader,
  3078. IN CONTROLMSGINFO* pControl )
  3079. // Determines if a message not matched to any VC warrants a "zombie"
  3080. // re-acknowledge, and if so, schedules one. This situation arises when
  3081. // our side sends an acknowledge to peer's CDN on a given call and the
  3082. // acknowledge is lost. Our side tears down the VC immediately, but peer
  3083. // will eventually drop the entire tunnel if no acknowledge of his follow
  3084. // on CDN retransmits are received, thus affecting calls beyond the one
  3085. // dropped. This routine acknowledges such retransmissions.
  3086. //
  3087. // Another simpler approach would be to take a reference on the call and
  3088. // hold it for a full retransmission interval before dereferencing.
  3089. // However, this would block the drop indications up and would therefore,
  3090. // from dial-out user's point of view, cause a potentially long delay
  3091. // whenever server disconnected a call. This is judged undesirable enough
  3092. // to tolerate the zombie ack messiness.
  3093. //
  3094. // 'PTunnel' is the associated tunnel control block. 'PHeader' is the
  3095. // exploded L2TP header. 'PControl' is the exploded control header, or
  3096. // NULL if not a control message. Caller should already have determined
  3097. // that no VC is associated with the message.
  3098. //
  3099. {
  3100. if (pControl
  3101. && pControl->usXError == GERR_None
  3102. && pControl->pusMsgType
  3103. && *(pControl->pusMsgType) == CMT_CDN
  3104. && pControl->pusAssignedCallId)
  3105. {
  3106. // It's a CDN message and a candidate for re-acknowledgement. See if
  3107. // it's sequence number is prior to or equal to the next expected
  3108. // packet. If so, schedule a zombie acknowledge.
  3109. //
  3110. if (CompareSequence( *(pHeader->pusNs), pTunnel->usNr ) <= 0)
  3111. {
  3112. TRACE( TL_A, TM_Send, ( "Zombie acking" ) );
  3113. NdisAcquireSpinLock( &pTunnel->lockT );
  3114. {
  3115. // Cancel any pending delayed acknowledge timeout.
  3116. //
  3117. if (pTunnel->pTqiDelayedAck)
  3118. {
  3119. TimerQCancelItem(
  3120. pTunnel->pTimerQ, pTunnel->pTqiDelayedAck );
  3121. pTunnel->pTqiDelayedAck = NULL;
  3122. }
  3123. }
  3124. NdisReleaseSpinLock( &pTunnel->lockT );
  3125. ScheduleTunnelWork(
  3126. pTunnel, NULL, SendControlAck, 0, 0, 0, 0, FALSE, FALSE );
  3127. }
  3128. }
  3129. }