編輯:關於android開發
TCP服務端收到syn但是不回復syn ack問題分析
——lvyilong316
最近在分析客戶的一個問題時遇到了一種奇怪的情況,客戶在服務端開啟了某個端口,但是在客戶端telnet確一直不通。通過在服務端抓包發現,客戶端的syn分節已經到達,但是服務端並沒有應答。查看了一下當前連接數,發現連接數也不大,所以排除是連接隊列滿造成的。後來忽然想起了net.ipv4.tcp_tw_recycle選項可能引起這個問題,於是關閉了這個選項,問題果然得以解決。這裡分析一下原因。
有些服務器(當然客戶端也可以)為了避免TIME_WAIT狀態占用連接,希望能加快TIME_WAIT狀態的回收,通常將net.ipv4.tcp_tw_recycle選項開啟。當然這個選項的生效要依賴net.ipv4.tcp_timestamps選項的開啟。雖然開啟這個選項能夠加快TIME_WAIT連接的回收,但卻引入了另一個問題。我們先看下tcp_tw_recycle選項的工作機制:
當開啟了tcp_tw_recycle選項後,當連接進入TIME_WAIT狀態後,會記錄對應遠端主機最後到達分節的時間戳。如果同樣的主機有新的分節到達,且時間戳小於之前記錄的時間戳,即視為無效,相應的數據包會被丟棄(rfc1323)。
Linux是否啟用這種行為取決於tcp_timestamps和tcp_tw_recycle,因為tcp_timestamps缺省就是開啟的,所以當tcp_tw_recycle被開啟後,實際上這種行為就被激活了。
現在很多公司都用LVS做負載均衡,通常是前面一台LVS,後面多台後端服務器,這其實就是NAT,當請求到達LVS後,它修改地址數據後便轉發給後端服務器,但不會修改時間戳數據,對於後端服務器來說,請求的源地址就是LVS的地址,加上端口會復用,所以從後端服務器的角度看,原本不同客戶端的請求經過LVS的轉發,就可能會被認為是同一個連接,加之不同客戶端的時間可能不一致,所以就會出現時間戳錯亂的現象,於是後面的數據包就被丟棄了,具體的表現通常是是客戶端明明發送的SYN,但服務端就是不響應ACK,還可以通過下面命令來確認數據包不斷被丟棄的現象:
shell> netstat -s | grep timestamp
... packets rejects in established connections because of timestamp
如果服務器身處NAT環境,安全起見,通常要禁止tcp_tw_recycle,至於TIME_WAIT連接過多的問題,可以通過激活tcp_tw_reuse來緩解(只對客戶端有作用)。
當然關閉tcp_timestamps選項也是可以避免這個問題的:
設置sysctl.conf裡面tcp_timestamps=0也可以只用命令sysctl -w net.ipv4.tcp_timestamps=0
但個人建議關閉tcp_tw_recycle選項,而不是timestamp;因為 在tcp timestamp關閉的條件下,開啟tcp_tw_recycle是不起作用的;而tcp timestamp可以獨立開啟並起作用。此外tcp timestamp還和其他選項起作用有關,如tcp_tw_reuse。
Android安全之旅系列博客導讀 總結下近一年的學習經歷,以中國的新年為節點。時間從2015年年後到今天,2015年年末。 首先我必須要感謝前輩的書籍和高質量的博客。
Android RecyclerView的使用,androidrecyclerRecyclerView是什麼? RecyclerView是一種新的視圖組,目標是為任何基於
階段一:AsyncTask的三個屬性值和四個步驟,asynctask屬性值“階段一”是指我第一次系統地學習Android開發。這主要是對我的學習過
一個帖子學會Android開發四大組件,android四大來自:http://www.cnblogs.com/pepcod/archive/2013/02/11/2937