Source code of Windows XP (NT5)
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.

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