前面一篇文章分析了套接字缓冲区sk_buff的创建过程,但一般来讲,一个套接字缓冲区总是属于一个套接字,所以,除了调用sk_buff本身的
alloc_skb函数创建一个套接字缓冲区,套接字本身还要对sk_buff进行一些操作,以及设置自身的一些成员值。下面我们来分析这个过程。
如果检查到待发送数据报没有传输层协议头(不是传输层的tcp或udp数据报),套接字创建缓冲区的函数是sock_alloc_send_skb,它的函数原型是:
struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
int noblock, int *errcode)
它直接调用函数:
static struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
unsigned long header_len,
unsigned long data_len,
int noblock, int *errcode)
参数sk是要创建缓冲区的那个套接字,header_len是sk_buff中,成员data指向的那块数据区的长度,而data_len则是指除那块数
据区以外的被分片的数据的总长。noblock指示是否阻塞模式。对于非传输层协议包,不使用分散/聚集IO,所以,置data_len为0。
网络层代表一个套接字的结构体struct
sock有两个成员sk_wmem_alloc和sk_sndbuf,sk_wmem_alloc表示在这个套接字上已经分配的写缓冲区(发送缓冲区)的
总长,每次分配完一个属于它的写sk_buff,这个值总是加上sk_buff->truesize。而sk_sndbuf则是这个socket所
允许的最大发送缓冲区。它的值在系统初始化的时候设为变量sysctl_wmem_max的值,可以通过系统调用进行修改。其缺省值
sysctl_wmem_max为107520字节,因为它的计算长度还包括了struct sk_buff,所以,一般认为其缺省值是64K数据。
而对于传输层协议包,我们使用sock_wmalloc创建套接字缓冲区,这是一个更为简单的创建函数,没有超时、出错判断机制,直接通过调用
alloc_skb创建一个sk_buff并返回。但对于传输层协议有一个不同点就是sk_wmem_alloc最大可以达到两倍sk_sndbuf,即
缺省的发送缓冲区可以达到128K。
到这里,我们就不难理解struct sk_buff中另外两个成员的含义了:
len是指数据包全部数据的长度,包括data指向的数据和end后面的分片的数据的总长,而data_len只包括分片的数据的长度。而truesize的最终值是len+sizeof(struct sk_buff)。
阅读(759) | 评论(0) | 转发(0) |