当前位置:首页 » 操作系统 » linuxack

linuxack

发布时间: 2023-01-15 15:42:11

linux内核中tcp分组是怎么实现的

以前一直使用的网络通讯的函数都是工作在阻塞模式。在看connect实现源码时,突然想到tcp/ip的
三次握手在内核如何实现的,尤其是在非阻塞模式下式,涉及到等待对端回送ack包,而本端又要立即返
回,想来这种实现肯定是遵循某种规则或是将所有的相关函数组合起来。
查看一些网络通信书籍,可知果然如此。应用编程如果设置为非阻塞模式,则连接时,connect发送
SYN包后立即返回-EINPROGRESS,表示操作正在处理中;随后应用可以在connect返回后做一些其它的处理,
最后在select函数中来捕获socket的连接、读写、异常事件以触发相关操作,下面我们看看内核中的相关
实现:
一、tcp/ip连接的三次握手过程:
client SYN包---> server
client <---ACK包 server
client ACK包---> server
二、客户端支持
client发送2个包,一个SYN包,一个对服务器的响应ACK包。
client函数调用链:connect-->sys_connect->inet_stream_connect->tcp_connect...
看inet_stream_connect中实现的部分代码段:
...
switch (sock->state) {
...
/*此处调用tcp_connect函数发送SYN包*/
err = sk->prot->connect(sk, uaddr, addr_len);
if (err < 0) //出错则退出
goto out;
sock->state = SS_CONNECTING;
/* 此处仅设置socket的状态为SS_CONNECTING表示连接状态正在处理;
* 不同之处在于非阻塞情况下,返回值设置为-EINPROGRESS表示操作正在处理
* 而阻塞式情况则在获得ACK包后将返回值置为-EALREADY.
*/
err = -EINPROGRESS;
break;
}

timeo = sock_sndtimeo(sk, flags&O_NONBLOCK); //注意,如果此时设置了非阻塞选项,则timeo返回0
//如果socket对应的sock状态是SYN包已发送或收到SYN包并发送了ACK包,并等待对端发送第三此的ACK包
if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
/* 错误返回码err前面已经设置 */
if (!timeo || !inet_wait_for_connect(sk, timeo))
/*注意上面所判断的2中情况,1、如果是非阻塞模式,则!timeo为1,则直接跳到out返回-EINPROGRESS结束connect函数
2、若为阻塞模式,则在inet_wait_for_connect函数中通过schele_timeout函数放弃cpu控制权睡眠,等待服务器端
发送ACK响应包后被唤醒继续处理。如果没有异常出现,则置socket状态为SS_CONNECTED,表示连接成功,正确返回
*/
goto out;

err = sock_intr_errno(timeo);
if (signal_pending(current)) /*处理未决信号*/
goto out;
}
...
sock->state = SS_CONNECTED;
err = 0;
out:
release_sock(sk);
return err;
...
上面的描述有一个问题:对服务器的响应ACK包是什么时候发送的?对于非阻塞模式,应该是应用处理过程中
的某个异步时间;对于阻塞模式,则是在inet_wait_for_connect函数中睡眠时处理。
即网卡在收到对方的ack包后,上传给对应的socket时发送服务器的响应ACK包
函数调用链为:netif_rx-->net_rx_action-->...(IP层处理)-->tcp_v4_rcv-->tcp_v4_do_rcv-->
tcp_rcv_state_process-->tcp_rcv_synsent_state_process-->tcp_send_synack-->tcp_transmit_skb...
发送SYN包后,socket对应的sock的状态变成TCPF_SYN_SENT,网卡收到服务器的ack传到tcp层时,根据TCPF_SYN_SENT
状态,做相关判断后再发送用于第三次握手的ack包。至此,将socket的状态改为连接建立,即TCP_ESTABLISHED。
具体的代码大家可以根据我提供的函数调用链查看。
注意,以TCPF_前缀开头的状态都表示是中间状态,而已TCP_为前缀的状态才是socket的一个相对稳定的状态。

这里有一个疑问,,根据接收处理源码,先前的SYN包应该发送给服务器的监听socket,而第三次握手似乎应该发送给
连接(未真正连接,因为三次握手还没完成呢)的socket,这个问题有待进一步确认
三、服务器端支持
服务器端此时必须是监听状态,则其函数调用链为:
netif_rx-->net_rx_action-->...(IP层处理)-->tcp_v4_rcv-->tcp_v4_do_rcv-->
tcp_rcv_state_process-->tcp_v4_conn_request-->tcp_v4_send_synack...
在tcp_v4_conn_request,中部分代码如下:
...
case TCP_LISTEN:
if(th->ack) /*监听时收到的ack包都丢弃?*/
return 1;
if(th->syn) {/*如果是SYN包,则调用tcp_v4_conn_request*/
if(tp->af_specific->conn_request(sk, skb) < 0)
return 1;

⑵ linux内核优化参数

cat >> /etc/sysctl.conf << EOF
# kernel optimization
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
EOF # 《Linux就该这么学》
将上面的内核参数加入/etc/sysctl.conf文件中,执行如下命令使之生效:
sysctl -p

⑶ linux查看是否有ack flood

ACK Flood攻击。在TCP连接建立之后,所有的数据传输TCP报文都是带有ACK标志位的,主机在接收到一个带有ACK标志位的数据包的时候,需要检查该数据包所表示的连接四元组是否存在,如果存在则检查该数据包所表示的状态是否合法,然后再向应用层传递该数据包。如果在检查中发现该数据包不合法,例如该数据包所指向的目的端口在本机并未开放,则主机操作系统协议栈会回应RST包告诉对方此端口不存在。通常状态检测防火墙所做的事情与此类似,只不过防火墙只拦截非法的数据包,而不主动回应。

热点内容
文件如何定时上传至服务器 发布:2025-07-04 20:06:17 浏览:857
菜鸟商城源码 发布:2025-07-04 20:01:31 浏览:443
英雄联盟头像文件夹 发布:2025-07-04 19:49:59 浏览:579
取消电脑连接wifi密码怎么设置密码 发布:2025-07-04 19:31:32 浏览:507
电脑服务器市场 发布:2025-07-04 19:14:06 浏览:503
没签名只加密 发布:2025-07-04 18:54:38 浏览:255
红米手机存储问题 发布:2025-07-04 18:50:43 浏览:844
水电煤算法 发布:2025-07-04 18:36:44 浏览:330
天翼视讯缓存文件夹 发布:2025-07-04 18:36:43 浏览:97
unix网络编程第2卷 发布:2025-07-04 18:33:41 浏览:782