内核模块中的可靠 UDP

发布于 2024-07-16 16:16:46 字数 87 浏览 4 评论 0 原文

如何开发 Linux 内核模块以使 UDP 可靠? 如何通过加载新的内核模块来更改 Linux 内核中的默认 UDP 行为? 那么如何编写这样的内核模块呢?

How can I develop a Linux kernel module in order to make UDP reliable? How to change the default UDP behaviour in linux kernel by loading a new kernel module? And how to program such kernel module?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

余生再见 2024-07-23 16:16:46

可靠的 UDP 与仅使用 TCP 不同。 有许多差异,但最重要的是保证您始终收到完整的 UDP 消息或根本不收到它。 然而,接收部分 TCP 消息不仅可能而且很常见。

由于这只是一项家庭作业,我建议只实现一条发送消息,等待 ACK,发送下一条消息例程并设置超时。 如果超时,则在声明失败之前重新发送消息一定次数。 是的,这会比必要的慢。 有很多技术可以提高吞吐量,但对于您的作业来说,您很可能不需要使用它们。

Reliable UDP is not the same as just using TCP. There are a number of differences but the most predominant is that you are guaranteed to always receive an entire UDP message or not receive it at all. Whereas, it is not only possible but very common to receive partial TCP messages.

Since this is just a homework assignment I would suggest just implementing a single send message, wait for an ACK, send next message routine with a timeout. If the timeout kicks in then resend message some number of times before declaring a failure. Yes, this will be slower than necessary. There are lots of techniques to improve throughput, but for your assignment the odds are that you don't need to use them.

北陌 2024-07-23 16:16:46

实际上有可靠的UDP,它被称为RUDP,它是为 Plan 9 发明的。然而,这确实没有意义,只需使用 TCP。

编辑:此外, UDT 可能有用。 它基于UDP,但很可靠。

There actually is reliable UDP, it's called RUDP, and it was invented for Plan 9. However, there really is no point to this, just use TCP.

Edit: Also, UDT might be useful. It is based on UDP, but is reliable.

一紙繁鸢 2024-07-23 16:16:46

那些一直告诉可怜人“只使用 TCP”的人忽略了为什么在 TCP 上使用可靠的 UDP 实现是有充分理由的 - 而且它不是数据报语义(很容易分层在 TCP 之上)

主要合法驱动程序是与许多节点之间的无连接通信,否则可能需要承载过多的连接多重性。

这通常用于广播数据馈送、集群内系统软件通信等。

Those who keep telling the poor guy to "just use TCP" ignore that there are good reasons why a reliable UDP implementation would be used over TCP - and it's not datagram semantics (which dead easy to layer on top of TCP)

A primary legit driver is connectionless communications to/between many nodes that could otherwise require carrying excessive connection multiplicity

This is often used for broadcast datafeeds, intra-cluster system software communications, etc.

乱了心跳 2024-07-23 16:16:46

用于可靠传输数据的技术统称为“ARQ”,代表自动重复请求。

这是一个过于冗长的主题,无法在这里解释,但维基百科页面是一个很好的起点,但仅此而已。 我建议您拿起一本有关计算机网络的教科书(例如 Tanenbaum 或 Kurose/Ross)并从那里开始。 如果您认为它足以满足您的任务,则实施基本的停止等待 ARQ 并忘记更高级的 ARQ 方案,那么构建它们还有很多工作要做。

我没有开发 Linux 内核模块的经验,但如果您选择一种更高级的 ARQ 方案,如果 ARQ 机制的实现比将其打包为内核模块需要更多工作,我不会感到惊讶。

祝你的任务顺利。

The techniques for reliable transmission of data are collectively known as "ARQ", which stands for Automatic Repeat reQuest.

It's too verbose a subject to explain here, but the wikipedia pages are a good place to start, but little more than that. I recommend you pick up one of the text books on computer networking (e.g. Tanenbaum or Kurose/Ross) and go from there. If you think it suffices for your assignment, implement basic stop-and-wait ARQ and forget about the more advanced ARQ schemes, they're a lot more work to build.

