我们在介绍TCP头的时候,提到过其中有个RST标志位。当一个TCP报文中这个标志位打开的时候,我们叫做reset包(严格的说应该叫做reset段,但是很多时候段包帧并不加以区分)或者简单称呼为reset、RST。通常reset的产生是由于一个异常包导致,reset一般会导致TCP连接的快速断开。产生reset的几种常见的情形如下

  1. 向一个未打开的端口发送连接请求

  2. 应用程序主动终止一个连接

  3. 应用程序还没有接收缓存中的数据,连接被提前关闭

  4. TWA(TIME-WAIT Assassination)

  5. 半开连接的情况下发送数据

注意我们这里是描述的reset产生的一些场景(而且是部分场景),在具体reset的产生原因上可能会有重复,比如第1、4、5都可以认为是对端没有打开相对应的TCP端口。

一、向一个未打开的端口发送连接请求

reset产生的一个常见的原因是,在一个未打开的端口发送连接请求。这里未打开的端口是指没有应用程序在监听这个端口等待连接。

如下图wireshark抓包,再不开启server情况下,没有应用程序监听9877端口,当client连接9877端口的时候就会产生reset消息。

注意我截图中的系列号,在这个截图中我设置了wireshark显示绝对系列号(前面文章截图显示的都是相对系列号),因为SYN包中的ACK标志没有置位,ack number字段无效(实际是以0填充的),所以在reset中的seq=0,ack则为SYN包中的seq+1(因为SYN标志和FIN标志在逻辑上占1byte)。一个reset包如果要被TCP endpoint接收,ACK标志必须置位且ack number落在有效的窗口区间内(窗口相关知识后面细讲)。这帮助阻止了一个简单的reset攻击(RFC5961),否则攻击者可以通过伪造源IP地址、源端口号构造一个reset消息来中断TCP连接。

二、应用程序主动通过reset消息终止一个连接

应用程序可以通过socket API接口设置主动reset一个TCP连接,这种情况下的连接中断过程称为abortive release。之前我们介绍过的四次挥手之类的通过FIN终止连接的过程我们称呼为orderly release。在abortive release情况下,reset包的发送端缓存的待发送数据都会直接丢弃,接收端接收到reset后也可以知道是对端主动abort了这个tcp连接。

wireshark截图如下,注意client发送reset后,并不会引起server回应ACK之类的消息。

可以看到RST消息的seq正好是对端期望接收的seq,按照RFC5961要求,非SYN_SENT状态下,接收端需要判断RST消息的系列号seq为正好为自己期望接收的seq,才会认为这个RST消息有效。如果RST的系列号seq落在接收窗口内但不是期望的seq时候,接收端需要发送challenge ACK,如果落在接收窗口外则会直接丢弃这个RST消息。(实际上challenge ACK也会引起RST,详见RFC5961,此处不做介绍。)

三、应用层还没有读取完接收缓存中的数据,连接被提前关闭

当TCP接收端缓存中还有缓存数据而没有被应用层接收,但是应用层直接关闭TCP连接时候就会产生reset,如下图wireshark抓包所示,连接建立后client向server发送10bytes的数据,server应用层并没有读取这10bytes的数据而是直接关闭tcp连接就会产生reset。

四、TWA(TIME-WAIT Assassination)

TCP在TIME-WAIT状态下的时候,如果接收到reset包,它可能会提前结束TIME-WAIT状态,这种行为即叫做TIME-WAIT Assassination(TWA),数据包的流程如下图所示

为了避免TIME-WAIT状态提前被reset结束,一些系统的TCP实现在TIME-WAIT状态下不会响应rst消息。linux则可以通过net.ipv4.tcp_rfc1337设置TCP在TIME-WAIT下是否响应reset,如果设置tcp_rfc1337为0,在TIME-WAIT下如果接收到reset则会直接关闭tcp连接,而不会等到2MSL超时。

五、半开连接的情况下发送数据

关于半开连接我们前面已经进行了介绍,同时wireshark抓包中也有对应的reset的展示,此处不再介绍。

