Назад | Перейти на главную страницу

Невозможно создать сеть сокетов QEMU на узле Windows с помощью сбоев многоадресной рассылки с неизвестной ошибкой

Я пытаюсь создать смоделированную VLAN с использованием сети сокетов, и единственный способ подключить несколько виртуальных машин в одной сети в QEMU с помощью сети сокетов - использовать многоадресную рассылку 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 (например, ожидание запуска многоадресного прослушивателя и т. Д.)?

Кстати, я использую Windows 10 и использую кросс-скомпилированный QEMU 4.2.0. Я распечатал ошибку прямо перед неудачей при привязке net/socket.c исходного кода QEMU в строке 256 и WSAGetLastError возвращается WSAEADDRNOTAVAIL.

Судя по всему, в 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, но я считаю, что оно будет работать и в других операционных системах.