I have no experience developing Linux kernel modules, but if you go for one of the more advanced ARQ schemes I wouldn't be surprised if the implementation of the ARQ mechanism turns out to be more work than packing that as a kernel module.

Good luck with your assignment.

你与清晨阳光 2024-07-23 16:16:46

我认为询问如何使 UDP 可靠可能是以错误的方式解决这个问题。 根据定义,UDP 或多或少是不可靠的——事实上。 您无法使协议的操作系统端实现更加“可靠”。

许多使用 UDP 的应用程序之所以使用它,是因为它们需要 UDP 的低开销、低延迟特性,而不是 TCP 的精确可靠性。 但几乎所有这些应用程序仍然需要某种机制来验证某些类型消息的端到端接收,甚至可能重新组装和/或初始握手。 例如,考虑 VoIP 电话中的 SIP; TCP 的潜在三向握手和非常渐进的拥塞控制对于良好的呼叫建立时间或 QoS 来说实际上是不可接受的,但肯定需要某种确认消息的方式(这就是 SIP 术语中临时响应的用途)。 或者在线游戏使用的各种协议——基本思想相同。

即使没有明确说明,该作业的真正意图很可能并不是要使 UDP 可靠,而是创建一个使用 UDP 的简单程序在其自己的通信方案中具有一些原始的可靠性抽象层,可以说封装在UDP中。

I think asking how to make UDP reliable may be approaching the question the wrong way. UDP is unreliable more or less by definition - ipso facto. You aren't going to get anywhere making the OS-side implementation of the protocol more "reliable."

