icmp与SO_SNDBUF相关的发送部分:
函数调用链为:icmp_send() -> icmp_push_reply() -> ip_append_data() -> __ip_append_data()
在__ip_append_data()函数中的其中一段代码为:
if(atomic_read(&sk->sk_wmem_alloc)) <=
2 * sk->sk_sndbuf)
skb = sock_wmalloc(sk,
alloclen + hh_len + 15 , 1,
sk->sk_allocation);
这段代码就是利用SO_SNDBUF设置的值进行的判断,sk结构体是sock相关所有内容的结构体,sk->sk_sndbuf存放的值=2*SO_SNDBUF设置值;
这里主要功能是申请skb,skb使用来保存发送内容的一个结构体,这个结构体包含了很多的内容,这里在icmp发送的时候会先判断sk_sndbuf的值大小;
如果值未超过 2倍的sk_sndbuf则malloc一块新的空间给skb,其中注意sock_wmalloc函数中的skb_set_owner_w()函数;
skb_set_owner_w():这个函数中的两个点需要注意
skb->destructor = sock_wfree;
stomic_add(skb->truesize,&sk->sk_wmem_alloc);
sock_wfree()这个函数在后面skb释放的时候会被用到,这个下面会说到;
而sk_wmem_alloc这个值在此处会被加上skb的实际内容大小,包括要发送的内容和skb的header等,这个值用来每次发送的时候判断buf的大小是否超过限制;
icmp与SO_SNDBUF相关的接收部分:
函数调用链为:icmp_rcv() -> kfree_skb() -> __kfree_skb() -> skb_release_all() -> skb_release_head_state()
if(skb->destructor){
WARN_ON(in_irq());
skb->destructor(skb);
}
此处用到的destructor函数就是上面的sock_wfree()
sock_wfree()函数中:
atomic_sub(len-1,&sk->sk_wmem_alloc);
这条语句将之前add给sk_wmem_alloc的值再sub下去;
这样icmp发包的时候将sk_wmem_alloc加一部分上去,在recv到回复报文的时候再减一部分下去;