IP 协议和路由
IP的作用–路由
路由是什么?一个数据包如何在网络上传输?会对ip包做什么动作?
从广义上讲,路由是路线图,就像百度地图上源地址到目的地址的路线,路线有很多,故路由也很多;
从网络层面讲,路由是一个数据包从源地址到目的地的传输路径,它如何被决定怎么走,即中间经过哪些路由器,选择哪一条路线等等。一个数据包在网络上传输实例:
A,B连上AP进行上网,AP和外网连接,AP的下一站是D;
A 在构造了数据包后选择发送,要查询路由表,若该数据包发送给B,则通过路由表中的直连路由,找到B的ip,发送时不知道B的mac地址,故先做arp,得到后将数据包发给B:
数据包:源ip:A,源mac A ,目的IP:B,目的mac:B
若A在构造了数据包后,查询路由,该数据包是发送给外网,目的地址是百度ip,则无此条目,向默认路由;即发给路由器,此时若不知道mac地址会做arp;
数据包:源ip:A,源mac:A ,目的ip:百度,目的mac:路由器(arp代理)
数据包到路由器后,将做下一步转发:
在路由发送的数据包:源ip:路由外网地址,源mac:路由,目的ip:百度ip.目的mac,D
(注意,在源ip改为路由外网地址后,此时ip唯一,源地址在传输过程中不会再改变)内网的路由器会将源地址改为路由器的外网地址
—想想像192.168.0.4这样的源地址是内网地址,如果在包的传输过程中不做处理,到达目的地如QQ的服务器,那QQ处理完要发给你,这时得到包是从192.168.0.4来的,它作为内网地址,全世界很多个,怎么决定—–所以ip首部中的源地址和目的地址必须是全球唯一的ip地址,即外网地址;
4. 路由器会对ttl做减1,然后再重新做校验和–即直接加1
5. 路由器会将数据包的mac首部,源地址改为路由的mac地址,目的地址改为默认路由(或其他导向路由)ip对应的mac地址
网络地址和子网
这里不记录太多的ip地址相关的内容,毕竟比较基础,且协议卷或者网上很多介绍
网络地址简介
网络地址用来在网络上代表一台设备,就像家庭地址一样,当然现在的设备,如手机可以同时拥有几个ip地址(数据网,wifi,等等,可以理解为家有多个门)
而现在的网络地址从32位点分十进制地址,
- 决定了它的数量–>一个网络中的设备数量决定了它如何划分网络
- 网络中的设备数量动态性,可能很少,ip地址不够用–>子网出现(CIDR)
- 网络地址不够用了–>NAT出现,内网
网段,网络范围内,由谁主导生效进行实际的网络隔离和连接?
—其实本质上,设备间可以通过知道mac地址相互通信,即没有网络的隔离(只要介质支持如wifi,或者有线网下设备能被连在一起)在二层上考虑的
- 到了三层,ip层,设备与设备之间的通信,取决于网络的大小,在同一个局域网中,设备间可以直接通信,但是不同局域网,就必须借助路由器,网络,为什么?
首先,考虑他们的距离,若很远,则单纯直连很难,则需要转发,转发单知道mac地址(好吧,假设一开始知道对方的mac地址),很难像现在用ip地址的方式去找到它emm感觉考虑到协议设计了。。。
其次,考虑相邻的不同网络,对应不同的网段,路由表规定了只能和该网络地址范围的主机直接连接,否则就要用默认路由了 - 考虑这样一个例子:A 在子网192.168.0.0中,地址为192.168.0.3,B在子网10.170.3.0,地址为10.170.3.2,使用wifi,他们之间相邻,此时,A向B发送ARP请求,广播帧,所以B可以接收到,接着B给A回复了响应帧,单波能收到,因为在二层传递,能接收到,不被内核过滤,此时arp表中应该多了条目;接着为了能在三层通信,在路由表中增加一条路由指示不同网段的一个地址,表示他们可以直连,接着测试看看能不能相互发送ip包,ping通,当然可能因为防火墙等;就理论而言,应该是能通的,没试过~–>问题总结:IP地址网段不同的两个设备,一定不能直接通信码?
- 网关地址必须是.1结尾码?
恩当然可以是别的地址 - 路由表和路由规则决定了这些
路由表如何决定了网络的方向,下一跳,和限制了网络范围?
IP封包简介
- ip封包网上能找到详情,这里记录几个注意点:
- 网络字节序的概念,是大端字节序,传输的次序是先0-7bit—最后到24-31这样,所以小端的设备需要线转换为网络字节序再传输
- 首部长度字段是指占32bit的数量,有4bit,最大1111*4bytes=60bytes,即ip首部最长为60字节,普通ip同不带选项时是20字节
- 服务类型现在已经不怎么用,主要是指在不同服务下拥有不同的最小时延,最大吞吐,最高可靠性的情况,具体见协议卷1图3-2
- 总长度,指整个ip数据包的长度,包含首部和数据报,16位,即最大2^16=65535个字节,(考虑超级通道的mtu=65535并非是真正的mtu,而是最长ip数据报),数据报分片时会随着变化
- 标示和分片偏移等后面补充
- 校验和为ip首部校验和:首先校验和设置为0,接着每个16bit进行反码求和。rfc1071
网络的拓扑结构:
理论上,网络中的每台设备都能相互通信,即使是点对点通信p2p.但是这要求设备能在网络上被唯一标示,如外网ip地址;
- 所以常见的设备A和B的通信借助服务器如:
主机A<–>路由器(给主机唯一标识)<–>服务器<–>路由器<–>主机B
(现有的大部分通信软件等都是这样的) - 而主机A可以直接和主机B通信不通过服务器吗?
答案是可以,我们使用的迅雷,bt,这些下载资源就是利用的各个主机的资源,其结构如何:
主机A<–>路由器(做NAPT等)<–>路由器<–>主机B
那和主机A和B如何在网络上被唯一标示,且被B知道该地址呢?路由器在其中充当什么角色,会做什么限制呢?
见下NAT和NAT穿透路由深入–NAT和NAT穿透
感谢这两篇文章把我带进门:
https://blog.csdn.net/u012908515/article/details/53518062
https://blog.csdn.net/ustcgy/article/details/5655050
rfc :nat
https://tools.ietf.org/html/rfc1631
https://tools.ietf.org/html/rfc2663
rfc:p2p
https://tools.ietf.org/html/rfc5694NAT的由来
- NAT的出现是因为ipv4的地址不够用,所以大量主机在内网使用内网地址,这样在互联网上通信的时候不能被寻找到,此时路由器将内网的设备发送的包中的ip转换为外网的ip,并记录映射在路由器中,这样就能实现主机在互联网上的正常通信,即发包和收包都能找到;
- 而这种方式阻碍了不同内网的主机之间的通信,即p2p;
NAT的分类(路由器决定)
- 静态NAT:即内网的一个IP对应外网的一个IP,且一一对应,即每次分配的时候都是相同的,永久的
- 动态NAT:即内网的一个IP对应外网的一个IP,但是每次分配的外网IP可能不同,映射不同
- NAPT:即为了使同一个外网IP能被多个内网的主机使用而出现;
如何区分各个主机?即路由器发包时和收包时,如收包时,如何确定该包是发给主机A还是B?即用NAPT,IP加端口号的形式来区分 - NAPT分为以下两大类:cone锥形NAT和symmetric 对称NAT
- cone NAT的特点是对内网的主机A,和外网所有的服务器通信,都使用相同的端口号;
如:内网:192.168.4.5:4323–>server:222.33.22.334:80
则经过路由器:外网ip:122.332.43.32:1234–>server:22…路由器把源地址改为122.332.43.32:1234后发送
进过服务器2也是类似的,使用同一个端口1234
//这里有个疑问,即内网下相同的ip地址,不同的端口时,经过路由器转换后是否为不同端口
考虑在接收服务器回复的内容时:
222.33.22.334:80–>122.332.43.32:1234此时路由器根据映射,即端口122.332.43.32:1234对应的是192.168.4.5把目的地址和端口更改为它后发送。所以为了能让包在主机内找到对应端口的程序,路由器的设置应为内网同ip不同端口,映射外网的ip+不同端口(待验证)
- 锥形NAT类型:完全锥形full cone和受限锥形( restricted cone) 以及端口受限锥形(port restricted cone)
- 完全锥形:任何知道主机B银蛇在NAT上的外部地址和端口的主机都可以通过它发包给内部主机B,即使A在内网(在内网时通过映射的外网地址)
- 受限锥形:只有内部主机B向其发送过包的主机A才能对这个内部主机B发包(通过主机B映射在外部的地址端口)
- 端口受限:在受限锥形的基础上加了端口限制
- 对称NAT(symmetric nat):
会为新的session分配新的端口,即和服务器1通信时使用端口1234,接着发起新的服务器2访问时,使用端口1235等
如何检测类型?https://blog.csdn.net/u012908515/article/details/53518062
ipv6不需要NAT
ipv6地址很多,有人形容世界上的每个沙子都能被定址,所以地址够用,也就不用内网,所以用来做p2p更适用,自然也就不用什么nat转换
p2p网络架构和内网穿透
基于上面的napt类型介绍,可以知道内网的主机如何和外网的服务器通信,那内网的主机1如何和另一个内网的主机2直接通信?(不借助服务器)
答案:基于上面的限制,有几种方案:
- 针对full cone类型的,内网主机2只要知道内网主机1映射到外部的ip地址和端口,就可以直接发送数据包给1,且能接收;
- 针对受限的cone类型,内网机2像上面的方式是不行的:得满足两个条件:1是知道主机1映射到外部的ip和端口,2是主机1曾向主机2发送过请求,相当于开了个口,显然这个条件下2为服务器或者有公网ip的设备;所以针对此受限的类型,有一下场景+方案:
- 场景1:主机1在nat后,打开了和服务器A通信,主机2想和1通信,主机2不在nat后;显然直接向主机1发起请求是不行的,上述条件2不满足,主机1不曾向2发起请求;
- 解决方案是,借助服务器A请求主机1做一个反向连接,即向2发起请求,从而打开通道,进而2就可以跟1通信了
- 场景2:主机1在nat后,主机2在nat后,主机1,2均打开了和服务器A通信,主机1想直接和2通过双方映射到外网的地址端口进行通信
- 解决方案:UDP打洞:假如1开始发送一个UDP信息到2的公网地址上,与此同时,他又通过A中转发送了一个邀请信息给2,请求2也给1发送一个UDP信息到1的公网地址上.这时1向2的公网IP发送的信息导致 NAT 1 打开一个处于1的私有地址和2的公网地址之间的新的通信会话,与此同时NAT 2也打开了一个处于2的私有地址和1的公网地址之间的新的通信会话.一旦这个新的UDP会话各自向对方打开了,1和2之间就可以直接通信,而无需A来牵线搭桥了.这就是所谓的打洞技术.一旦这种处于NAT之后的端对端的直连建立之后,连接的双方可以轮流担任对方的”媒人”,把对方介绍给其他的客户端,这样就极大的降低了服务器A的工作量.
- 场景3:主机1和2处于同一个NAT下,他们却不知道:
- 解决方案:综合相同内网下主机可以直接相互通信原理:在主机1发送给A的包中携带其内网地址和端口,A从而知道了1的外网端口地址和内网端口地址,相互都发给1,2,若接着1发起请求给2能收到回复说明在同一个内网,否则采用场景2的解决方案
- 场景4:主机1处于多层NAT下
- 问题:udp空闲状态下超时断开的问题:使用心跳包
- 扩展:tcp的打洞,同时开放tcp连接,原理类似,较复杂
- 针对对称性的cone,不定因素多,不建议写
- 所以p2p网络即是多个内网主机1,2,3,4等之间的相互直接通信,即他们之间的下载数据可以相互共享,也就是平常说的挂种子,bt下载,也是为什么能达到那么快速的原因;当然可想这个过程和普通的cs架构区别:
- p2p架构,bt模型(猜测):首先客户端负责下载和挂种的基本功能。下载:需要向服务器取得可以获取资源的主机的nat外网地址和ip,接着服务器为其打洞,将正在挂种的客户ip等提供给该客户端,从而能下载;挂种:给服务器声明自己能提供资源,并通过心跳维持一个持续的洞;BT服务器做什么?综合客户端资源和打洞,即让下载方能方访问挂种放 。 这个过程需要考虑:下载方面对多个挂种方,如何下载文件块和组装,最多同时和几个挂种方下载等等;
- 回忆:之前学校的rs bt站就是这样,只是开放在学校的内网,可以说是相同nat下的不同主机???好像也不能这么说。。然后采用的原理就是上述的,记得一开始速度不是很快,但是后面15年吧,下载速度能达到10+m/s,很快的,我想可能是优化了下载多个挂种方的方案,增加了最多的下载源,或者学校的网络变优~
Cbitterrot源码分析(待~)
https://linux.cn/thread-5529-1-1.html
对于p2p架构的软件设计,其实跟平常的cs架构很象,都需要用到socket等