TCP系列09—连接管理—8、TCP Reset的更多相关文章

  1. TCP系列08—连接管理—7、TCP 常见选项(option)

    一.TCP选项概述 在前面介绍TCP头的时候,我们说过tcp基本头下面可以带有tcp选项,其中有些选项只能在连接过程中随着SYN包发送,有些可以延后.下表汇总了一些tcp选项 其中我标记为红色的部分是 ...

  2. TCP系列07—连接管理—6、TCP连接管理的状态机

            经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化 一.TCP状态机整体状态转换图(截取自第二版TCPIP详解) 二.TCP连接建立 ...

  3. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接

    一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...

  4. TCP系列02—连接管理—1、三次握手与四次挥手

    一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...

  5. TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭

    在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...

  6. TCP系列04—连接管理—3、TCP连接的半打开和半关闭

    在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...

  7. TCP系列06—连接管理—5、TCP fastopen(TFO)

    一.TFO背景 当前web和web-like应用中一般都是在三次握手后开始数据传输,相比于UDP,多了一个RTT的时延,即使当前很多应用使用长连接来处理这种情况,但是仍然由一定比例的短连接,这额外多出 ...

  8. TCP系列10—连接管理—9、syncookie、fastopen与backlog

    这部分内容涉及较多linux实现,可以跳过. 一.listen系统调用对backlog的处理 当socket处于LISTEN或者CLOSED状态时,fastopen队列的长度可以通过TCP_FASTO ...

  9. TCP的运输连接管理

    TCP的运输连接管理 TCP是面向连接的协议,有三个阶段:连接建立.数据传送 和 连接释放.运输连接的管理就是使运输连接的简历和释放都能正常地进行. 在TCP连接建立过程中要解决一下三个问题: 1.  ...

随机推荐

  1. [转]关于sdk更新Android SDK Tools 25.3.1版本后使用sdk manager闪退

    昨天这两个manager还工作正常,今天更新了一下,发现不可用了,运行avd manager和sdk manager没反应,搜了好多文章,然后看到了下这篇文章<关于sdk更新Android SD ...

  2. vim ,vi总是卡死,终于找到原因了。

    玩了这么多年linux 居然不知道这个..特此记录. 使用vim时,如果你不小心按了 Ctrl + s后,你会发现不能输入任何东西了,像死掉了一般,其实vim并没有死掉,这时vim只是停止向终端输出而 ...

  3. Python3练习:对员工信息文件,实现增删改查操作

    1.练习要求: 2.数据文件(data_staff.txt) 1,Alex Li,22,13651054684,运维,2013-02-04 2,Jack Wang,20,13312331232,HR, ...

  4. JS中数组方法的封装之slice

    slice方法的功能 // 1) : 数组的截取 // 2) :slice(m,n): 从数组索引m开始,截取到索引n,但是不包含n;[前包后不包] // slice(m) : 从索引m开始,截取到末 ...

  5. Python学习:4.运算符以及数据类型解析

    运算符 一.算数运算: 二.比较运算: 三.赋值运算 四.逻辑运算 五.成员运算 基本数据类型 一.Number(数字) Python3中支持int.float.bool.complex. 使用内置的 ...

  6. 统一建模语言——UML

    一.UML概述 Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的 ...

  7. QtChart 初体验

    早就知道 Qt 5.7 中引入了 QtChart 模块.一直没时间试用.周末正好空闲,就简单的试了试 QtChart.QtChart 学起来还是挺简单的,基于 Qt Graphics View Fra ...

  8. 机器学习常用算法(LDA,CNN,LR)原理简述

    1.LDA LDA是一种三层贝叶斯模型,三层分别为:文档层.主题层和词层.该模型基于如下假设:1)整个文档集合中存在k个互相独立的主题:2)每一个主题是词上的多项分布:3)每一个文档由k个主题随机混合 ...

  9. dva webpack 利用require.context加载多个model

    dva redux数据管理都在models,根据业务不同models可能会有几十甚至上百的 [模块.js], 每次在index.js使用 app.model(require('./models/exa ...

  10. 「日常训练」Divisibility by Eight(Codeforces Round 306 Div.2 C)

    题意与分析 极简单的数论+思维题. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #de ...