TCP传输差错总结

上传人:m**** 文档编号:165276454 上传时间:2022-10-27 格式:DOCX 页数:12 大小:204.75KB
返回 下载 相关 举报
TCP传输差错总结_第1页
第1页 / 共12页
TCP传输差错总结_第2页
第2页 / 共12页
TCP传输差错总结_第3页
第3页 / 共12页
点击查看更多>>
资源描述
、ICMP 在域中的结构控制每个 domain 结构引用相应的 protosw 结构数组。一个内核可以通过提供多 个 protosw 项为同一协议提供多个接口。 源文件: protosw.h对于Internet协议,inetsw数组包含protosw结构。inetsw 数组的定义在文件 in_proto.c 中struct protosw inetsw=当进程创建一个插口时,pffindproto和pffindtype函数函数被调用来查找相应的 protosw 项。Internet 传输分用一个网络层协议像 IP 必须分用输入数据报,并将它们传递到相应的运输层 协议。为了完成这些,相应的protosw结构必须通过一个在数据报中出现的协议 编号得到。对于 Internet 协议,这由数组 ip_protox 来完成。0厂2645eaitetssJ:IP-UDP-TCPICMPIGMP-亦(原始)数组 ip_protox 将协议编号映射到数组 Inetsw 中的一项数组ip_protox的下标是来自IP首部的协议值(ip_p),被选项是inetsw数 组中处理此数据报的协议的下标。到达非最终目的地系统的分组需要被转发。只有当ipforwarding非零(6.1节) 或当分组中包含源路由(9.6节)时,ipintr才调用实现转发算法的ip_forward函数。ip_input.c ip_forward()icmp_error在IP或运输层协议的请求下,构造一个ICMP差错请求报文,并把它 传给icmp_reflect,在那里该报文被返回无效数据包的源站。ip_forward 可能会由于 ip_output 失败或重定向而发送 ICMP 报文。如果没有 原始分组的复制(可能当要复制时,曾经缓存不足 ),则无法发送重定向报文, ip_forward 返回。如果有重定向, type 和 code 以前又被置位,但如果 ip_output 失败, switch 语句基于从 ip_output 返回的值重新设置新的 ICMP 类型和码值。 icmp_error 发送该报文。来自失败的 ip_output ICMP 报文将覆盖任何重定向报文。处理来自 ip_output 的差错的 switch 语句非常重要。它把本地差错翻译成适 当的ICMP差错报文,并返回给分组的源站。二、差错在底层输入处理在以太网接口中,对于一个 IP 分组, schednetisr 调度一个 IP 软件中断,并 选择IP输入队列ipintrq,代码实现如下:switch(eh-ether_type)case ETHERTYPE_IP:schednetisr(NETISR_IP);inq=&ipintrq;当接口把分组放到 ipintrq 上排队后,调用中断发生后, IP 处理过程由 schednetisr 调度,则内核调用 ipintr。在ipintr中对数据报进行分用是根据IP首部中的传输协议编号ip_p。对于 ICMP报文,ip_p是1,并通过ip_protox选择inetsw4。当一个ICMP报文到达 时,IP层通过inetsw4的prinput函数,间接调用icmp_input。三、ICMP报文输入/输出处理我们将看到,在icmp_input 中,每一个ICMP报文要被处理3次:被icmp_input 处理一次;被与 ICMP 差错报文中的 IP 分组相关联的传输协议处理一次;被记 录收到 ICMP 报文的进程处理一次。注意:以rip_xxx的函数中的rip表示RAW IP是原始IP的意思,而非RIP 路由。icmp_input 调用 rip_input 处理所有未知的 ICMP 报文类型和所有非响应的 ICMP 报文。调用 rip_input 的一个原因是允许创建了原始插口的应用进程处理新增的 ICMP报文,内核可能不支持它们。图11-14 ICMP的输入处理过程内核不处理任何ICMP回答报文。ICMP请求由进程产生,内核从不产生请 求。所以内核把它接收到的所有回答传给等待ICMP报文的进程。由下图可知,有三种方法产生外出的ICMP报文。前面提到用icmp_error来 产生和发送 ICMP 差错报文。 icmp_reflect 发送 ICMP 报文,同时进程也可能通 过原始ICMP协议产生ICMP报文ICMP 和原始 IP 都会调用 rip_output 实现原始 IP 输出。应用程序调用 5 个写函数之一:send、sendto、sendmsg、write和writev,系统将输出报文段。四、控制块中ICMP差错处理在控制块(in_pcb.c)中,当收到一个ICMP差错时,调用in_pcbnotify函数, 把差错通知给合适的进程。通过对所有的PCB搜索一个协议(TCP或者UDP), 并把本地和外部 IP 地址以及端口号与 ICMP 差错返回的值进行比较,找到“合 适的进程”例如,当因为一些路由器丢掉了某个TCP报文段而收到ICMP源抑 制差错时,TCP必须找到产生该差错的连接的PCB,放慢在该连接上的传输速 度。下图给出了处理ICMP差错时调用的函数。udp_inputipinrItcp_input;tcp_ctlinpuz或 协议的控制 输入函数和pf ct 1 input :,有 协议的控制输入函数(软件中断)|22-32 ICMP差错处理总结当收到一个ICMP报文时,调用icmp_input。ICMP的五种报文按差错来划一其他JCMP卄亠二dp_i 京爻(见 正文)目的主机不可达; 参数问题; 重定向; 源抑制; 超时。每个协议都定义了它的控制输入函数,即 protosw 结构(7.4 节)中的 prctlinput入口。对 TCP 和 UDP,它们分别称为 tcp_ctlinput 和 udp_ctlinput。因为收到的 ICMP 差错中包含了引起差错的数据报的 IP 首部,所以引起该 差错的协议(TCP或UDP )是已知的。这五个ICMP差错中的四个将引起对协议 的控制输入函数的调用。重定向的处理不同:调用函数pfctlinput,它继续调用协议族(Internet )中所 有协议的控制输入函数。 TCP 和 UDP 是 Internet 协议族中仅有的两个具有控制 输入函数的协议。重定向的处理是特殊的,因为它们不仅影响产生重定向的数据报,还将影响 所有到该目的地的 IP 数据报。另一方面,其他四个差错只需由产生差错的协议 进行处理。有关图22-32 我们要做的最后一点说明是, TCP 在处理源抑制差错时,与其 他差错的处理不同(由tcp_quench函数处理);而重定向由in_pcbnotify特别处理: 不管引起差错的是什么协议,都调用 in_rtchange 函数。五、差错在TCP中的处理所有重定向差错会交给相应的 TCP 和 UDP 进行处理。 对于其他四种差错,仅当他们是被 TCP 报文段引发的,才会调用 tcp_ctlinput 进行处理。(以下函数均在tcp_subr.c文件中)void tcp_ctlinput(cmd, sa, ip)int cmd;struct sockaddr *sa;register struct ip *ip;register struct tcphdr *th;extern struct in_addr zeroin_addr;extern u_char inetctlerrmap;void (*notify) (struct inpcb *, int) = tcp_notify;if (cmd = PRC_QUENCH)notify = tcp_quench;else if (!PRC_IS_REDIRECT(cmd) &(unsigned)cmd PRC_NCMDS | inetctlerrmapcmd = 0) return;if (ip) th = (struct tcphdr *)(caddr_t)ip + (ip-ip_hl th_dport, ip-ip_src, th-th_sport, cmd, notify); elsein_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify);在逻辑上,tcp_ctlinput与udp_ctlinput的唯一区别是如何处理ICMP源站抑 制差错。因为inetctlerrmap等于0, UDP忽略源站抑制差错。TCP检查源站抑制 差错,并把 notify 函数的默认值 tcp_notify 改为 tcp_quench 。 tcp_notify 被 tcp_ctlinput 调用,处理目的地不可达、数据报参数错、数据报超时和重定向差错。tcp_notify 被 tcp_ctlinput 调用,处理目的地不可达、数据报参数错、数据报 超时和重定向差错。与UDP的差错处理函数相比,它要复杂得多,因为TCP必 须灵活地处理连接上收到的各种软差错。void tcp_notif(iynp, error)struct inpcb *inp;int error;register struct tcpcb *tp = (struct tcpcb *)inp-inp_ppcb; register struct socket *so = inp-inp_socket;/*如果连接状态为 ESTABLISHED,忽略 ENETUNREACH (网络不可达)、 EHOSTUNREACH (找不到到主机的路由)和 EHOSTDOWN (主机关闭)差 错代码*/f (tp-t_state = TCPS_ESTABLISHED &(error = EHOSTUNREACH | error = ENETUNREACH |error = EHOSTDOWN) return;/*/ else if (tp-t_state t_rxtshift 3 & tp-t_softerror)so-so_error = error;else tp-t_softerror = error;wakeup(&so-so_timeoSem);sorwakeup(so); sowwakeup(so);TCP 在两种情况下调用它:当连接上收到源站抑制差错时,由 tcp_input 调 用。当ip_output返回ENOBUFS(缓存空间不足)差错代码时,由tcp_output调用。tcp_quench(inp, error)struct inpcb *inp;int error;struct tcpcb *tp = intotcpcb(inp);if (tp)tp-snd_cwnd = tp-t_maxseg;拥塞窗口设定为最大报文段长度,强迫 TCP 执行慢起动。慢起动门限不变(与 tcp_timers 处理重传超时的思想相同),因此,窗口大小将成指数地增加,直 至达到 snd_ssthresh 门限或发生拥塞。ICMP与TCP的差错控制对比比如主机 A 到主机 B 的通信,中间 Router r1 到 Router r2 的网络连接断 了。通过ICMP,则可以快速诊断出出错原因,并且报告主机。(差错诊断)TCP的差错控制,主要是体现在,网络断了,收不到确认回复,TCP会一 直再次发送数据包,直到收到确认回复。(差错处理)RST 报文TCP在下列三种情况下产生RST复位报文段。1、到不存在的端口的连接请求 产生复位的一种常见情况是当连接请求到达时,目的端口没有进程正在监听对于UDP,当一个数据报到达目的端口时,该端口没在使用,它将产生一个ICMP 端口不可达的信息;而TCP则使用复位。2、异常终止一个连接终止一个连接的正常方式是一方发送FIN,这也称为有序释放,因为在所有 排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失。但也有可 能 发送一个复位报文段而不是 FIN 来中途释放一个连接,这也称为异常释放。异 常终止一个连接对应用程序来说有两个优点:( 1)丢弃任何待发数据并立即发 送复位报文段;(2) RST的接收方会区分另一端执行的是异常关闭还是正常关 闭。3、检测半关闭连接如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的TCP 连接称为半打开的。任何一端的主机异常都可能导致发生这种情况。只要不打算 在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异 常。下面介绍一种建立半打开连接的情形。例如,用户在一天工作结束时关闭 PC 机的电源。当关闭 PC 机电源时,如果已不再有要向服务器发送的数据,服 务器将永远不知道客户程序已经消失了。当用户在第二天到来时,打开 PC 机, 并启动新的Telnet客户程序,在服务器主机上会启动一个新的服务器程序。这样 会导致服务器主机中产生许多半打开的 TCP 连接。 TCP 处理的原则是接收方以 复位作为应答。简言之:1、connect 一个不存在的端口(或者端口未打开)2、send 一个已经关掉的连接3、send 一个已经死掉的连接4、设置SO_LINGER选项这个处理比较特殊,这个插口选项负责的是插口的拖延定时器(linger timer), 它是一个插口级的定时器,由系统函数close直接调用。即使在插口关闭时,TCP 会首先检查该选项是否置位,拖延时间是否为0如果满足条件,将不采取TCP 正常的关闭方式,连接直接被复位。5、如果close 一个接收缓冲区中还有数据的连接,会给对方发一个RST。 eg:假如在服务器段有这么一段程序listen(listen_fd,WAIT_COUNT);while(1) if(fork()=0)close(listen_fd);char pcContent4096;read(real_fd,pcContent,4096); close(real_fd); 服务器端是每次只读socket的前4096个字节,然后就关闭连接。再看客户端一段简单代码:char pcContent5000=0;write(send_sk,pcContent,5000);sleep(1);打开一个socket然后连接一个服务器并发送5000个字节,那么客户端发送剩下 的4个字节服务端的应用程序没有接收到,服务器端的socket就会被关闭掉。抓 包分析以后:经过3次握手,客户端向服务器发送5000字节数据,服务器端发 送一个ACK进行确认,然后紧接着会向客户端发送一个RST断开连接。6、请求超时:一个客户端连接服务器,connect返回-1并且error=EINPROGRESS, 直接telnet发现网络没问题,ping没有出现丢包。用抓包工具查看,客户端是在 受到服务器发送的SYN之后就莫名其妙的发送了 RST。客服端建立socket之后 用setsockopt的SO_RCVTIMEO选项设置了 recv的超时时间为100ms,但是客 户端发送SYN到接收SYN的时间为110ms。此时服务器的程序就会认为接收超 时,所以发送RST拒绝客户端进一步发送数据。实现部分:1、tcp_input 调用 tcp_respond 函数(tcp_subr.c 中)生成 RST 报文段,携带 或不携带ACK(参数可选),同时接收到的报文段可能会引发tcp_input发送RST。 tcp_subr.c 如果tcp_input收到一个不属于任何连接的报文段(tp为空,使用win和ro的初 始值),则可能生成RSTint win = 0;struct route *ro = 0;if (tp) win = sbspace(&tp-t_inpcb-inp_socket-so_rcv);ro = &tp-t_inpcb-inp_route;2、tcp_drop函数(tcp_subr.c中)发送RST报文以丢弃连接,并向应用程序返回 差错(在 TCP 状态转移图中也可以看到)。?3、寻找 Internet PCBTCP的缓存(tcp_last_inpcb)中保存了收到的最后一个报文段的PCB地址,采 用的技术与UDP相同。1)如果没有找到PCB,则丢弃输入报文段,并发送RST作为响应。eg: TCP收 至U个SYN,但报文段指定的服务器并不存在,则直接向对端发送RST。出现这种情况时 UDP 的处理方式是发送一个 ICMP 端口不可达差错。2)如果PCB存在,但是对应的TCP控制块不存在,可能插口已关闭(tcp_close 释放TCP之后,才释放PCB),则丢弃报文段,发送RST作为响应。RST 报文处理处理RST标志是在switch语句,取决于当前的连接状态。(tcp_input.c) if(tiflags & TH_RST)switch (tp-t_state)1、SYN_RCVD 状态case TCPS_SYN_RECEIVED:so -so_error = ECONNREFUSED;goto close;两种情况:连接收到 SYN 后,从 LISTEN 转移到 SYN_RCVD 状态。 TCP 发送带有ACK的SYN作为响应,但接着却收到对端的RST (对应状态图中从 SYN_RCVD转回到LISTEN);应用程序调用connect后,出现同时打开,状态 也转移到SYN_RCVD。收到RST后,向应用进程返回插口差错。2、ESTABLISHED、FIN_WAIT_1、FIN_WAIT_2 或 CLOSE_WAIT 状态so -so_error = ECONNRESET;3、CLOSING、 LAST_ACK 或 TIME_WAIT tp=tcp_close(tp);由于应用进程已经关闭插口,无需返回差错代码。六、垂直切换对TCP传输的影响
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑环境 > 建筑资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!