Marek Küthe 4ab39a2e9e Add problem description | преди 8 месеца | |
---|---|---|
src | преди 8 месеца | |
.gitignore | преди 8 месеца | |
LICENSE | преди 8 месеца | |
README.md | преди 8 месеца |
My program should simultaneously read packets from a generated TAP device and process them. For this I use the tuntap library from LaKabane together with Boost.Asio's posix::stream_descriptor
.
However, since I am acting as a client and not a server, there is no option to accept packets asynchronously.
The proviorical solution I have chosen is to read asynchronously again and again. However, there are two major problems with this:
sudo ping -f ff02::1%test
.The following is my code so far:
#include <iostream>
#include <cstdlib>
#include <boost/asio.hpp>
#include <unistd.h>
#include "tun_tap.hpp"
void handle_packet([[maybe_unused]] const boost::system::error_code& error, [[maybe_unused]] std::size_t bytes_transferred, [[maybe_unused]] const std::array<char, 1520>& buffer)
{
if (error)
{
std::clog << "Error in handle_packet: " << error.message() << std::endl;
return;
}
std::clog << "Received packet of size: " << bytes_transferred << std::endl;
std::clog << std::flush;
// To something with the packet
sleep(5);
}
void start(boost::asio::posix::stream_descriptor& tap_device)
{
std::array<char, 1520> buffer;
tap_device.async_read_some(boost::asio::buffer(buffer),
[&](const boost::system::error_code& error, std::size_t bytes_transferred) {
start(tap_device);
handle_packet(error, bytes_transferred, buffer);
});
}
int main() {
try {
boost::asio::io_context io;
const ::size_t mtu = 1500;
std::clog << "Create TUN device." << std::endl;
tun_tap dev = tun_tap("test", tun_tap_mode::tap);
std::clog << "Set MTU to " << mtu << "." << std::endl;
dev.set_mtu(1500);
std::clog << "Set the TUN device up." << std::endl;
dev.up();
boost::asio::posix::stream_descriptor tap_device(io, ::dup(dev.native_handler()));
start(tap_device);
io.run();
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl << "Exit program.";
::exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
My question now is, how can I read from the TAP device with Boost.Asio without losing packets?
$ meson setup src build
$ meson compile -C build
# ./build/cpp_tap_device