Erlang:识别协议而不消耗套接字中的数据

  发布于 2022-12-13 19:35

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

遗憾的是,协议升级设计不正确,因此在较旧的协议中切换到较新的协议或版本控制中的"升级协议"选项,新协议是普通的TLS连接(较旧的是普通的TCP请求 - 响应行导向的) ).

现有的C实现用于recvmsg(MSG_PEEK)从连接开始嗅探几个字节,然后将套接字传递给其中一个处理程序.Erlang没有公开功能以"偷看"到套接字而不从中读取.

如何在Erlang中有效地做到这一点?

我想出了一些想法,但没有一个看起来令人满意:

一个小型的C前端服务器,它嗅探协议并调度到Erlang中的一个端点.缺点:使部署复杂化.

暴露MSG_PEEK于NIF.缺点:recvmsg可能会阻塞,这会对调度程序造成严重破坏.

从套接字读取,然后在自定义套接字模块中重放完整数据(使用cb_infoSSL套接字选项).缺点:使用纯Erlang来回代理数据会使实现变得复杂并减慢速度.

Steve Vinosk.. 6

要考虑的是首先通过读取几个字节gen_tcp:recv/2,3,检查数据以决定您正在处理哪个协议,然后使用未记录的gen_tcp:unrecv/2函数将接收的数据推回到套接字中.像这样的东西:

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

其中,decide_which_protocol/1handle_this_socket/1函数代表您自己的逻辑,用于检测和处理两个协议,并ProtocolHandler代表处理不同协议的不同模块.确保套接字处于{active,false}此模式.如果代码检测到较新的基于TLS的协议,则可以按照此处的说明将TCP套接字升级到TLS (搜索"升级示例").

1 个回答
  • 要考虑的是首先通过读取几个字节gen_tcp:recv/2,3,检查数据以决定您正在处理哪个协议,然后使用未记录的gen_tcp:unrecv/2函数将接收的数据推回到套接字中.像这样的东西:

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

    其中,decide_which_protocol/1handle_this_socket/1函数代表您自己的逻辑,用于检测和处理两个协议,并ProtocolHandler代表处理不同协议的不同模块.确保套接字处于{active,false}此模式.如果代码检测到较新的基于TLS的协议,则可以按照此处的说明将TCP套接字升级到TLS (搜索"升级示例").

    2022-12-13 19:39 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有