Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1390 lines
31 KiB

  1. /*++
  2. Copyright (c) 2001-2002 Microsoft Corporation
  3. Module Name:
  4. client.c
  5. Abstract:
  6. This module contains the teredo client implementation.
  7. Author:
  8. Mohit Talwar (mohitt) Mon Oct 22 15:17:20 2001
  9. Environment:
  10. User mode only.
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. TEREDO_CLIENT_STATE TeredoClient;
  15. TEREDO_PACKET_IO_COMPLETE TeredoClientReadComplete;
  16. TEREDO_PACKET_IO_COMPLETE TeredoClientWriteComplete;
  17. TEREDO_PACKET_IO_COMPLETE TeredoClientBubbleComplete;
  18. TEREDO_PACKET_IO_COMPLETE TeredoClientReceiveComplete;
  19. TEREDO_PACKET_IO_COMPLETE TeredoClientTransmitComplete;
  20. TEREDO_PACKET_IO_COMPLETE TeredoClientMulticastComplete;
  21. VOID TeredoTransmitMulticastBubble( VOID );
  22. BOOL
  23. TeredoAddressPresent(
  24. VOID
  25. )
  26. /*++
  27. Routine Description:
  28. Determine whether an IPv6 tunnel interface has a teredo address.
  29. The address must have been configured from a router advertisement.
  30. Arguments:
  31. None.
  32. Return Value:
  33. TRUE if present, FALSE if not.
  34. --*/
  35. {
  36. DWORD Error;
  37. ULONG Bytes;
  38. PIP_ADAPTER_ADDRESSES Adapters, Next;
  39. PIP_ADAPTER_UNICAST_ADDRESS Address;
  40. WCHAR Guid[MAX_ADAPTER_NAME_LENGTH];
  41. BOOL Found = FALSE;
  42. TraceEnter("TeredoAddressPresent");
  43. //
  44. // 10 Adapters, each with 3 strings and 4 unicast addresses.
  45. // This would usually be more than enough!
  46. //
  47. Bytes = 10 * (
  48. sizeof(IP_ADAPTER_ADDRESSES) +
  49. 2 * MAX_ADAPTER_NAME_LENGTH + MAX_ADAPTER_DESCRIPTION_LENGTH +
  50. 4 * (sizeof(IP_ADAPTER_UNICAST_ADDRESS) + sizeof(SOCKADDR_IN6)));
  51. Adapters = MALLOC(Bytes);
  52. if (Adapters == NULL) {
  53. return FALSE;
  54. }
  55. do {
  56. Error = GetAdaptersAddresses(
  57. AF_INET6,
  58. GAA_FLAG_SKIP_FRIENDLY_NAME |
  59. GAA_FLAG_SKIP_DNS_SERVER |
  60. GAA_FLAG_SKIP_MULTICAST |
  61. GAA_FLAG_SKIP_ANYCAST,
  62. NULL, Adapters, &Bytes);
  63. if (Error == ERROR_BUFFER_OVERFLOW) {
  64. Next = REALLOC(Adapters, Bytes);
  65. if (Next != NULL) {
  66. Adapters = Next;
  67. } else {
  68. Error = ERROR_OUTOFMEMORY;
  69. }
  70. }
  71. } while (Error == ERROR_BUFFER_OVERFLOW);
  72. if (Error != NO_ERROR) {
  73. goto Bail;
  74. }
  75. for (Next = Adapters; Next != NULL; Next = Next->Next) {
  76. //
  77. // Disregard non-Teredo interfaces.
  78. //
  79. ConvertOemToUnicode(Next->AdapterName, Guid, MAX_ADAPTER_NAME_LENGTH);
  80. if (_wcsicmp(TeredoClient.Io.TunnelInterface, Guid) != 0) {
  81. continue;
  82. }
  83. ASSERT(Next->IfType == IF_TYPE_TUNNEL);
  84. //
  85. // Bail if the interface is disconnected.
  86. //
  87. if (Next->OperStatus != IfOperStatusUp) {
  88. break;
  89. }
  90. for (Address = Next->FirstUnicastAddress;
  91. Address != NULL;
  92. Address = Address->Next) {
  93. if ((Address->PrefixOrigin != PREFIX_CONF_RA) ||
  94. (Address->DadState != IpDadStatePreferred)) {
  95. continue;
  96. }
  97. if (TeredoEqualPrefix(
  98. &(((PSOCKADDR_IN6) Address->Address.lpSockaddr)->sin6_addr),
  99. &(TeredoClient.Ipv6Prefix))) {
  100. Found = TRUE;
  101. goto Bail;
  102. }
  103. }
  104. }
  105. Bail:
  106. FREE(Adapters);
  107. return Found;
  108. }
  109. VOID
  110. CALLBACK
  111. TeredoClientIoCompletionCallback(
  112. IN DWORD ErrorCode,
  113. IN DWORD Bytes,
  114. IN LPOVERLAPPED Overlapped
  115. )
  116. /*++
  117. Routine Description:
  118. Callback routine for I/O completion on TUN interface device or UDP socket.
  119. Arguments:
  120. ErrorCode - Supplies the I/O completion status.
  121. Bytes - Supplies the number of bytes transferred.
  122. Overlapped - Supplies the completion context.
  123. Return Value:
  124. None.
  125. --*/
  126. {
  127. static CONST PTEREDO_PACKET_IO_COMPLETE Callback[] =
  128. {
  129. TeredoClientReadComplete,
  130. TeredoClientWriteComplete,
  131. TeredoClientBubbleComplete,
  132. NULL, // No bouncing...
  133. TeredoClientReceiveComplete,
  134. TeredoClientTransmitComplete,
  135. TeredoClientMulticastComplete,
  136. };
  137. PTEREDO_PACKET Packet = Cast(
  138. CONTAINING_RECORD(Overlapped, TEREDO_PACKET, Overlapped),
  139. TEREDO_PACKET);
  140. ASSERT(Packet->Type != TEREDO_PACKET_BOUNCE);
  141. //
  142. // This completion function usually posts the packet for another I/O.
  143. // Since we are called by a non-I/O worker thread, asynchronous I/O
  144. // requests posted here might terminate when this thread does. This
  145. // is rare enough that we don't special case it. Moreover, we only
  146. // make best effort guarantees to the upper layer!
  147. //
  148. (*Callback[Packet->Type])(ErrorCode, Bytes, Packet);
  149. }
  150. VOID
  151. CALLBACK
  152. TeredoClientTimerCallback(
  153. IN PVOID Parameter,
  154. IN BOOLEAN TimerOrWaitFired
  155. )
  156. /*++
  157. Routine Description:
  158. Callback routine for TeredoClient.Timer expiration.
  159. The timer is active in the probe and qualified states.
  160. Arguments:
  161. Parameter, TimerOrWaitFired - Ignored.
  162. Return Value:
  163. None.
  164. --*/
  165. {
  166. ENTER_API();
  167. if (TeredoClient.State == TEREDO_STATE_PROBE) {
  168. if (TeredoClient.RestartQualifiedTimer) {
  169. //
  170. // Probe -> Qualified.
  171. //
  172. if (TeredoAddressPresent()) {
  173. //
  174. // The stack has validated and processed an RA.
  175. //
  176. TeredoQualifyClient();
  177. } else {
  178. //
  179. // The stack has not received any valid RA.
  180. //
  181. TeredoStopClient();
  182. }
  183. } else {
  184. //
  185. // Probe -> Offline.
  186. //
  187. TeredoStopClient();
  188. }
  189. } else {
  190. if (TeredoClient.RestartQualifiedTimer) {
  191. //
  192. // Qualified -> Qualified.
  193. //
  194. TeredoQualifyClient();
  195. } else {
  196. //
  197. // Qualified -> Probe.
  198. //
  199. TeredoProbeClient();
  200. }
  201. }
  202. LEAVE_API();
  203. }
  204. VOID
  205. CALLBACK
  206. TeredoClientTimerCleanup(
  207. IN PVOID Parameter,
  208. IN BOOLEAN TimerOrWaitFired
  209. )
  210. /*++
  211. Routine Description:
  212. Callback routine for TeredoClient.Timer deletion.
  213. Deletion is performed asynchronously since we acquire a lock in
  214. the callback function that we hold when deleting the timer.
  215. Arguments:
  216. Parameter, TimerOrWaitFired - Ignored.
  217. Return Value:
  218. None.
  219. --*/
  220. {
  221. TeredoDereferenceClient();
  222. }
  223. VOID
  224. TeredoClientAddressDeletionNotification(
  225. IN IN_ADDR Address
  226. )
  227. /*++
  228. Routine Description:
  229. Process an address deletion request.
  230. Arguments:
  231. Address - Supplies the address that was deleted.
  232. Return Value:
  233. None.
  234. Caller LOCK: API.
  235. --*/
  236. {
  237. if (!IN4_ADDR_EQUAL(Address, TeredoClient.Io.SourceAddress.sin_addr)) {
  238. return;
  239. }
  240. //
  241. // Refresh the socket state (the socket bound to SourceAddress).
  242. //
  243. if (TeredoRefreshSocket(&(TeredoClient.Io)) != NO_ERROR) {
  244. //
  245. // [Probe | Qualified] -> Offline.
  246. //
  247. TeredoStopClient();
  248. return;
  249. }
  250. if (IN4_ADDR_EQUAL(
  251. TeredoClient.Io.SourceAddress.sin_addr,
  252. TeredoClient.Io.ServerAddress.sin_addr)) {
  253. //
  254. // [Probe | Qualified] -> Offline.
  255. //
  256. TeredoStopClient();
  257. return;
  258. }
  259. //
  260. // [Probe | Qualified] -> Probe.
  261. //
  262. TeredoProbeClient();
  263. }
  264. VOID
  265. TeredoClientRefreshIntervalChangeNotification(
  266. VOID
  267. )
  268. /*++
  269. Routine Description:
  270. Process a refresh interval change request.
  271. Arguments:
  272. None.
  273. Return Value:
  274. None.
  275. Caller LOCK: API.
  276. --*/
  277. {
  278. if (TeredoClient.RefreshInterval == TeredoClientRefreshInterval) {
  279. return;
  280. }
  281. TeredoClient.RefreshInterval = TeredoClientRefreshInterval;
  282. if (TeredoClient.State == TEREDO_STATE_QUALIFIED) {
  283. //
  284. // Refresh interval has been updated.
  285. // Qualified -> Qualified.
  286. //
  287. TeredoQualifyClient();
  288. }
  289. }
  290. VOID
  291. TeredoStartClient(
  292. VOID
  293. )
  294. /*++
  295. Routine Description:
  296. Attempt to start the teredo service at the client.
  297. Events / Transitions
  298. ServiceStart Offline -> Probe.
  299. ServiceEnable Offline -> Probe.
  300. AdapterArrival Offline -> Probe.
  301. AddressAddition Offline -> Probe.
  302. Arguments:
  303. None.
  304. Return Value:
  305. None.
  306. Caller LOCK: API.
  307. --*/
  308. {
  309. TraceEnter("TeredoStartClient");
  310. //
  311. // Can't have both the client and server on the same node.
  312. //
  313. if (TeredoServer.State != TEREDO_STATE_OFFLINE) {
  314. return;
  315. }
  316. //
  317. // Well, the service has already been started!
  318. //
  319. if (TeredoClient.State != TEREDO_STATE_OFFLINE) {
  320. return;
  321. }
  322. TeredoClient.State = TEREDO_STATE_PROBE;
  323. //
  324. // Start I/O processing.
  325. //
  326. if (TeredoStartIo(&(TeredoClient.Io)) != NO_ERROR) {
  327. goto Bail;
  328. }
  329. if (IN4_ADDR_EQUAL(
  330. TeredoClient.Io.SourceAddress.sin_addr,
  331. TeredoClient.Io.ServerAddress.sin_addr)) {
  332. goto Bail;
  333. }
  334. //
  335. // Start a one shot probe timer.
  336. //
  337. if (!CreateTimerQueueTimer(
  338. &(TeredoClient.Timer),
  339. NULL,
  340. TeredoClientTimerCallback,
  341. NULL,
  342. TEREDO_PROBE_INTERVAL * 1000, // in milliseconds.
  343. INFINITE_INTERVAL,
  344. 0)) {
  345. goto Bail;
  346. }
  347. //
  348. // Obtain a reference on the teredo client for the running timer.
  349. //
  350. TeredoReferenceClient();
  351. return;
  352. Bail:
  353. TeredoClient.State = TEREDO_STATE_OFFLINE;
  354. TeredoStopIo(&(TeredoClient.Io));
  355. }
  356. VOID
  357. TeredoStopClient(
  358. VOID
  359. )
  360. /*++
  361. Routine Description:
  362. Stop the teredo service at the client.
  363. Events / Transitions
  364. ProbeTimer Probe -> Offline.
  365. ServiceStop [Probe | Qualified] -> Offline.
  366. ServiceDisable [Probe | Qualified] -> Offline.
  367. AdapterRemoval [Probe | Qualified] -> Offline.
  368. AddressDeletion [Probe | Qualified] -> Offline.
  369. Arguments:
  370. None.
  371. Return Value:
  372. None.
  373. Caller LOCK: API.
  374. --*/
  375. {
  376. TraceEnter("TeredoStopClient");
  377. //
  378. // Well, the service was never started!
  379. //
  380. if (TeredoClient.State == TEREDO_STATE_OFFLINE) {
  381. return;
  382. }
  383. TeredoClient.State = TEREDO_STATE_OFFLINE;
  384. TeredoClient.Ipv6Prefix = in6addr_any;
  385. TeredoClient.RestartQualifiedTimer = FALSE;
  386. DeleteTimerQueueTimer(
  387. NULL, TeredoClient.Timer, TeredoClient.TimerEvent);
  388. TeredoClient.Timer = NULL;
  389. TeredoStopIo(&(TeredoClient.Io));
  390. TeredoUninitializePeerSet();
  391. }
  392. VOID
  393. TeredoProbeClient(
  394. VOID
  395. )
  396. /*++
  397. Routine Description:
  398. Probe the teredo service at the client.
  399. Events / Transitions
  400. QualifiedTimer Qualified -> Probe.
  401. AddressDeletion [Probe | Qualified] -> Probe.
  402. Arguments:
  403. None.
  404. Return Value:
  405. None.
  406. Caller LOCK: API.
  407. --*/
  408. {
  409. TraceEnter("TeredoProbeClient");
  410. TeredoClient.State = TEREDO_STATE_PROBE;
  411. //
  412. // Reconnect!
  413. //
  414. if (!ReconnectInterface(TeredoClient.Io.TunnelInterface)) {
  415. //
  416. // [Probe | Qualified] -> Offline.
  417. //
  418. TeredoStopClient();
  419. return;
  420. }
  421. if (!ChangeTimerQueueTimer(
  422. NULL,
  423. TeredoClient.Timer,
  424. TEREDO_PROBE_INTERVAL * 1000, // in milliseconds.
  425. INFINITE_INTERVAL)) {
  426. TeredoStopClient();
  427. return;
  428. }
  429. TeredoClient.RestartQualifiedTimer = FALSE;
  430. }
  431. VOID
  432. TeredoQualifyClient(
  433. VOID
  434. )
  435. /*++
  436. Routine Description:
  437. Qualify the teredo service at the client.
  438. Events / Transitions
  439. RouterAdvertisement Probe -> Qualified.
  440. NatMappingRefresh Qualified -> Qualified.
  441. RefreshIntervalChange Qualified -> Qualified.
  442. Arguments:
  443. None.
  444. Return Value:
  445. None.
  446. Caller LOCK: API.
  447. --*/
  448. {
  449. TraceEnter("TeredoQualifyClient");
  450. TeredoClient.State = TEREDO_STATE_QUALIFIED;
  451. if (!ChangeTimerQueueTimer(
  452. NULL,
  453. TeredoClient.Timer,
  454. TeredoClient.RefreshInterval * 1000, // in milliseconds.
  455. INFINITE_INTERVAL)) {
  456. //
  457. // [Probe | Qualified] -> Offline.
  458. //
  459. TeredoStopClient();
  460. return;
  461. }
  462. TeredoTransmitMulticastBubble();
  463. TeredoClient.RestartQualifiedTimer = FALSE;
  464. }
  465. DWORD
  466. TeredoInitializeClient(
  467. VOID
  468. )
  469. /*++
  470. Routine Description:
  471. Initializes the client.
  472. Arguments:
  473. None.
  474. Return Value:
  475. NO_ERROR or failure code.
  476. --*/
  477. {
  478. DWORD Error;
  479. //
  480. // Obtain a reference on the teredo client for initialization.
  481. //
  482. TeredoClient.ReferenceCount = 1;
  483. TeredoClient.PeerHeap
  484. = TeredoClient.TimerEvent
  485. = TeredoClient.TimerEventWait
  486. = NULL;
  487. TeredoClient.BubbleTicks = 0;
  488. TeredoClient.BubblePosted = FALSE;
  489. TeredoInitializePacket(&(TeredoClient.Packet));
  490. TeredoClient.Packet.Type = TEREDO_PACKET_MULTICAST;
  491. TeredoClient.Packet.Buffer.len = sizeof(IP6_HDR);
  492. ASSERT(TeredoClient.Packet.Buffer.buf ==
  493. (PUCHAR) &(TeredoClient.Bubble));
  494. TeredoClient.Bubble.ip6_flow = 0;
  495. TeredoClient.Bubble.ip6_plen = 0;
  496. TeredoClient.Bubble.ip6_nxt = IPPROTO_NONE;
  497. TeredoClient.Bubble.ip6_hlim = IPV6_HOPLIMIT;
  498. TeredoClient.Bubble.ip6_vfc = IPV6_VERSION;
  499. // Peer->Bubble.ip6_src... Filled in when sending.
  500. TeredoClient.Bubble.ip6_dest = TeredoIpv6MulticastPrefix;
  501. //
  502. // Multicast bubble destination UDP port & IPv4 address.
  503. //
  504. TeredoParseAddress(
  505. &(TeredoClient.Bubble.ip6_dest),
  506. &(TeredoClient.Packet.SocketAddress.sin_addr),
  507. &(TeredoClient.Packet.SocketAddress.sin_port));
  508. Error = TeredoInitializeIo(
  509. &(TeredoClient.Io),
  510. TeredoClient.Packet.SocketAddress.sin_addr,
  511. TeredoReferenceClient,
  512. TeredoDereferenceClient,
  513. TeredoClientIoCompletionCallback);
  514. if (Error != NO_ERROR) {
  515. return Error;
  516. }
  517. TeredoClient.PeerHeap = HeapCreate(0, 0, 0);
  518. if (TeredoClient.PeerHeap == NULL) {
  519. Error = GetLastError();
  520. goto Bail;
  521. }
  522. TeredoClient.TimerEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  523. if (TeredoClient.TimerEvent == NULL) {
  524. Error = GetLastError();
  525. goto Bail;
  526. }
  527. if (!RegisterWaitForSingleObject(
  528. &(TeredoClient.TimerEventWait),
  529. TeredoClient.TimerEvent,
  530. TeredoClientTimerCleanup,
  531. NULL,
  532. INFINITE,
  533. 0)) {
  534. Error = GetLastError();
  535. goto Bail;
  536. }
  537. TeredoClient.RestartQualifiedTimer = FALSE;
  538. TeredoClient.Time = TeredoGetTime();
  539. TeredoClient.State = TEREDO_STATE_OFFLINE;
  540. TeredoClient.Ipv6Prefix = in6addr_any;
  541. TeredoClient.RefreshInterval = TeredoClientRefreshInterval;
  542. TeredoClient.Timer = INVALID_HANDLE_VALUE;
  543. Error = TeredoInitializePeerSet();
  544. if (Error != NO_ERROR) {
  545. goto Bail;
  546. }
  547. IncEventCount("TeredoInitializeClient");
  548. return NO_ERROR;
  549. Bail:
  550. TeredoCleanupIo(&(TeredoClient.Io));
  551. if (TeredoClient.PeerHeap != NULL) {
  552. HeapDestroy(TeredoClient.PeerHeap);
  553. TeredoClient.PeerHeap = NULL;
  554. }
  555. if (TeredoClient.TimerEventWait != NULL) {
  556. UnregisterWait(TeredoClient.TimerEventWait);
  557. TeredoClient.TimerEventWait = NULL;
  558. }
  559. if (TeredoClient.TimerEvent != NULL) {
  560. CloseHandle(TeredoClient.TimerEvent);
  561. TeredoClient.TimerEvent = NULL;
  562. }
  563. return Error;
  564. }
  565. VOID
  566. TeredoUninitializeClient(
  567. VOID
  568. )
  569. /*++
  570. Routine Description:
  571. Uninitializes the client. Typically invoked upon service stop.
  572. Arguments:
  573. None.
  574. Return Value:
  575. None.
  576. --*/
  577. {
  578. TeredoStopClient();
  579. TeredoDereferenceClient();
  580. }
  581. VOID
  582. TeredoCleanupClient(
  583. VOID
  584. )
  585. /*++
  586. Routine Description:
  587. Cleans up the client after the last reference to it has been released.
  588. Arguments:
  589. None.
  590. Return Value:
  591. None.
  592. --*/
  593. {
  594. TeredoCleanupPeerSet();
  595. UnregisterWait(TeredoClient.TimerEventWait);
  596. TeredoClient.TimerEventWait = NULL;
  597. CloseHandle(TeredoClient.TimerEvent);
  598. TeredoClient.TimerEvent = NULL;
  599. HeapDestroy(TeredoClient.PeerHeap);
  600. TeredoClient.PeerHeap = NULL;
  601. TeredoCleanupIo(&(TeredoClient.Io));
  602. DecEventCount("TeredoCleanupClient");
  603. }
  604. VOID
  605. TeredoTransmitMulticastBubble(
  606. VOID
  607. )
  608. /*++
  609. Routine Description:
  610. Transmit a teredo multicast bubble on the native link.
  611. Arguments:
  612. None.
  613. Return Value:
  614. None.
  615. Caller LOCK: API.
  616. --*/
  617. {
  618. ASSERT(TeredoClient.State == TEREDO_STATE_QUALIFIED);
  619. if (TeredoClient.BubbleTicks == 0) {
  620. //
  621. // No multicast bubbles should be sent.
  622. //
  623. return;
  624. }
  625. if (--TeredoClient.BubbleTicks != 0) {
  626. //
  627. // Our time is not yet up!
  628. //
  629. return;
  630. }
  631. if (TeredoClient.BubblePosted == TRUE) {
  632. //
  633. // At most one outstanding multicast bubble is allowed! Try later.
  634. //
  635. TeredoClient.BubbleTicks = 1;
  636. return;
  637. }
  638. //
  639. // Reset the timer.
  640. //
  641. TeredoClient.BubbleTicks = TEREDO_MULTICAST_BUBBLE_TICKS;
  642. //
  643. // Obtain a reference for the posted multicast bubble.
  644. //
  645. TeredoReferenceClient();
  646. TeredoClient.Bubble.ip6_src = TeredoClient.Ipv6Prefix;
  647. if (TeredoTransmitPacket(
  648. &(TeredoClient.Io), &(TeredoClient.Packet)) != NULL) {
  649. TeredoClientMulticastComplete(
  650. NO_ERROR, sizeof(IP6_HDR), &(TeredoClient.Packet));
  651. }
  652. }
  653. VOID
  654. TeredoTransmitBubble(
  655. IN PTEREDO_PEER Peer
  656. )
  657. /*++
  658. Routine Description:
  659. Transmit a teredo bubble to a peer.
  660. Arguments:
  661. Peer - Supplies the peer of interest.
  662. Return Value:
  663. None.
  664. --*/
  665. {
  666. if (TIME_GREATER(
  667. Peer->LastTransmit,
  668. (TeredoClient.Time - TEREDO_BUBBLE_INTERVAL))) {
  669. //
  670. // Rate limit bubble transmission.
  671. //
  672. return;
  673. }
  674. if (TIME_GREATER(
  675. (TeredoClient.Time - TEREDO_BUBBLE_THRESHHOLD),
  676. Peer->LastReceive) &&
  677. TIME_GREATER(
  678. Peer->LastTransmit,
  679. (TeredoClient.Time - TEREDO_SLOW_BUBBLE_INTERVAL))) {
  680. //
  681. // If the peer refuses to respond, drop rate (to once in 5 minutes).
  682. //
  683. return;
  684. }
  685. if (InterlockedExchange(&(Peer->BubblePosted), TRUE)) {
  686. //
  687. // At most one outstanding bubble is allowed!
  688. //
  689. return;
  690. }
  691. //
  692. // Obtain a reference for the posted bubble.
  693. //
  694. TeredoReferencePeer(Peer);
  695. Peer->LastTransmit = TeredoClient.Time;
  696. Peer->BubbleCount++;
  697. Peer->Bubble.ip6_src = TeredoClient.Ipv6Prefix;
  698. if (TeredoTransmitPacket(
  699. &(TeredoClient.Io), &(Peer->Packet)) != NULL) {
  700. TeredoClientBubbleComplete(
  701. NO_ERROR, sizeof(IP6_HDR), &(Peer->Packet));
  702. }
  703. }
  704. BOOL
  705. TeredoReceiveRouterAdvertisement(
  706. IN PTEREDO_PACKET Packet,
  707. IN ULONG Bytes
  708. )
  709. /*++
  710. Routine Description:
  711. Process the router advertisement packet received on the UDP socket.
  712. Arguments:
  713. Packet - Supplies the packet that was received.
  714. Bytes - Supplies the length of the packet.
  715. Return Value:
  716. TRUE if the packet should be forwarded to the stack, FALSE otherwise.
  717. --*/
  718. {
  719. PUCHAR Buffer = Packet->Buffer.buf;
  720. ICMPv6Header *Icmp6;
  721. UCHAR Type;
  722. ULONG Length;
  723. NDOptionPrefixInformation *Prefix = NULL;
  724. if (!IN4_SOCKADDR_EQUAL(
  725. &(Packet->SocketAddress), &(TeredoClient.Io.ServerAddress))) {
  726. //
  727. // Only the teredo server is allowed to send an RA.
  728. //
  729. return FALSE;
  730. }
  731. //
  732. // Parse up until the ICMPv6 header for the router advertisement.
  733. //
  734. Icmp6 = TeredoParseIpv6Headers(Buffer, Bytes);
  735. if (Icmp6 == NULL) {
  736. return FALSE;
  737. }
  738. if ((Icmp6->Type != ICMPv6_ROUTER_ADVERT) || (Icmp6->Code != 0)) {
  739. return FALSE;
  740. }
  741. Buffer = (PUCHAR) (Icmp6 + 1);
  742. Bytes -= (ULONG) (Buffer - Packet->Buffer.buf);
  743. //
  744. // Parse the rest of the router advertisement header.
  745. //
  746. if (Bytes < sizeof(NDRouterAdvertisement)) {
  747. return FALSE;
  748. }
  749. Buffer += sizeof(NDRouterAdvertisement);
  750. Bytes -= sizeof(NDRouterAdvertisement);
  751. while (Bytes != 0) {
  752. //
  753. // Parse TLV options.
  754. //
  755. if (Bytes < 8) {
  756. return FALSE;
  757. }
  758. Type = Buffer[0];
  759. Length = (Buffer[1] * 8);
  760. if ((Length == 0) || (Bytes < Length)) {
  761. return FALSE;
  762. }
  763. if (Type == ND_OPTION_PREFIX_INFORMATION) {
  764. if (Prefix != NULL) {
  765. //
  766. // There should only be one advertised prefix.
  767. //
  768. return FALSE;
  769. }
  770. if (Length != sizeof(NDOptionPrefixInformation)) {
  771. return FALSE;
  772. }
  773. Prefix = (NDOptionPrefixInformation *) Buffer;
  774. if (!TeredoValidAdvertisedPrefix(
  775. &(Prefix->Prefix), Prefix->PrefixLength)) {
  776. return FALSE;
  777. }
  778. }
  779. Buffer += Length;
  780. Bytes -= Length;
  781. }
  782. //
  783. // We have a valid router advertisement!
  784. // [Probe | Qualified] -> Qualified.
  785. //
  786. if (!IN6_ADDR_EQUAL(&(TeredoClient.Ipv6Prefix), &(Prefix->Prefix))) {
  787. //
  788. // We've either created a new IPv6 address or changed the existing one.
  789. // Transmit a multicast bubble as soon as the client qualifies.
  790. //
  791. TeredoClient.BubbleTicks =
  792. (TEREDO_MULTICAST_BUBBLE_TICKS != 0) ? 1 : 0;
  793. }
  794. TeredoClient.Ipv6Prefix = Prefix->Prefix;
  795. TeredoClient.RestartQualifiedTimer = TRUE;
  796. return TRUE;
  797. }
  798. BOOL
  799. TeredoClientReceiveData(
  800. IN PTEREDO_PACKET Packet
  801. )
  802. /*++
  803. Routine Description:
  804. Process the data packet received on the UDP socket.
  805. Arguments:
  806. Packet - Supplies the packet that was received.
  807. Return Value:
  808. TRUE if the packet should be forwarded to the stack, FALSE otherwise.
  809. --*/
  810. {
  811. PIP6_HDR Ipv6;
  812. IN_ADDR Address;
  813. USHORT Port;
  814. PTEREDO_PEER Peer;
  815. if (IN6_IS_ADDR_UNSPECIFIED(&(TeredoClient.Ipv6Prefix))) {
  816. //
  817. // The client hasn't been qualified ever!
  818. //
  819. return FALSE;
  820. }
  821. if (IN4_SOCKADDR_EQUAL(
  822. &(Packet->SocketAddress), &(TeredoClient.Io.ServerAddress))) {
  823. //
  824. // The client received the packet from the teredo server.
  825. //
  826. if (TeredoClient.State == TEREDO_STATE_QUALIFIED) {
  827. //
  828. // The NAT mapping has been refreshed.
  829. // NOTE: Since we don't acquire the API lock here, there is a small
  830. // chance that we have now transitioned to PROBE state. If so,
  831. // setting the flag to TRUE below will mistakenly cause us to
  832. // re-enter the qualified state. However that's quite harmless.
  833. //
  834. TeredoClient.RestartQualifiedTimer = TRUE;
  835. }
  836. return TRUE;
  837. }
  838. Ipv6 = (PIP6_HDR) Packet->Buffer.buf;
  839. if (!TeredoServicePrefix(&(Ipv6->ip6_src))) {
  840. //
  841. // The IPv6 source address should be a valid teredo address.
  842. //
  843. return FALSE;
  844. }
  845. TeredoParseAddress(&(Ipv6->ip6_src), &Address, &Port);
  846. if (!TeredoIpv4GlobalAddress((PUCHAR) &Address)) {
  847. //
  848. // The IPv4 source address should be global scope.
  849. //
  850. return FALSE;
  851. }
  852. if (!IN4_ADDR_EQUAL(Packet->SocketAddress.sin_addr, Address) ||
  853. (Packet->SocketAddress.sin_port != Port)) {
  854. //
  855. // Should have been constructed by the *right* teredo peer.
  856. //
  857. return FALSE;
  858. }
  859. Peer = TeredoFindOrCreatePeer(&(Ipv6->ip6_src));
  860. if (Peer != NULL) {
  861. Peer->LastReceive = TeredoClient.Time;
  862. TeredoTransmitBubble(Peer);
  863. TeredoDereferencePeer(Peer);
  864. }
  865. return TRUE;
  866. }
  867. VOID
  868. TeredoClientReadComplete(
  869. IN DWORD Error,
  870. IN ULONG Bytes,
  871. IN PTEREDO_PACKET Packet
  872. )
  873. /*++
  874. Routine Description:
  875. Process a read completion on the TUN device.
  876. --*/
  877. {
  878. PIP6_HDR Ipv6;
  879. IN_ADDR Address;
  880. USHORT Port;
  881. PTEREDO_PEER Peer;
  882. if ((Error != NO_ERROR) || (Bytes < sizeof(IP6_HDR))) {
  883. //
  884. // Attempt to post the read again.
  885. // If we are going offline, the packet is destroyed in the attempt.
  886. //
  887. TeredoPostRead(&(TeredoClient.Io), Packet);
  888. return;
  889. }
  890. TraceEnter("TeredoClientReadComplete");
  891. TeredoClient.Time = TeredoGetTime();
  892. Ipv6 = (PIP6_HDR) Packet->Buffer.buf;
  893. //
  894. // Default to tunneling the packet to the teredo server.
  895. //
  896. Packet->SocketAddress = TeredoClient.Io.ServerAddress;
  897. if (TeredoServicePrefix(&(Ipv6->ip6_dest))) {
  898. //
  899. // If the IPv6 destination address is a teredo address,
  900. // the IPv4 destination address should be global scope.
  901. //
  902. TeredoParseAddress(&(Ipv6->ip6_dest), &Address, &Port);
  903. if (!TeredoIpv4GlobalAddress((PUCHAR) &Address)) {
  904. goto Bail;
  905. }
  906. Peer = TeredoFindOrCreatePeer(&(Ipv6->ip6_dest));
  907. if (Peer != NULL) {
  908. if (TIME_GREATER(
  909. Peer->LastReceive,
  910. (TeredoClient.Time - TEREDO_REFRESH_INTERVAL))) {
  911. //
  912. // Tunnel the packet directly to the peer.
  913. //
  914. Packet->SocketAddress.sin_addr = Address;
  915. Packet->SocketAddress.sin_port = Port;
  916. Peer->LastTransmit = TeredoClient.Time;
  917. } else {
  918. TeredoTransmitBubble(Peer);
  919. }
  920. TeredoDereferencePeer(Peer);
  921. }
  922. }
  923. Packet->Type = TEREDO_PACKET_TRANSMIT;
  924. Packet->Buffer.len = Bytes;
  925. if (TeredoTransmitPacket(&(TeredoClient.Io), Packet) == NULL) {
  926. return;
  927. }
  928. Bail:
  929. //
  930. // We are done processing this packet.
  931. //
  932. TeredoClientTransmitComplete(NO_ERROR, Bytes, Packet);
  933. }
  934. VOID
  935. TeredoClientWriteComplete(
  936. IN DWORD Error,
  937. IN ULONG Bytes,
  938. IN PTEREDO_PACKET Packet
  939. )
  940. /*++
  941. Routine Description:
  942. Process a write completion on the TUN device.
  943. --*/
  944. {
  945. TraceEnter("TeredoClientWriteComplete");
  946. //
  947. // Attempt to post the receive again.
  948. // If we are going offline, the packet is destroyed in the attempt.
  949. //
  950. Packet->Type = TEREDO_PACKET_RECEIVE;
  951. Packet->Buffer.len = IPV6_TEREDOMTU;
  952. TeredoPostReceives(&(TeredoClient.Io), Packet);
  953. }
  954. VOID
  955. TeredoClientBubbleComplete(
  956. IN DWORD Error,
  957. IN ULONG Bytes,
  958. IN PTEREDO_PACKET Packet
  959. )
  960. /*++
  961. Routine Description:
  962. Process a bubble transmit completion on the UDP socket.
  963. --*/
  964. {
  965. PTEREDO_PEER Peer = Cast(
  966. CONTAINING_RECORD(Packet, TEREDO_PEER, Packet), TEREDO_PEER);
  967. TraceEnter("TeredoClientBubbleComplete");
  968. Peer->BubblePosted = FALSE;
  969. TeredoDereferencePeer(Peer);
  970. }
  971. VOID
  972. TeredoClientReceiveComplete(
  973. IN DWORD Error,
  974. IN ULONG Bytes,
  975. IN PTEREDO_PACKET Packet
  976. )
  977. /*++
  978. Routine Description:
  979. Process a receive completion on the UDP socket.
  980. --*/
  981. {
  982. PIP6_HDR Ipv6;
  983. BOOL Forward = FALSE;
  984. InterlockedDecrement(&(TeredoClient.Io.PostedReceives));
  985. if ((Error != NO_ERROR) || (Bytes < sizeof(IP6_HDR))) {
  986. //
  987. // Attempt to post the receive again.
  988. // If we are going offline, the packet is destroyed in the attempt.
  989. //
  990. TeredoPostReceives(&(TeredoClient.Io), Packet);
  991. return;
  992. }
  993. TraceEnter("TeredoClientReceiveComplete");
  994. TeredoClient.Time = TeredoGetTime();
  995. Ipv6 = (PIP6_HDR) Packet->Buffer.buf;
  996. if (IN6_IS_ADDR_LINKLOCAL(&(Ipv6->ip6_src)) ||
  997. IN6_IS_ADDR_LINKLOCAL(&(Ipv6->ip6_dest))) {
  998. //
  999. // This should be a valid router advertisement. Note that only router
  1000. // advertisement packets are accepted from/to link-local addresses.
  1001. //
  1002. Forward = TeredoReceiveRouterAdvertisement(Packet, Bytes);
  1003. } else {
  1004. //
  1005. // This may be a packet of any other kind. Note that the IPv6 stack
  1006. // drops router advertisements with a non link-local source address.
  1007. //
  1008. Forward = TeredoClientReceiveData(Packet);
  1009. }
  1010. if (Forward) {
  1011. Packet->Type = TEREDO_PACKET_WRITE;
  1012. Packet->Buffer.len = Bytes;
  1013. if (TeredoWritePacket(&(TeredoClient.Io), Packet) == NULL) {
  1014. return;
  1015. }
  1016. }
  1017. //
  1018. // We are done processing this packet.
  1019. //
  1020. TeredoClientWriteComplete(NO_ERROR, Bytes, Packet);
  1021. }
  1022. VOID
  1023. TeredoClientTransmitComplete(
  1024. IN DWORD Error,
  1025. IN ULONG Bytes,
  1026. IN PTEREDO_PACKET Packet
  1027. )
  1028. /*++
  1029. Routine Description:
  1030. Process a transmit completion on the UDP socket.
  1031. --*/
  1032. {
  1033. TraceEnter("TeredoClientTransmitComplete");
  1034. //
  1035. // Attempt to post the read again.
  1036. // If we are going offline, the packet is destroyed in the attempt.
  1037. //
  1038. Packet->Type = TEREDO_PACKET_READ;
  1039. Packet->Buffer.len = IPV6_TEREDOMTU;
  1040. TeredoPostRead(&(TeredoClient.Io), Packet);
  1041. }
  1042. VOID
  1043. TeredoClientMulticastComplete(
  1044. IN DWORD Error,
  1045. IN ULONG Bytes,
  1046. IN PTEREDO_PACKET Packet
  1047. )
  1048. /*++
  1049. Routine Description:
  1050. Process a multicast bubble transmit completion on the UDP socket.
  1051. --*/
  1052. {
  1053. ASSERT(Packet == &(TeredoClient.Packet));
  1054. TraceEnter("TeredoClientMulticastComplete");
  1055. TeredoClient.BubblePosted = FALSE;
  1056. TeredoDereferenceClient();
  1057. }