TCP_TW用法介绍



免费领取服务器

点击领取

TCP_TW用法介绍

2023-12-15 14:49:01网络知识悟空

一、TCP_TW概述

TCP_TW全称为TCP Time Wait状态,指的是一种TCP协议中的状态,一般出现在TCP连接断开的过程中。在一个TCP连接的关闭过程中,经过FIN、ACK、ACK的握手确认,最终由一方发送最后的ACK包,这个包在发送后需要等待一段时间后才能进入CLOSE状态。这个等待时间就是TCP_TW状态。

TCP_TW状态主要的目的是确保确认方正确的接受了另外一方的FIN包,并在此时判断一些延迟的重复数据包等问题。TCP_TW状态的默认等待时间是2分钟,这个时间可以通过修改操作系统的参数来进行设置。

二、TCP_TW状态产生原因

TCP_TW状态的主要原因是防止由于网络原因,FIN包或者ACK包没有到达对方。如果没有进入TCP_TW状态,那么就会立即回收socket和相关资源,这个时候FIN包到了接收方,接收方返回一个ACK包,但是由于sender已经释放了相关资源,这个时候ACK就无处可去,接收方无法获取到这个ACK,这就不只是一个连接的问题了,可能会导致链接资源耗尽等问题。

三、TCP_TW如何回收

TCP_TW状态的回收是通过定时器来完成的。每当一个socket进入TCP_TW状态时,系统就会开启一个定时器,并等待固定时间,比如2分钟。在这个时间内,如果接收到对方的ACK包,那么这个定时器就会被立即销毁,并进入CLOSE状态。

然而,在TCP_TW状态下,如果由于ACK漏接或者其他原因,这个时间到了之后还没有收到对方的ACK包,那么这个socket就需要被回收。如果这个socket处于端口共享状态,那么socket实际上不会被立即回收,而是进入假CLOSE状态。这个时候,TCP协议会重新分配一个随机数seq,同时重置计时器,如果在一段时间之内,没有收到对方发来的重复的ACK包,那么socket就会被彻底关闭。

四、TCP_TW状态需要注意的问题

TCP_TW状态实际上是一个非常重要的状态,需要注意以下三个问题:

1. 系统中同时存在大量TCP_TW状态的socket就会导致系统资源的压力,可能会引导奔溃。为了避免这种情况,可以通过修改内核参数来限制TCP_TW状态的数量。一般来说,建议将内核参数设置为6000左右。

2. 防止SYN等IP攻击。攻击者可以通过大量的SYN包来伪造TCP协议中的一个socket,从而放置于TCP_TW状态。如果这种攻击成功,系统的队列资源将被占满,无法被其他请求使用,系统就会崩溃。为了防止这个问题,可以在系统中添加过滤规则,阻止来自可疑IP地址的请求。

3. 在协议栈中,应用程序和内核之间的性能问题。每进入一个TCP_TW状态,都意味着会在内核中创建一个资源对象,这个资源对象的使用可能会带来一些性能问题。如果TCP_TW状态对象过多,就有可能导致内存使用过高,而且更加影响网络系统的性能。

五、TCP_TW状态的代码实现

#include 
#include 
#include 
#include 

int tcp_time_wait(struct sock *sk, int state, int timeo)
{
int flags = sk->sk_shutdown;
whitle (timeo) {
flags |= send_sigurg(sk->sk_socket, NULL);
release_sock(sk);

if (signal_pending(current))
goto ;

if (sk->sk_state != state)
goto ;

if (tcp_out_of_resources(sk, GFP_ATOMIC))
tcp_enter_memory_pressure(sk);

if (time_after(jiffies, timeo))
goto ;

set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(to_backoff(timeo));
set_current_state(TASK_RUNNING);

lock_sock(sk);
}

exit_reset:
if (TCP_SKB_CB(sk->sk_send_head)->when == 0)
TCP_SKB_CB(sk->sk_send_head)->when = tcp_time_stamp;

if (sk->sk_state != TCP_TIME_WAIT)
sk->sk_shutdown = flags|SEND_SHUTDOWN;

sk->sk_state = TCP_TIME_WAIT;
tcp_set_state(sk, TCP_TIME_WAIT);
tcp_time_wait(sk, timeo);

exit_ok:
release_sock(sk);
return 1;

exit_signal:
release_sock(sk);
return -EINTR;
}

发表评论: