RESET來自何處

2021-09-22 23:30:15 字數 2616 閱讀 5672

有時候我們抓取網路包發現tcp reset幀,我們想知道此時網路出了什麼問題。僅看到tcp reset幀不能說明網路出現問題,因為reset幀傳送的原因有很多,並不是所有的原因都是網路出問題導致的。事實上,reset是個好東西,它可以用於關閉之前開啟的連線。舉個例子,我們的應用建立了很多短連線,但我們不想在服務端time wait狀態時繼續保持連線,所以,客戶端通過reset重置連線。

先說下tcp連線。當網路中的乙個節點通過tcp協議向另乙個節點通訊,它們就會建立tcp連線。此時,客戶端節點向服務端節點傳送synchronization(syn)幀。該資料報中包含了建立連線和傳送資料所需的所有資訊,但這兒我們感興趣的是埠資訊,連線通常在客戶端的源埠和服務端的目標埠之間發生。syn幀中會包含傳送者的源埠和節點想要連線到的目標埠。

下圖就是乙個syn幀資料報,你可以看到tcp:flags= .......s,表示這是乙個syn幀。srcport是源埠,這是客戶端用來建立連線的客戶端埠。dstport是目標埠,本例是445(direct smb埠)。服務端會監聽該埠以便接收syn資料報和後續通訊。

接下來的兩幀會完成連線的建立。第二個幀是ack+syn幀,服務端確認接收第乙個syn幀,並傳送自己的syn幀。這兩個動作在同乙個幀中發生。注意,此時源和目標埠與第一幀syn中的源和目標埠是對換的。

最後一幀是客戶端收到服務端的syn後巷服務端傳送的確認幀,此後,兩節點之間的連線建立。

什麼是time wait狀態?為什麼說它很重要?當tcp連線關閉(gracefully)時,主動關閉一端會向對端傳送fin幀。表示主動關閉端不再有資料傳送。對端會傳送ack幀。當對端不再有資料傳送,也會主動傳送fin幀給這一端,這一端也會向對端傳送ack幀。當兩端都傳送了fin幀,並且都收到了ack幀,此時,tcp連線會進入time wait狀態。預設情況下,連線會保持time wait狀態4分鐘。這保證了仍然在網路中的資料報可以使用該連線繼續傳輸。

現在我們知道了如何建立和優雅關閉tcp連線,接下來讓我們討論一下如何/為什麼我們會重置tcp連線。

什麼是reset?tcp reset表示立即關閉tcp連線。這保證了之前連線分配的資源能夠得以釋放,並為系統所用。以下是一些發生tcp重置的場景。

有的客戶端與服務端建立tcp連線時傳送兩個syn幀,分別使用不同的目標埠。服務端收到兩個syn幀後,分別對兩個幀傳送ack+syn。客戶端收到ack+syn後選擇乙個傳送ack建立連線,另乙個傳送reset關閉連線。

客戶端傳送syn幀,服務端由於某些原因無法與客戶端建立連線,結果傳送ack+reset幀。這些原因包括:

假設我們已經經過三次握手建立了乙個tcp連線。當乙個網路資料報連續傳送了六次都沒有收到響應,此時傳送端會主動重置tcp連線。重置前的重傳次數是可以配置的,預設情況下是5。(預設情況下,建立連線時重傳syn幀的最大值是2,但也是可配的)。

這裡有幾個要點需要牢記,初學者很容易忽略並認為發生了tcp重置,而實際上沒有。注意重傳次數。在上例中,傳送端傳送幀,並且沒有收到確認,此時tcp傳送重傳,每次都沒有收到確認。當資料報第五次重傳以後,傳送端等待一定時間確認。如果仍然沒有收到確認,傳送reset幀重置連線。需要注意的要點:

如果我們觀察網路通訊狀況,但找不到tcp傳送重置的原因,那麼重置一定是來自應用程式本身。這在建立大量tcp短連線的應用程式裡很常見。由於大量埠出在time wait狀態,這可能導致服務端埠枯竭。儘管如此,在重置所有連線之前,應用開發人員仍需要了解為什麼time wait狀態的存在。

note:看一下程式**裡有沒有呼叫close(socket)。如果在傳送資料的連線數呼叫了close,會產生乙個reset資料幀。如果在三次握手建立連線後,直接呼叫close,而沒有資料傳輸,這會產生乙個fin資料幀來優雅關閉連線。

另一種可能性就是目標節點上的其他程序已經監聽了該目標埠,這也可能導致應用重置的發生。

在網路傳輸中發生的問題是最難以解決的問題。如果對reset的發生理解不深,很難跟蹤除錯。網路中的很多裝置,如路由器、防火牆等,都可能重置網路連線。解決這種特殊重置行為的唯一辦法就是跟蹤從源到目的節點的整個網路路徑。比如,從乙個節點捕獲到了reset幀,並且期望在另乙個節點也能捕獲到,而實際上沒有捕獲到,說明這兩個節點直接存在問題。

另乙個有趣的現象是中間裝置可以重置客戶端和服務端的連線。舉個例子,在兩個節點之間建立了tcp連線。源ip10.10.10.20,目的ip10.10.10.30,在tcp埠2301和445之間建立了連線。我們可能捕獲到了發往10.10.10.20:2301的重置幀和發往10.10.10.30:445的重置幀。

如果應用程式試圖重用出在time wait狀態的埠,這可能導致reset。當客戶端和服務端之間的連線已經經由優雅關閉進入time wait狀態時,同乙個客戶端通過傳送syn幀(相同的源和目標埠)試圖重用同乙個埠對。根據rfc1122,這是允許的。但請注意,這樣做是有風險的,別忘了埠保持time wait是有原因的。

警告:syn幀中的序列號(被傳送以通過已有的連線建立新連線)應該大於之前連線中最後幀的序列號。如果不是,會導致連線重置。

tcp重置是個好東西。如果沒有它們,當tcp遇到網路連線問題時,會出現大量問題。請記住,連線重置可能發生自網路棧和應用程式。僅僅因為存在重傳資料報並不能推斷連線會自動重置。重要的是,確定資料幀並理解傳送重傳的原因。

關於Reset命令

自從完成redboot的啟動工作以來,一直有乙個問題困擾著我,只是由於影響不大,所以都沒有進行研究。這個問題就是在使用reset命令重啟的時候,總是會在 resetting.之後列印出亂碼,和前面在cs8900驅動中遇到的亂碼類似的。今天有點閒工夫,於是決定解決這個問題,首先看了一下 發現經過了好幾...

表單重置reset

最近一直在做各種頁面的 增刪改查 只是在做新增功能的時候,自己一直在使用 reset來清空form表單,原以為這樣子的清空方法是萬無一失的,可惜最終還是在進行 修改 操作完了之後再 新增 的時候,就會報錯,於是自己的解決方法便是在使用新增方法的時候,先把隱藏域傳過來的id刪掉,這樣才不會再程式執行過...

回到從前 reset

有時候我們總會忘了什麼,比如已經提交了commit卻發現在這個commit中忘了附上另乙個檔案.接下來我們模擬這種情況.上節內容中,我們最後乙個commit是change 2,我們將要新增另外乙個檔案,將這個修改也commit進change 2.所以我們複製1.py這個檔案,改名為2.py.並把2....