NAT穿越原理——STUN

2023-11-11

STUN是RFC3489规定的一种NAT穿透方式,它采用辅助的方法探测NAT的IP和端口。毫无疑问的,它对穿越早期的NAT起了巨大的作用,并且还将继续在ANT穿透中占有一席之地。 

STUN的探测过程需要有一个公网IP的STUN server,在NAT后面的UAC必须和此server配合,互相之间发送若干个UDP数据包。UDP包中包含有UAC需要了解的信息,比如NAT外网 IP,PORT等等。UAC通过是否得到这个UDP包和包中的数据判断自己的NAT类型。 

假设有如下UAC(B),NAT(A),SERVER(C),UAC的IP为IPB,NAT的IP为 IPA ,SERVER的 IP为IPC1 、IPC2。请注意,服务器C有两个IP,后面你会理解为什么需要两个IP。 

(1)NAT的探测过程:(吃个芒果先,呵呵,老妈给的) 

STEP1:B向C的IP1的pot1端口发送一个UDP 包。C收到这个包后,会把它收到包的源IP和port写到UDP包中,然后把此包通过IP1和port1发还给B。这个IP和port也就是NAT的外网 IP和port(如果你不理解,那么请你去看我的BLOG里面的NAT的原理和分类),也就是说你在STEP1中就得到了NAT的外网IP。 

熟悉NAT工作原理的朋友可以知道,C返回给B的这个UDP包B一定收到(如果你不知道,去读下我的其它文章)。如果在你的应用中,向一个STUN服务器发送数据包后,你没有收到STUN的任何回应包,那只有两种可能:1、STUN服务器不存在,或者你弄错了port。2、你的NAT拒绝一切UDP包从外部向内部通过(我们公司的NAT就是)。 

当B收到此UDP后,把此UDP中的IP和自己的IP做比较,如果是一样的,就说明自己是在公网,下步NAT将去探测防火墙类型,我不想多说。如果不一样,说明有NAT的存在,系统进行STEP2的操作。 

STEP2:B向C的IP1发送一个UDP包,请求C通过另外一个IP2和PORT(不同与SETP1的IP1)向B返回一个UDP数据包(现在知道为什么C要有两个IP了吧,虽然还不理解为什么,呵呵)。 

我们来分析一下,如果B收到了这个数据包,那说明什么?说明NAT来着不拒,不对数据包进行任何过滤,这也就是STUN标准中的full cone NAT。遗憾的是,full cone nat太少了,这也意味着你能收到这个数据包的可能性不大。如果没收到,那么系统进行STEP3的操作。 

STEP3:B向C的IP2的port2发送一个数据包,C收到数据包后,把它收到包的源IP和port写到UDP包中,然后通过自己的IP2和port2把此包发还给B。 

和step1一样,B肯定能收到这个回应UDP包。此包中的port是我们最关心的数据,下面我们来分析: 

如果这个port和step1中的port一样,那么可以肯定这个NAT是个CONE NAT,否则是对称NAT。道理很简单:根据对称NAT的规则,当目的地址的IP和port有任何一个改变,那么NAT都会重新分配一个port使用,而在step3中,和step1对应,我们改变了IP和port。因此,如果是对称NAT,那这两个port肯定是不同的。 

如果在你的应用中,到此步的时候PORT是不同的,恭喜你,你的STUN已经死了。如果不同,那么只剩下了restrict cone 和port restrict cone。系统用step4探测是是那一种。 

STEP4:B向C的IP2的一个端口PD发送一个数据请求包,要求C用IP2和不同于PD的port返回一个数据包给B。 

我们来分析结果:如果B收到了,那也就意味着只要IP相同,即使port不同,NAT也允许UDP包通过。显然这是restrict cone NAT。如果没收到,没别的好说,port restrict NAT. 

(2)SIP怎么使用STUN 

