應用層如何強制發送RST即相關內核實現
前幾天群里有個同學問,「如何讓應用層強制發送RST中止連接」,而不是通過FIN包的四次交互來關閉連接。當時,我只是憑藉以往的經驗,猜測使用linger選項可以做到。之所以這麼猜測,完全是出於對TCP和linger的理解。
當TCP套接字正常關閉時,close會立刻返回,內核會儘力去保證把未發送的緩存發送出去——注意,是儘力保證,並沒有說一定會發出去。使用linger選項時,可以設置一個延時時間。調用close時,不再立刻返回,而是嘗試在設置的延時時間內,將數據發送出去。當全部發送成功,或者到達設置的超時時間時,close就會返回。注意,網上很多資料,都說在延時時間內還沒有成功發送所有的數據時,close會返回錯誤,但這些說法網上資料都是錯的。實際上不管是否在linger的時間內成功發送了所有數據,close都返回0。
回過頭來,先繼續咱們的原來話題。linger選項有一個特殊的情況。即開啟linger選項,但是超時時間為0,這意味著內核根本不會嘗試發送緩存中的數據,而是直接關閉fd。這樣的處理,對於TCP來說,實際上是一種異常情況。如果仍然是正常的發送FIN包關閉連接,就等於告訴對端,我所有的數據已經發送完畢,但實際情況則不是。所以,這時就需要使用RST來中斷連接,來通知對端發生了異常情況。
下面就看,應用層如何強制發送RST來中止連接的關鍵代碼:
啟用linger選項,同時linger的超時時間設置為0。完整的測試代碼位於:https://github.com/gfreewind/LinuxDetails/blob/master/networks/7.tcp_send_rst/tcp_send_rst.c。
利用nc監聽指定的TCP埠,然後運行測試程序,抓包如下:
可以明顯的看到,在關閉TCP套接字時,應用層強制發送了RST中止連接。
任務達成!接下來就要看看內核對於linger的處理。在tcp_close函數中,
如果套接字設置了linger且lingertime值為0,那麼就調用disconnect函數,即tcp_disconnect。在這個函數中,
只要tcp_need_reset(old_state)為真,就會調用tcp_send_active_reset來發送RST報文中止連接。而「已連接」的TCP狀態是TCPF_ESTABLISHED,就是需要RESET的狀態之一。
至此,就已經了解了設置linger選項,強制發送RST的內核實現。還剩下一點:就是開頭提到的,內核沒有在linger時間內發送完所有數據,會不會返回錯誤。
這個證據很簡單。我們都不用去分析tcp_close,直接看sock_close。
其無不關心具體的套接字的實現,之間返回0。所以對於套接字的fd來說,其close永遠返回0——至少到目前的linux最新內核是這樣的:D
※最愛黑白配:奧利奧版雪媚娘
※針灸和中藥配合治療腰痛腰間盤突出
※6個動作在家練出翹臀!一個月後驚艷朋友圈
※王晴川的唐傳奇
※第32期《美麗的龍亭湖》 尹子恆
TAG:公眾號 |
※微軟全新PC遊戲應用現身,內含XGP相關功能
※ofo 回應「利用 GSE 進行融資」相關報道:內容嚴重失實
※蘋果證實iPhone X屏幕問題,並提供相關售後服務
※SAP移動應用解決方案之一:HTML5應用+Cordova=平台相關的混合應用
※如何使用Imkoken錢包映射EOS及相關問題整理
※Soul回應下架整改:將嚴格審核相關功能和內容
※蘋果將首次參加GDC 進行ARKit相關演講
※利福昔明在肝硬化相關併發症中的應用
※相關機構預測DRAM存儲價格將會隨華為禁令繼續下跌
※蘋果公司對VR、AR興趣越來越大,獲得虛擬現實耳機相關專利
※J INTERN MED:繼發性急性髓細胞白血病首次緩解期間的臍帶血移植與良好預後相關
※如何實現中澳關係真正轉圜?中方:希望澳方把相關表態切實落實到具體行動
※索尼「迷你PS」發售以後不會增加新遊戲 也不包含PSN相關的功能
※將不相關的事物用PS融合在一起
※蘋果回應Siri泄露隱私問題:正在改善相關政策
※再生PET進口相關
※外媒稱,蘋果公司獲得虛擬現實耳機相關專利
※AMD提交GPU顯存保護相關專利:保證指令正確運行、免受故障影響
※超越合成致死性!發現與癌症中存活相關的「基因對」相互作用
※高端SoC測試產能供不應求漲價 相關股受益