Add basic forwarding/multiplexing functionality
This commit is contained in:
79
lib/listener.ex
Normal file
79
lib/listener.ex
Normal file
@@ -0,0 +1,79 @@
|
||||
defmodule Frajtano.Listener do
|
||||
require Logger
|
||||
use Task
|
||||
|
||||
def start_link(path) do
|
||||
Task.start_link(__MODULE__, :run, [path])
|
||||
end
|
||||
|
||||
def run(path) do
|
||||
Logger.info("Serving on path #{path}")
|
||||
File.rm(path)
|
||||
{:ok, sock} = :gen_tcp.listen(0, [:binary, active: false, packet: :raw, ifaddr: {:local, path}])
|
||||
loop(sock)
|
||||
end
|
||||
|
||||
def loop(sock) do
|
||||
Logger.info("Accepting connections on #{inspect sock}")
|
||||
{:ok, conn} = :gen_tcp.accept(sock)
|
||||
Frajtano.ClientHandler.start(conn)
|
||||
loop(sock)
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Frajtano.ClientHandler do
|
||||
alias Frajtano.Proto
|
||||
require Logger
|
||||
|
||||
def start(conn) do
|
||||
Logger.info("Got connection: #{inspect conn}")
|
||||
Task.Supervisor.start_child(Frajtano.ClientSupervisor, fn ->
|
||||
:gen_tcp.controlling_process(conn, self())
|
||||
handle(conn, <<>>)
|
||||
end)
|
||||
end
|
||||
|
||||
defp handle(conn, buffer) do
|
||||
Logger.info("Handling connection: #{inspect conn}, buffer: #{inspect buffer}")
|
||||
case Proto.decode(buffer) do
|
||||
{nil, buffer} ->
|
||||
Logger.debug("Need more data")
|
||||
case :gen_tcp.recv(conn, 0) do
|
||||
{:ok, msg} ->
|
||||
Logger.debug("Got more data: #{inspect msg}")
|
||||
handle(conn, buffer <> msg)
|
||||
{:error, :closed} ->
|
||||
nil
|
||||
{:error, error} ->
|
||||
Logger.warning("Got network error: #{inspect error}")
|
||||
end
|
||||
{packet, buffer} ->
|
||||
:gen_tcp.send(conn, Proto.encode(handle_packet(packet)))
|
||||
handle(conn, buffer)
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_packet({:agentc_request_identities, nil}) do
|
||||
Logger.info("Got identities request")
|
||||
case Frajtano.Agent.identities() do
|
||||
{:ok, identities} -> {:agent_identities_answer, identities}
|
||||
{:error, error} ->
|
||||
Logger.warning("Error fetching identities: #{error}")
|
||||
{:agent_failure, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_packet({:agentc_sign_request, request}) do
|
||||
case Frajtano.Agent.sign(request) do
|
||||
{:ok, signature} -> {:agent_sign_response, signature}
|
||||
{:error, error} ->
|
||||
Logger.warning("Error signing: #{error}")
|
||||
{:agent_failure, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_packet({type, body}) do
|
||||
Logger.warning("Can't handle #{type} packet with body #{inspect body}")
|
||||
{:agent_failure, nil}
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user