Linux内核分析 - 网络[十二]:UDP模块 - 收发
|
数据已经处理完成,释放取到的路由项rt,如果有IP选项,也释放它。如果发送数据成功,返 回发送的长度len;否则根据错误值err进行错误处理并返回err。
ip_rt_put(rt);
if (free)
kfree(ipc.opt);
if (!err)
return len;
if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_SNDBUFERRORS, is_udplite);
}
return err;
在 “ICMP模块” 中往IP层发送数据使用的是ip_push_pending_frames()。而在UDP模块中往IP层发送数 据使用的是ip_push_pending_frames()。而在UDP模块中往IP层发送数据的udp_push_pending_frames()只是对 ip_push_pending_frames()的封装,主要是增加对UDP的报头的处理。同理,udp_flush_pending_frames()也是,只是它更简单 ,仅仅重置了up->len和up->pending的值,重置后可以开始一个新报文。那么udp_push_pending_frames()封装了哪些处 理呢。 udp_push_pending_frames() 发送数据给IP层 设置udp报头,包括源端口source,目的端口dest,报文长度len 。 uh = udp_hdr(skb); uh->source = fl->fl_ip_sport; uh->dest = fl->fl_ip_dport; uh->len = htons(up->len); uh->check = 0; 计算udp报头中的校验和,包括了伪报头、udp报头和报文内容。
if (is_udplite)
csum = udplite_csum_outgoing(sk, skb);
else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */
skb->ip_summed = CHECKSUM_NONE;
goto send;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
udp4_hwcsum_outgoing(sk, skb, fl->fl4_src, fl->fl4_dst, up->len);
goto send;
} else /* `normal' UDP */
csum = udp_csum_outgoing(sk, skb);
uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len, sk->sk_protocol, csum);
将报文发送给IP层,这个函数已经分析过了。 err = ip_push_pending_frames(sk); 同样,在发送完报文 后,重置len和pending的值,以便开始下一个报文发送。 up->len = 0; up->pending = 0; (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


