UDP mDNS в MacOS с использованием C, Rust, JVM – пакеты не принимаются

Я сделаю все возможное, чтобы оно было кратким.

  • При реализации протоколов многоадресной DNS я не могу прослушивать многоадресный DNS ни на C, ни на Rust (однако в JVM он работает отлично)
  • Я смотрю сеть с помощью Wireshark
  • Я пробовал отключить брандмауэр, отключить некоторые функции брандмауэра, ничего не помогло.
  • В сети включен IPv6

Вопрос: что может быть причиной невозможности получения многоадресных пакетов в невиртуализированном коде (не JVM)

ОПЕРАЦИОННЫЕ СИСТЕМЫ:

  • MacOS 14.4 (ARM)
  • Windows 11 (ARM ~ VM на Mac)

Код ржавчины: (Не работает)

use std::net::UdpSocket;

fn main() {
    let udp = UdpSocket::bind("[::]:0").expect("Unable to bind!");
    println!("{}", udp.local_addr().unwrap());
    udp.connect("ff02::fb%en0:5353").unwrap();
    let mut buffer = [0; 65000];
    let size = udp.recv(&mut buffer).unwrap();
    println!("Data received: {}", size);
}

Код Kotlin (JVM): Работает

import java.net.DatagramPacket
import java.net.MulticastSocket

fun main() {
    val port = 5353 // Multicast port
    val socket = MulticastSocket(port)
    val buffer = ByteArray(1024)
    val packet = DatagramPacket(buffer, buffer.size)
    println("UDP server listening for multicast packets on ${socket.localSocketAddress}")
    while (true) {
        socket.receive(packet)
        val receivedData = packet.data.copyOf(packet.length)
        val receivedMessage = String(receivedData)
        println("Received message: $receivedMessage")
    }
}

Код C: (Не работает)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define MAX_LEN 1024 // Maximum message length

int main() {
    int sockfd;
    struct sockaddr_in addr;
    struct ip_mreq mreq;
    char buffer[MAX_LEN + 1];
    int bytes_received;

    // Create a UDP socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(addr));

    // Fill in the address structure
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY); // Listen on any interface
    addr.sin_port = htons(12345); // Choose any port number you like

    // Bind the socket to the address
    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // Specify the multicast group to join
    mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.251"); // Multicast group address
    mreq.imr_interface.s_addr = htonl(INADDR_ANY); // Listen on any interface

    // Join the multicast group
    if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    // Receive multicast messages
    while (1) {
        bytes_received = recvfrom(sockfd, buffer, MAX_LEN, 0, NULL, NULL);
        if (bytes_received < 0) {
            perror("recvfrom failed");
            exit(EXIT_FAILURE);
        }
        buffer[bytes_received] = '\0'; // Null-terminate the received data
        printf("Received message: %s\n", buffer);
    }

    // Close the socket
    close(sockfd);

    return 0;
}

Является ли %en0 в адресе, данном Расту UdpSocket::connect, намеренным? Я не думаю, что это действительно так.

eggyal 12.04.2024 16:09

Да, сэр, он предоставляет информацию для маршрутизации на хост (я предполагаю, что это зависит от платформы, поскольку это было разрешено только на MacOS - также проверено с помощью netcat).

Programmer 12.04.2024 16:27

Согласно RFC, идентификатор зоны %en0 действителен только для адресации IPv6 Link-Local (fe80::/10). «Чтобы ограничить этот риск, реализации НЕ ДОЛЖНЫ разрешать использование этого формата, за исключением четко определенных случаев использования, таких как отправка на локальные адреса с префиксом fe80::/10. На момент написания это единственный четко определенный формат. использование известно».

Ron Maupin 12.04.2024 22:05

Интересно... Есть идеи, в чем может быть причина, по которой я не могу слушать mDNS с помощью Rust и C?

Programmer 13.04.2024 01:06

версия c выше получает пакеты ipv4 в присоединенной группе, насчет ржавчины и Java - понятия не имею, что код на разных языках не равен

yvs2014 13.04.2024 10:48

@ yvs2014 yvs2014 на какой ОС вы это тестируете? На моем MacOS код C не получает никаких пакетов.

Programmer 13.04.2024 11:00

в Linux: отправка чего-то многоадресного на записанный ipv4addr:port и получение этого

yvs2014 13.04.2024 11:07

Другое дело, что и как вы это проверяете

yvs2014 13.04.2024 11:10

Что ж, я сравниваю это с тем, что вижу другой трафик на Wireshark, отправленный другими устройствами (Spotify, Homepods и тому подобное), но ни одно из них не поступает в программу с приведенным выше кодом (кроме Kotlin).

Programmer 13.04.2024 11:53

«Другой трафик» — это слишком расплывчато. В примерах на Rust и Kotlin я даже не вижу присоединения к мультикаст-группе, вы думаете, что там сделано неявно?

yvs2014 13.04.2024 11:58

Давайте продолжим обсуждение в чате.

Programmer 13.04.2024 11:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я ответил на аналогичный вопрос (также опубликованный мной, пытаясь прояснить ситуацию): mDNS / Bonjour / UDP 5353 Повторное использование портов

Другие вопросы по теме