无法使用多播在 Windows 主机中创建 QEMU 套接字网络,出现未知错误

无法使用多播在 Windows 主机中创建 QEMU 套接字网络,出现未知错误

我正在尝试使用套接字网络创建一个模拟 VLAN,而在 QEMU 中使用套接字网络连接一个网络中的多个 VM 的唯一方法是使用网络后端mcast的多播选项socket来创建共享总线。

但是,当我尝试在 QEMU 中使用以下参数创建多播套接字网络时:

-device e1000,netdev=sock-0 -netdev id=sock-0,mcast=230.0.0.1:1234

它失败了:

can't bind ip=230.0.0.1 to socket: Unknown error在我的 Windows 主机中。

这是 QEMU 的错误吗,或者我在运行 QEMU 命令之前缺少先决条件(例如期望运行多播侦听器,...等)?

net/socket.c顺便说一句,我使用的是 Windows 10,并且运行的是交叉编译的 QEMU 4.2.0。我在 QEMU 源代码的第 256 行的绑定失败之前打印了错误,然后WSAGetLastError返回WSAEADDRNOTAVAIL

答案1

显然,QEMU 4.2.0 在使用多播的套接字网络中存在错误。它不使用INADDR_ANY(或0.0.0.0) 作为侦听套接字,而是使用用户传入的多播组地址。为了解决这个问题,我更改了以下源代码行net/socket.c(从 256 行更改为 261 行,含):

   ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    if (ret < 0) {
        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
                         inet_ntoa(mcastaddr->sin_addr));
        goto fail;
    }

    struct in_addr group_addr = mcastaddr->sin_addr;
    if (localaddr) {
        mcastaddr->sin_addr = *localaddr;
    } else {
        mcastaddr->sin_addr.s_addr = htonl(INADDR_ANY);
    }
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    if (ret < 0) {
        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
                         inet_ntoa(mcastaddr->sin_addr));
        goto fail;
    }
    mcastaddr->sin_addr = group_addr;

我将把组的地址保存在一个变量中,将套接字地址设置为INADDR_ANY用户传入的本地地址,创建监听套接字,然后恢复为组的地址,以便我稍后可以加入该组。该解决方案适用于 Windows 构建的二进制文件,但我相信它也可以适用于其他操作系统。

相关内容