diff options
Diffstat (limited to 'p11p-daemon/src/p11p_server.erl')
-rw-r--r-- | p11p-daemon/src/p11p_server.erl | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/p11p-daemon/src/p11p_server.erl b/p11p-daemon/src/p11p_server.erl index 668a51c..ff1a8df 100644 --- a/p11p-daemon/src/p11p_server.erl +++ b/p11p-daemon/src/p11p_server.erl @@ -37,27 +37,27 @@ add_to_clientbuf(Pid, Data) -> -spec reply(pid(), p11rpc_msg()) -> {ok, non_neg_integer()}. reply(Pid, Response) -> - gen_server:call(Pid, {response, Response}). + gen_server:call(Pid, {respond, Response}). %% Genserver callbacks. init([Token, Socket]) -> lager:debug("~p: p11p_server:init", [self()]), - process_flag(trap_exit, true), % We want terminate(). - gen_server:cast(self(), accept), % Perform accept in gen-server loop. + process_flag(trap_exit, true), % Need terminate/2. + gen_server:cast(self(), accept), % Invoke accept, returning a socket in state. {ok, #state{tokname = Token, socket = Socket}}. -handle_call({add_to_clientbuf, Data}, _From, #state{clientbuf = Buf} = State) -> - NewBuf = <<Buf/binary, Data/binary>>, - {reply, {ok, size(NewBuf)}, State#state{clientbuf = NewBuf}}; -handle_call({response, Response}, _From, #state{socket = ClientPort, clientbuf = Buf} = State) -> - Data = p11p_rpc:serialise(Response), - NewBuf = <<Buf/binary, Data/binary>>, - %%lager:debug("~p: sending ~B octets back to client as reply", [self(), size(NewBuf)]), - ok = gen_tcp:send(ClientPort, NewBuf), % TODO: what about short writes? - {reply, {ok, size(NewBuf)}, State#state{clientbuf = <<>>}}; -handle_call(Call, _From, State) -> +handle_call({add_to_clientbuf, Data}, _, #state{clientbuf = B} = S) -> + Buf = <<B/binary, Data/binary>>, + {reply, {ok, size(Buf)}, S#state{clientbuf = Buf}}; +handle_call({respond, R}, _, #state{socket = Client, clientbuf = B} = S) -> + Data = p11p_rpc:serialise(R), + Buf = <<B/binary, Data/binary>>, + %%lager:debug("~p: sending ~B octets to client as response", [self(), size(Buf)]), + ok = gen_tcp:send(Client, Buf), % TODO: what about short writes? + {reply, {ok, size(Buf)}, S#state{clientbuf = <<>>}}; +handle_call(Call, _, S) -> lager:debug("~p: Unhandled call: ~p~n", [self(), Call]), - {reply, unhandled, State}. + {reply, unhandled, S}. handle_cast(accept, State = #state{tokname = TokName, socket = ListenSocket}) -> %% Blocking until client connects or timeout fires. @@ -80,25 +80,26 @@ handle_cast(Cast, State) -> lager:debug("~p: Unhandled cast: ~p~n", [self(), Cast]), {noreply, State}. -handle_info({tcp, _Port, Data}, #state{tokname = TokName, remote = Remote} = State) when Remote == undefined -> +handle_info({tcp, _Port, DataIn}, #state{tokname = TokName} = S) + when S#state.remote == undefined -> %%lager:debug("~p: received ~B octets from client on socket ~p, from new client", [self(), size(Data), Port]), - <<Version:8, NewData/binary>> = Data, - NewRemote = p11p_remote_manager:remote_for_token(TokName), - p11p_remote:add_to_outbuf(NewRemote, <<Version>>), - NewState = State#state{remote = NewRemote}, - {noreply, handle_client_data(NewState, p11p_rpc:new(), NewData)}; -handle_info({tcp, _Port, Data}, #state{msg = Msg} = State) -> + <<Version:8, Data/binary>> = DataIn, + Remote = p11p_remote_manager:remote_for_token(TokName), + p11p_remote:add_to_outbuf(Remote, <<Version>>), + State = S#state{remote = Remote}, + {noreply, handle_client_data(State, p11p_rpc:new(), Data)}; +handle_info({tcp, _Port, DataIn}, #state{msg = Msg} = S) -> %%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)]), - {noreply, handle_client_data(State, Msg, Data)}; -handle_info({tcp_closed, Port}, State) -> + {noreply, handle_client_data(S, Msg, DataIn)}; +handle_info({tcp_closed, Port}, S) -> lager:debug("~p: socket ~p closed", [self(), Port]), - {stop, normal, State}; -handle_info(Info, State) -> + {stop, normal, S}; +handle_info(Info, S) -> lager:debug("~p: Unhandled info: ~p~n", [self(), Info]), - {noreply, State}. + {noreply, S}. -terminate(Reason, #state{socket = Socket, tokname = TokName, remote = Remote}) -> - gen_tcp:close(Socket), +terminate(Reason, #state{socket = Sock, tokname = TokName, remote = Remote}) -> + gen_tcp:close(Sock), p11p_remote_manager:client_event(client_gone, [TokName, Remote]), lager:debug("~p: terminated with reason ~p", [self(), Reason]), ignored. @@ -107,11 +108,11 @@ code_change(_OldVersion, State, _Extra) -> {ok, State}. %% Private functions. -handle_client_data(#state{remote = Remote} = State, Msg, Data) -> - case p11p_rpc:parse(Msg, Data) of - {done, NewMsg} -> - ok = p11p_remote:request(Remote, NewMsg), - State#state{msg = p11p_rpc:new(NewMsg#p11rpc_msg.buffer)}; - {needmore, NewMsg} -> - State#state{msg = NewMsg} +handle_client_data(#state{remote = Remote} = S, MsgIn, DataIn) -> + case p11p_rpc:parse(MsgIn, DataIn) of + {done, Msg} -> + ok = p11p_remote:request(Remote, Msg), + S#state{msg = p11p_rpc:new(Msg#p11rpc_msg.buffer)}; + {needmore, Msg} -> + S#state{msg = Msg} end. |