我正在实现一个gen_server,它作为ssl身份验证服务器的接口。如果收到的数据包错误(例如用户名和密码错误),则ssl服务器会断开连接。连接必须是持久的。
在我的gen_server中,我使用handle_cast / 2打开服务器的ssl连接:
handle_cast(connect, State) ->
......
case ssl:connect(Address, Port, Options, Timeout) of
{ok, NewSocket} ->
{noreply, State#state{socket=NewSocket}};
{error, Reason} ->
gen_server:cast(?SERVER, connect),
{noreply, State#state{socket=undefined}};
然后我等待handle_cast / 2中的其他消息,例如可以使用:
发送 gen_server:cast(Pid, {authenticate, User, Password}).
每当我收到这样的强制转换消息时,我会生成一个新函数,它使用gen_server:call / 3从服务器状态恢复SSL套接字,并将验证消息发送到SSL服务器。如果发送部分返回错误,我尝试重新连接,否则我在套接字上读了一会儿,以确保套接字没有关闭,如果是,我重新连接。
send_auth(_, _, 0) ->
{error, max_num_reached};
send_auth(User, Password, Num) ->
Socket = gen_server:call(?SERVER, socket),
%% also a check that socket is not 'undefined'
case ssl:send(Socket, AuthMessage) of
ok ->
case ssl:recv(Socket, 0, 2000) of
{error, timeout} ->
ok;
_ ->
gen_server:cast(?SERVER, connect),
send_auth(User, Password, Num-1)
end,
{error, closed} ->
gen_server:cast(?SERVER, connect),
send_auth(User, Password, Num-1)
end.
我做了很多测试,但每次,如果一条消息(不是最后一条消息)出错,则实际上不会传递以下消息。
如何授予所有有效的身份验证消息都传递到身份验证服务器?此外,只有在服务器尚未尝试连接的情况下才能确定服务器是否可以连接?否则就像DOS攻击一样!
答案 0 :(得分:0)