defmodule P2pChat.Transport.GenTun do require Logger use Rustler, otp_app: :p2p_chat, crate: "p2pchat_transport_gen_tun" @behaviour GenServer defstruct [:tun_handle] # # Server API # @impl true def init(args) do {:ok, tun_handle} = make_tun_device() state = %__MODULE__{tun_handle: tun_handle} { :ok, state, { :continue, :recv } } end @impl true def handle_continue(:recv, state) do case tun_recv(state.tun_handle) do {:ok, buf} -> Logger.debug("Received #{byte_size(buf)} bytes") {:error, :would_block} -> {} {:error, e} -> Logger.error("Error during receive: #{e}") end {:noreply, state, { :continue, :recv }} end @impl true def handle_call({:recv}, _from, state) do data = tun_recv(state.tun_handle) { :reply, data, state } end # # Client API # def open() do GenServer.start_link(__MODULE__, nil) end # # NIFs # defp make_tun_device(), do: :erlang.nif_error(:nif_not_loaded) defp tun_recv(_handle, _bufsize \\ 2*16), do: :erlang.nif_error(:nif_not_loaded) end