首页 > 代码库 > 第十九章 APO连接与网络v节点
第十九章 APO连接与网络v节点
第十九章 APO连接与网络v节点
在编写网络底层实现前,需要做许多的准备工作;除了修改前面的章节外,可能还需写3章;本章、文件号管理类的实现、本地内存管理类的实现。我很希望最终的网络编程能给我惊喜;IP/TCP/UDP/ICMP的实现、包括所有的网络服务器的实现(HTTP、DNS、FTP等等),能到达300行的代码量;多于300行代码量那就更好了、我会很高兴。网络编程第一层简为socket层,第二层简称为TCP层,第三层简称为IP层;以后,不再说明。
这章会写得慢,因为要仔细的研究那个:复杂的、巨大的、认真的、严肃的、搞笑的、牛角尖的、牛逼的TCP协议。
一、APO的连接
什么是连接?这简单的问题要耗费我不少时间,简单其实意味着复杂、是很多内容浓缩而形成。Socket、插座、电话号码、端口,就算我们通过类比来描述一个通信连接过程;但能完全描述一个连接吗?对于一个socket客户端口,确实对应着一个客户端连接。但对于同一个socket服务端口,可以有许多连接啊;显然不行。使用双方的IP地址、和socket端口来定义一个连接,那显然可以;但那需要32字节啊,想快速定位一个连接是不行的。嗯、查了一下网上资料,天哟、真的是用什么5元组、7元组来确定一个连接!五元组是: 源IP地址、目的IP地址、协议号、源端口、目的端口。七元组是: 源IP地址、目的IP地址、协议号、源端口、目的端口,服务类型及接口索引。
1、连接的表示
对于客户端,可以用16位socket客户端口来表示;那么、如何知道一个连接是客户端还是服务端?我们需要建立一个端口表,并不大、因为一个服务端口就对应很多连接;APO的表大小只是8K项。那么、表项的内容是什么?应该是跟操作系统有关,我不清楚,或许它们不是使用端口表来表示。不管怎样,接收了一个数据包,就应该判断其属于哪一个连接;想法与文件号sockfd关联。APO的端口表项就是一个字,如果是客户端口:高8位是状态标志、低24位是文件号sockfd;对于服务端口,高8位是状态标志、低24位是0;该端口项不用、全0。实际上,还需管理端口的位图(用于端口的分配、释放),及端口查询表(表项内容就是端口值)。提取IP数据包的目标socket端口值,先在端口查询表找出端口值在第i项(通常需要耗费约30ns);之后、再用i去端口表获得文件号,如是0、则提取IP数据包的24位的服务端文件号字段。如果主机的MAC端口速度是1GBPS,包之间的最小间隔160ns;APO的最小包是512位、等效512ns;所以、在IP层处理一个IP数据包的最短时间只有672ns。IP层处理需要包含内存管理、IP数据包组装成IP数据报、错误包处理、正确提交到TCP层(该层最复杂,连接、文件号管理、端口管理等,处理的最短时间只有672ns。)、ICMP报文处理等。APO的处理速度也就每秒1百多万个数据包,支持千万个连接应该问题不大。
使用五元组,目的方不是本机吗?三元组不行?嗯,它们不像APO主机是唯一的IP地址,是可以有多个IP地址。好了,五元组的字节数太多、直接比较耗费太大(千个连接就会耗尽inte类主机资源),想法每元抽取8位、形成32位哈希值(哈希算法简单、只抽取4元、够啰嗦的)。那不一定是唯一哈希值啊,嗯、增加冲突处理;我要晕了!也许千个连接还行,对付10万个连接时,主机要歇菜。它们应该是用链表去关联到文件号sockfd,对于复杂脑袋型的操作系统、我无法进行仔细探讨,所以、只能是对它们推测。
既然我们将socket看作文件,那么为何不直接使用文件号sockfd来代表一个连接呢?可以,APO就是这样的。客户端就不用说了;在服务端,我们用不同的文件号来代表不同的客户端到同一个服务端的连接;而描述连接的是文件号相对应的内存v节点。但客户端是不知道它们到服务端的连接、在服务端的相应文件号啊;所以,需要在IP包中使用到24位的服务端文件号字段了。服务端文件号字段是服务端设置,而客户端发送数据报时、也将服务端文件号字段一起转发就行了。这样,客户端的数据报到达服务端主机的网络底层时,就可提取24位的服务端文件号字段、快速定位到相应的内存v节点,从而得到该连接的描述。网络底层通常是先提取数据包的目标socket端口、查socket端口表,如是客户端口,那就可以立即得到相应的文件号;如果是0(服务端口),那就需提取IP包头的24位服务端文件号字段了;当然、进入相应的v节点后,还需进一步比较确认,那只是不到10ns的一次性比较吧。
2、建立连接
信令必须可靠,TCP是使用三次握手连接,为何?要保证“信令可靠”,就需要对一个信令数据包进行ack确认表示接收端收到。如果收不到ack,就要做超时重发、APO最多2次超时重发。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻售,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要63s,TCP才会把断开这个连接。我们知道一个512的信令包只是不到1us,就算路径有100个中间路由交换机的存储转发会产生一定的时延,从A到达B也不会到1ms、来回2ms;为何需要重试时间间隔为多于 1s呢?这不浪费时间吗? 给黑客利用的机会?有点像脱裤子放屁哟?你可能说,如果server端接到了clien发的SYN后回了SYN-ACK后client就突然掉线了(或故意不发ACK、这概率更大),server端没有收到client回来的ACK,那么,应该给client端1分钟、和重发5次的机会。要知道主机每秒处理1百万个数据包,那么1分钟就6千万个数据包啊;如果这些数据包都是请求连接信令包、主机的资源就给耗尽。一些恶意的人就为此制造了SYNFlood攻击——给服务器发了一个SYN后,就下线了,于是服务器需要默认等63s才会断开连接;这样,攻击者就可以把服务器的syn连接的队列耗尽,让正常的连接请求不能处理。于是,为了纠正一个小错误,就要付出更为复杂和耗时的代价。Linux下给了一个叫tcp_syncookies的 参数来应对这个事——当SYN队列满了后,TCP会通过源地址端口、目标地址端口和时间戳打造出一个特别的Sequence Number发回去(又叫cookie),如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie发回来,然后服务端可以通过cookie建连接(即使你不在SYN队列中)。代价就是,本可以每秒处理1百万个数据包,可能变成每秒处理1万个数据包。关于这些,linux还有不少的复杂处理方法;不再讨论。我就想不通,为何复杂脑袋的产物总是九曲十八弯的;就不能简明些;协议也不应该是专为垃圾主机制定的。
MSS是最大传输大小的缩写,就是TCP数据包每次能够传输的最大数据报分段。一个数据报被分段成多个小于MTU的数据包(也叫数据报分段)。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去MAC头18字节、IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1518 – 58 = 1460B。通常MTU是1536B,而传输一个TCP信令只是64B,浪费啊;3次握手、还要探查MTU和协商MSS值、测试往返时间,你说要建立一个连接需要多少次信令报往返?浪费多少资源?我以前远看TCP协议、感觉严谨、伟大,就像充满迷一样的大石山;为何、现在看上去就像垃圾山?漏洞百出、被黑客攻击得遍体鳞伤,好搞笑啊!小学生水平都不如,却复杂无比、扁扁我还看几天才略懂;诶、矛盾的世界。
在APO中,TCP是双工连接、UDP是简单型半双工连接。APO的连接并非是通常的TCP三次握手连接,而是使用ICMP探查数据包来进行连接的;只是2次握手,请求、确认。当客户端的请求连接ICMP探查数据包到达服务端时,探查数据包已经包含了沿途路由交换机的MTU、时间戳、IP地址标记等(共16字节);那么、服务端就可知道客户端的地球位置、路径信息、IP地址、单向耗时,并做过滤分析:源IP地址、路由交换机的链路地址是否上了黑名单;如果安全,那么服务端建立描述该连接的文件号、保存连接描述到内存v节点,转发ICMP探查数据包,并在上面打上服务端文件号字段、分段大小MSS、允许的数据报大小、单向耗时、ACK确认等印记。APO网络是无法假冒源地址的,除非你劫持了路由交换机的子网地址。但服务端规定了子网每秒发出到服务端的连接请求数不能超过1000个、主机每秒发出到服务端的连接请求数不能超过10个;黑客想SYN Flood攻击是不可能的,要知道服务端可是允许千万个连接啊;APO取消了广播,你用组播服务器、还是相当于从一台机器发包,没用。那么,劫持路由交换机的子网地址,每秒连接请求数1000个,连续n秒;也没用,APO的重发时间是1s、上一批的1000个连接,如果没发数据包、就被取消了连接。黑客啊,千万别上黑名单,否则来多少数据包、就被丢掉还是小事;事后、追究、报警才大件事。那么,使用招数:占着茅坑不拉屎;一台主机正常连接、每10分钟发一个垃圾GET请求来保持连接。这也不行,服务端规定每台主机只给50个连接;黑客需要劫持30多万台主机。如果主机用APO操作系统,你想劫持那么多主机的root、只是做梦。APO信令报文只是最多发3次,重发时间间隔是,200ms、600ms,延迟到1s时、如果没收到ACK(客户端)或数据包(服务端)、就释放了该连接。APO的探查ICMP数据包最多45E,只能最多90个路由交换机的印记;如果往返超过90个,那么会有部分印记被消除。使用汇聚路由交换机,这种情形不会出现,再远、往返也不会超过50个路由交换机。
客户端发送SYN连接请求ICMP探查数据包后、进入SYN_SENT状态。服务端收到连接请求ICMP探查数据包后、转发打上印记ACK+SYN的ICMP探查数据包、进入SYN_RECEIVED状态;如果在1s内、再次收到相应客户端的IP数据包,则进入ESTABLISHED连接建立状态。否则、在1s内重发2次后,没收到数据包;释放该连接!客户端收到确认ICMP探查数据包后,才确认该连接、进入ESTABLISHED状态,并计算往返时间、确定MSS、初始化发送数据报的头;发送第一个IP数据包。如果收到如目标不可到达等的ICMP差错报文,释放连接、返回错误消息给应用层。如果、超时则重发最多2次的请求连接ICMP探查数据包;如果在1s内没收到服务端的确认ICMP探查数据包,则释放连接、返回错误消息给应用层。
3、连接建立后的TCP通信
待续。。。。。
第十九章 APO连接与网络v节点
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。