發送tcp的時候,數據包是如何拷貝的
發送數據包的時候,用戶態的數據包是如何拷貝到內核的kiovec
msghd 結構體
icmp是走sock嗎?
每一個skb_buffer的大小都是固定的嗎?所以有skb_available這樣的函數
1883 /** 1884 * skb_availroom - bytes at buffer end 1885 * @skb: buffer to check 1886 * 1887 * Return the number of bytes of free space at the tail of an sk_ buff 1888 * allocated by sk_stream_alloc() 1889 */ 1890 static inline int skb_availroom(const struct sk_buff *skb) 1891 { 1892 if (skb_is_nonlinear(skb)) 1893 return 0; 1894 1895 return skb->end - skb->tail - skb->reserved_tailroom; 1896 } 1897
skb->end和skb->tail有什麽區別?end tail reserved_room
end 和 tail的設置位於函數__alloc_skb
在分配skb的時候怎麽把下層協議的數據全部都考慮在內?
skb_reset_tail_pointer函數中會把函數data和head都是函數頭
<head, tail> head是有效數據的頭, tail是有效數據尾,是想相對偏移!相對偏移!相對偏移!end是整個skb的最後
看下是如何發送一個數據包的,
skb = alloc_skb_fclone(size + sk->sk_prot->max_header,
其中sk->sk_prot->max_header = MAX_TCP_HEADER
#define MAX_TCP_HEADER (128 + MAX_HEADER)
150 #if !IS_ENABLED(CONFIG_NET_IPIP) && !IS_ENABLED(CONFIG_NET_IPGRE) && \
151 !IS_ENABLED(CONFIG_IPV6_SIT) && !IS_ENABLED(CONFIG_IPV6_TUNNEL)
152 #define MAX_HEADER LL_MAX_HEADER
153 #else
154 #define MAX_HEADER (LL_MAX_HEADER + 48)
155 #endif
138 #if defined(CONFIG_HYPERV_NET) 139 # define LL_MAX_HEADER 128 140 #elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) 141 # if defined(CONFIG_MAC80211_MESH) 142 # define LL_MAX_HEADER 128 143 # else 144 # define LL_MAX_HEADER 96 145 # endif 146 #else 147 # define LL_MAX_HEADER 32 148 #endif
用戶態的數據都是在內核中有一份拷貝, 每創造一個skb,就把這個skb放到了sock的send_list中去
tcp_write_xmit 函數
順序問題;丟包問題;鏈接維護;流量控制;擁塞控制;
順序問題、丟包問題、流量問題都是通過滑動窗口來解決的。這三個問題都是更和接收端強相關,是因為發送端按部就班地發送,接收端收到的順序是錯亂的,發送端把包發送出去了,是接收端沒有接收到包(另外ack包也有可能丟失),流量問題是接收端主動向發送端上報我的接收窗口,從而達到了流量控制的目的; 但是解決方法在發送端解決:(超時重傳|快速重傳|SACK)。所以丟包和順序都是通過滑動窗口來解決的!在對包的確認中會攜帶一個窗口的大小!
擁塞控制更和發送端相關。是因為發送窗口,才會導致網絡擁塞啊。
tcp_transmit_skb中是真正發送;
在發送數據包之前什麽會導致數據包下發失敗呢?發送窗口不允許
有幾個重要的概念: tso(tcp segment offload), mss, RTT(round trip time)
內核裏面是怎麽計算rtt的?超時重傳會用到RTT,超時重傳時使用!
mss(max segment size)
擁塞窗口:snd_cwnd
滑動窗口是TCP協議中的核心,順序、丟包都是通過滑動窗口來指導,但是在這個窗口之內的發送的速率呢?確定過了滑動窗口之後,發送端當然可以一股腦把數據全部都送出去啊,此時肯定不會把接收端打滿,但是會把網絡打滿!所以會把網絡打滿!會把網絡打滿!所以給了你一個quota,怎麽用這個quota,至於你怎麽用那就是你的事情了!使用網絡擁塞算法解決網絡擁堵的問題呀!
函數中:tcp_cwnd_test tcp_packages_in_flight
發送tcp的時候,數據包是如何拷貝的