VpnPlugin.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "pch.h"
  2. #include "VpnPlugin.h"
  3. #include "VpnPlugin.g.cpp"
  4. #include "winrt/Windows.Storage.h"
  5. #include "winrt/Windows.Storage.Streams.h"
  6. extern "C" void* lwip_strerr(uint8_t) {
  7. return "";
  8. }
  9. namespace winrt::Maple_Task::implementation
  10. {
  11. using Windows::Networking::HostName;
  12. using Windows::Networking::Sockets::DatagramSocket;
  13. using Windows::Storage::Streams::IOutputStream;
  14. using namespace Windows::Networking::Vpn;
  15. using namespace Windows::Storage;
  16. void VpnPlugin::Connect(VpnChannel const& channel)
  17. {
  18. const auto localhost = HostName{ L"127.0.0.1" };
  19. DatagramSocket transport{}, backTransport{};
  20. channel.AssociateTransport(transport, nullptr);
  21. transport.BindEndpointAsync(localhost, L"").get();
  22. backTransport.BindEndpointAsync(localhost, L"").get();
  23. transport.ConnectAsync(localhost, backTransport.Information().LocalPort()).get();
  24. backTransport.ConnectAsync(localhost, transport.Information().LocalPort()).get();
  25. VpnRouteAssignment routeScope{};
  26. routeScope.ExcludeLocalSubnets(true);
  27. routeScope.Ipv4InclusionRoutes(std::vector<VpnRoute>{
  28. // 直接写 0.0.0.0/0 哪怕绑了接口也会绕回环
  29. // VpnRoute(HostName{ L"0.0.0.0" }, 0)
  30. VpnRoute(HostName{ L"0.0.0.0" }, 1),
  31. VpnRoute(HostName{ L"128.0.0.0" }, 1),
  32. });
  33. // 排除代理服务器的话就会 os 10023 以一种访问权限不允许的方式做了一个访问套接字的尝试
  34. // routeScope.Ipv4ExclusionRoutes(std::vector<VpnRoute>{
  35. // VpnRoute(HostName{ L"172.25.0.0" }, 16)
  36. // });
  37. VpnDomainNameAssignment dnsAssignment{};
  38. const auto outputStreamAbi = winrt::detach_abi(backTransport.OutputStream());
  39. StopLeaf();
  40. {
  41. std::lock_guard _guard{ m_decapQueueLock };
  42. while (!m_decapQueue.empty()) {
  43. m_decapQueue.pop();
  44. }
  45. }
  46. m_backTransport = backTransport;
  47. m_netStackHandle = netstack_register([](uint8_t* data, size_t size, void* outputStreamAbi) {
  48. bool needSendDummyBuffer = false;
  49. {
  50. std::lock_guard _guard{ VpnPluginInstance->m_decapQueueLock };
  51. auto& q = VpnPluginInstance->m_decapQueue;
  52. {
  53. std::vector<uint8_t> buf(size);
  54. if (memcpy_s(buf.data(), buf.capacity(), data, size)) {
  55. return;
  56. }
  57. needSendDummyBuffer = q.empty();
  58. q.emplace(buf);
  59. }
  60. }
  61. if (!needSendDummyBuffer) {
  62. return;
  63. }
  64. IOutputStream outputStream{ nullptr };
  65. winrt::attach_abi(outputStream, outputStreamAbi);
  66. try {
  67. const auto _ = outputStream.WriteAsync(dummyBuffer);
  68. }
  69. catch (...) {}
  70. winrt::detach_abi(outputStream);
  71. }, outputStreamAbi);
  72. if (m_netStackHandle == nullptr) {
  73. channel.TerminateConnection(L"Error initializing Leaf netstack.");
  74. return;
  75. }
  76. const auto& confPathW = ApplicationData::Current().LocalSettings().Values().TryLookup(CONFIG_PATH_SETTING_KEY).try_as<hstring>().value_or(L"");
  77. const auto& outNetifW = ApplicationData::Current().LocalSettings().Values().TryLookup(NETIF_SETTING_KEY).try_as<hstring>().value_or(L"");
  78. const auto& confPath = winrt::to_string(confPathW);
  79. const auto& outNetif = winrt::to_string(outNetifW);
  80. m_leaf = run_leaf(confPath.data(), outNetif == "" ? nullptr : outNetif.data());
  81. if (m_leaf == nullptr) {
  82. channel.TerminateConnection(L"Error initializing Leaf runtime.\r\nPlease check your configuration file and default interface.");
  83. StopLeaf();
  84. return;
  85. }
  86. channel.StartWithMainTransport(
  87. std::vector<HostName> { HostName{ L"192.168.3.1" } },
  88. nullptr,
  89. nullptr,
  90. routeScope,
  91. dnsAssignment,
  92. 1500,
  93. 1512,
  94. false,
  95. transport
  96. );
  97. }
  98. void VpnPlugin::StopLeaf() {
  99. m_backTransport = nullptr;
  100. auto leafHandle = m_leaf;
  101. if (leafHandle != nullptr) {
  102. stop_leaf(leafHandle);
  103. m_leaf = nullptr;
  104. }
  105. auto netStackHandle = m_netStackHandle;
  106. if (netStackHandle != nullptr) {
  107. const auto context = netstack_release(netStackHandle);
  108. m_netStackHandle = nullptr;
  109. // Release context, which is an ABI of IOutputStream
  110. IInspectable obj{};
  111. winrt::attach_abi(obj, context);
  112. m_netStackHandle = nullptr;
  113. }
  114. }
  115. void VpnPlugin::Disconnect(VpnChannel const& channel)
  116. {
  117. try {
  118. channel.Stop();
  119. }
  120. catch (...) {}
  121. StopLeaf();
  122. }
  123. void VpnPlugin::GetKeepAlivePayload(VpnChannel const&, VpnPacketBuffer&)
  124. {
  125. }
  126. void VpnPlugin::Encapsulate([[maybe_unused]] VpnChannel const& channel, VpnPacketBufferList const& packets, VpnPacketBufferList const&)
  127. {
  128. auto packetCount = packets.Size();
  129. while (packetCount-- > 0) {
  130. const auto packet = packets.RemoveAtBegin();
  131. const auto buffer = packet.Buffer();
  132. netstack_send(m_netStackHandle, buffer.data(), static_cast<size_t>(buffer.Length()));
  133. packets.Append(packet);
  134. }
  135. }
  136. void VpnPlugin::Decapsulate(VpnChannel const& channel, [[maybe_unused]] VpnPacketBuffer const& encapBuffer, VpnPacketBufferList const& decapsulatedPackets, VpnPacketBufferList const&)
  137. {
  138. std::lock_guard _guard{ VpnPluginInstance->m_decapQueueLock };
  139. auto& q = VpnPluginInstance->m_decapQueue;
  140. while (!q.empty()) {
  141. auto&& incomingBuffer = q.front();
  142. const auto outBuffer = channel.GetVpnReceivePacketBuffer();
  143. decapsulatedPackets.Append(outBuffer);
  144. const auto outBuf = outBuffer.Buffer();
  145. const auto size = incomingBuffer.size();
  146. if (memcpy_s(outBuf.data(), outBuf.Capacity(), incomingBuffer.data(), size)) {
  147. return;
  148. }
  149. outBuf.Length(static_cast<uint32_t>(size));
  150. q.pop();
  151. }
  152. }
  153. }