A great many applications that use UDP use it because they need the low-overhead, low-latency nature of it much more than they need the precise reliability of TCP. But almost all of these applications still need some mechanism for verifying end-to-end receipt of certain types of messages, and perhaps even reassembly and/or initial handshaking. Think about SIP in VoIP telephony, for example; TCP's latent three-way handshake and very gradual congestion control aren't really acceptable for decent call setup time or QoS, but some way of acknowledging messages is definitely needed (that's what provisional responses are for, in SIP terminology). Or various protocols in use by online games -- same basic idea.

It is very likely that the real intent of the assignment - even if is not stated clearly - is not so much to make UDP reliable as to create a simple program that uses UDP and has some primitive reliability abstraction layer within its own communication scheme, encapsulated in UDP as it were.

贱贱哒 2024-07-23 16:16:46

我经常使用 UDP,而我最终看到的主要“可靠性”问题是丢失数据包(特别是在碎片 IP 数据包中)。 通过防止碎片(添加一个将数据报切成 IP 大小的块的层)以及让recipeint 检测并请求重新发送丢失的“块”,您可能可以完成 90% 需要完成的工作。

然而,TCP 正是为这种事情而发明的。 UDP 最适合用于时间敏感的数据,无论如何重新发送这些数据都会过时。

有一个网络拓扑解决方案。 只需安排好一切,以免发生任何冲突(LAN 上丢失数据包的第一大来源)。 以下是我为使 UDP 可靠而所做的工作:

  • 一个客户端和服务器放在专用以太网链路上(可能是它们之间的交换机,但其专用 LAN 上没有其他系统)。
  • 在 UDP LAN 上保持严格的客户端-服务器通信协议。 除非响应客户端,否则服务器永远不允许进行对话。
  • 关闭该 UDP 链接上的所有外部网络垃圾(Netbios 等)。
  • 将两端的 ARP 表项设为静态(这样 ARP 就不会每 10 分钟干扰一次)。

(注意:最后一项特别重要。在许多系统上,引起 ARP 请求的 IP 数据包只是被丢弃,而不是在 ARP 解析后发送)。

I use UDP a lot, and the main "reliability" issue I end up seeing is lost packets (particularly in fragmented IP packets). You could probably do 90% of what needs to be done by preventing fragmenting (add a layer that chops up datagrams into IP-sized chunks), and by having the recipeint detect and request resends for lost "chunks".

However, this kind of thing is really what TCP was invented for. UDP is best used for time-sensitive data that would be stale on a resend anyway.

There is a network topological solution. Just arrange things so that there can't be any collisions (the #1 source of lost packets on a LAN). Here's what we do where I work to make UDP reliable:

  • Put one client and server on a dedicated ethernet link (perhaps a switch between them, but no other systems on their private LAN).
  • Keep a strict client-server communications protocol on the UDP LAN. The server is never allowed to talk, except in response to the client.
  • Turn off all exteranious networking garbage on that UDP link (Netbios, etc).
  • Make ARP entries on both ends static (so ARP won't interfere once every 10 minutes).

(Note: The last one is particularly important. On many systems IP packets that cause an ARP request are just thrown away, rather than sent after ARP is resolved).

淡淡離愁欲言轉身 2024-07-23 16:16:46

将 TCP 覆盖在 UDP 之上,就像 TCP 已经做的那样。 “可靠的 UDP”是一个矛盾的说法。 它不是被设计成这样的。

Overlay TCP on top of UDP, as TCP already does. 'Reliable UDP' is an oxymoron. It's not designed to be such.

裂开嘴轻声笑有多痛 2024-07-23 16:16:46

如果您绝对需要基于消息的传输层协议,可以在其中关闭一些 TCP 可靠性功能(例如队头阻塞),请查看 SCTP。 该 API 甚至具有“UDP 模式” 掩盖了底层的连接。

它仍然是一项正在进行的工作,因此您不能指望用户拥有它 - 但如果您只需要您维护的计算机,那么它应该没问题。 它在 各种风格的 unix 中实现,尽管 FreeBSD 是大部分开发工作发生的地方。 YMMV。

If you absolutely need a message-based transport layer protocol where you can turn off some of the TCP reliability features like head-of-line blocking, check out SCTP. The API even has a "UDP mode" that masks the underlying connections.

It's still a work in progress, so you can't expect users to have it -- but if you only need it for computers you maintain, it should be fine. It's implemented in various flavors of unix, though FreeBSD is where most of the development work happens. YMMV.

云裳 2024-07-23 16:16:46

如果您想了解有关如何修改 Linux 内核的更多信息,我的第一反应是搜索“linux kernel”,甚至可能向其中添加“socket”。 Linux Kernel 网站看起来可能还有其他一些线索供您关注。

我的建议是

1) 看看 UDP 在 Linux 中是如何实现的
2)看看RUDP是如何实现的(正如有人已经提到的)
3)...(你让魔法在这里发生)
4)利润! 呃……作业完成了!

If you want more information on how to modify the Linux Kernel, my first response is to google "linux kernel" and maybe even add "socket" to it. The Linux Kernel website looks like it might have some other leads for you to follow.

My suggestions are that

1) Look at how UDP is implemented in Linux
2) Look at how RUDP is implemented (as somebody already mentioned)
3) ... (you make magic happen here)
4) Profit! err... Finished Homework!

幸福%小乖 2024-07-23 16:16:46

我不确定是否有一种简单的方法可以通过新模块修改现有 UDP 代码的行为。

更简单的是采用 UDP 代码 (net/ipv4/udp.c) 并使用新的 IP 协议号创建一个新模块,并修改此代码以实现可靠的 UDP 协议。 您将需要重命名所有外部符号,以便名称不会与现有符号冲突,找出它注册协议号 (17) 的位置并进行更改,然后更新 Makefile 来构建新模块,并可能在其中添加一个条目Kconfig。

查看 /etc/protocols 看看已经分配了哪些协议 ID。

编辑:看起来 udp.c 无法构建为模块。 您将需要查看一些其他协议(例如 ipip.c 或 ip_gre.c)以了解如何将代码放入模块中。

I'm not sure that there is a simple way to modify the behaviour of the existing UDP code via a new module.