个人认为这是个很不值得提的问题,不过有许多人问我,还是简要提一下。其实这是个很简单的问题,SIP通过STUN得到NAT的外网IP和SIP的信令监听端口的外网port,替换SIP注册包中的contact头中的IP和port,然后注册。这样就可以确保当有人呼叫你的的时候注册服务器能找到你。需要提醒你的是,NAT发现一个连接超过一段时间后没有活动,它就会关闭这个影射,因此你必须间隔一端时间发送一个数据包出去以keep alive。 

另外,当你要和别人建立RTP通讯的时候,不要忘记把你的SDP中的IP和PORT改成公网IP和PORT。
原文:http://www.yuanma.org/data/2007/0323/article_2446.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NAT穿越原理——STUN 的相关文章

  • 嵌入式 Windows XP 中的网络接口设置

    给定设备描述 即出现在 设备属性 gt 连接使用 文本框中的字符串 我们如何获取网络接口名称 即出现在 网络连接 对话框中的名称 我们必须使用纯 C C 语言 或者通过一些标准命令行工具 例如 netsh ipconfig 或者两者的组合来
  • Android 流量统计数据报告的内容比我下载的内容还要多

    您好 我正在运行一个简单的下载测试 看看我的连接速度有多快 我记录了trafficStats rx值 然后下载了一个5MB的文件 记录了rx值 然后计算了差异 我知道这个文件正好是 5MB 这是代码 URL url new URL urlS
  • 对等网络应用程序的网络发现

    我希望有两个类 一个服务器类和一个客户端类 服务器类应该接收每个新客户端的 IP 地址和端口号并将它们存储在列表中 它应该为每个客户端提供已连接客户端及其 IP 地址的列表 然后 客户端可以使用 TCP 连接相互通信 问题是客户端不知道服务
  • 无法远程连接到Python Socket

    我已经使用 python 套接字和 Tkinter 创建了一个聊天应用程序 它在本地运行得很好 但是客户端无法远程连接到服务器 当我输入我的公共 IP 地址作为主机时 我已经完全端口转发了我的网络并且我知道如何很好地进行端口转发 当我运行在
  • C++ Boost.asio Ping

    我正在尝试编写一个程序来列出网络上设备的所有 IP 地址 其主要组成部分之一是能够对设备执行 ping 操作 这个程序必须在Linux Windows和Mac上运行 所以我选择了Boost库 我设法在文档中找到这个示例 http www b
  • 在下载的同时从 UnityWebRequest 获取数据?

    我有这段代码可以进行 REST 调用 public IEnumerator GetCooroutine string route string finalURL URL route UnityWebRequest www UnityWebR
  • 接收UDP数据包

    假设我的程序通过网络 UDP 发送 1000 字节 它是否保证接收方将 一批 接收 1000 个字节 或者他可能需要执行多次 读取 直到收到完整的消息 如果后者为真 我如何确保同一消息的数据包顺序不会 混淆 按顺序 或者协议可能保证这一点
  • 模拟网络断开连接以在本地测试分布式应用程序分区

    我有几个在本地主机上运行的分布式应用程序实例 每个实例都通过某些端口与其他实例通信 所有实例一起构成一个整体 我实际上是在谈论动物园管理员 http hadoop apache org zookeeper 在 Linux 上运行 现在我想编
  • 是否可以通过 MX 查找获取端口?

    我正在了解什么是的旅程从 Python 代码发送电子邮件的正确方法 https stackoverflow com questions 50695188 what is the proper way to actually send mai
  • Python 套接字库认为套接字未打开时已打开

    我正在使用一些Python 如下所示 HOST 127 0 0 1 PORT 43434 single socket socket socket AF INET socket SOCK STREAM try single bind HOST
  • IE 下的 Http 请求速度变慢

    在我的 javascript 应用程序中工作时 我注意到使用 IE 11 时 相同的 ajax 请求时间最多延长 10 倍 响应大小完全相同 12 6KB 我看到的唯一区别是 IE 添加 Pragma no cache 不是铬 Chrome
  • 如何以编程方式证明“六度分离”概念?

    我有一个包含 2000 万用户以及这些人之间的联系的数据库 如何证明 六度分离 的概念以最有效的方式在编程中 链接到有关六度分离的文章 http en wikipedia org wiki Six degrees of separation
  • 基于邻近度的负载均衡

    我正在开展一个项目 我们在世界各地拥有大量 目前为 5 台 服务器 客户端通过集中式代理连接到其中一台服务器 我们知道客户的原籍国 但除此之外一无所知 我们完全控制服务器 因此我们可以获得所需的所有信息 我们不控制客户 他们必须按照标准通过
  • 在 Linux/Ubuntu 计算机上通过 Python/Django 设置网络设置

    我正在为嵌入式计算机开发一个简单的网络界面 计算机将附带一个静态默认 IP 然后需要由可能不懂技术 Linux 的安装技术人员进行更新 基本上我需要从 Django 应用程序更改以下系统设置 IP地址 Subnet 默认网关 DNS 服务器
  • 使用 Shell 脚本提供密码

    我已将客户端和服务器设置为无密码登录 就像无密码登录一样 通过将服务器的 RSA 密钥复制到所有客户端的 root ssh id rsa pub 来实现 但这是我手动完成的 我喜欢使用 shell 脚本自动执行此过程 并通过脚本向计算机提供
  • 如何修改s_client的代码?

    我正在玩apps s client c in the openssl源代码 我想进行一些更改并运行它 但是在保存文件并执行操作后 我的更改没有得到反映make all or a make 例如 我改变了sc usage函数为此 BIO pr
  • 如何使用 iPhone 将照片上传到服务器?

    我正在编写一个 iPhone 应用程序 它可以拍摄照片然后将其上传到服务器 如何使用 Cocoa 将照片上传到服务器 我想我在某处使用 NSUrl Thanks Header interface EPUploader NSObject NS
  • C# 自动检测代理设置

    C 2008 SP1 我正在使用代码来检测是否已在 Internet 选项 下设置代理 如果有代理 那么我将在我的网络客户端中设置它 所以我只是检查代理的地址是否存在 如果没有 则说明 Web 客户端中没有要设置的代理 这是执行此操作的正确
  • 通过 Telnet 运行应用程序

    我需要创建一个 BAT 文件来通过 telnet 运行应用程序 但据我所知 在 DOS 上无法执行此操作 Telnet 不允许在连接的瞬间向远程计算机发送任何命令 并且 BAT 文件中的每个后续命令只有在 telnet 停止后才会执行 这段
  • 为什么 h_addr_list (在 hostent 结构中)类型为 char** 而不是 void*?

    我试图找出一段构建 hostent 对象的代码 更具体地说 它的工作部分是填充 h addr list 数组 我对分配到数组中的值被强制转换为这一事实感到困惑char 据我所知 这个数组与字符串无关 我注意到h addr list数组实际上

