Erlang:在不使用套接字数据的情况下识别协议

Erlang:在不使用套接字数据的情况下识别协议,erlang,Erlang,我需要在Erlang中的单个侦听套接字上处理两个不兼容的协议版本 不幸的是,协议升级设计不正确,因此新协议不是切换到新协议或版本控制的旧协议中的升级协议选项,而是一个普通TLS连接,旧协议是一个面向普通TCP请求-响应行的协议 现有的C实现使用recvmsgMSG_PEEK从连接开始嗅探几个字节,然后将套接字传递给其中一个处理程序。Erlang不会在不读取套接字的情况下公开窥视套接字的功能 如何在Erlang中有效地实现这一点 我提出了一些想法,但似乎没有一个令人满意: 一个小型的C前端服务器,

我需要在Erlang中的单个侦听套接字上处理两个不兼容的协议版本

不幸的是,协议升级设计不正确,因此新协议不是切换到新协议或版本控制的旧协议中的升级协议选项,而是一个普通TLS连接,旧协议是一个面向普通TCP请求-响应行的协议

现有的C实现使用recvmsgMSG_PEEK从连接开始嗅探几个字节,然后将套接字传递给其中一个处理程序。Erlang不会在不读取套接字的情况下公开窥视套接字的功能

如何在Erlang中有效地实现这一点

我提出了一些想法,但似乎没有一个令人满意:

一个小型的C前端服务器,它嗅探协议并发送到Erlang中的一个端点。缺点:使部署复杂化。 在NIF中暴露MSG_PEEK。缺点:recvmsg可能会阻塞,这会对调度程序造成严重破坏。 从套接字读取数据,然后使用SSL套接字的cb_info选项在自定义套接字类模块中重播完整数据。缺点:使用纯粹的Erlang来回代理数据会使实现变得复杂和缓慢。

要考虑的是首先通过读取几个字节,检查数据来决定你正在处理的协议,然后使用它将接收到的数据推回到套接字中。大概是这样的:

{ok, Data} = gen_tcp:recv(Socket, NumberOfBytesToRead),
ProtocolHandler = decide_which_protocol(Data),
gen_tcp:unrecv(Socket, Data),
ProtocolHandler:handle_this_socket(Socket).

其中,decision_哪个协议/1和handle_this_socket/1函数表示您自己检测和处理两个协议的逻辑,ProtocolHandler表示处理不同协议的不同模块。为此,请确保套接字处于{active,false}模式。如果代码检测到新的基于TLS的协议,那么可以将TCP套接字升级为TLS AS。

< P>要考虑的是首先通过读取几个字节,检查数据以决定您正在处理的协议,然后使用该方法将接收到的数据推回到套接字中。大概是这样的:

{ok, Data} = gen_tcp:recv(Socket, NumberOfBytesToRead),
ProtocolHandler = decide_which_protocol(Data),
gen_tcp:unrecv(Socket, Data),
ProtocolHandler:handle_this_socket(Socket).

其中,decision_哪个协议/1和handle_this_socket/1函数表示您自己检测和处理两个协议的逻辑,ProtocolHandler表示处理不同协议的不同模块。为此,请确保套接字处于{active,false}模式。如果代码检测到较新的基于TLS的协议,那么您可以将TCP套接字升级为TLS。

我不明白您的解释中有什么阻止您模仿C实现,模式匹配通常非常适合此工作。您的问题不清楚较旧的协议是否仅为TCP,而较新的协议是否为TLS,或者他们都是TLS?C代码只是执行常规的侦听/接受,然后在嗅探后升级到TLS吗?@Pascal Erlang不提供任何方法来窥视流而不从流中读取。@SteveVinoski旧代码是纯TCP请求-响应代码。我已经更新了这个问题。@SteveVinoski是的,较旧的代码确实侦听/接受、recvmsgMSG_PEEK并启动较旧的请求-响应协议或TLS会话。在您的解释中,我不明白是什么阻止您模仿C实现,模式匹配通常非常适合这项工作。从您的问题中不清楚较旧的协议是仅TCP协议还是较新的TLS协议,或者它们都是TLS协议?C代码只是执行常规的侦听/接受,然后在嗅探后升级到TLS吗?@Pascal Erlang不提供任何方法来窥视流而不从流中读取。@SteveVinoski旧代码是纯TCP请求-响应代码。我已经更新了这个问题。@SteveVinoski是的,较旧的代码确实在侦听/接受、recvmsgMSG_PEEK并启动较旧的请求-响应协议或TLS会话。unrecv正是需要的。非常感谢你!unrecv正是我们所需要的。非常感谢你!