Можно ли обернуть существующий сеанс TCP / OpenSSL с помощью `iostream`? - PullRequest
0 голосов
/ 02 ноября 2018

Я использую пользовательский код для создания SSL-соединения через собственный интерфейс сокетов Беркли. Мне нужно обернуть полученный сокет iostream, чтобы использовать существующие алгоритмы, написанные на C ++, с этими данными сокетов.

Есть ли простой способ сделать это без необходимости внедрять stream и streambuf с нуля?

Я выучил boost::iostreams и boost::asio.

Я не нашел способа обернуть существующий сеанс OpenSSL с boost::asio. Или, может быть, кто-нибудь знает, как это сделать?

После boost:asio я сосредоточил свои исследования на boost:iostreams.

boost::iostreams выглядит хорошей идеей, однако проблема в том, что он использует буферизацию чтения. Таким образом, если нам нужно прочитать только 1 байт из сеанса SSL, он просит устройство TCP прочитать 4 килобайта, что приводит к тайм-ауту. С другой стороны, когда я устанавливаю размер буфера 0, boost::iostreams начинает вызывать метод write для каждого байта, поэтому, когда я пытаюсь записать 10 байтов в поток, он вызывает SSL_write 10 раз. Само устройство TCP не может использовать буферизацию записи, поскольку нет способа перенаправить метод flush на устройство, поэтому протокол уровня приложения может ожидать, что данные будут отправлены другому узлу, пока данные остаются в буфере вывода.

Итак, нам нужно небуферизованное чтение и буферизованное очищаемое письмо; это возможно с boost::iostreams?

1 Ответ

0 голосов
/ 15 ноября 2018

Я нашел решение сам.

Прежде всего, необходимо пометить устройство как сбрасываемое. Поскольку для такого устройства нет готовых шаблонов, необходимо унаследовать device<dual_use, Ch> и переопределить его категорию множественным наследованием:

struct category : device<dual_use, Ch>::category, flushable_tag

Теперь, когда вы будете звонить flush в потоке, он будет перенаправлять вызов на ваше устройство.

Следующим шагом является отключение собственной буферизации потока (т.е. вызов open с параметрами 2 и 3, равными 0).

В такой конфигурации boost будет записывать на устройство каждый байт данных отдельно. Однако вы можете реализовать буферизацию на уровне устройства и очистить буфер при вызове flush.

...