随机推荐

  • STL源码剖析——deque的实现原理和使用方法详解

    Deque 简介 deque是 double ended queue 的缩写 和vector一样都是STL的容器 deque 是双端数组 而 vector 是单端的 deque 在接口上和 vector 非常相似 在许多操作的地方可以直接替
  • 【IOS】移动端设置input只能输入数字,在IOS系统没有效果

    在移动端设置input的type为number类型的时候需要区分一下安卓还是IOS 如果只设置type为number类型的时候 在安卓生效 但是IOS还是会有可以输入汉字的问题出现 所以就需要一个新的属性 pattern 0 9 来控制输入
  • BigDecimal的使用小结

    文章目录 1 为什么用 BigDecimal 2 构造函数的选择 3 加减乘除的使用 4 保留小数 5 RoundingMode类 6 其他方法 1 为什么用 BigDecimal 因为 double float的计算很不靠谱 莫名其妙的会
  • 《微积分基础》学习(一)

    本系列文章主要记录我在学习coursera上的 Calculus One 在线课程的笔记 该课程是俄亥俄州立大学的经典课程 教授的发音比较标准 授课方式轻松愉悦 是不可错过的 微积分 入门课程 本文直接从第二周切入 第一周是课程介绍和学习方
  • intelli idea中配置Tomcat找不到的解决办法

    这两天新入职一家公司 公司用的是intelli idea 以前用习惯了eclipse 感觉到有点不太习惯 当然 intelli idea也有自己的强大之处 在开始配置Tomact之前 按照网上的说法 发现点击 号之后没有Tomcat 于是乎
  • printf 和scanf

    1 printf 简介 1 1 printf 的格式 printf 函数的原型为 include
  • Xbox One 升级后黑屏修复

    好久没用Xbox了 近期突然想要利用体感游戏进行锻炼 结果打开后提示需要更新 更新包有4G左右 随手选了更新后就让xbox后台更新了 过了一段时间切回hdmi信号发现一片黑屏 手柄的xbox键可以唤出关闭菜单 但是其他操作都无效 经过一番研
  • 20230322 元宇宙

    VR AR MR XR的区别和联系 知乎
  • 解决Kaggele无法下载输出output文件夹下的文件

    import os os chdir kaggle working print os getcwd print os listdir kaggle working from IPython display import FileLink F
  • 支付宝给个人账号转账付款

    一 说明 转账到支付宝账户是为了满足支付宝商户向其他支付宝账户进行单笔转账的需求 针对具备开发能力的商户 提供通过 API 接口完成单笔转账的功能 商家只需输入另一个正确的支付宝账号 即可将单笔资金从本人的支付宝账户转账至另一个支付宝账户
  • GPT带我学-设计模式-代理模式

    什么是代理模式 代理模式 Proxy Pattern 是设计模式中的一种结构型模式 它为其他对象提供一种代理以控制对这个对象的访问 代理模式有三个主要角色 抽象主题 Subject 真实主题 Real Subject 和代理 Proxy 抽
  • Bootstrap使用方法(个人经验,仅限参考)

    下载Bootstrap 将Bootstrap导入到所需要的项目中 将Bootstrap的css和js的路径引入到所需要的页面 选择所需要的插件 粘贴到所需要的位置 菜鸟教程实例 Bootstrap的JavaScript脚本带有监听事件方法
  • kl散度matlab实现,Kullback–Leibler divergence KL散度

    In probability theory and information theory the Kullback Leibler divergence 1 2 3 also information divergence informati
  • Bash中分号“;”、与“&&“、或(

    linux 中 bash 下执行多个命令时 操作符的区别 cmd1 cmd2 cmd1 和 cmd2 都会 被执行 cmd1 cmd2 如果 cmd1 执行 成功 则执行 cmd2 cmd1 cmd2 如果 cmd1 执行 失败 则执行 c
  • 2022-12-30 Ubuntu 运行qt creator提示qt.qpa.plugin: Could not load the Qt platform plugin “xcb“

    一 Ubuntu 运行qt creator提示qt qpa plugin Could not load the Qt platform plugin xcb qt qpa plugin Could not load the Qt platf
  • python弹球游戏彩蛋

    在上一期 我们已经实现了基本弹球的功能 先总结一下上期的代码 import pygame pygame init width 800 height 600 screen pygame display set mode width heigh
  • OpenGL ES2.0粒子系统(附有源码)

    http blog csdn net cxy200927099 article details 38584487 刚学OpenGL 2个多星期 也算是入门了吧 在看了老外写的书 OpenGL ES 2 for Android A Quick
  • 雅特力at421f串口2串口1互发透传

    void USART1 IRQHandler void static u8 k USART ClearFlag USART1 USART FLAG TC 清除USARTx的待处理标志位 if USART GetITStatus USART1
  • 目标检测:SSD算法原理综述

    SSD Single Shot Detection 是一个流行且强大的目标检测网络 网络结构包含了基础网络 Base Network 辅助卷积层 Auxiliary Convolutions 和预测卷积层 Predicton Convolu
  • NAT穿越原理——STUN

    STUN是RFC3489规定的一种NAT穿透方式 它采用辅助的方法探测NAT的IP和端口 毫无疑问的 它对穿越早期的NAT起了巨大的作用 并且还将继续在ANT穿透中占有一席之地 STUN的探测过程需要有一个公网IP的STUN server