大师的错误?UNP1中raw socket不能接收TCP和UDP的错误

简介:
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
  
   

在UNP1中的28.4 Raw Socket Input中,大师是这样说的。
  • Received UDP packets and received TCP packets are never passed to a raw socket. If a process wants to read IP datagrams containing UDP or TCP packets, the packets must be read at the datalink layer, as described in Chapter 29.

中文版是这样说的。
1. 接收到UDP分组和TCP分组绝不传递到任何原始套接口。如果一个进程想要读取含有UDP分组或TCP分组的IP数据报,它就必须在数据链路层读取这些分组。

首先,要严重鄙视一下中文版的翻译!什么叫UDP分组和TCP分组?!
反正我在看到中文版这个部分的时候,就很疑惑?分组,是分片的笔误还是组播?然后对照了原文,唉,为啥不翻译成报文呢。
看来我以后全看英文版的决定还是无比正确的。

下面回到正题。根据大师的说法,raw socket是无法收到TCP和UDP的数据包的。可是根据我的使用,情况不是这样。在我前面的博文《kernel对于SO_REUSEADDR的处理——避免滥用引发Bug》 http://blog.chinaunix.net/space.php?uid=23629988&do=blog&id=217123中,我特意用了raw socket在不影响绑定同一地址和端口的socket情况下,来获取UDP数据包(clone)。代码工作完全正常。

今天跟同事谈到这个问题,跟他说明linux选择socket机制时,对于raw socket,只要该包符合了raw socket的过滤条件,该raw socket就可以获得一个该包的拷贝。他想让我找出理论依据,我就找出UNP1来作说明。这才发现UNP1中虽然说了raw socket可以获得数据包拷贝的事情,但是也说了前提条件。其中UDP和TCP不会交给raw socket是首要条件。这让我很困惑啊。

如何解决?代码说明一切。让我们直接看linux kernel的代码。
我的kernel代码是2.6.36.2
  1. static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
  2.         unsigned short num, __be32 raddr, __be32 laddr, int dif)
  3. {
  4.     struct hlist_node *node;

  5.     sk_for_each_from(sk, node) {
  6.         struct inet_sock *inet = inet_sk(sk);

  7.         if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
  8.             !(inet->inet_daddr && inet->inet_daddr != raddr) &&
  9.             !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
  10.             !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
  11.             goto found; /* gotcha */
  12.     }
  13.     sk = NULL;
  14. found:
  15.     return sk;
  16. }

  17. static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
  18. {
  19.     struct sock *sk;
  20.     struct hlist_head *head;
  21.     int delivered = 0;
  22.     struct net *net;

  23.     read_lock(&raw_v4_hashinfo.lock);
  24.     head = &raw_v4_hashinfo.ht[hash];
  25.     if (hlist_empty(head))
  26.         goto out;

  27.     net = dev_net(skb->dev);
  28.     sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
  29.                  iph->saddr, iph->daddr,
  30.                  skb->dev->ifindex);

  31.     while (sk) {
  32.         delivered = 1;
  33.         if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) {
  34.             struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);

  35.             /* Not releasing hash */
  36.             if (clone)
  37.                 raw_rcv(sk, clone);
  38.         }
  39.         sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
  40.                      iph->saddr, iph->daddr,
  41.                      skb->dev->ifindex);
  42.     }
  43. out:
  44.     read_unlock(&raw_v4_hashinfo.lock);
  45.     return delivered;
  46. }
在__raw_v4_lookup中,只是去比较地址,端口等过滤条件,则这个raw socket就是匹配的。然后在raw_v4_input中,只要不是ICMP或者不是需要过滤的ICMP type,这个raw socket就可以获得一个数据包的拷贝。

kernel的代码无疑已经说明了raw socket完全可以接受TCP或者UDP的数据包。我又检查了linux2.4的处理,同样没有这个限制。

也许大师写的这个条件不是针对linux的吧——因为对其他unix系统没有了解,所以不敢枉然说这是大师的错误。

不过从这件事可以看出,尽信书不如无书。对于linux程序员,既然kernel是开源的,还是代码说明了一切!
目录
相关文章
|
7月前
|
网络协议 安全 网络安全
什么是TCP/UDP/HTTP?它们如何影响你的内网穿透体验?
数据的传输离不开各种协议,它们就像现实世界中的交通规则,规定了数据如何打包、寻址、传输和接收。对于使用内网穿透的用户来说,理解TCP、UDP和HTTP这些基础协议的特点,能帮助你更好地理解其性能表现,并选择最适合的配置方案。
|
9月前
|
网络协议 API
区分TCP/IP、HTTP、Socket三者的差异
HTTP关注于应用层的协议规范,而Socket关注于为应用程序提供编程中的网络功能,这些功能本身是建立在底层的TCP/IP协议之上;HTTP是更高层次的抽象,定义了如何包装数据,而TCP/IP定义了如何传送数据,Socket则是两者之间在程序中的桥梁,负责实现细节。在实际应用中,通常HTTP通信也是通过Socket来完成,因为HTTP仅是具体内容的封装形式,而Socket则是传送方式的实现形式。
813 16
|
9月前
|
网络协议 安全 网络安全
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
635 2
|
12月前
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
676 1
|
网络协议 算法 网络性能优化
|
监控 网络协议 网络性能优化
不再困惑!一文搞懂TCP与UDP的所有区别
本文介绍网络基础中TCP与UDP的区别及其应用场景。TCP是面向连接、可靠传输的协议,适用于HTTP、FTP等需要保证数据完整性的场景;UDP是无连接、不可靠但速度快的协议,适合DNS、RIP等对实时性要求高的应用。文章通过对比两者在连接方式、可靠性、速度、流量控制和数据包大小等方面的差异,帮助读者理解其各自特点与适用场景。
|
存储 网络协议 安全
用于 syslog 收集的协议:TCP、UDP、RELP
系统日志是从Linux/Unix设备及网络设备生成的日志,可通过syslog服务器集中管理。日志传输支持UDP、TCP和RELP协议。UDP无连接且不可靠,不推荐使用;TCP可靠,常用于rsyslog和syslog-ng;RELP提供可靠传输和反向确认。集中管理日志有助于故障排除和安全审计,EventLog Analyzer等工具可自动收集、解析和分析日志。
1140 2
|
网络协议 网络性能优化 数据处理
深入解析:TCP与UDP的核心技术差异
在网络通信的世界里,TCP(传输控制协议)和UDP(用户数据报协议)是两种核心的传输层协议,它们在确保数据传输的可靠性、效率和实时性方面扮演着不同的角色。本文将深入探讨这两种协议的技术差异,并探讨它们在不同应用场景下的适用性。
584 4
|
监控 网络协议 网络性能优化
网络通信的核心选择:TCP与UDP协议深度解析
在网络通信领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种基础且截然不同的传输层协议。它们各自的特点和适用场景对于网络工程师和开发者来说至关重要。本文将深入探讨TCP和UDP的核心区别,并分析它们在实际应用中的选择依据。
764 3
|
缓存 负载均衡 网络协议
面试:TCP、UDP如何解决丢包问题
TCP、UDP如何解决丢包问题。TCP:基于数据块传输/数据分片、对失序数据包重新排序以及去重、流量控制(滑动窗口)、拥塞控制、自主重传ARQ;UDP:程序执行后马上开始监听、控制报文大小、每个分割块的长度小于MTU