Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 动力壳;为什么此代码总是返回';正确';即使没有IPv6?错了吗?_.net_Powershell_Udp - Fatal编程技术网

.net 动力壳;为什么此代码总是返回';正确';即使没有IPv6?错了吗?

.net 动力壳;为什么此代码总是返回';正确';即使没有IPv6?错了吗?,.net,powershell,udp,.net,Powershell,Udp,不是powershell专家,但作为Windows 10小项目的一部分,正在检查IPv6连接。这(下面的代码)就是我正在使用的,如果可能的话,我想继续使用它,因为它速度快,并且不涉及某个网站返回公共视图IPv6地址。使用的远程IPv6地址(2001:4860:4860::8888)是Google公共IPv6 DNS。我从一些代码中得到了这个想法,其中Google Ipv6 DNS服务器用于检查Chrome中的全局Ipv6连接 它的问题是,即使在接口适配器上禁用IPv6并禁用Teredo,当它不应

不是powershell专家,但作为Windows 10小项目的一部分,正在检查IPv6连接。这(下面的代码)就是我正在使用的,如果可能的话,我想继续使用它,因为它速度快,并且不涉及某个网站返回公共视图IPv6地址。使用的远程IPv6地址(2001:4860:4860::8888)是Google公共IPv6 DNS。我从一些代码中得到了这个想法,其中Google Ipv6 DNS服务器用于检查Chrome中的全局Ipv6连接


它的问题是,即使在接口适配器上禁用IPv6并禁用Teredo,当它不应该连接时,它仍然返回“True”(即其已连接)。如果接口适配器上没有启用IPv6,或者IPv6在防火墙或通过其他方式被阻止,我希望它返回“False”。我做错了什么

UDP协议是无连接的。所以,“连接”状态对它没有实际意义,不像TCP(我怀疑您只收到硬编码的存根值)。然后,您可以尝试从一开始就切换到DNS请求的TCP版本(尽管RFC建议仅当UDP响应包含“截断”标志时才使用TCP DNS)。

再看一看,我们可以看到它在做什么

TL;DR,它检查机器是否实际分配了有效的非本地、非隧道式ipv6地址

关键函数(或方法,它是C++)是

它从一个带有函数头的锅炉板、一个跟踪函数和一个UDP套接字指针的创建开始

// Attempts to connect a UDP socket to |dest|:53.
bool IsGloballyReachable(const IPAddress& dest,
             const NetLogWithSource& net_log) {
  // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
  tracked_objects::ScopedTracker tracking_profile_1(
  FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 IsGloballyReachable")
  );

  std::unique_ptr<DatagramClientSocket> socket(
    ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket(
      DatagramSocket::DEFAULT_BIND, 
      RandIntCallback(), 
      net_log.net_log(),
      net_log.source()
    )
  );
如果失败了,那就是我们的回报

这就是powershell代码停止的地方

但我们还没做完

下一个测试:我们可以得到套接字的本地地址吗

  IPEndPoint endpoint;
  rv = socket->GetLocalAddress(&endpoint);
  if (rv != OK)
      return false;
如果行得通,我们就开始检查实际地址

  DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily());
  const IPAddress& address = endpoint.address();
我们首先消除本地地址的链接:

  bool is_link_local =
  (address.bytes()[0] == 0xFE) && ((address.bytes()[1] & 0xC0) == 0x80);
  if (is_link_local)
      return false;
我们消除了带有teredo前缀的地址

  const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
  if (IPAddressStartsWith(address, kTeredoPrefix))
      return false;
其他任何内容都假定为全局地址空间中的有效本地ipv6地址:

  return true;
}
这实际上是在测试全球连通性吗?不,因为你实际上并没有发送任何数据包,所以不会看到是否有防火墙会阻止你的流量。但它验证至少一个网络接口具有有效的非本地ipv6地址


要复制此测试,您需要检查连接的网络接口是否为ipv6地址。

粗略地看一下chromium代码片段,我发现它实际上向Google公共DNS解析程序发送了一个DNS数据包,只有在收到响应时才返回true。上面的代码只创建了一个udp6套接字并停在那里。我一开始也是这么想的,但从我想到的链接中读到的是“(注意,检查的结果实际上没有发送任何数据包;UDP不需要发送任何数据包来连接,HostResolverImpl也不显式地通过套接字发送任何数据)。”从:
如果在用户数据报协议(UDP)套接字上调用Connect,则Connected属性始终返回true;但是,此操作不会改变UDP固有的无连接特性。
Ahhh-HA!所以它总是会返回真的,如果它实际连接或没有,如果它的UDP。嗯,我想这就是答案。我没想过,但也许。我想知道它是如何在Chrome代码中正确工作的,但是当同样的东西在Powershell中创建时,它就失败了@约翰:这个问题与PowerShell per无关;这就是
System.Net.Sockets.Socket
.Net类的设计方式:“action”一词可能会让人困惑;他们的意思是,即使属性声明连接状态,连接的概念实际上并不适用于无连接的UDP协议。我误认为它实际上是在检查Ipv6全球连接,而实际上它所做的基本上是检查全球Ipv6地址是否可用。很好的总结。我应该补充一点,即tl;博士
  const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
  if (IPAddressStartsWith(address, kTeredoPrefix))
      return false;
  return true;
}