欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

理解IPVS协议中的TCP超时机制

最编程 2024-08-10 21:12:31
...

对于TCP协议,其协议数据结构在函数__ip_vs_tcp_init中初始化,tcp_timeouts是预先定义好的TCP相关timeout值。

static int __ip_vs_tcp_init(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd)
{
    ip_vs_init_hash_table(ipvs->tcp_apps, TCP_APP_TAB_SIZE);
    pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts, sizeof(tcp_timeouts));
    if (!pd->timeout_table)
        return -ENOMEM;
    pd->tcp_state_table =  tcp_states;
    return 0;
}
int *ip_vs_create_timeout_table(int *table, int size)
{
    return kmemdup(table, size, GFP_KERNEL);
}  

在tcp_timeouts数组中,内核为TCP协议的每个状态都定义了相应的超时时间,回忆以上的介绍,ipvsadm工具仅是可修改IP_VS_TCP_S_ESTABLISHED状态和IP_VS_TCP_S_FIN_WAIT状态的超时值,默认情况下分别为1560(900s)和260(120s)。

static const int tcp_timeouts[IP_VS_TCP_S_LAST+1] = {
    [IP_VS_TCP_S_NONE]      =   2*HZ,
    [IP_VS_TCP_S_ESTABLISHED]   =   15*60*HZ,
    [IP_VS_TCP_S_SYN_SENT]      =   2*60*HZ,
    [IP_VS_TCP_S_SYN_RECV]      =   1*60*HZ,
    [IP_VS_TCP_S_FIN_WAIT]      =   2*60*HZ,
    [IP_VS_TCP_S_TIME_WAIT]     =   2*60*HZ,
    [IP_VS_TCP_S_CLOSE]     =   10*HZ,
    [IP_VS_TCP_S_CLOSE_WAIT]    =   60*HZ,
    [IP_VS_TCP_S_LAST_ACK]      =   30*HZ,
    [IP_VS_TCP_S_LISTEN]        =   2*60*HZ,
    [IP_VS_TCP_S_SYNACK]        =   120*HZ,
    [IP_VS_TCP_S_LAST]      =   2*HZ,
};

内核函数set_tcp_state在处理TCP状态转换的同时,更新当前连接的超时时间。

static inline void set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, int direction, struct tcphdr *th)
{
    if (likely(pd))
        cp->timeout = pd->timeout_table[cp->state = new_state];
    else    /* What to do ? */
        cp->timeout = tcp_timeouts[cp->state = new_state];
}

另外,对于TCP协议,在函数ip_vs_tcp_conn_listen中也进行超时时间的更新,此函数主要由IPVS的FTP模块使用。

void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp)
{
    struct ip_vs_proto_data *pd = ip_vs_proto_data_get(cp->ipvs, IPPROTO_TCP);

    spin_lock_bh(&cp->lock);
    cp->state = IP_VS_TCP_S_LISTEN;
    cp->timeout = (pd ? pd->timeout_table[IP_VS_TCP_S_LISTEN] : tcp_timeouts[IP_VS_TCP_S_LISTEN]);
    spin_unlock_bh(&cp->lock);
}

推荐阅读