【问题标题】:how to ensure message sending with ssl如何确保使用 ssl 发送消息
【发布时间】:2012-08-25 08:51:39
【问题描述】:

我正在实现一个 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 攻击一样!

【问题讨论】:

    标签: erlang


    【解决方案1】:
    1. 据我所知,系统中只有一个身份验证服务器,为什么不能在 gen_server 的初始化中直接连接到它?如果连接有点可靠,如果连接有任何问题,您可以杀死 gen_server 并让 supervisor 重新启动它。它可能会解决您的 DOS 问题。
    2. 当您使用 send_auth 生成其他进程时,您可以只在参数中传递套接字连接,而不是执行 gen_server 调用。
    3. 为保证交付,您将在协议中添加某种确认。身份验证服务器应回复 send_auth 并确认已收到。 send_auth 应该重试,直到它收到该确认或有一些其他后备行为,以防它永远不会。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-17
      • 2021-08-08
      • 2017-08-19
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 2017-05-31
      • 2019-06-06
      相关资源
      最近更新 更多