为什么 vsock 使用 32 位端口号而不是 16 位?

为什么 vsock 使用 32 位端口号而不是 16 位?

在阅读 vsock 规范时,我遇到了下面的引用

套接字地址定义为 32 位上下文标识符 (CID) 和 32 位端口号的组合。

来源:http://man7.org/linux/man-pages/man7/vsock.7.html

我认为我们不能使用高于 65535 的端口号,因为它是一个 16 位值。有谁知道为什么 vsock 使用 32 位端口号?我错过了什么吗?

答案1

我不熟悉这个功能,但在阅读该手册页后,我的猜测是它听起来确实很像 TCP 和 UDP,但并不相同。因此 TCP/UDP 端口限制不适用。 TCP 和 UDP 的地址族是AF_INET

答案2

在 Berkeley Sockets 中,“端口号”的概念始终特定于特定的地址族。AF_INET(IPv4) 和AF_INET6(IPv6) 都使用 16 位端口号,因为这是 TCP/IP 协议栈的标准。端口号属于传输层协议(TCP/UDP/SCTP/DCCP/等),而不是网络层(IP);虽然原则上没有什么可以阻止某人在使用非 16 位端口号(8 位端口号、32 位端口号、可变长度端口号、没有端口号概念)的 IP 网络上运行传输协议。所有),实际上,每个直接在 IP 上运行的广泛使用的传输协议都使用 16 位端口。如果有人想向 Berkeley Sockets 添加对带有非 16 位端口号的不寻常的基于 IP 的协议的支持,他们可能无法使用带有自定义协议号 ( ) 的标准地址族 ( AF_INET, ),他们会可能必须定义一个自定义地址族(嗯,有一些黑客方法可以避免这样做,但这些黑客可能不是一个好主意。)AF_INET6IPPROTO_WHATEVER

但是,尽管AF_INETAF_INET6都有 16 位端口号,但许多其他地址系列却没有。 的定义struct sockaddr取决于每个地址系列。其他一些地址系列有端口号,一些有名称不同的等效概念,一些没有实际等效概念。而在那些有端口号(或等效端口号)的地址系列中,并不要求它们必须是 16 位。

例如,AF_IB(Infiniband) 没有这样的端口号,但近似等效的是服务 ID – 64 位。与 TCP/IP 一样,AF_IPX使用 16 位端口号(尽管 Linux 在 4.18 中放弃了 IPX 支持,并且在此之前很久就放弃了 SPX 支持。)AF_X25根本没有端口号的概念,只有网络地址 (X.121);通过 X.25 支持多个服务的唯一方法是为主机分配多个 X.121 网络地址(每个服务一个),或者在 Berkeley Sockets 层之上使用某种应用程序级多路复用。AF_ISO(有时也称为AF_OSI),传统的 OSI TP 传输协议 (X.224 / ISO 8073),甚至允许端口号 (TSAP) 具有可变的字节数,尽管这是广泛遵循的美国政府标准 (GOSIP / FIPS 146)强制 2 字节 TSAP(因此 16 位就像 TCP/IP 或 IPX/SPX)。 (AF_ISO/AF_OSI从未出现在主线 Linux 中,但包含在 4.4BSD、一些商业 Unix 和一些大型机/小型机操作系统中;请注意,最近的 Linux 内核现在有一个struct sockaddr_iso,但这与传统的 OSI 协议栈无关,那就是实际上用于同步蓝牙地址。)

TIPC(透明进程间通信)是一种设计用于计算机集群中节点之间通信的协议,Linux 内核中包含支持。 TIPC 可以通过 UDP/IP 运行,或者直接通过以太网或 Infiniband 运行。 TIPC ( AF_TIPC, struct sockaddr_tipc) 具有 32 位端口号。如果您通过 UDP 运行它,则 32 位 TIPC 端口号与 16 位 UDP 端口号没有关系; UDP 端口号是在系统管理员配置集群中节点之间的 UDP 链路时确定的,并且对于使用AF_TIPC套接字的应用程序来说是不可见的。

VSOCK 是一种协议,旨在用于AF_VSOCK虚拟机中运行的软件与其运行的虚拟机管理程序之间的通信。由于它仅在单台机器上运行,而不是通过 IP 等网络协议运行,因此没有充分的理由将端口号限制为 16 位。在 32 位架构上,16 位值的性能往往比 32 位值差,除非将它们填充为 32 位;因为为了获得良好的性能,必须将其填充为 32 位,因此您最好一开始就将其设为 32 位。虽然相同的逻辑可能会导致您为了 64 位架构而将它们设为 64 位,但这会在 32 位平台上带来更差的性能,这在设计 VSOCK 时比现在要重要得多; 32 位端口可能足以满足每个人的需求,并且 64 位端口号的边际收益并不能超过 32 位平台的性能缺点。

NoteAF_VSOCK并不是 Linux 内核中用于虚拟机管理程序通信的唯一地址系列。 VSOCK 是由 VMware 发明的,但后来被其他供应商复制,包括 KVM、QEMU 和 Microsoft Hyper-V。 IBM 的 z/VM 管理程序(用于大型机)不使用 VSOCK,它有自己的协议,称为 IUCV,执行相同的功能。 IUCV 比 VSOCK 要老很多——VMware 在 2008 年推出了 VSOCK; IBM 发布了 IUCV 的第一个版本1980年。据我所知,Linux 内核开发团队向所有人明确表示,他们不希望每个单独的虚拟机供应商都为虚拟机管理程序通信定义自己的地址系列,因此其他人都必须使用AF_VSOCKVMware 发明的地址系列; IBM 不受该规则的约束,因为他们的 IUCV 协议早于 VMware 协议,并且寻址完全不兼容。

AF_IUCV地址 ( )不是使用数字端口号,而是struct sockaddr_iucv基于 8 字节空格填充的人类可读字符串(在 EBCDIC 中,尽管在 Linux 下它们在用户空间中是 ASCII,但 ASCII/EBCDIC 转换发生在内核内部。) ,sockaddr_iucv实际上在它的开头有一个32位地址号和16位端口号字段,这些字段是保留的并且始终设置为0。您会发现在Linux上是这样,但是Linux从IBM的大型机操作系统复制了这些保留字段(例如 CMS 和 z/OS),它们在 Berkeley Sockets IUCV 实现中执行相同的操作。我怀疑 IBM 这样做的原因是为了减少错误,如果您不小心将 a 传递sockaddr_iucv给只需要sockaddr_in( AF_INET, IPv4) 的应用程序/库,那么它会被解释为0.0.0.0:0,这会造成比尝试将任意字符串解释为 IPv4 地址和端口。

相关内容