Хай пиплы! Давно сюда не заходил.
Имеется сервер, который согласно настройкам проксирует tcp-трафик. Имеется
boost::asio::ip::tcp::socket
с подключенным клиентом и объект такого же типа с подключением к проксируемому серверу. Если настройки приложения требуют вмешаться в поток данных, то он модифицируется. Иначе передаётся так как есть.
При требовании модифицировать данные я через
std::weak_ptr< Channel > self = shared_from_this();
socket_.async_read_some( boost::asio::buffer( buffer_ ),
std::bind( &Channel::GetChunkFromSocketHandler,
self,
std::placeholders::_1,
std::placeholders::_2 ) );
беру данные, модифицирую buffer_ или набор из несколько идущих подряд buffer_-ов и передаю в другой socket.
В случае, когда не требуется модифицировать данные, я мог бы просто передавать buffer_ в другой socket. Так я и делаю. Но это неправильно. Хотелось бы не нагружать сервер лишними операциями копирования buffer_ из ядра в user space и обратно. В Linux для этого есть вызов
splice. Тогда я могу связать 2 сокета через пайп в системе и не гонять данные в промежуточный буфер.
Вопрос в том, как это сделать так, чтобы смотрелось красиво вместе с кодом, использующим boost::asio. Вроде бы есть boost::asio::ip::tcp::socket::native, но я не нашел способа, чтобы, не ломая логику работы boost::asio с сокетами, взять у boost::asio::ip::tcp::socket файловый дескриптор и через системные вызовы выполнить задуманное. Идеально написать бы, чтобы была возможность потом под Windows положить рядом похожую логику. Через один и тот же сокет надо уметь передавать как модифицируемые данные, так и данные, проходящие напрямую.