當前位置:首頁 » 操作系統 » 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包告訴對方此埠不存在。通常狀態檢測防火牆所做的事情與此類似,只不過防火牆只攔截非法的數據包,而不主動回應。

熱點內容
java直播網站源碼 發布:2025-07-04 14:46:35 瀏覽:169
安卓應用市場消費記錄怎麼刪除 發布:2025-07-04 14:39:47 瀏覽:30
知道一個伺服器的ip地址 發布:2025-07-04 14:20:33 瀏覽:597
蘋果7鎖屏密碼怎麼改 發布:2025-07-04 14:04:44 瀏覽:710
P三零是什麼配置 發布:2025-07-04 13:58:41 瀏覽:361
哪個安卓機有長方形home鍵 發布:2025-07-04 13:43:58 瀏覽:861
android腳本錄制 發布:2025-07-04 13:17:47 瀏覽:342
嵌入式和安卓哪個硬體成本高 發布:2025-07-04 13:05:56 瀏覽:229
360代理伺服器怎麼設置 發布:2025-07-04 12:49:49 瀏覽:515
iphone在哪清除緩存 發布:2025-07-04 12:49:38 瀏覽:340