diff options
author | Linus Nordberg <linus@sunet.se> | 2019-06-28 14:17:55 +0200 |
---|---|---|
committer | Linus Nordberg <linus@sunet.se> | 2019-06-28 14:17:55 +0200 |
commit | f829ef06f81d5a8642ebaff7b6bb01c1483a86a7 (patch) | |
tree | 4ec6394d08806f43d2d1f0cdb11ce28aab4039dd /p11p-daemon/src | |
parent | 91911b2816f79b5526f9b437906c7fcf5e7dd9be (diff) |
parse rpc requests and don't send until we've got a full request
Diffstat (limited to 'p11p-daemon/src')
-rw-r--r-- | p11p-daemon/src/p11p_server.erl | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/p11p-daemon/src/p11p_server.erl b/p11p-daemon/src/p11p_server.erl index 4009c72..ea49219 100644 --- a/p11p-daemon/src/p11p_server.erl +++ b/p11p-daemon/src/p11p_server.erl @@ -4,6 +4,8 @@ -module(p11p_server). -behaviour(gen_server). +-include("p11p-rpc.hrl"). + %% API. -export([start_link/1]). -export([reply/2]). @@ -16,7 +18,8 @@ -record(state, { tokname :: string(), sockpath :: string(), % FIXME: filename(3erl) - socket :: gen_tcp:socket() + socket :: gen_tcp:socket(), + msg :: p11rpc_msg() | undefined }). %% API. @@ -36,15 +39,14 @@ init([Token, SocketPath, Socket]) -> handle_call(Request, _From, State) -> - lager:debug("Unhandled call: ~p~n", [Request]), + lager:debug("~p: Unhandled call: ~p~n", [self(), Request]), {reply, unhandled, State}. handle_cast(accept, State = #state{tokname = TokName, sockpath = SocketPath, socket = ListenSocket}) -> - %% Blocking until client connects or timeout fires. Without a + %% Blocking until client connects or timeout fires -- without a %% timeout our supervisor cannot terminate us. case gen_tcp:accept(ListenSocket, 900) of {ok, Sock} -> - %% TODO: authz lager:debug("~p: ~p: new connection accepted", [self(), Sock]), p11p_server_sup:start_server([TokName, SocketPath, ListenSocket]), % Start a new acceptor. {noreply, State#state{socket = Sock}}; % Use the new socket. @@ -59,18 +61,23 @@ handle_cast({response, Data}, #state{socket = ClientPort} = State) -> lager:debug("~p: received ~B octets from remote", [self(), length(Data)]), ok = gen_tcp:send(ClientPort, Data), {noreply, State}; -handle_cast(Request, State) -> - lager:debug("Unhandled cast: ~p~n", [Request]), +handle_cast(Cast, State) -> + lager:debug("~p: Unhandled cast: ~p~n", [self(), Cast]), {noreply, State}. -handle_info({tcp, Port, Data}, #state{tokname = TokName} = State) -> - lager:debug("~p: received ~B octets from client on socket ~p", - [self(), length(binary_to_list(Data)), Port]), - %% TODO: parse incoming data, start timer per p11 request and - %% cancel after full response - Remote = p11p_remote_manager:remote_for_token(TokName), - ok = p11p_remote:send(self(), Remote, Data), - {noreply, State}; +handle_info({tcp, Port, Data}, #state{tokname = TokName, msg = Msg} = State) when Msg == undefined -> + lager:debug("~p: received ~B octets from client on socket ~p, from new client", + [self(), size(Data), Port]), + <<Version:8, NewData/binary>> = Data, + %% FIXME: don't send, just add to outbuf + ok = p11p_remote:send(self(), p11p_remote_manager:remote_for_token(TokName), <<Version>>), + NewState = handle_client_data(State, p11p_rpc:new(), NewData), + {noreply, NewState}; +handle_info({tcp, Port, Data}, #state{msg = Msg} = State) -> + lager:debug("~p: received ~B octets from client on socket ~p, with ~B octets already in buffer", + [self(), size(Data), Port, size(Msg#p11rpc_msg.buffer)]), + NewState = handle_client_data(State, Msg, Data), + {noreply, NewState}; handle_info({tcp_closed, Port}, State) -> lager:debug("~p: socket ~p closed", [self(), Port]), {stop, {shutdown, close_by_client}, State}; @@ -87,3 +94,12 @@ code_change(_OldVersion, State, _Extra) -> {ok, State}. %% Private functions. +handle_client_data(#state{tokname = TokName} = State, Msg, Data) -> + case p11p_rpc:parse(Msg, Data) of + {done, NewMsg} -> + Remote = p11p_remote_manager:remote_for_token(TokName), + ok = p11p_remote:send(self(), Remote, p11p_rpc:serialise(NewMsg)), + State#state{msg = p11p_rpc:new(NewMsg#p11rpc_msg.buffer)}; + {needmore, NewMsg} -> + State#state{msg = NewMsg} + end. |