-
rfc793原文
If the connection is in any non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED), and the incoming segment acknowledges something not yet sent (the segment carries an unacceptable ACK), or if an incoming segment has a security level or compartment which does not exactly match the level and compartment requested for the connection, a reset is sent.
翻译:
如果连接处于任何非同步状态(LISTEN,SYN-SENT,SYN-RECEIVED),并且传入的数据段确认了尚未发送的内容(即传入的数据段携带了一个不可接受的确认),或者如果传入的数据段具有与连接请求的安全级别或隔间不完全匹配的安全级别或隔间,那么将发送一个复位(reset)。
Linux的实现中,reset报文分为auto-reset和active-reset,其中auto-reset仅仅根据引发reset的报文构造一个附带RST位的TCP回复报文,它并不和任何的socket相关联,发送了reset报文之后也不会针对本地的连接进行任何操作,这种方式reset报文有一个假设,那就是它将引发auto-reset的“坏报文”的产生归结为两点:
1.远端主机的“异常行为”或者是有人没有按照TCP规范而有意为之,比如establish状态时收到一个syn;
2.本端实在没有可以和该坏报文相关联的TCP连接,比如连接了一个不存在或未开启的端口。
对于active-reset,则是在可以将坏报文和既有连接联系的可预知事件发生时发送的,比如重传定时器连续超时超过了一定的次数等,当这种active-reset发送之后,本端的连接也随之烟消云散。在Linux中,auto-reset是由tcp_v4_send_reset来执行的,我想其注释已经阐述的很清晰了:
/*
* This routine will send an RST to the other tcp.
*
* Someone asks: why I NEVER use socket parameters (TOS, TTL etc.)
* for reset.
* Answer: if a packet caused RST, it is not for a socket
* existing in our system, if it is matched to a socket,
* it is just duplicate segment or bug in other side's TCP.
* So that we build reply only basing on parameters
* arrived with segment.
* Exception: precedence violation. We do not implement it in any case.
*/
static void tcp_v4_send_reset(struct sk_buff *skb)
{
...
}