Сокеты: Android для Unity, возможная атака по распределению?

У меня есть клиентское приложение на Android с использованием Java и сервер на моем ноутбуке в игре Unity. Оба находятся в одной сети, и я заставил их подключиться. Однако, когда я отправляю небольшое строковое сообщение с клиента на сервер, сервер блокирует его следующим предупреждением: ReadMessageBlocking: possible allocation attack with a header of 1298494342 bytes. Как мне вообще начинать приблизиться к этому блокпосту?

Для сервера я использую библиотеку Unity Зеркало, которая построена поверх фреймворка Телепатия. Для клиента я следовал клиентской части учебника это.

Этот (от Telepathy) содержит соответствующий метод (ReadMessageBlocking), который выдает это предупреждение. Я попытался установить MaxMessageSize на int.MaxValue (что составляет 2 ГБ), чтобы хотя бы принять сообщение, чтобы я мог проверить его, распечатав его содержимое, но безрезультатно.

У меня нет проблем с ReadMessageBlocking, это не зря. Меня беспокоит: почему мой андроид якобы отправляет заголовок размером 1 ГБ со строкой? Что я могу с этим поделать?

Редактировать: это соответствующая функция, которая отправляет сообщение от клиента (как указано в руководстве, упомянутом ранее).

void sendMessage(final String message) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (null != socket) {
                            PrintWriter out = new PrintWriter(new BufferedWriter(
                                    new OutputStreamWriter(socket.getOutputStream())),
                                    true);
                            out.println(message);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

    }

Для получения сервера (Unity) я ничего не писал. Предупреждение исходит от внутренней функции обработки сообщений Telepathy, которая, я думаю, здесь ПолучениеЦикл.

Я думаю, было бы полезно, если бы вы показали код, который вы используете для отправки и получения сообщения.

derHugo 20.05.2019 11:48

Там я добавил все, что мог. Код приемника сервера очень длинный, и я не думаю, что там есть что-то ценное, поэтому связан. Но я не знаю. Надеюсь, что достаточно.

Tanmay Band 20.05.2019 12:46

Это похоже на код Android С++. Где код Unity С#?

derHugo 20.05.2019 13:10

Я упомянул, что клиент «на Android с использованием Java». Это приложение для Android, которое я написал. Пока сервер на ноуте, а является в Unity C#. Это игра на юнити.

Tanmay Band 20.05.2019 13:14
1
4
420
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы отправляете свой пакет с неправильным заголовком, говоря, что ваш пакет очень большой в заголовке, который затем обнаруживает сервер, потому что он хочет предотвратить перегрузку из нескольких пакетов с отправленными заголовками, говорящими, что он намного больше, чем на самом деле.

Пусть заголовок будет соответствующего размера

I tried setting the MaxMessageSize to int.MaxValue

слишком большой

Я установил его на int.MaxValue в серверная часть, чтобы, по крайней мере, сервер принимать получил сообщение вместо того, чтобы сразу его отбрасывать (поскольку 2 ГБ > заголовок сообщения размером 1 ГБ, который он получает). В противном случае сервер выдает предупреждение и отбрасывает сообщение по адресу соответствующий размер. Я не трогал сообщение или его заголовки. Я вообще-то делать хочу отредактировать заголовок пакета, но не знаю как, вот в чем вопрос.

Tanmay Band 20.05.2019 12:49

Это говорит о том, что серверная часть не была изменена, если она отказывается от соответствующих размеров, я предлагаю некоторый код, который наверняка не сможет проверить, изменена ли серверная часть.

Discord expert 20.05.2019 12:54

Я подозреваю, что мы не на той же странице. Позвольте мне уточнить. MaxMessageSize — это переменная, которая существует в коде сервера и помогает определить максимальный размер сообщений (от клиента), которые сервер может принять. Каждый раз, когда клиент отправляет сообщение, сервер использует эту переменную, чтобы проверить, меньше ли его размер этого размера. По умолчанию для этой переменной установлено значение 16 КБ. Теперь по какой-то загадочной причине клиент отправляет сообщение с заголовком 1 ГБ. Естественно, увидев это, сервер приходит в ярость, поскольку 1 ГБ на все намного больше, чем 16 КБ по умолчанию, и полностью отбрасывает сообщение.

Tanmay Band 20.05.2019 13:09

Поскольку сервер просто отбрасывает, я не мог проверить содержимое того, что он получил. Вот почему я попытался установить максимально возможную переменную, надеясь, что пакет сообщения будет лежать в диапазоне размеров, не будет отброшен, и позвольте мне хотя бы проверить, что такое гигантский ** заголовок. При этом пакет (и его заголовки) я не трогал.

Tanmay Band 20.05.2019 13:11
Ответ принят как подходящий

Я понял. Телепатия (и, соответственно, зеркало) использует массив byte[] для передачи пакетов в обычном формате <size,message>. Это означает, что размер (в байтах) сообщения, которое вы хотите отправить, должен быть указан в массиве сначала, а затем байты фактического содержимого сообщения.

Поскольку я использую Java с другой стороны, DataOutputStream немного упрощает задачу:

DataOutputStream d_out = new DataOutputStream(socket.getOutputStream());
byte [] byte_message = message.getBytes();
d_out.writeInt(byte_message.length);
d_out.write(byte_message);

Поскольку раньше я не использовал DataOutputStream, Телепатия интерпретировала полное содержание сообщения как size и плач. Итак, полный рабочий код Send теперь выглядит так:

void sendMessage(final String message) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (null != socket) {
                            DataOutputStream d_out = new                             
                            DataOutputStream(socket.getOutputStream());
                            byte [] byte_message = message.getBytes();
                            d_out.writeInt(byte_message.length);
                            d_out.write(byte_message);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

    }

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