1. udp_proto
struct proto udp_prot = { sock_wmalloc, sock_rmalloc, sock_wfree, sock_rfree, sock_rspace, sock_wspace, udp_close, udp_read, udp_write, udp_sendto, udp_recvfrom, ip_build_header, udp_connect, NULL, ip_queue_xmit, NULL, NULL, NULL, udp_rcv, datagram_select, udp_ioctl, NULL, NULL, ip_setsockopt, ip_getsockopt, 128, 0, {NULL,}, "UDP", 0, 0 };
2. udp_err function,
void udp_err(int err, unsigned char *header, unsigned long daddr, unsigned long saddr, struct inet_protocol *protocol) { struct udphdr *th; struct sock *sk; struct iphdr *ip=(struct iphdr *)header; header += 4*ip->ihl; /* * Find the 8 bytes of post IP header ICMP included for us */ th = (struct udphdr *)header; sk = get_sock(&udp_prot, th->source, daddr, th->dest, saddr); if (sk == NULL) return; /* No socket for error */ if (err & 0xff00 ==(ICMP_SOURCE_QUENCH << 8)) { /* Slow down! */ if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2; return; } 说明:这是对类型码进行检查,如果类型码为源端节制,就表示远端处理速度跟不上本地发送速度,故其要求本地节制数据包的发送,本地在接收到这种ICMP 通知数据包后,需要相应的减缓本地发送数据包的速度。以代码通过将拥塞窗口值减半达到的,拥塞窗口表示本地发送去但尚未得到远端应答的最大数据包个数,对于UDP 协议而言,其不存在应答机制,所以无所谓拥塞窗口。这儿只是形式上的实现,实际上UDP 协议实现模块在发送数据包并不检查拥塞窗口大小。正因如此,UDP 协议提供不可靠的数据传输方式。
3. udp_send function
#ifdef CONFIG_IP_MULTICAST if (MULTICAST(sin->sin_addr.s_addr)) ttl = sk->ip_mc_ttl; #endif
如果目的地址是多播,则设置TTL 值为1,表示局限于本地网络,不可跨越路由器。
reference: LINUX-2.4.0内核网络栈实现源代码分析