首页 > 其他分享 >NAT类型发现

NAT类型发现

时间:2024-07-01 11:09:35浏览次数:1  
标签:发现 端口 响应 NAT ADDRESS 类型 服务器 客户端

一、前言

之前一篇文章中,提出了一个判断NAT类型的方案。该方案是自己研究设计的,比较粗糙。近期研读了关于STUN的一些协议标准,其中RFC3489中就包含了判断NAT类型的标准方案。

与自己设计的方案相比,标准方案有以下优点:

1,利用了STUN协议中定义的一些属性,如CHANGE-REQUEST/MAPPED-ADDRESS/RESPONSE-ADDRESS/CHANGED-ADDRESS等;

2,使用单台服务器就可以完成(需要服务器上至少配置2个IP地址);

3,步骤更精简;

注意:RFC3489已被RFC5389废弃,且RFC5389也已被RFC8489废弃。在最新的STUN协议标准中,上面提到的属性都已被废弃。

下面介绍一下RFC3489中的NAT类型发现方案。

二、名词解释

首先介绍一下方案中用到的STUN协议中的一些属性。

CHANGE-REQUEST

此属性被客户端使用,请求服务器在发送响应时,使用不同的源IP地址或端口(与客户端请求的目的IP地址和端口不同)。此属性包含2个标志位:

“change IP”:指示服务器更换源IP

“change port”:指示服务器更换源端口

MAPPED-ADDRESS

此属性被包含在服务器的响应中,内容是服务器看到的客户端的源IP和端口信息(经过NAT映射后的)。

RESPONSE-ADDRESS

此属性由客户端使用,指示服务器应该将响应发往哪里。其内容包含地址和端口。

CHANGED-ADDRESS

此属性被包含在服务器的响应中,内容是IP地址和端口。其含义是若客户端在CHANGE-REQUEST中指定了任意的标志位后,服务器的响应将要使用的源IP和端口。

无论客户端是否设置了这些标志位,此属性总是被包含在响应中。

三、NAT类型发现流程

客户端执行3种测试来发现NAT类型。

测试I:

客户端发送一个请求给服务器。此请求中不设置CHANGE-REQUEST中的任何标志位,也不携带RESPONSE-ADDRESS属性。

测试II:

客户端发送一个请求给服务器。此请求中同时设置CHANGE-REQUEST中的两个标志位。

测试III:

客户端发送一个请求给服务器。此请求中设置CHANGE-REQUEST中的“change port”标志位。

客户端首先执行测试I

有以下几种情况:

1,没有收到响应;则客户端会立即知道它无法发起UDP连接;

2,收到响应,客户端检查MAPPED-ADDRESS属性;

  (1) 若属性中的地址和端口与发送请求时使用的一致,则客户端知道自己不在NAT之后。继续执行测试II

    ① 若收到响应,则客户端知道它可以访问互联网(或者,至少客户端位于行为类似完全锥形NAT的防火墙之后,且没有地址转换)。

    ② 若未收到响应,则客户端知道它位于对称UDP防火墙之后。

    上述2种情况,都可以认定客户端位于公网上。

  (2) 若不一致,则客户端知道它位于NAT之后。继续执行测试II。

    ① 若收到响应,则客户端知道它位于完全锥形NAT之后。------测试II中,服务器使用不同的源IP地址和端口进行响应,若能收到,则表面是完全锥形NAT,这种NAT不检查下行报文的源IP和端口。

    ② 若未收到响应,则客户端重复执行测试I,但使用不同的目的IP地址和端口(这些信息可以从首次执行测试I的响应中获取,包含在CHANGED-ADDRESS属性中)

      1) 若此次响应中包含的MAPPED-ADDRESS属性中的IP地址和端口和第一次时不一致,则客户端知道它位于对称NAT之后。

      2) 若两次结果一致,则客户端位于限制锥形NAT或端口限制锥形NAT之后。为了确定是哪一种NAT,需要执行测试III。

        执行测试III后,若收到响应,则客户端位于限制锥形NAT之后。

        执行测试III后,若未收到响应,则客户端位于端口限制锥形NAT之后。

上述过程的流程图总结如下:

IMG_256

 

标签:发现,端口,响应,NAT,ADDRESS,类型,服务器,客户端
From: https://www.cnblogs.com/bluntwu2022/p/18277639

相关文章

  • React-Native优质开源项目
            ReactNative是一个由Facebook开发的开源框架,允许开发者使用JavaScript和React来构建原生移动应用。它允许开发者编写一次代码,然后可以在iOS和Android平台上运行,而无需为每个平台单独编写代码。以下是ReactNative的一些关键特点和优势:跨平台开......
  • Hibernate组件映射
    在组件映射中,我们将依赖对象映射作为组件。组件是存储为值而不是实体引用的对象。如果从属对象没有主键,则要使用此方法。它用于组合(HAS-A关系)的情况下,这就是为什么把它称为组件。下面来看看看有HAS-A关系的类。Hibernate组件映射示例创建一个Java项目:componentmapping,......
  • 第二章·数据类型与运算符
    第二章·数据类型与运算符文章目录第二章·数据类型与运算符数据类型分类基本数据类型整型(int)浮点型(float)复数(complex)属性与方法字符串(str)表示方式字符串运算符字符串的常见操作替换:replace()分割:split()去除两侧空格:strip()格式化输出索引和切片大小写转换查找......
  • C++文件路径处理3 - 判断指定目录的文件类型(文件夹|普通文件|软连接)
    1.关键词2.filetype.h3.filesystem.h4.filesystem_unix.cpp5.filesystem_win.cpp6.filepath.h7.filepath.cpp8.测试代码9.运行结果10.源码地址1.关键词关键词:C++文件路径处理文件夹普通文件软连接跨平台应用场景:根据指定的目录路径,判断该目录的文......
  • ts Symbol 属性类型的特点
    概论Symbol是一种用于创建唯一标识符的原始数据类型。Symbol通常用作对象属性的键,以避免属性名冲突。Symbol.for()可以在全局Symbol注册表中创建或查找Symbol。内置Symbol用于定义语言级别的行为和协议。Symbol属性与普通属性的区别Symbol属性不会出现在普通的对......
  • [JS] 数据类型与特殊值的判断方法
    由于JS是弱类型语言,判断一个变量的数据类型是一个很常见的需求。下面介绍一些常用的判断方法:typeof操作符typeof可以用来判断除了``null的基本数据类型和function,其它引用数据类型都会返回object`。console.log(typeof"Hello");//"string"console.log(typeof42);//"num......
  • 不同类型Drawable解析
    不同类型Drawable解析这里简单分析下不同xml是怎么解析成Drawable的一般获取一个Drawable资源有很多方法,如下方截图是一种,不同方法最后其实殊途同归,都是一个地方解析转化的,这里只以下面代码为入口分析前面代码片段比较简单,Resources的gerDrawable方法有多个不同数量参数的重载方法......
  • 【Redis二】Redis数据类型
    目录一.Redis数据类型分布二.字符串类型string 1.概述2.操作三.列表list1.概述2.操作四.哈希hash1.概述2.操作五.无序集合set1.概述2.应用范围3.操作六.有序集合zset1.概述2.应用范围3.操作七.通用命令一.Redis数据类型分布通常Redis的数据类型有五大......
  • “了解MySQL中的enum枚举数据类型“
    目录#开篇1.创建包含枚举类型的表2.插入枚举类型的数据3.查询包含枚举类型的表4.更新枚举类型的数据5.使用枚举类型的好处注意事项示例总结附加#开篇        在数据库中,枚举(ENUM)是一种数据类型,用于存储一组预定义的值。这在某些情况下非常有用,例如......
  • 数据分析神器Pandas快速入门3类型转换
    序列类型转换3.1自动转换在pandas1.0中,引入了一种新的转换方法.convert_dtypes。它会尝试将Series换为支持pd.NA类型。以city_mpg系列为例,它将把类型从int64转换为Int64:>>>city_mpg.convert_dtypes()01919223310417......