2013年2月11日 星期一

linux socket下的TCP three way handshake淺析

之前好奇three way handshake被包裝在socket api之後,那麼到底是哪個function call完成了這個工作?事實上...我想簡單了,這個工作根本是被kernel完成!?也就是是在function call之外,這樣講有些模糊,首先假設大家知道richard stevens提出來的TCP state diagram,那麼從LISTEN狀態轉換到ESTABLISHED狀態就是經過three way handshake

當呼叫listen()的時候,linux將狀態設定為LISTEN,這是相當直觀,但是accept()在呼叫之後會產生怎樣的事情,我倒是不知道!?根據網路上的說法accept()會因為狀態不是ESTABLISHED而被block,然linux kernel會將LISTEN狀態改為ESTABLISHED狀態整個過程是由:
tcp_v4_rcv()=> tcp_v4_do_rcv() => tcp_rcv_state_process()
在tcp_rcv_state_process()中由LISTEN轉換藉由送出SYN,ACK轉為SYN_RCVD,然後等待client端,送回SYN就可以轉換為ESTABLISHED狀態。當轉換為SYN_RCVD狀態時,建立了request_sock結構,在接收到回傳的SYN建立/轉換成了INET SOCKET

這裡的疑惑就是,誰呼叫了tcp_v4_rcv() !?是accept()?還是kernel?如果是kernel表示,其實accept()呼叫之前,就可以進行three way handshake

根據accept()的呼叫次序
accept()==>sys_accept()==>sys_accept4()==>inet_accept()==>inet_csk_accept()
最後一個function直接處理了inet_connection_sock結構,我比較傾向kernel處理了three way handshake

最後覺得,果然Linux網路實作還真是複雜阿!!

參考資料:
http://blog.csdn.net/yanook/article/details/7019558
http://blog.csdn.net/chensichensi/article/details/5272696
http://www.kernel.org/doc/man-pages/online/pages/man2/accept.2.html
http://basiccoder.com/linux-kernel-network-socket-creation.html
http://blog.csdn.net/yanook/article/details/7019600
http://hi.baidu.com/linux_kernel/item/7a5ae7027ede2edcdde5b094
http://tinyurl.com/aejh37lhttp://linux.chinaunix.net/techdoc/net/2008/12/30/1055672.shtml
http://blog.sina.com.cn/s/blog_52355d840100b6sd.html

沒有留言:

張貼留言