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; (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |