Почему многоадресный прием не работает на некоторых устройствах Android?

Похоже, многоадресный прием не работает на некоторых устройствах Android. Я не могу получить многоадресную рассылку с 4 из 13 тестовых устройств. Похоже, что на этих 4 устройствах приложение не отправляет IGMP-запрос на присоединение к многоадресной группе.

Код для получения многоадресной рассылки выглядит так:

WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiManager.WifiLock wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TAG);
WifiManager.MulticastLock multicastLock = wifiManager.createMulticastLock(TAG);
multicastLock.setReferenceCounted(true);

wifiLock.acquire();
multicastLock.acquire();

try {
    MulticastSocket socket = new MulticastSocket(32123);

    InetAddress group = InetAddress.getByName("224.1.2.3");
    socket.joinGroup(group);

    DatagramPacket packet;
    byte[] buf = new byte[256];
    packet = new DatagramPacket(buf, buf.length);

    socket.receive(packet);

    socket.leaveGroup(group);
    socket.close();
} catch (IOException e) {
    e.printStackTrace();
}

multicastLock.release();
wifiLock.release();

Приложение имеет следующие разрешения:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

Чтобы продемонстрировать проблему, я создал небольшой тестовый проект с использованием приведенного выше кода на GitHub: MulticastTest.

Есть ли проблема с моим кодом? Я пропускаю разрешение?

РЕДАКТИРОВАТЬ 1: Эта проблема, похоже, не относится к конкретной версии Android. Я могу воспроизвести поведение на Android 4.x, 5.x и 6.x.

РЕДАКТИРОВАТЬ 2: Есть связанный вопрос.

1 ответ

Решение

Плохие новости: похоже, это связано с уязвимыми устройствами. Здесь нет /proc/net/igmp доступно именно на тех устройствах, которые не могут принимать многоадресный трафик. Как уже ожидалось, это очень вероятно приводит к отсутствию запроса группы присоединения (IP_ADD_MEMBERSHIP).

Мы пробовали использовать Android API Java, сокеты BSD и Boost.Asio. Тот же результат со всеми тремя вариантами.

Мы проверили проблему с приложением под названием Multicast Tester. Это приложение имеет ту же проблему на тех же устройствах, что и наше приложение. IGMP-запрос не отправляется устройством и, конечно, многоадресный трафик не принимается.

В трекере проблем Android есть некоторые открытые и закрытые (со статусами устаревшие и WrongForum) проблемы. Я думаю, что закрытые проблемы помечены как устаревшие /WrongForum, потому что это не проблема в Android, а специфическая для уязвимых устройств (настройка).

Кажется, ядро ​​на затронутых устройствах было собрано с

CONFIG_IP_MULTICAST=n

в файле конфигурации ядра. Вот почему /proc/net/igmp недоступно на затронутых устройствах. Очевидно, он создается только тогда, когда CONFIG_IP_MULTICAST устанавливается, как видно из кода ядра Linux.

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