使用 SO_REUSEPORT 时,将来自同一客户端的 UDP 数据包传送到同一服务器进程?

Get UDP packets from the same client delivered to the same server process, when using SO_REUSEPORT?

我正在编写一个多进程 UDP 服务器,它使用 SO_REUSEPORT 让多个工作进程侦听同一端口。

有没有办法告诉内核我希望根据数据包的源地址一致地将数据包传送到进程?

(服务器需要根据源地址保存一些状态。将状态保存在进程本地会更容易,而不是必须在进程之间共享状态。)

你应该看看并配置 RPS: Receive Packet Steering:

The first step in determining the target CPU for RPS is to calculate a flow hash over the packet’s addresses or ports (2-tuple or 4-tuple hash depending on the protocol). This serves as a consistent hash of the associated flow of the packet. The hash is either provided by hardware or will be computed in the stack.

...

Each receive hardware queue has an associated list of CPUs to which RPS may enqueue packets for processing. For each received packet, an index into the list is computed from the flow hash modulo the size of the list. The indexed CPU is the target for processing the packet, and the packet is queued to the tail of that CPU’s backlog queue.

...

RPS scales kernel receive processing across CPUs without introducing reordering. The trade-off to sending all packets from the same flow to the same CPU is CPU load imbalance if flows vary in packet rate.

另一种选择是Intel Ethernet Flow Director:

Intel Ethernet FD supports advanced filters that direct received packets to different queues, and enables tight control on flow in the platform. It matches flows and CPU cores where the processing application is running for flow affinity, and supports multiple parameters for flexible flow classification and load balancing. When operating in Application Targeting Routing (ATR) mode, Intel Ethernet FD is essentially the hardware offloaded version of Receive Flow Steering available on Linux* systems, and when running in this mode, Receive Packet Steering and Receive Flow Steering are disabled.

您可以使用带有 SO_ATTACH_REUSEPORT_CBPF 或 SO_ATTACH_REUSEPORT_EBPF socket options 的 BPF 将每个客户端分配给特定的套接字索引,从而获得类似的结果。