带有Unix.select的OCaml-ssl导致读取错误

时间:2019-05-30 14:30:34

标签: ssl select ocaml

我正在使用SSL通过安全的Websocket从各种远程服务读取数据,如下所示:我创建套接字,将其嵌入SSL上下文中,然后将套接字添加到Unix.select的读取列表中。当套接字触发时,我使用Ssl.read来获取数据。

4个服务运行良好。在收到每个websocket帧(大小约为5-6Kb)后,我得到了Ssl.Read_error.Error_syscall:error:00000000:lib(0):func(0):reason(0)。顺便说一句,这里的框架比其他服务要大得多,但是我不确定这是原因。

我忽略系统调用错误(并且很可能会丢失一些数据),因为帧继续到达。然后,总是在一分钟后,我得到Ssl.Read_error.Error_zero_return:error:00000000:lib(0):func(0):reason(0),这意味着对等方关闭了用于写入的SSL套接字,我必须重新启动该过程,因为不会从此套接字接收新数据。

问题是完全可重复的。同时,此服务的示例以及我自己使用Node.JS进行的测试实现可以​​在数小时内接收到数据,而不会出现任何问题。

我认为我做错了什么,或者设置套接字/ SSL太简单了(见下文)。

我们将不胜感激任何帮助或想法。

let sock = Unix.socket PF_INET SOCK_STREAM 0 in
let laddr = Unix.inet_addr_of_string p.interface in
Unix.bind sock (ADDR_INET (laddr,0));
Unix.connect sock addr;
let (sock, res) =
let req = Bytes.of_string http_request in
if ssl then begin
  Ssl.init ();
  let ctx = create_context TLSv1_2 Client_context in
  let sock = Ssl.embed_socket sock ctx in
  Ssl.connect sock;
  (SslSock sock, (write sock req 0 http_request_len))
end else
  (UnixSock sock, (Unix.write sock req 0 http_request_len))

1 个答案:

答案 0 :(得分:0)

WireShark达到了目的:此“不良”服务在一个tcp数据包中发送了两个websocket帧,其中第二个帧的净荷长度为零。自然,我的Websocket实现不正确地处理了有效载荷为零的帧,从而导致Ping帧丢失和远程服务器关闭TCP连接。