What would be simpler is to take the UDP code (net/ipv4/udp.c) and create a new module with a new IP protocol number, and modify this code to implement your reliable UDP protocol. You will need to rename all the external symbols so the names dont clash with the existing symbols, find out where it registers the protocol number (17) and change that, and then update the Makefile to build your new module and probably put an entry in Kconfig.

Have a look in /etc/protocols to see what protocol IDs are allocated already.

Edit: It looks like that udp.c cannot be built as a module. You will need to look at some of the other protocols (such as ipip.c or ip_gre.c) to see how to make your code into a module.

生来就爱笑 2024-07-23 16:16:46

说实话,我想知道这是否是一个棘手的问题。 需要两方进行通信,并且您所做的任何事情都绝对无法确保发送者知道(或关心)您希望它重新发送数据包,除非您已经建立了一个协议来传达此愿望。 如果UDP本身可以做到这一点,我强烈怀疑内核已经支持它。

剩下的就是识别并实现一个实现新协议的模块。 这没有什么问题,其他人已经给了你建议,我确信你可以使用 UDP 实现来处理实际的数据包传输。 但请记住,它是新协议的实现,而不仅仅是稍微改变 UDP 以获得新功能。

To be honest I wonder if this is a trick question. It takes two parties to communicate and absolutely nothing you do can ensure the sender knows (or cares) that you want it to resend a packet unless you have already established a protocol to communicate this wish. If UDP itself can do this, I strongly suspect the kernel already supports it.

What you're left with is identifying and implementing a module that implements a new protocol. There's nothing wrong with that, others have already given you suggestions, and I'm sure that you can use the UDP implementation to handle the actual packet transport. But just remember that it's an implementation of a new protocol, not just twisting UDP a little to get new functionality in it.

魔法唧唧 2024-07-23 16:16:46

您可能会陷入“可靠”这个概念。 您是否清楚地知道您所说的技术术语到底是什么意思? (或者,更相关的是,我想,你的导师所说的意思是什么。)

当你准确地了解一个协议必须具备哪些特征才能使你称之为可靠时,这可能会为你的工作提供指导。作为最低要求,而不是迷失在功能更齐全的现实世界实现中,还可以使完成作业变得更加可行。

Possibly what you may be getting stuck on is the concept 'reliable'. Do you have a clear concept of what, exactly, in technical terms, you mean by that? (Or, more relevantly I suppose, what your instructor means by it.)

When you have a precise idea of what characteristics a protocol has to have for you to call it reliable, that's likely to provide directions for you to work in. Building to that as a minimal requirement, rather than getting lost in more fully-featured real-world implementations, may also make completing your homework more feasible.

情绪操控生活 2024-07-23 16:16:46

您需要考虑可靠意味着什么。 此外,您还需要决定是否需要按顺序排列数据包,或者是否可以按顺序排列数据包。 如果乱序是可以的,你需要想出一个 ACK​​、重传和超时方案。 您还需要决定是否要处理数据包碎片。 如果您可以避免这种情况,您可能需要限制数据包的大小以防止碎片。

You need to think about what reliable means. Also you need to decide if you need the packets in order or if out of order is ok. If out of order is ok you need to come up with an ACK, re-transmit, and timeout scheme. Also you need to decide if you are going to handle packet fragmentation. If you can get away with it yo might want to limit the size of a packet to prevent fragmentation.

冬天旳寂寞 2024-07-23 16:16:46

如果您想要可靠的 UDP,最好的选择是使用 SCTP(流控制传输协议) 。 它现在已成为到处使用的成熟协议。

If you want a reliable UDP, your best choice is to use the SCTP (Stream Control Transmission Protocol). It is now a well-established protocol used everywhere.

生生漫 2024-07-23 16:16:46

如果出于某种原因您必须使用 UDP(说真的,只需使用 TCP),一些快速且简单的可靠性功能将是存在心跳、确认和异或校验和。

If for some reason you MUST use UDP (seriously, just use TCP) some quick and easy reliability features would be a presence heartbeat, acks, and xor'ed checksums.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文