说下结论:linux下,在某个tcp未监听端口收到报文时,会回复reset报文,代码层面初步分析如下。
tcp_v4_rcv中调用__inet_lookup_skb查找报文对应得socket,当没有socket时,会走到“no_tcp_socket”流程,该流程会发送reset报文。
lookup:
sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
th->dest, sdif, &refcounted);
if (!sk)
goto no_tcp_socket;
... ... ...
no_tcp_socket:
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard_it;
tcp_v4_fill_cb(skb, iph, th);
if (tcp_checksum_complete(skb)) {
csum_error:
__TCP_INC_STATS(net, TCP_MIB_CSUMERRORS);
bad_packet:
__TCP_INC_STATS(net, TCP_MIB_INERRS);
} else {
tcp_v4_send_reset(NULL, skb);
}
上述__inet_lookup_skb查找报文对应得socket主要是:
1)根据sip、dip、sport、dport查找establish表;
2)根据sip、dip、sport、dport查找listen表。